change coercion to use target region if not LUB

This commit is contained in:
Niko Matsakis 2016-03-17 04:15:06 -04:00
parent 24bb607e7d
commit 1922041e7f
18 changed files with 53 additions and 56 deletions

View File

@ -166,8 +166,8 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
return self.coerce_unsafe_ptr(a, b, mt_b.mutbl);
}
ty::TyRef(_, mt_b) => {
return self.coerce_borrowed_pointer(exprs, a, b, mt_b.mutbl);
ty::TyRef(r_b, mt_b) => {
return self.coerce_borrowed_pointer(exprs, a, b, r_b, mt_b.mutbl);
}
_ => {}
@ -199,6 +199,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
exprs: &E,
a: Ty<'tcx>,
b: Ty<'tcx>,
r_b: &'tcx ty::Region,
mutbl_b: hir::Mutability)
-> CoerceResult<'tcx>
// FIXME(eddyb) use copyable iterators when that becomes ergonomic.
@ -213,17 +214,28 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
// to type check, we will construct the type that `&M*expr` would
// yield.
match a.sty {
ty::TyRef(_, mt_a) => {
let (_r_a, _mutbl_a) = match a.sty {
ty::TyRef(r_a, mt_a) => {
try!(coerce_mutbls(mt_a.mutbl, mutbl_b));
(r_a, mt_a.mutbl)
}
_ => return self.unify(a, b)
}
};
let span = self.origin.span();
let coercion = Coercion(span);
let r_borrow = self.fcx.infcx().next_region_var(coercion);
let r_borrow = self.tcx().mk_region(r_borrow);
let r_borrow = {
// If are coercing from `&'a T` to `&'b U`, then we want to
// reborrow the contents of `'a` for the lifetime `'b`
// (which ought to be a sublifetime of `'a`).
if !self.use_lub {
r_b
} else {
// With LUB, we need more flexibility.
let r_borrow = self.fcx.infcx().next_region_var(coercion);
self.tcx().mk_region(r_borrow)
}
};
let autoref = Some(AutoPtr(r_borrow, mutbl_b));
let lvalue_pref = LvaluePreference::from_mutbl(mutbl_b);

View File

@ -11,8 +11,7 @@
fn test<'x>(x: &'x isize) {
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
x
//~^ ERROR cannot infer an appropriate lifetime
x //~ ERROR E0312
}));
}

View File

@ -24,11 +24,9 @@ impl CrateId {
}
pub fn remove_package_from_database() {
let mut lines_to_use: Vec<&CrateId> = Vec::new();
let mut lines_to_use: Vec<&CrateId> = Vec::new(); //~ ERROR E0495
let push_id = |installed_id: &CrateId| {
lines_to_use.push(installed_id);
//~^ ERROR cannot infer an appropriate lifetime for automatic coercion due to
// conflicting requirements
};
list_database(push_id);

View File

@ -14,19 +14,19 @@ use std::marker::PhantomData;
struct Bar<'x, 'y, 'z> { bar: &'y i32, baz: i32, marker: PhantomData<(&'x(),&'y(),&'z())> }
fn bar1<'a>(x: &Bar) -> (&'a i32, &'a i32, &'a i32) {
//~^ HELP: consider using an explicit lifetime parameter as shown: fn bar1<'b, 'c, 'a>(x: &'a Bar<'b, 'a, 'c>) -> (&'a i32, &'a i32, &'a i32)
//~^ HELP: consider using an explicit lifetime parameter as shown: fn bar1<'a>(x: &'a Bar) -> (&'a i32, &'a i32, &'a i32)
(x.bar, &x.baz, &x.baz)
//~^ ERROR: cannot infer
//~^^ ERROR: cannot infer
//~^^^ ERROR: cannot infer
//~^ ERROR E0312
//~| ERROR cannot infer
//~| ERROR cannot infer
}
fn bar2<'a, 'b, 'c>(x: &Bar<'a, 'b, 'c>) -> (&'a i32, &'a i32, &'a i32) {
//~^ HELP: consider using an explicit lifetime parameter as shown: fn bar2<'a, 'c>(x: &'a Bar<'a, 'a, 'c>) -> (&'a i32, &'a i32, &'a i32)
//~^ HELP: consider using an explicit lifetime parameter as shown: fn bar2<'a, 'b, 'c>(x: &'a Bar<'a, 'b, 'c>) -> (&'a i32, &'a i32, &'a i32)
(x.bar, &x.baz, &x.baz)
//~^ ERROR: cannot infer
//~^^ ERROR: cannot infer
//~^^^ ERROR: cannot infer
//~^ ERROR E0312
//~| ERROR cannot infer
//~| ERROR cannot infer
}
fn main() { }

View File

@ -39,8 +39,7 @@ struct Cat<'x, T> { cat: &'x isize, t: T }
struct Dog<'y> { dog: &'y isize }
fn cat2<'x, 'y>(x: Cat<'x, Dog<'y>>) -> &'x isize {
//~^ HELP: consider using an explicit lifetime parameter as shown: fn cat2<'x>(x: Cat<'x, Dog<'x>>) -> &'x isize
x.t.dog //~ ERROR: cannot infer
x.t.dog //~ ERROR E0312
}
struct Baz<'x> {
@ -49,11 +48,8 @@ struct Baz<'x> {
impl<'a> Baz<'a> {
fn baz2<'b>(&self, x: &isize) -> (&'b isize, &'b isize) {
//~^ HELP: parameter as shown: fn baz2<'b>(&self, x: &'b isize) -> (&'a isize, &'a isize)
// The lifetime that gets assigned to `x` seems somewhat random.
// I have disabled this test for the time being. --pcwalton
(self.bar, x) //~ ERROR: cannot infer
//~^ ERROR: cannot infer
(self.bar, x) //~ ERROR E0312
//~^ ERROR E0312
}
}

View File

@ -35,14 +35,14 @@ pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
"(none)"
} else {
let s: &'a str = maybestr.as_ref().unwrap();
s //~ ERROR cannot infer an appropriate lifetime for automatic coercion due to conflicting
s //~ ERROR E0312
}
}
pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
if maybestr.is_some() {
let s: &'a str = maybestr.as_ref().unwrap();
s //~ ERROR cannot infer an appropriate lifetime for automatic coercion due to conflicting
s //~ ERROR E0312
} else {
"(none)"
}

View File

@ -37,8 +37,7 @@ pub fn opt_str2<'a>(maybestr: &'a Option<String>) -> &'static str {
None => "(none)",
Some(ref s) => {
let s: &'a str = s;
s
//~^ ERROR cannot infer an appropriate lifetime
s //~ ERROR E0312
}
}
}
@ -47,8 +46,7 @@ pub fn opt_str3<'a>(maybestr: &'a Option<String>) -> &'static str {
match *maybestr {
Some(ref s) => {
let s: &'a str = s;
s
//~^ ERROR cannot infer an appropriate lifetime
s //~ ERROR E0312
}
None => "(none)",
}

View File

@ -34,8 +34,7 @@ fn load1<'a,'b>(a: &'a MyBox<SomeTrait>,
b: &'b MyBox<SomeTrait>)
-> &'b MyBox<SomeTrait>
{
a
//~^ ERROR cannot infer
a //~ ERROR E0312
}
fn load2<'a>(ss: &MyBox<SomeTrait+'a>) -> MyBox<SomeTrait+'a> {

View File

@ -15,7 +15,7 @@ fn a<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) where 'b: 'a {
fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) {
// Illegal now because there is no `'b:'a` declaration.
*x = *y; //~ ERROR cannot infer
*x = *y; //~ ERROR E0312
}
fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {

View File

@ -16,8 +16,8 @@ fn a<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) where
fn b<'a, 'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {
// Illegal now because there is no `'b:'a` declaration.
*x = *y; //~ ERROR cannot infer
*z = *y; //~ ERROR cannot infer
*x = *y; //~ ERROR E0312
*z = *y; //~ ERROR E0312
}
fn c<'a,'b, 'c>(x: &mut &'a isize, y: &mut &'b isize, z: &mut &'c isize) {

View File

@ -28,8 +28,7 @@ impl<'a> GetRef<'a> for Box<'a> {
impl<'a> Box<'a> {
fn or<'b,G:GetRef<'b>>(&self, g2: G) -> &'a isize {
g2.get()
//~^ ERROR cannot infer an appropriate lifetime for automatic coercion due to
//~| ERROR mismatched types
//~^ ERROR mismatched types
//~| expected `&'a isize`
//~| found `&'b isize`
//~| lifetime mismatch

View File

@ -27,11 +27,7 @@ impl<'a,T:Clone> GetRef<'a,T> for Box<'a,T> {
fn get<'a,'b,G:GetRef<'a, isize>>(g1: G, b: &'b isize) -> &'b isize {
g1.get()
//~^ ERROR cannot infer an appropriate lifetime for automatic coercion due to
//~| ERROR mismatched types
//~| expected `&'b isize`
//~| found `&'a isize`
//~| lifetime mismatch
//~^ ERROR mismatched types
}
fn main() {

View File

@ -22,9 +22,9 @@ mod argparse {
impl<'a> Flag<'a> {
pub fn set_desc(self, s: &str) -> Flag<'a> {
Flag {
Flag { //~ ERROR cannot infer
name: self.name,
desc: s, //~ ERROR cannot infer an appropriate lifetime for automatic coercion due t
desc: s,
max_count: self.max_count,
value: self.value
}

View File

@ -15,13 +15,13 @@ fn a<'a, 'b:'a>(x: &mut &'a isize, y: &mut &'b isize) {
fn b<'a, 'b>(x: &mut &'a isize, y: &mut &'b isize) {
// Illegal now because there is no `'b:'a` declaration.
*x = *y; //~ ERROR cannot infer
*x = *y; //~ ERROR E0312
}
fn c<'a,'b>(x: &mut &'a isize, y: &mut &'b isize) {
// Here we try to call `foo` but do not know that `'a` and `'b` are
// related as required.
a(x, y); //~ ERROR cannot infer
a(x, y); //~ ERROR E0495
}
fn d() {

View File

@ -14,16 +14,16 @@ fn ignore<T>(t: T) {}
fn nested<'x>(x: &'x isize) {
let y = 3;
let mut ay = &y;
let mut ay = &y; //~ ERROR E0495
ignore::<Box<for<'z> FnMut(&'z isize)>>(Box::new(|z| {
ay = x; //~ ERROR cannot infer
ay = x;
ay = &y;
ay = z;
}));
ignore::< Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
if false { return x; } //~ ERROR cannot infer an appropriate lifetime for automatic
if false { return x; } //~ ERROR E0312
if false { return ay; }
return z;
}));

View File

@ -13,7 +13,7 @@ fn static_id<'a,'b>(t: &'a ()) -> &'static ()
fn static_id_indirect<'a,'b>(t: &'a ()) -> &'static ()
where 'a: 'b, 'b: 'static { t }
fn static_id_wrong_way<'a>(t: &'a ()) -> &'static () where 'static: 'a {
t //~ ERROR cannot infer an appropriate lifetime
t //~ ERROR E0312
}
fn error(u: &(), v: &()) {

View File

@ -24,6 +24,6 @@ fn doit<T,F>(val: T, f: &F)
pub fn main() {
doit(0, &|x, y| {
x.set(y); //~ ERROR cannot infer
x.set(y); //~ ERROR E0312
});
}

View File

@ -24,7 +24,7 @@ struct Evil<'a, 'b: 'a>(Option<&'a &'b ()>);
impl<'a, 'b> Foo<'a, 'b, Evil<'a, 'b>> for () {
fn make_me() -> Self { }
fn static_evil(u: &'b u32) -> &'a u32 {
u //~ ERROR cannot infer an appropriate lifetime
u //~ ERROR E0312
}
}
@ -40,7 +40,7 @@ impl<'a, 'b> Foo<'a, 'b, ()> for IndirectEvil<'a, 'b> {
impl<'a, 'b> Evil<'a, 'b> {
fn inherent_evil(u: &'b u32) -> &'a u32 {
u //~ ERROR cannot infer an appropriate lifetime
u //~ ERROR E0312
}
}