@@ -295,6 +295,32 @@ where
295
295
result
296
296
}
297
297
298
+ #[ instrument( level = "info" , skip( selcx, param_env, cause, obligations) ) ]
299
+ pub fn try_normalize_with_depth_to < ' a , ' b , ' tcx , T > (
300
+ selcx : & ' a mut SelectionContext < ' b , ' tcx > ,
301
+ param_env : ty:: ParamEnv < ' tcx > ,
302
+ cause : ObligationCause < ' tcx > ,
303
+ depth : usize ,
304
+ value : T ,
305
+ obligations : & mut Vec < PredicateObligation < ' tcx > > ,
306
+ ) -> T
307
+ where
308
+ T : TypeFoldable < ' tcx > ,
309
+ {
310
+ debug ! ( obligations. len = obligations. len( ) ) ;
311
+ let mut normalizer = AssocTypeNormalizer :: new_without_eager_inference_replacement (
312
+ selcx,
313
+ param_env,
314
+ cause,
315
+ depth,
316
+ obligations,
317
+ ) ;
318
+ let result = ensure_sufficient_stack ( || normalizer. fold ( value) ) ;
319
+ debug ! ( ?result, obligations. len = normalizer. obligations. len( ) ) ;
320
+ debug ! ( ?normalizer. obligations, ) ;
321
+ result
322
+ }
323
+
298
324
pub ( crate ) fn needs_normalization < ' tcx , T : TypeFoldable < ' tcx > > ( value : & T , reveal : Reveal ) -> bool {
299
325
match reveal {
300
326
Reveal :: UserFacing => value
@@ -314,6 +340,10 @@ struct AssocTypeNormalizer<'a, 'b, 'tcx> {
314
340
obligations : & ' a mut Vec < PredicateObligation < ' tcx > > ,
315
341
depth : usize ,
316
342
universes : Vec < Option < ty:: UniverseIndex > > ,
343
+ /// If true, when a projection is unable to be completed, an inference
344
+ /// variable will be created and an obligation registered to project to that
345
+ /// inference variable. Also, constants will be eagerly evaluated.
346
+ eager_inference_replacement : bool ,
317
347
}
318
348
319
349
impl < ' a , ' b , ' tcx > AssocTypeNormalizer < ' a , ' b , ' tcx > {
@@ -324,7 +354,33 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
324
354
depth : usize ,
325
355
obligations : & ' a mut Vec < PredicateObligation < ' tcx > > ,
326
356
) -> AssocTypeNormalizer < ' a , ' b , ' tcx > {
327
- AssocTypeNormalizer { selcx, param_env, cause, obligations, depth, universes : vec ! [ ] }
357
+ AssocTypeNormalizer {
358
+ selcx,
359
+ param_env,
360
+ cause,
361
+ obligations,
362
+ depth,
363
+ universes : vec ! [ ] ,
364
+ eager_inference_replacement : true ,
365
+ }
366
+ }
367
+
368
+ fn new_without_eager_inference_replacement (
369
+ selcx : & ' a mut SelectionContext < ' b , ' tcx > ,
370
+ param_env : ty:: ParamEnv < ' tcx > ,
371
+ cause : ObligationCause < ' tcx > ,
372
+ depth : usize ,
373
+ obligations : & ' a mut Vec < PredicateObligation < ' tcx > > ,
374
+ ) -> AssocTypeNormalizer < ' a , ' b , ' tcx > {
375
+ AssocTypeNormalizer {
376
+ selcx,
377
+ param_env,
378
+ cause,
379
+ obligations,
380
+ depth,
381
+ universes : vec ! [ ] ,
382
+ eager_inference_replacement : false ,
383
+ }
328
384
}
329
385
330
386
fn fold < T : TypeFoldable < ' tcx > > ( & mut self , value : T ) -> T {
@@ -428,14 +484,28 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
428
484
// there won't be bound vars there.
429
485
430
486
let data = data. super_fold_with ( self ) ;
431
- let normalized_ty = normalize_projection_type (
432
- self . selcx ,
433
- self . param_env ,
434
- data,
435
- self . cause . clone ( ) ,
436
- self . depth ,
437
- & mut self . obligations ,
438
- ) ;
487
+ let normalized_ty = if self . eager_inference_replacement {
488
+ normalize_projection_type (
489
+ self . selcx ,
490
+ self . param_env ,
491
+ data,
492
+ self . cause . clone ( ) ,
493
+ self . depth ,
494
+ & mut self . obligations ,
495
+ )
496
+ } else {
497
+ opt_normalize_projection_type (
498
+ self . selcx ,
499
+ self . param_env ,
500
+ data,
501
+ self . cause . clone ( ) ,
502
+ self . depth ,
503
+ & mut self . obligations ,
504
+ )
505
+ . ok ( )
506
+ . flatten ( )
507
+ . unwrap_or_else ( || ty:: Term :: Ty ( ty. super_fold_with ( self ) ) )
508
+ } ;
439
509
debug ! (
440
510
?self . depth,
441
511
?ty,
@@ -501,7 +571,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
501
571
}
502
572
503
573
fn fold_const ( & mut self , constant : ty:: Const < ' tcx > ) -> ty:: Const < ' tcx > {
504
- if self . selcx . tcx ( ) . lazy_normalization ( ) {
574
+ if self . selcx . tcx ( ) . lazy_normalization ( ) || ! self . eager_inference_replacement {
505
575
constant
506
576
} else {
507
577
let constant = constant. super_fold_with ( self ) ;
0 commit comments