@@ -25,29 +25,39 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
25
25
let def_id = goal. predicate . def_id ( ) ;
26
26
match self . tcx ( ) . def_kind ( def_id) {
27
27
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 => {
38
46
let candidates = self . assemble_and_evaluate_candidates ( goal) ;
39
47
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" )
43
51
}
44
52
}
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 )
46
56
}
47
57
}
48
58
DefKind :: AnonConst => self . normalize_anon_const ( goal) ,
49
59
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) ) ,
51
61
}
52
62
}
53
63
@@ -203,17 +213,10 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
203
213
) ;
204
214
205
215
// 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" ) ,
217
220
} ;
218
221
219
222
ecx. eq ( goal. param_env , goal. predicate . term , term. subst ( tcx, substs) )
0 commit comments