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
This commit is contained in:
bors 2018-03-10 23:34:11 +00:00
commit 0bae326f6d
3 changed files with 75 additions and 0 deletions

View file

@ -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(),

View file

@ -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(){}

View file

@ -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"