Skip to content

Commit 84196f3

Browse files
Elaborate comment, make sure we do normalizes-to hack eventually for IATs, don't partially support const projection for impls
1 parent 8912015 commit 84196f3

File tree

1 file changed

+29
-26
lines changed

1 file changed

+29
-26
lines changed

compiler/rustc_trait_selection/src/solve/project_goals.rs

+29-26
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,39 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
2525
let def_id = goal.predicate.def_id();
2626
match self.tcx().def_kind(def_id) {
2727
DefKind::AssocTy | DefKind::AssocConst => {
28-
match self.tcx().associated_item(def_id).container {
29-
ty::AssocItemContainer::TraitContainer => {
30-
// To only compute normalization once for each projection we only
31-
// normalize if the expected term is an unconstrained inference variable.
32-
//
33-
// E.g. for `<T as Trait>::Assoc == u32` we recursively compute the goal
34-
// `exists<U> <T as Trait>::Assoc == U` and then take the resulting type for
35-
// `U` and equate it with `u32`. This means that we don't need a separate
36-
// projection cache in the solver.
37-
if self.term_is_fully_unconstrained(goal) {
28+
// To only compute normalization once for each projection we only
29+
// assemble normalization candidates if the expected term is an
30+
// unconstrained inference variable.
31+
//
32+
// Why: For better cache hits, since if we have an unconstrained RHS then
33+
// there are only as many cache keys as there are (canonicalized) alias
34+
// types in each normalizes-to goal. This also weakens inference in a
35+
// forwards-compatible way so we don't use the value of the RHS term to
36+
// affect candidate assembly for projections.
37+
//
38+
// E.g. for `<T as Trait>::Assoc == u32` we recursively compute the goal
39+
// `exists<U> <T as Trait>::Assoc == U` and then take the resulting type for
40+
// `U` and equate it with `u32`. This means that we don't need a separate
41+
// projection cache in the solver, since we're piggybacking off of regular
42+
// goal caching.
43+
if self.term_is_fully_unconstrained(goal) {
44+
match self.tcx().associated_item(def_id).container {
45+
ty::AssocItemContainer::TraitContainer => {
3846
let candidates = self.assemble_and_evaluate_candidates(goal);
3947
self.merge_candidates(candidates)
40-
} else {
41-
self.set_normalizes_to_hack_goal(goal);
42-
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
48+
}
49+
ty::AssocItemContainer::ImplContainer => {
50+
bug!("IATs not supported here yet")
4351
}
4452
}
45-
ty::AssocItemContainer::ImplContainer => bug!("IATs not supported here yet"),
53+
} else {
54+
self.set_normalizes_to_hack_goal(goal);
55+
self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
4656
}
4757
}
4858
DefKind::AnonConst => self.normalize_anon_const(goal),
4959
DefKind::OpaqueTy => self.normalize_opaque_type(goal),
50-
kind => bug!("uknown DefKind {} in projection goal: {goal:#?}", kind.descr(def_id)),
60+
kind => bug!("unknown DefKind {} in projection goal: {goal:#?}", kind.descr(def_id)),
5161
}
5262
}
5363

@@ -203,17 +213,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
203213
);
204214

205215
// Finally we construct the actual value of the associated type.
206-
let is_const = matches!(tcx.def_kind(assoc_def.item.def_id), DefKind::AssocConst);
207-
let ty = tcx.type_of(assoc_def.item.def_id);
208-
let term: ty::EarlyBinder<ty::Term<'tcx>> = if is_const {
209-
let identity_substs =
210-
ty::InternalSubsts::identity_for_item(tcx, assoc_def.item.def_id);
211-
let did = assoc_def.item.def_id;
212-
let kind =
213-
ty::ConstKind::Unevaluated(ty::UnevaluatedConst::new(did, identity_substs));
214-
ty.map_bound(|ty| tcx.mk_const(kind, ty).into())
215-
} else {
216-
ty.map_bound(|ty| ty.into())
216+
let term = match assoc_def.item.kind {
217+
ty::AssocKind::Type => tcx.type_of(assoc_def.item.def_id).map_bound(|ty| ty.into()),
218+
ty::AssocKind::Const => bug!("associated const projection is not supported yet"),
219+
ty::AssocKind::Fn => unreachable!("we should never project to a fn"),
217220
};
218221

219222
ecx.eq(goal.param_env, goal.predicate.term, term.subst(tcx, substs))

0 commit comments

Comments
 (0)