Skip to content

Commit d2a1803

Browse files
Winnow specializing impls
1 parent 9227ff2 commit d2a1803

File tree

3 files changed

+37
-4
lines changed

3 files changed

+37
-4
lines changed

compiler/rustc_middle/src/ty/instance.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -410,8 +410,8 @@ impl<'tcx> Instance<'tcx> {
410410
) -> Instance<'tcx> {
411411
match ty::Instance::resolve(tcx, param_env, def_id, substs) {
412412
Ok(Some(instance)) => instance,
413-
_ => bug!(
414-
"failed to resolve instance for {}",
413+
instance => bug!(
414+
"failed to resolve instance for {}: {instance:#?}",
415415
tcx.def_path_str_with_substs(def_id, substs)
416416
),
417417
}

compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ impl<'tcx> InferCtxtSelectExt<'tcx> for InferCtxt<'tcx> {
5252
let mut i = 0;
5353
while i < candidates.len() {
5454
let should_drop_i = (0..candidates.len()).filter(|&j| i != j).any(|j| {
55-
candidate_should_be_dropped_in_favor_of(&candidates[i], &candidates[j])
55+
candidate_should_be_dropped_in_favor_of(
56+
ecx.tcx(),
57+
&candidates[i],
58+
&candidates[j],
59+
)
5660
});
5761
if should_drop_i {
5862
candidates.swap_remove(i);
@@ -160,12 +164,19 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
160164
}
161165

162166
fn candidate_should_be_dropped_in_favor_of<'tcx>(
167+
tcx: TyCtxt<'tcx>,
163168
victim: &Candidate<'tcx>,
164169
other: &Candidate<'tcx>,
165170
) -> bool {
166171
match (victim.source, other.source) {
167-
(CandidateSource::ParamEnv(i), CandidateSource::ParamEnv(j)) => i >= j,
172+
(CandidateSource::ParamEnv(victim_idx), CandidateSource::ParamEnv(other_idx)) => {
173+
victim_idx >= other_idx
174+
}
168175
(_, CandidateSource::ParamEnv(_)) => true,
176+
(CandidateSource::Impl(victim_def_id), CandidateSource::Impl(other_def_id)) => {
177+
tcx.specializes((other_def_id, victim_def_id))
178+
&& other.result.value.certainty == Certainty::Yes
179+
}
169180
_ => false,
170181
}
171182
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// build-pass
2+
// compile-flags: -Ztrait-solver=next
3+
4+
// Tests that the specializing impl `<() as Foo>` holds during codegen.
5+
6+
#![feature(min_specialization)]
7+
8+
trait Foo {
9+
fn bar();
10+
}
11+
12+
impl<T> Foo for T {
13+
default fn bar() {}
14+
}
15+
16+
impl Foo for () {
17+
fn bar() {}
18+
}
19+
20+
fn main() {
21+
<() as Foo>::bar();
22+
}

0 commit comments

Comments
 (0)