From d4ee408afc59b36ff59b6fd12d47c1beeba8e985 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 25 Sep 2024 19:19:22 -0400 Subject: [PATCH] Check allow instantiating object trait binder when upcasting and in new solver --- .../src/solve/trait_goals.rs | 6 ++--- .../src/traits/select/mod.rs | 6 ++--- tests/ui/coercion/sub-principals.rs | 27 +++++++++++++++++++ .../higher-ranked-upcasting-ok.current.stderr | 22 --------------- .../higher-ranked-upcasting-ok.next.stderr | 14 ---------- .../higher-ranked-upcasting-ok.rs | 12 +++++---- .../higher-ranked-upcasting-ub.current.stderr | 8 +++--- tests/ui/traits/trait-upcasting/sub.rs | 26 ++++++++++++++++++ 8 files changed, 70 insertions(+), 51 deletions(-) create mode 100644 tests/ui/coercion/sub-principals.rs delete mode 100644 tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.current.stderr delete mode 100644 tests/ui/traits/trait-upcasting/higher-ranked-upcasting-ok.next.stderr create mode 100644 tests/ui/traits/trait-upcasting/sub.rs 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() +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 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> {} +#![feature(trait_upcasting)] + +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() +where + T: Unsize, +{ +} + +fn main() { + test:: Fn(&'a ()) -> &'a (), dyn FnOnce(&'static ()) -> &'static ()>(); + + trait Foo: for<'a> Bar<'a> {} + trait Bar<'a> {} + test::>(); + test::>(); +}