about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2016-03-17 04:15:06 -0400
committerNiko Matsakis <niko@alum.mit.edu>2016-03-18 16:38:29 -0400
commit1922041e7f69407e7fa40bf90e8ec47d49a97fd2 (patch)
treeb5d9f40ec24c43f7d56f318336b7f47b2108ee5a
parent24bb607e7d65ebfc487eba62e053ac049f140efc (diff)
downloadrust-1922041e7f69407e7fa40bf90e8ec47d49a97fd2.tar.gz
rust-1922041e7f69407e7fa40bf90e8ec47d49a97fd2.zip
change coercion to use target region if not LUB
-rw-r--r--src/librustc_typeck/check/coercion.rs26
-rw-r--r--src/test/compile-fail/issue-10291.rs3
-rw-r--r--src/test/compile-fail/issue-7573.rs4
-rw-r--r--src/test/compile-fail/lifetime-inference-give-expl-lifetime-param-3.rs16
-rw-r--r--src/test/compile-fail/lifetime-inference-give-expl-lifetime-param.rs10
-rw-r--r--src/test/compile-fail/lub-if.rs4
-rw-r--r--src/test/compile-fail/lub-match.rs6
-rw-r--r--src/test/compile-fail/object-lifetime-default-mybox.rs3
-rw-r--r--src/test/compile-fail/region-lifetime-bounds-on-fns-where-clause.rs2
-rw-r--r--src/test/compile-fail/region-multiple-lifetime-bounds-on-fns-where-clause.rs4
-rw-r--r--src/test/compile-fail/regions-early-bound-error-method.rs3
-rw-r--r--src/test/compile-fail/regions-early-bound-error.rs6
-rw-r--r--src/test/compile-fail/regions-glb-free-free.rs4
-rw-r--r--src/test/compile-fail/regions-lifetime-bounds-on-fns.rs4
-rw-r--r--src/test/compile-fail/regions-nested-fns.rs6
-rw-r--r--src/test/compile-fail/regions-static-bound.rs2
-rw-r--r--src/test/compile-fail/unboxed-closures-infer-argument-types-two-region-pointers.rs2
-rw-r--r--src/test/compile-fail/wf-static-method.rs4
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
     }
 }