diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-05-06 18:50:35 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-06 18:50:35 +0200 |
| commit | 2d557ba9f4cbc1cdc01a515864867c12e3b85ad1 (patch) | |
| tree | 3ff6e0bc6ce71a8145fb6547d56be1ad6d001664 | |
| parent | 44cbf7d8537738cc155503df66e19bdb754bf458 (diff) | |
| parent | a4ee20eb130895cb253015c1fb36e5e18148e1ce (diff) | |
| download | rust-2d557ba9f4cbc1cdc01a515864867c12e3b85ad1.tar.gz rust-2d557ba9f4cbc1cdc01a515864867c12e3b85ad1.zip | |
Rollup merge of #124724 - compiler-errors:prefer-lower, r=lcnr
Prefer lower vtable candidates in select in new solver Also, adjust the select visitor to only winnow when the *parent* goal is `Certainty::Yes`. This means that we won't winnow in cases when we have any ambiguous inference guidance from two candidates. r? lcnr
| -rw-r--r-- | compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs | 18 | ||||
| -rw-r--r-- | 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,13 +111,15 @@ 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<T: ?Sized> 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 { .. }), ) => true, 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; |
