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 781ca127e151e..0befe7f5e8a2c 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 cbc17a058f6d1..2922a4898e983 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 0000000000000..c38769f0d0986 --- /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() +where + T: Unsize, +{ +} + +fn main() { + test:: Fn(&'a ()) -> &'a (), dyn Fn(&'static ()) -> &'static ()>(); + + trait Foo<'a, 'b> {} + test:: Foo<'a, 'b>, dyn for<'a> Foo<'a, 'a>>(); + + trait Bar<'a> {} + test:: 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 098ab71e946e9..0000000000000 --- 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 ac516fd697535..0000000000000 --- 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 0074320317970..7f793e1269fd7 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 bac8298326879..e5885ea35a71e 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 0000000000000..255c4895b7f36 --- /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() +where + T: Unsize, +{ +} + +fn main() { + test:: Fn(&'a ()) -> &'a (), dyn FnOnce(&'static ()) -> &'static ()>(); + + trait Foo: for<'a> Bar<'a> {} + trait Bar<'a> {} + test::>(); + test::>(); +}