Prefer lower vtable candidates in select in new solver
This commit is contained in:
parent
d568423a7a
commit
a4ee20eb13
2 changed files with 16 additions and 5 deletions
|
@ -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`.
|
// We need to winnow. See comments on `candidate_should_be_dropped_in_favor_of`.
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while i < candidates.len() {
|
while i < candidates.len() {
|
||||||
|
@ -86,7 +92,7 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
|
||||||
other: &inspect::InspectCandidate<'_, 'tcx>,
|
other: &inspect::InspectCandidate<'_, 'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
// Don't winnow until `Certainty::Yes` -- we don't need to winnow until
|
// 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(..)) {
|
if matches!(other.result().unwrap(), Certainty::Maybe(..)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -105,12 +111,14 @@ fn candidate_should_be_dropped_in_favor_of<'tcx>(
|
||||||
bug!("should not have assembled a CoherenceUnknowable candidate")
|
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
|
// 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`.
|
// 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::Impl(_) | CandidateSource::ParamEnv(_) | CandidateSource::AliasBound,
|
||||||
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }),
|
CandidateSource::BuiltinImpl(BuiltinImplSource::Object { .. }),
|
||||||
|
|
|
@ -4,6 +4,9 @@
|
||||||
// comparing the supertrait `Derived<()>` to the expected trait.
|
// comparing the supertrait `Derived<()>` to the expected trait.
|
||||||
|
|
||||||
//@ build-pass
|
//@ build-pass
|
||||||
|
//@ revisions: current next
|
||||||
|
//@ ignore-compare-mode-next-solver (explicit revisions)
|
||||||
|
//@[next] compile-flags: -Znext-solver
|
||||||
|
|
||||||
trait Proj {
|
trait Proj {
|
||||||
type S;
|
type S;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue