about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2020-05-20 14:31:51 +0000
committerNiko Matsakis <niko@alum.mit.edu>2020-06-22 15:33:07 +0000
commit1e00e1b6debce8270dd75e795458ba8becdffe1f (patch)
tree61b186bfde82f9b3954da9bc5b269383ac383b99
parent5a7a850753b60abfd2a806bf6bba4259d3535e7b (diff)
downloadrust-1e00e1b6debce8270dd75e795458ba8becdffe1f.tar.gz
rust-1e00e1b6debce8270dd75e795458ba8becdffe1f.zip
upcasting traits requires only that things become more general
Revert the code that states that upcasting traits requires full
equality and change to require that the source type is a subtype of
the target type, as one would expect. As the comment states, this was
an old bug that we didn't want to fix yet as it interacted poorly with
the old leak-check. This fixes the old-lub-glb-object test, which was
previously reporting too many errors (i.e., in the previous commit).
-rw-r--r--src/librustc_trait_selection/traits/select/confirmation.rs16
-rw-r--r--src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir4
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-object.rs18
-rw-r--r--src/test/ui/lub-glb/old-lub-glb-object.stderr14
4 files changed, 12 insertions, 40 deletions
diff --git a/src/librustc_trait_selection/traits/select/confirmation.rs b/src/librustc_trait_selection/traits/select/confirmation.rs
index 50c04e8fc34..4837acbd1de 100644
--- a/src/librustc_trait_selection/traits/select/confirmation.rs
+++ b/src/librustc_trait_selection/traits/select/confirmation.rs
@@ -612,24 +612,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
 
                 // 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 guides 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)
-                    .eq(target, source_trait) // FIXME -- see below
+                    .sup(target, source_trait)
                     .map_err(|_| Unimplemented)?;
                 nested.extend(obligations);
 
diff --git a/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir b/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir
index 9742530bd81..aeb38f3f910 100644
--- a/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir
+++ b/src/test/mir-opt/address-of/rustc.address_of_reborrow.SimplifyCfg-initial.after.mir
@@ -12,7 +12,7 @@
 | 8: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:16:12: 16:24
 | 9: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:16:12: 16:24
 | 10: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:18:5: 18:18
-| 11: Canonical { max_universe: U3, variables: [CanonicalVarInfo { kind: Region(U3) }], value: Ty(*const dyn std::marker::Send) } at $DIR/address-of.rs:20:5: 20:25
+| 11: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*const dyn std::marker::Send) } at $DIR/address-of.rs:20:5: 20:25
 | 12: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:23:12: 23:20
 | 13: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*const ^0) } at $DIR/address-of.rs:23:12: 23:20
 | 14: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32; 10]) } at $DIR/address-of.rs:24:12: 24:28
@@ -22,7 +22,7 @@
 | 18: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:26:12: 26:24
 | 19: Canonical { max_universe: U0, variables: [], value: Ty(*const [i32]) } at $DIR/address-of.rs:26:12: 26:24
 | 20: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) } at $DIR/address-of.rs:28:5: 28:16
-| 21: Canonical { max_universe: U6, variables: [CanonicalVarInfo { kind: Region(U6) }], value: Ty(*mut dyn std::marker::Send) } at $DIR/address-of.rs:30:5: 30:23
+| 21: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Region(U0) }], value: Ty(*mut dyn std::marker::Send) } at $DIR/address-of.rs:30:5: 30:23
 | 22: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) } at $DIR/address-of.rs:33:12: 33:18
 | 23: Canonical { max_universe: U0, variables: [CanonicalVarInfo { kind: Ty(General(U0)) }], value: Ty(*mut ^0) } at $DIR/address-of.rs:33:12: 33:18
 | 24: Canonical { max_universe: U0, variables: [], value: Ty(*mut [i32; 10]) } at $DIR/address-of.rs:34:12: 34:26
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 63bbae59991..39d351c2355 100644
--- a/src/test/ui/lub-glb/old-lub-glb-object.rs
+++ b/src/test/ui/lub-glb/old-lub-glb-object.rs
@@ -1,22 +1,17 @@
 // 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.
 
-trait Foo<T, U> { }
+trait Foo<T, U> {}
 
-fn foo(
-    x: &dyn for<'a, 'b> Foo<&'a u8, &'b u8>,
-    y: &dyn for<'a> Foo<&'a u8, &'a u8>,
-) {
+fn foo(x: &dyn for<'a, 'b> Foo<&'a u8, &'b u8>, y: &dyn for<'a> Foo<&'a u8, &'a u8>) {
     let z = match 22 {
+        //~^ ERROR mismatched types
         0 => x,
-        _ => y, //~ ERROR `match` arms have incompatible types
+        _ => y,
     };
 }
 
-fn bar(
-    x: &dyn for<'a, 'b> Foo<&'a u8, &'b u8>,
-    y: &dyn for<'a> Foo<&'a u8, &'a u8>,
-) {
+fn bar(x: &dyn for<'a, 'b> Foo<&'a u8, &'b u8>, y: &dyn for<'a> Foo<&'a u8, &'a u8>) {
     // Accepted with explicit case:
     let z = match 22 {
         0 => x as &dyn for<'a> Foo<&'a u8, &'a u8>,
@@ -24,5 +19,4 @@ fn bar(
     };
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/src/test/ui/lub-glb/old-lub-glb-object.stderr b/src/test/ui/lub-glb/old-lub-glb-object.stderr
index 81f07df3f50..6eabe5eaeee 100644
--- a/src/test/ui/lub-glb/old-lub-glb-object.stderr
+++ b/src/test/ui/lub-glb/old-lub-glb-object.stderr
@@ -1,8 +1,9 @@
 error[E0308]: mismatched types
-  --> $DIR/old-lub-glb-object.rs:10:13
+  --> $DIR/old-lub-glb-object.rs:7:13
    |
 LL |       let z = match 22 {
    |  _____________^
+LL | |
 LL | |         0 => x,
 LL | |         _ => y,
 LL | |     };
@@ -11,15 +12,6 @@ LL | |     };
    = note: expected trait object `dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
               found trait object `dyn for<'a> Foo<&'a u8, &'a u8>`
 
-error[E0308]: mismatched types
-  --> $DIR/old-lub-glb-object.rs:22:14
-   |
-LL |         0 => x as &dyn for<'a> Foo<&'a u8, &'a u8>,
-   |              ^ one type is more general than the other
-   |
-   = note: expected trait object `dyn for<'a> Foo<&'a u8, &'a u8>`
-              found trait object `dyn for<'a, 'b> Foo<&'a u8, &'b u8>`
-
-error: aborting due to 2 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0308`.