diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs index 16fe045b82de7..1738190fe510e 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -58,6 +58,12 @@ impl<'tcx> inspect::ProofTreeVisitor<'tcx> for Select { ))); } + // Don't winnow until `Certainty::Yes` -- we don't need to winnow until + // codegen, technically, and all goals should hold in codegen. + if matches!(goal.result().unwrap(), Certainty::Maybe(..)) { + return ControlFlow::Break(Ok(None)); + } + // We need to winnow. See comments on `candidate_should_be_dropped_in_favor_of`. let mut i = 0; while i < candidates.len() { @@ -85,12 +91,6 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>( victim: &inspect::InspectCandidate<'_, 'tcx>, other: &inspect::InspectCandidate<'_, 'tcx>, ) -> bool { - // Don't winnow until `Certainty::Yes` -- we don't need to winnow until - // codegen, technically. - if matches!(other.result().unwrap(), Certainty::Maybe(..)) { - return false; - } - let inspect::ProbeKind::TraitCandidate { source: victim_source, result: _ } = victim.kind() else { return false; @@ -105,12 +105,14 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>( bug!("should not have assembled a CoherenceUnknowable candidate") } + // In the old trait solver, we arbitrarily choose lower vtable candidates + // over higher ones. + ( + CandidateSource::BuiltinImpl(BuiltinImplSource::Object { vtable_base: a }), + CandidateSource::BuiltinImpl(BuiltinImplSource::Object { vtable_base: b }), + ) => a >= b, // Prefer dyn candidates over non-dyn candidates. This is necessary to // handle the unsoundness between `impl Any for T` and `dyn Any: Any`. - ( - CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }), - CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }), - ) => false, ( CandidateSource::Impl(_) | CandidateSource::ParamEnv(_) | CandidateSource::AliasBound, CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }), diff --git a/tests/ui/traits/normalize-supertrait.rs b/tests/ui/traits/normalize-supertrait.rs index 1ab2b8ecfc108..3ba4a8b8bab31 100644 --- a/tests/ui/traits/normalize-supertrait.rs +++ b/tests/ui/traits/normalize-supertrait.rs @@ -4,6 +4,9 @@ // comparing the supertrait `Derived<()>` to the expected trait. //@ build-pass +//@ revisions: current next +//@ ignore-compare-mode-next-solver (explicit revisions) +//@[next] compile-flags: -Znext-solver trait Proj { type S;