From 525cdc75dc2a821ab01867f904f06cc8a7f66c41 Mon Sep 17 00:00:00 2001 From: Adwin White Date: Fri, 21 Nov 2025 11:54:27 +0800 Subject: [PATCH] skip checking supertraits in assembly_object_bound_candidate for NormalizesTo goal --- .../src/solve/assembly/mod.rs | 2 + .../src/solve/normalizes_to/mod.rs | 14 +++++++ .../skip-supertraits-in-object-candidate.rs | 39 +++++++++++++++++++ 3 files changed, 55 insertions(+) create mode 100644 tests/ui/traits/next-solver/normalize/skip-supertraits-in-object-candidate.rs diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs index 4ecd56dfa40b6..d27d80a086ad1 100644 --- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs @@ -74,6 +74,8 @@ where /// Consider a clause specifically for a `dyn Trait` self type. This requires /// additionally checking all of the supertraits and object bounds to hold, /// since they're not implied by the well-formedness of the object type. + /// `NormalizesTo` overrides this to not check the supertraits for backwards + /// compatibility with the old solver. cc trait-system-refactor-initiative#245. fn probe_and_consider_object_bound_candidate( ecx: &mut EvalCtxt<'_, D>, source: CandidateSource, diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs index 794bda7726a4a..c65e0bb25897c 100644 --- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs +++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs @@ -184,6 +184,20 @@ where then(ecx) } + // Hack for trait-system-refactor-initiative#245. + // FIXME(-Zhigher-ranked-assumptions): this impl differs from trait goals and we should unify + // them again once we properly support binders. + fn probe_and_consider_object_bound_candidate( + ecx: &mut EvalCtxt<'_, D>, + source: CandidateSource, + goal: Goal, + assumption: I::Clause, + ) -> Result, NoSolution> { + Self::probe_and_match_goal_against_assumption(ecx, source, goal, assumption, |ecx| { + ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes) + }) + } + fn consider_additional_alias_assumptions( _ecx: &mut EvalCtxt<'_, D>, _goal: Goal, diff --git a/tests/ui/traits/next-solver/normalize/skip-supertraits-in-object-candidate.rs b/tests/ui/traits/next-solver/normalize/skip-supertraits-in-object-candidate.rs new file mode 100644 index 0000000000000..9b13b78d024b4 --- /dev/null +++ b/tests/ui/traits/next-solver/normalize/skip-supertraits-in-object-candidate.rs @@ -0,0 +1,39 @@ +//@ check-pass +//@ compile-flags: -Znext-solver +//@ edition: 2024 + +// A regression test for trait-system-refactor-initiative#245. +// The old solver doesn't check the supertraits of the principal trait +// when considering object candidate for normalization. +// And the new solver previously did, resulting in a placeholder error +// while normalizing inside of a generator witness. + +trait AsyncFn: Send + 'static { + type Fut: Future + Send; + + fn call(&self) -> Self::Fut; +} + +type BoxFuture<'a, T> = std::pin::Pin + Send + 'a>>; +type DynAsyncFnBoxed = dyn AsyncFn>; + +fn wrap_call(func: Box

) -> impl Future { + func.call() +} + +fn get_boxed_fn() -> Box { + todo!() +} + +async fn cursed_fut() { + wrap_call(get_boxed_fn()).await; +} + +fn observe_fut_not_send() { + fn assert_send(t: T) -> T { + t + } + assert_send(cursed_fut()); +} + +fn main() {}