about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs6
-rw-r--r--tests/ui/coercion/sub-principals.rs27
-rw-r--r--tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr22
-rw-r--r--tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr14
-rw-r--r--tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs10
-rw-r--r--tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr8
-rw-r--r--tests/ui/traits/trait-upcasting/sub.rs26
8 files changed, 69 insertions, 50 deletions
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 781ca127e15..0befe7f5e8a 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -896,7 +896,7 @@ where
                     && ecx
                         .probe(|_| ProbeKind::UpcastProjectionCompatibility)
                         .enter(|ecx| -> Result<(), NoSolution> {
-                            ecx.eq(param_env, source_projection, target_projection)?;
+                            ecx.sub(param_env, source_projection, target_projection)?;
                             let _ = ecx.try_evaluate_added_goals()?;
                             Ok(())
                         })
@@ -909,7 +909,7 @@ where
                     // Check that a's supertrait (upcast_principal) is compatible
                     // with the target (b_ty).
                     ty::ExistentialPredicate::Trait(target_principal) => {
-                        ecx.eq(
+                        ecx.sub(
                             param_env,
                             upcast_principal.unwrap(),
                             bound.rebind(target_principal),
@@ -934,7 +934,7 @@ where
                                 Certainty::AMBIGUOUS,
                             );
                         }
-                        ecx.eq(param_env, source_projection, target_projection)?;
+                        ecx.sub(param_env, source_projection, target_projection)?;
                     }
                     // Check that b_ty's auto traits are present in a_ty's bounds.
                     ty::ExistentialPredicate::AutoTrait(def_id) => {
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index cbc17a058f6..2922a4898e9 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2582,12 +2582,12 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                     nested.extend(
                         self.infcx
                             .at(&obligation.cause, obligation.param_env)
-                            .eq(
+                            .sup(
                                 DefineOpaqueTypes::Yes,
+                                bound.rebind(target_principal),
                                 upcast_principal.map_bound(|trait_ref| {
                                     ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref)
                                 }),
-                                bound.rebind(target_principal),
                             )
                             .map_err(|_| SelectionError::Unimplemented)?
                             .into_obligations(),
@@ -2620,7 +2620,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                     nested.extend(
                         self.infcx
                             .at(&obligation.cause, obligation.param_env)
-                            .eq(DefineOpaqueTypes::Yes, source_projection, target_projection)
+                            .sup(DefineOpaqueTypes::Yes, target_projection, source_projection)
                             .map_err(|_| SelectionError::Unimplemented)?
                             .into_obligations(),
                     );
diff --git a/tests/ui/coercion/sub-principals.rs b/tests/ui/coercion/sub-principals.rs
new file mode 100644
index 00000000000..c38769f0d09
--- /dev/null
+++ b/tests/ui/coercion/sub-principals.rs
@@ -0,0 +1,27 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Verify that the unsize goal can cast a higher-ranked trait goal to
+// a non-higer-ranked instantiation.
+
+#![feature(unsize)]
+
+use std::marker::Unsize;
+
+fn test<T: ?Sized, U: ?Sized>()
+where
+    T: Unsize<U>,
+{
+}
+
+fn main() {
+    test::<dyn for<'a> Fn(&'a ()) -> &'a (), dyn Fn(&'static ()) -> &'static ()>();
+
+    trait Foo<'a, 'b> {}
+    test::<dyn for<'a, 'b> Foo<'a, 'b>, dyn for<'a> Foo<'a, 'a>>();
+
+    trait Bar<'a> {}
+    test::<dyn for<'a> Bar<'a>, dyn Bar<'_>>();
+}
diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr
deleted file mode 100644
index 098ab71e946..00000000000
--- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr
+++ /dev/null
@@ -1,22 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/higher-ranked-upcasting-ok.rs:17:5
-   |
-LL |     x
-   |     ^ one type is more general than the other
-   |
-   = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
-              found existential trait ref `for<'a> Supertrait<'a, 'a>`
-
-error[E0308]: mismatched types
-  --> $DIR/higher-ranked-upcasting-ok.rs:17:5
-   |
-LL |     x
-   |     ^ one type is more general than the other
-   |
-   = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
-              found existential trait ref `for<'a> Supertrait<'a, 'a>`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr
deleted file mode 100644
index ac516fd6975..00000000000
--- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/higher-ranked-upcasting-ok.rs:17:5
-   |
-LL | fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
-   |                                                ------------------------------- expected `&dyn for<'a> Supertrait<'a, 'a>` because of return type
-LL |     x
-   |     ^ expected trait `Supertrait`, found trait `Subtrait`
-   |
-   = note: expected reference `&dyn for<'a> Supertrait<'a, 'a>`
-              found reference `&dyn for<'a, 'b> Subtrait<'a, 'b>`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs
index 00743203179..7f793e1269f 100644
--- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs
+++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.rs
@@ -1,19 +1,21 @@
 //@ revisions: current next
 //@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
+//@ check-pass
 
 // We should be able to instantiate a binder during trait upcasting.
 // This test could be `check-pass`, but we should make sure that we
 // do so in both trait solvers.
+
 #![feature(trait_upcasting)]
-#![crate_type = "rlib"]
-trait Supertrait<'a, 'b> {}
 
+trait Supertrait<'a, 'b> {}
 trait Subtrait<'a, 'b>: Supertrait<'a, 'b> {}
 
 impl<'a> Supertrait<'a, 'a> for () {}
 impl<'a> Subtrait<'a, 'a> for () {}
 fn ok(x: &dyn for<'a, 'b> Subtrait<'a, 'b>) -> &dyn for<'a> Supertrait<'a, 'a> {
-    x //~ ERROR mismatched types
-    //[current]~^ ERROR mismatched types
+    x
 }
+
+fn main() {}
diff --git a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr
index bac82983268..e5885ea35a7 100644
--- a/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr
+++ b/tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ub.current.stderr
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
 LL |     x
    |     ^ one type is more general than the other
    |
-   = note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
-              found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
+   = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
+              found existential trait ref `for<'a> Supertrait<'a, 'a>`
 
 error[E0308]: mismatched types
   --> $DIR/higher-ranked-upcasting-ub.rs:22:5
@@ -13,8 +13,8 @@ error[E0308]: mismatched types
 LL |     x
    |     ^ one type is more general than the other
    |
-   = note: expected existential trait ref `for<'a> Supertrait<'a, 'a>`
-              found existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
+   = note: expected existential trait ref `for<'a, 'b> Supertrait<'a, 'b>`
+              found existential trait ref `for<'a> Supertrait<'a, 'a>`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/traits/trait-upcasting/sub.rs b/tests/ui/traits/trait-upcasting/sub.rs
new file mode 100644
index 00000000000..255c4895b7f
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/sub.rs
@@ -0,0 +1,26 @@
+//@ check-pass
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+// Verify that the unsize goal can cast a higher-ranked trait goal to
+// a non-higer-ranked instantiation.
+
+#![feature(unsize)]
+
+use std::marker::Unsize;
+
+fn test<T: ?Sized, U: ?Sized>()
+where
+    T: Unsize<U>,
+{
+}
+
+fn main() {
+    test::<dyn for<'a> Fn(&'a ()) -> &'a (), dyn FnOnce(&'static ()) -> &'static ()>();
+
+    trait Foo: for<'a> Bar<'a> {}
+    trait Bar<'a> {}
+    test::<dyn Foo, dyn Bar<'static>>();
+    test::<dyn Foo, dyn Bar<'_>>();
+}