Skip to content

Commit 6a76cd3

Browse files
committed
blanket impls uwu
1 parent 078c52f commit 6a76cd3

File tree

7 files changed

+48
-9
lines changed

7 files changed

+48
-9
lines changed

compiler/rustc_middle/src/ty/context.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
631631
| ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
632632
}
633633

634-
let trait_impls = tcx.trait_impls_of(trait_def_id);
634+
#[allow(rustc::usage_of_type_ir_traits)]
635+
self.for_each_blanket_impl(trait_def_id, f)
636+
}
637+
fn for_each_blanket_impl(self, trait_def_id: DefId, mut f: impl FnMut(DefId)) {
638+
let trait_impls = self.trait_impls_of(trait_def_id);
635639
for &impl_def_id in trait_impls.blanket_impls() {
636640
f(impl_def_id);
637641
}

compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ where
188188
ecx: &mut EvalCtxt<'_, D>,
189189
goal: Goal<I, Self>,
190190
impl_def_id: I::DefId,
191+
finalize: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResult<I>,
191192
) -> Result<Candidate<I>, NoSolution>;
192193

193194
/// If the predicate contained an error, we want to avoid emitting unnecessary trait
@@ -491,7 +492,9 @@ where
491492
return;
492493
}
493494

494-
match G::consider_impl_candidate(self, goal, impl_def_id) {
495+
match G::consider_impl_candidate(self, goal, impl_def_id, |ecx, certainty| {
496+
ecx.evaluate_added_goals_and_make_canonical_response(certainty)
497+
}) {
495498
Ok(candidate) => candidates.push(candidate),
496499
Err(NoSolution) => (),
497500
}
@@ -959,13 +962,14 @@ where
959962
self_ty: I::Ty,
960963
candidates: &mut Vec<Candidate<I>>,
961964
) {
965+
let mut is_hidden_type_of_alias = false;
962966
for alias_ty in self.find_sup_as_registered_opaque(self_ty) {
967+
is_hidden_type_of_alias = true;
963968
for item_bound in self
964969
.cx()
965970
.item_self_bounds(alias_ty.def_id)
966971
.iter_instantiated(self.cx(), alias_ty.args)
967972
{
968-
// TODO: comment
969973
let assumption =
970974
item_bound.fold_with(&mut ReplaceOpaque { cx: self.cx(), alias_ty, self_ty });
971975
candidates.extend(G::probe_and_match_goal_against_assumption(
@@ -999,6 +1003,31 @@ where
9991003
}
10001004
}
10011005

1006+
if is_hidden_type_of_alias {
1007+
let cx = self.cx();
1008+
cx.for_each_blanket_impl(goal.predicate.trait_def_id(cx), |impl_def_id| {
1009+
// For every `default impl`, there's always a non-default `impl`
1010+
// that will *also* apply. There's no reason to register a candidate
1011+
// for this impl, since it is *not* proof that the trait goal holds.
1012+
if cx.impl_is_default(impl_def_id) {
1013+
return;
1014+
}
1015+
1016+
match G::consider_impl_candidate(self, goal, impl_def_id, |ecx, certainty| {
1017+
if ecx.shallow_resolve(self_ty).is_ty_var() {
1018+
ecx.evaluate_added_goals_and_make_canonical_response(
1019+
certainty.and(Certainty::AMBIGUOUS),
1020+
)
1021+
} else {
1022+
Err(NoSolution)
1023+
}
1024+
}) {
1025+
Ok(candidate) => candidates.push(candidate),
1026+
Err(NoSolution) => (),
1027+
}
1028+
});
1029+
}
1030+
10021031
if candidates.is_empty() {
10031032
candidates.extend(self.forced_ambiguity(MaybeCause::Ambiguity));
10041033
}

compiler/rustc_next_trait_solver/src/solve/effect_goals.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ where
124124
ecx: &mut EvalCtxt<'_, D>,
125125
goal: Goal<I, Self>,
126126
impl_def_id: I::DefId,
127+
finalize: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResult<I>,
127128
) -> Result<Candidate<I>, NoSolution> {
128129
let cx = ecx.cx();
129130

@@ -175,7 +176,7 @@ where
175176
});
176177
ecx.add_goals(GoalSource::ImplWhereBound, const_conditions);
177178

178-
ecx.evaluate_added_goals_and_make_canonical_response(certainty)
179+
finalize(ecx, certainty)
179180
})
180181
}
181182

compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,10 @@ where
10471047
self.delegate.resolve_vars_if_possible(value)
10481048
}
10491049

1050+
pub(super) fn shallow_resolve(&self, ty: I::Ty) -> I::Ty {
1051+
self.delegate.shallow_resolve(ty)
1052+
}
1053+
10501054
pub(super) fn eager_resolve_region(&self, r: I::Region) -> I::Region {
10511055
if let ty::ReVar(vid) = r.kind() {
10521056
self.delegate.opportunistic_resolve_lt_var(vid)

compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ where
194194
ecx: &mut EvalCtxt<'_, D>,
195195
goal: Goal<I, NormalizesTo<I>>,
196196
impl_def_id: I::DefId,
197+
finalize: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResult<I>,
197198
) -> Result<Candidate<I>, NoSolution> {
198199
let cx = ecx.cx();
199200

@@ -314,8 +315,7 @@ where
314315
// nested goal for consistency.
315316
ty::TypingMode::Coherence => {
316317
ecx.add_goal(GoalSource::Misc, goal.with(cx, PredicateKind::Ambiguous));
317-
return ecx
318-
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
318+
return finalize(ecx, Certainty::Yes);
319319
}
320320
ty::TypingMode::Analysis { .. }
321321
| ty::TypingMode::Borrowck { .. }
@@ -325,8 +325,7 @@ where
325325
goal,
326326
goal.predicate.alias,
327327
);
328-
return ecx
329-
.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
328+
return finalize(ecx, Certainty::Yes);
330329
}
331330
}
332331
} else {

compiler/rustc_next_trait_solver/src/solve/trait_goals.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ where
5555
ecx: &mut EvalCtxt<'_, D>,
5656
goal: Goal<I, TraitPredicate<I>>,
5757
impl_def_id: I::DefId,
58+
finalize: impl FnOnce(&mut EvalCtxt<'_, D>, Certainty) -> QueryResult<I>,
5859
) -> Result<Candidate<I>, NoSolution> {
5960
let cx = ecx.cx();
6061

@@ -112,7 +113,7 @@ where
112113
.map(|pred| goal.with(cx, pred)),
113114
);
114115

115-
ecx.evaluate_added_goals_and_make_canonical_response(maximal_certainty)
116+
finalize(ecx, maximal_certainty)
116117
})
117118
}
118119

compiler/rustc_type_ir/src/interner.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,7 @@ pub trait Interner:
334334
self_ty: Self::Ty,
335335
f: impl FnMut(Self::DefId),
336336
);
337+
fn for_each_blanket_impl(self, trait_def_id: Self::TraitId, f: impl FnMut(Self::DefId));
337338

338339
fn has_item_definition(self, def_id: Self::DefId) -> bool;
339340

0 commit comments

Comments
 (0)