diff options
| author | Niko Matsakis <niko@alum.mit.edu> | 2016-03-17 04:15:06 -0400 |
|---|---|---|
| committer | Niko Matsakis <niko@alum.mit.edu> | 2016-03-18 16:38:29 -0400 |
| commit | 1922041e7f69407e7fa40bf90e8ec47d49a97fd2 (patch) | |
| tree | b5d9f40ec24c43f7d56f318336b7f47b2108ee5a | |
| parent | 24bb607e7d65ebfc487eba62e053ac049f140efc (diff) | |
| download | rust-1922041e7f69407e7fa40bf90e8ec47d49a97fd2.tar.gz rust-1922041e7f69407e7fa40bf90e8ec47d49a97fd2.zip | |
change coercion to use target region if not LUB
18 files changed, 53 insertions, 56 deletions
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index aa359c95e2d..a8b4c2e12aa 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -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); diff --git a/src/test/compile-fail/issue-10291.rs b/src/test/compile-fail/issue-10291.rs index 9711d760ae6..43255db2ff3 100644 --- a/src/test/compile-fail/issue-10291.rs +++ b/src/test/compile-fail/issue-10291.rs @@ -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 })); } diff --git a/src/test/compile-fail/issue-7573.rs b/src/test/compile-fail/issue-7573.rs index 2d1cea1d44b..d13da1d9fd9 100644 --- a/src/test/compile-fail/issue-7573.rs +++ b/src/test/compile-fail/issue-7573.rs @@ -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); diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs index 66d8927ee51..655fe28b12b 100644 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs +++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs @@ -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() { } diff --git a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs index e32ed1c42a0..46160fbefcf 100644 --- a/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs +++ b/src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs @@ -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 } } diff --git a/src/test/compile-fail/lub-if.rs b/src/test/compile-fail/lub-if.rs index 06af8ac8719..8d2a0fd07e8 100644 --- a/src/test/compile-fail/lub-if.rs +++ b/src/test/compile-fail/lub-if.rs @@ -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)" } diff --git a/src/test/compile-fail/lub-match.rs b/src/test/compile-fail/lub-match.rs index 1b5824964a8..b9423feb5c1 100644 --- a/src/test/compile-fail/lub-match.rs +++ b/src/test/compile-fail/lub-match.rs @@ -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)", } diff --git a/src/test/compile-fail/object-lifetime-default-mybox.rs b/src/test/compile-fail/object-lifetime-default-mybox.rs index 80dbee3c481..014b0c1e80e 100644 --- a/src/test/compile-fail/object-lifetime-default-mybox.rs +++ b/src/test/compile-fail/object-lifetime-default-mybox.rs @@ -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> { diff --git a/src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs b/src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs index ee05ba676ac..6364db1f4b4 100644 --- a/src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs +++ b/src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs @@ -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) { diff --git a/src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs b/src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs index 30e6a4e1277..154135eba38 100644 --- a/src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs +++ b/src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs @@ -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) { diff --git a/src/test/compile-fail/regions-early-bound-error-method.rs b/src/test/compile-fail/regions-early-bound-error-method.rs index 4a3ca01c849..8cc35272282 100644 --- a/src/test/compile-fail/regions-early-bound-error-method.rs +++ b/src/test/compile-fail/regions-early-bound-error-method.rs @@ -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 diff --git a/src/test/compile-fail/regions-early-bound-error.rs b/src/test/compile-fail/regions-early-bound-error.rs index 57c8e3f1170..1fc3b4b3c6a 100644 --- a/src/test/compile-fail/regions-early-bound-error.rs +++ b/src/test/compile-fail/regions-early-bound-error.rs @@ -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() { diff --git a/src/test/compile-fail/regions-glb-free-free.rs b/src/test/compile-fail/regions-glb-free-free.rs index 323d5360029..c2e4fbac3c9 100644 --- a/src/test/compile-fail/regions-glb-free-free.rs +++ b/src/test/compile-fail/regions-glb-free-free.rs @@ -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 } diff --git a/src/test/compile-fail/regions-lifetime-bounds-on-fns.rs b/src/test/compile-fail/regions-lifetime-bounds-on-fns.rs index 43940d499d2..89254516ac6 100644 --- a/src/test/compile-fail/regions-lifetime-bounds-on-fns.rs +++ b/src/test/compile-fail/regions-lifetime-bounds-on-fns.rs @@ -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() { diff --git a/src/test/compile-fail/regions-nested-fns.rs b/src/test/compile-fail/regions-nested-fns.rs index f114a8bc7ce..5ef2a701a60 100644 --- a/src/test/compile-fail/regions-nested-fns.rs +++ b/src/test/compile-fail/regions-nested-fns.rs @@ -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; })); diff --git a/src/test/compile-fail/regions-static-bound.rs b/src/test/compile-fail/regions-static-bound.rs index 297b6a866da..de695e72d07 100644 --- a/src/test/compile-fail/regions-static-bound.rs +++ b/src/test/compile-fail/regions-static-bound.rs @@ -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: &()) { diff --git a/src/test/compile-fail/unboxed-closures-infer-argument-types-two-region-pointers.rs b/src/test/compile-fail/unboxed-closures-infer-argument-types-two-region-pointers.rs index 3dd5779914d..1e2b01856e7 100644 --- a/src/test/compile-fail/unboxed-closures-infer-argument-types-two-region-pointers.rs +++ b/src/test/compile-fail/unboxed-closures-infer-argument-types-two-region-pointers.rs @@ -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 }); } diff --git a/src/test/compile-fail/wf-static-method.rs b/src/test/compile-fail/wf-static-method.rs index 6c6522fe658..e99957c7914 100644 --- a/src/test/compile-fail/wf-static-method.rs +++ b/src/test/compile-fail/wf-static-method.rs @@ -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 } } |
