@@ -182,6 +182,9 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
182
182
selcx : & mut SelectionContext < ' cx , ' tcx > ,
183
183
obligation : & PolyProjectionObligation < ' tcx > ,
184
184
) -> ProjectAndUnifyResult < ' tcx > {
185
+ let pre_bound2placeholder_cache_key =
186
+ ProjectionCacheKey :: from_poly_projection_predicate ( selcx, obligation. predicate ) . unwrap ( ) ;
187
+
185
188
let infcx = selcx. infcx ( ) ;
186
189
let r = infcx. commit_if_ok ( |_snapshot| {
187
190
let old_universe = infcx. universe ( ) ;
@@ -190,7 +193,11 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
190
193
let new_universe = infcx. universe ( ) ;
191
194
192
195
let placeholder_obligation = obligation. with ( placeholder_predicate) ;
193
- match project_and_unify_type ( selcx, & placeholder_obligation) {
196
+ match project_and_unify_type (
197
+ selcx,
198
+ & placeholder_obligation,
199
+ Some ( & pre_bound2placeholder_cache_key) ,
200
+ ) {
194
201
ProjectAndUnifyResult :: MismatchedProjectionTypes ( e) => Err ( e) ,
195
202
ProjectAndUnifyResult :: Holds ( obligations)
196
203
if old_universe != new_universe
@@ -235,6 +242,7 @@ pub(super) fn poly_project_and_unify_type<'cx, 'tcx>(
235
242
fn project_and_unify_type < ' cx , ' tcx > (
236
243
selcx : & mut SelectionContext < ' cx , ' tcx > ,
237
244
obligation : & ProjectionObligation < ' tcx > ,
245
+ pre_bound2placeholder_cache_key : Option < & ProjectionCacheKey < ' tcx > > ,
238
246
) -> ProjectAndUnifyResult < ' tcx > {
239
247
let mut obligations = vec ! [ ] ;
240
248
@@ -246,6 +254,7 @@ fn project_and_unify_type<'cx, 'tcx>(
246
254
obligation. cause . clone ( ) ,
247
255
obligation. recursion_depth ,
248
256
& mut obligations,
257
+ pre_bound2placeholder_cache_key,
249
258
) {
250
259
Ok ( Some ( n) ) => n,
251
260
Ok ( None ) => return ProjectAndUnifyResult :: FailedNormalization ,
@@ -539,6 +548,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
539
548
self . cause . clone ( ) ,
540
549
self . depth ,
541
550
& mut self . obligations ,
551
+ None ,
542
552
)
543
553
. ok ( )
544
554
. flatten ( )
@@ -578,6 +588,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
578
588
self . cause . clone ( ) ,
579
589
self . depth ,
580
590
& mut self . obligations ,
591
+ None ,
581
592
)
582
593
. ok ( )
583
594
. flatten ( )
@@ -917,6 +928,7 @@ pub fn normalize_projection_type<'a, 'b, 'tcx>(
917
928
cause. clone ( ) ,
918
929
depth,
919
930
obligations,
931
+ None ,
920
932
)
921
933
. ok ( )
922
934
. flatten ( )
@@ -950,6 +962,7 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
950
962
cause : ObligationCause < ' tcx > ,
951
963
depth : usize ,
952
964
obligations : & mut Vec < PredicateObligation < ' tcx > > ,
965
+ pre_bound2placeholder_cache_key : Option < & ProjectionCacheKey < ' tcx > > ,
953
966
) -> Result < Option < Term < ' tcx > > , InProgress > {
954
967
let infcx = selcx. infcx ( ) ;
955
968
// Don't use the projection cache in intercrate mode -
@@ -1069,6 +1082,20 @@ fn opt_normalize_projection_type<'a, 'b, 'tcx>(
1069
1082
1070
1083
if use_cache {
1071
1084
infcx. inner . borrow_mut ( ) . projection_cache ( ) . insert_term ( cache_key, result. clone ( ) ) ;
1085
+ if let Some ( & pre_bound2placeholder_cache_key) = pre_bound2placeholder_cache_key {
1086
+ if !result. has_placeholders ( ) {
1087
+ // HACK(eddyb) `pre_bound2placeholder_cache_key` was never started.
1088
+ let mut infcx_inner = infcx. inner . borrow_mut ( ) ;
1089
+ if let Ok ( ( ) ) = infcx_inner
1090
+ . projection_cache ( )
1091
+ . try_start ( pre_bound2placeholder_cache_key)
1092
+ {
1093
+ infcx_inner
1094
+ . projection_cache ( )
1095
+ . insert_term ( pre_bound2placeholder_cache_key, result. clone ( ) ) ;
1096
+ }
1097
+ }
1098
+ }
1072
1099
}
1073
1100
obligations. extend ( result. obligations ) ;
1074
1101
Ok ( Some ( result. value ) )
0 commit comments