Skip to content

Commit 0bae326

Browse files
committed
Auto merge of #48419 - bobtwinkles:fix_late_bound_reg_self, r=nikomatsakis
Use free regions when determining self type in `compare_impl_method` The ExplicitSelf::determine function expects to be able to compare regions. However, when the compare_self_type error reporting code runs we haven't resolved bound regions yet. Thus we replace them with free regions first. Fixes #48276
2 parents 2f0e6a3 + c0d41fb commit 0bae326

File tree

3 files changed

+75
-0
lines changed

3 files changed

+75
-0
lines changed

src/librustc_typeck/check/compare_method.rs

+4
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,10 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
504504
let param_env = ty::ParamEnv::empty(Reveal::All);
505505

506506
tcx.infer_ctxt().enter(|infcx| {
507+
let self_arg_ty = tcx.liberate_late_bound_regions(
508+
method.def_id,
509+
&ty::Binder(self_arg_ty)
510+
);
507511
let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok();
508512
match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
509513
ExplicitSelf::ByValue => "self".to_string(),

src/test/ui/issue-48276.rs

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// Regression test for issue #48276 - ICE when self type does not match what is
12+
// required by a trait and regions are involved.
13+
14+
trait MyFrom<A> {
15+
fn from(a: A) -> Self;
16+
}
17+
18+
struct A;
19+
20+
impl<'a, 'b> MyFrom<A> for &'a str {
21+
fn from(self: &'a Self) -> &'b str {
22+
//~^ ERROR: method `from` has a `&self` declaration in the impl, but not in the trait
23+
"asdf"
24+
}
25+
}
26+
27+
struct B;
28+
29+
impl From<A> for B {
30+
fn from(&self) -> B {
31+
//~^ ERROR: method `from` has a `&self` declaration in the impl, but not in the trait
32+
B
33+
}
34+
}
35+
36+
impl From<A> for &'static str {
37+
fn from(&self) -> &'static str {
38+
//~^ ERROR: method `from` has a `&self` declaration in the impl, but not in the trait
39+
""
40+
}
41+
}
42+
43+
fn main(){}

src/test/ui/issue-48276.stderr

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait
2+
--> $DIR/issue-48276.rs:21:5
3+
|
4+
LL | fn from(a: A) -> Self;
5+
| ---------------------- trait method declared without `&self`
6+
...
7+
LL | fn from(self: &'a Self) -> &'b str {
8+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&self` used in impl
9+
10+
error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait
11+
--> $DIR/issue-48276.rs:30:5
12+
|
13+
LL | fn from(&self) -> B {
14+
| ^^^^^^^^^^^^^^^^^^^ `&self` used in impl
15+
|
16+
= note: `from` from trait: `fn(T) -> Self`
17+
18+
error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait
19+
--> $DIR/issue-48276.rs:37:5
20+
|
21+
LL | fn from(&self) -> &'static str {
22+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&self` used in impl
23+
|
24+
= note: `from` from trait: `fn(T) -> Self`
25+
26+
error: aborting due to 3 previous errors
27+
28+
If you want more information on this error, try using "rustc --explain E0185"

0 commit comments

Comments
 (0)