Skip to content

Commit

Permalink
Auto merge of #48419 - bobtwinkles:fix_late_bound_reg_self, r=nikomat…
Browse files Browse the repository at this point in the history
…sakis

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
  • Loading branch information
bors committed Mar 10, 2018
2 parents 2f0e6a3 + c0d41fb commit 0bae326
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/librustc_typeck/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -504,6 +504,10 @@ fn compare_self_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let param_env = ty::ParamEnv::empty(Reveal::All);

tcx.infer_ctxt().enter(|infcx| {
let self_arg_ty = tcx.liberate_late_bound_regions(
method.def_id,
&ty::Binder(self_arg_ty)
);
let can_eq_self = |ty| infcx.can_eq(param_env, untransformed_self_ty, ty).is_ok();
match ExplicitSelf::determine(self_arg_ty, can_eq_self) {
ExplicitSelf::ByValue => "self".to_string(),
Expand Down
43 changes: 43 additions & 0 deletions src/test/ui/issue-48276.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// Regression test for issue #48276 - ICE when self type does not match what is
// required by a trait and regions are involved.

trait MyFrom<A> {
fn from(a: A) -> Self;
}

struct A;

impl<'a, 'b> MyFrom<A> for &'a str {
fn from(self: &'a Self) -> &'b str {
//~^ ERROR: method `from` has a `&self` declaration in the impl, but not in the trait
"asdf"
}
}

struct B;

impl From<A> for B {
fn from(&self) -> B {
//~^ ERROR: method `from` has a `&self` declaration in the impl, but not in the trait
B
}
}

impl From<A> for &'static str {
fn from(&self) -> &'static str {
//~^ ERROR: method `from` has a `&self` declaration in the impl, but not in the trait
""
}
}

fn main(){}
28 changes: 28 additions & 0 deletions src/test/ui/issue-48276.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait
--> $DIR/issue-48276.rs:21:5
|
LL | fn from(a: A) -> Self;
| ---------------------- trait method declared without `&self`
...
LL | fn from(self: &'a Self) -> &'b str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&self` used in impl

error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait
--> $DIR/issue-48276.rs:30:5
|
LL | fn from(&self) -> B {
| ^^^^^^^^^^^^^^^^^^^ `&self` used in impl
|
= note: `from` from trait: `fn(T) -> Self`

error[E0185]: method `from` has a `&self` declaration in the impl, but not in the trait
--> $DIR/issue-48276.rs:37:5
|
LL | fn from(&self) -> &'static str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `&self` used in impl
|
= note: `from` from trait: `fn(T) -> Self`

error: aborting due to 3 previous errors

If you want more information on this error, try using "rustc --explain E0185"

0 comments on commit 0bae326

Please sign in to comment.