diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs index c0d591430f7fc..96750e4ab8534 100644 --- a/compiler/rustc_middle/src/ty/instance.rs +++ b/compiler/rustc_middle/src/ty/instance.rs @@ -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) ), } 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 466a03e21639c..18332d6811d56 100644 --- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs +++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs @@ -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, } } diff --git a/tests/ui/traits/new-solver/winnow-specializing-impls.rs b/tests/ui/traits/new-solver/winnow-specializing-impls.rs new file mode 100644 index 0000000000000..06f64de74030c --- /dev/null +++ b/tests/ui/traits/new-solver/winnow-specializing-impls.rs @@ -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 Foo for T { + default fn bar() {} +} + +impl Foo for () { + fn bar() {} +} + +fn main() { + <() as Foo>::bar(); +}