about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2019-02-21 12:14:30 -0500
committerNiko Matsakis <niko@alum.mit.edu>2019-02-22 16:43:39 -0500
commit551aafc407e5240cb9d14a612c1e9a1d11d53775 (patch)
treec97c338d4ad0b95f3b346473df65d9dc6d9d8d71
parent542ad5e2a017f542784ee0bcd7c44583389bb897 (diff)
downloadrust-551aafc407e5240cb9d14a612c1e9a1d11d53775.tar.gz
rust-551aafc407e5240cb9d14a612c1e9a1d11d53775.zip
partially revert 904a0bde93f0348f69914ee90b1f8b6e4e0d7cbc
This preserves the error you currently get on stable for the
old-lub-glb-object.rs test.
-rw-r--r--src/librustc/traits/select.rs20
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-object.rs6
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-object.stderr17
3 files changed, 37 insertions, 6 deletions
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 20d95de60b3..1c84603e9da 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -3254,9 +3254,27 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
                     tcx.mk_existential_predicates(iter)
                 });
                 let source_trait = tcx.mk_dynamic(existential_predicates, r_b);
+
+                // Require that the traits involved in this upcast are **equal**;
+                // only the **lifetime bound** is changed.
+                //
+                // FIXME: This condition is arguably too strong -- it
+                // would suffice for the source trait to be a
+                // *subtype* of the target trait. In particular
+                // changing from something like `for<'a, 'b> Foo<'a,
+                // 'b>` to `for<'a> Foo<'a, 'a>` should be
+                // permitted. And, indeed, in the in commit
+                // 904a0bde93f0348f69914ee90b1f8b6e4e0d7cbc, this
+                // condition was loosened. However, when the leak check was added
+                // back, using subtype here actually guies the coercion code in
+                // such a way that it accepts `old-lub-glb-object.rs`. This is probably
+                // a good thing, but I've modified this to `.eq` because I want
+                // to continue rejecting that test (as we have done for quite some time)
+                // before we are firmly comfortable with what our behavior
+                // should be there. -nikomatsakis
                 let InferOk { obligations, .. } = self.infcx
                     .at(&obligation.cause, obligation.param_env)
-                    .sup(target, source_trait)
+                    .eq(target, source_trait) // FIXME -- see below
                     .map_err(|_| Unimplemented)?;
                 nested.extend(obligations);
 
diff --git a/src/test/ui/lub-glb/old-lub-glb-object.rs b/src/test/ui/lub-glb/old-lub-glb-object.rs
index 3e95a7111e0..f45696bcaad 100644
--- a/src/test/ui/lub-glb/old-lub-glb-object.rs
+++ b/src/test/ui/lub-glb/old-lub-glb-object.rs
@@ -1,9 +1,5 @@
 // Test that we give a note when the old LUB/GLB algorithm would have
 // succeeded but the new code (which is stricter) gives an error.
-//
-// compile-pass
-//
-// TODO -- why does this test pass?
 
 trait Foo<T, U> { }
 
@@ -11,7 +7,7 @@ fn foo(
     x: &for<'a, 'b> Foo<&'a u8, &'b u8>,
     y: &for<'a> Foo<&'a u8, &'a u8>,
 ) {
-    let z = match 22 {
+    let z = match 22 { //~ ERROR match arms have incompatible types
         0 => x,
         _ => y,
     };
diff --git a/src/test/ui/lub-glb/old-lub-glb-object.stderr b/src/test/ui/lub-glb/old-lub-glb-object.stderr
new file mode 100644
index 00000000000..a31cd6f7a19
--- /dev/null
+++ b/src/test/ui/lub-glb/old-lub-glb-object.stderr
@@ -0,0 +1,17 @@
+error[E0308]: match arms have incompatible types
+  --> $DIR/old-lub-glb-object.rs:10:13
+   |
+LL |       let z = match 22 { //~ ERROR match arms have incompatible types
+   |  _____________^
+LL | |         0 => x,
+LL | |         _ => y,
+   | |              - match arm with an incompatible type
+LL | |     };
+   | |_____^ expected bound lifetime parameter 'a, found concrete lifetime
+   |
+   = note: expected type `&dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
+              found type `&dyn for<'a> Foo<&'a u8, &'a u8>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.