Winnow specializing impls
This commit is contained in:
parent
9227ff28af
commit
d2a1803d6f
3 changed files with 37 additions and 4 deletions
|
@ -410,8 +410,8 @@ impl<'tcx> Instance<'tcx> {
|
|||
) -> Instance<'tcx> {
|
||||
match ty::Instance::resolve(tcx, param_env, def_id, substs) {
|
||||
Ok(Some(instance)) => instance,
|
||||
_ => bug!(
|
||||
"failed to resolve instance for {}",
|
||||
instance => bug!(
|
||||
"failed to resolve instance for {}: {instance:#?}",
|
||||
tcx.def_path_str_with_substs(def_id, substs)
|
||||
),
|
||||
}
|
||||
|
|
|
@ -52,7 +52,11 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
|
|||
let mut i = 0;
|
||||
while i < candidates.len() {
|
||||
let should_drop_i = (0..candidates.len()).filter(|&j| i != j).any(|j| {
|
||||
candidate_should_be_dropped_in_favor_of(&candidates[i], &candidates[j])
|
||||
candidate_should_be_dropped_in_favor_of(
|
||||
ecx.tcx(),
|
||||
&candidates[i],
|
||||
&candidates[j],
|
||||
)
|
||||
});
|
||||
if should_drop_i {
|
||||
candidates.swap_remove(i);
|
||||
|
@ -160,12 +164,19 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
|||
}
|
||||
|
||||
fn candidate_should_be_dropped_in_favor_of<'tcx>(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
victim: &Candidate<'tcx>,
|
||||
other: &Candidate<'tcx>,
|
||||
) -> bool {
|
||||
match (victim.source, other.source) {
|
||||
(CandidateSource::ParamEnv(i), CandidateSource::ParamEnv(j)) => i >= j,
|
||||
(CandidateSource::ParamEnv(victim_idx), CandidateSource::ParamEnv(other_idx)) => {
|
||||
victim_idx >= other_idx
|
||||
}
|
||||
(_, CandidateSource::ParamEnv(_)) => true,
|
||||
(CandidateSource::Impl(victim_def_id), CandidateSource::Impl(other_def_id)) => {
|
||||
tcx.specializes((other_def_id, victim_def_id))
|
||||
&& other.result.value.certainty == Certainty::Yes
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
22
tests/ui/traits/new-solver/winnow-specializing-impls.rs
Normal file
22
tests/ui/traits/new-solver/winnow-specializing-impls.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
// build-pass
|
||||
// compile-flags: -Ztrait-solver=next
|
||||
|
||||
// Tests that the specializing impl `<() as Foo>` holds during codegen.
|
||||
|
||||
#![feature(min_specialization)]
|
||||
|
||||
trait Foo {
|
||||
fn bar();
|
||||
}
|
||||
|
||||
impl<T> Foo for T {
|
||||
default fn bar() {}
|
||||
}
|
||||
|
||||
impl Foo for () {
|
||||
fn bar() {}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
<() as Foo>::bar();
|
||||
}
|
Loading…
Add table
Reference in a new issue