From a4ee20eb130895cb253015c1fb36e5e18148e1ce Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Sat, 4 May 2024 15:47:20 -0400 Subject: [PATCH] Prefer lower vtable candidates in select in new solver --- .../src/solve/eval_ctxt/select.rs | 18 +++++++++++++----- tests/ui/traits/normalize-supertrait.rs | 3 +++ 2 files changed, 16 insertions(+), 5 deletions(-) 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 16fe045b82d..4d474b8e707 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, and only on the good path. + 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() { @@ -86,7 +92,7 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>( other: &inspect::InspectCandidate<'_, 'tcx>, ) -> bool { // Don't winnow until `Certainty::Yes` -- we don't need to winnow until - // codegen, technically. + // codegen, and only on the good path. if matches!(other.result().unwrap(), Certainty::Maybe(..)) { return false; } @@ -105,12 +111,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 1ab2b8ecfc1..3ba4a8b8bab 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;