@@ -450,153 +450,167 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
450
450
None => self . check_recursion_limit ( & obligation, & obligation) ?,
451
451
}
452
452
453
- match obligation. predicate . skip_binders ( ) {
454
- ty:: PredicateAtom :: Trait ( t, _) => {
455
- let t = ty:: Binder :: bind ( t) ;
456
- debug_assert ! ( !t. has_escaping_bound_vars( ) ) ;
457
- let obligation = obligation. with ( t) ;
458
- self . evaluate_trait_predicate_recursively ( previous_stack, obligation)
459
- }
453
+ ensure_sufficient_stack ( || {
454
+ match obligation. predicate . skip_binders ( ) {
455
+ ty:: PredicateAtom :: Trait ( t, _) => {
456
+ let t = ty:: Binder :: bind ( t) ;
457
+ debug_assert ! ( !t. has_escaping_bound_vars( ) ) ;
458
+ let obligation = obligation. with ( t) ;
459
+ self . evaluate_trait_predicate_recursively ( previous_stack, obligation)
460
+ }
461
+
462
+ ty:: PredicateAtom :: Subtype ( p) => {
463
+ let p = ty:: Binder :: bind ( p) ;
464
+ // Does this code ever run?
465
+ match self . infcx . subtype_predicate ( & obligation. cause , obligation. param_env , p) {
466
+ Some ( Ok ( InferOk { mut obligations, .. } ) ) => {
467
+ self . add_depth ( obligations. iter_mut ( ) , obligation. recursion_depth ) ;
468
+ self . evaluate_predicates_recursively (
469
+ previous_stack,
470
+ obligations. into_iter ( ) ,
471
+ )
472
+ }
473
+ Some ( Err ( _) ) => Ok ( EvaluatedToErr ) ,
474
+ None => Ok ( EvaluatedToAmbig ) ,
475
+ }
476
+ }
460
477
461
- ty:: PredicateAtom :: Subtype ( p) => {
462
- let p = ty:: Binder :: bind ( p) ;
463
- // Does this code ever run?
464
- match self . infcx . subtype_predicate ( & obligation. cause , obligation. param_env , p) {
465
- Some ( Ok ( InferOk { mut obligations, .. } ) ) => {
478
+ ty:: PredicateAtom :: WellFormed ( arg) => match wf:: obligations (
479
+ self . infcx ,
480
+ obligation. param_env ,
481
+ obligation. cause . body_id ,
482
+ arg,
483
+ obligation. cause . span ,
484
+ ) {
485
+ Some ( mut obligations) => {
466
486
self . add_depth ( obligations. iter_mut ( ) , obligation. recursion_depth ) ;
467
487
self . evaluate_predicates_recursively (
468
488
previous_stack,
469
489
obligations. into_iter ( ) ,
470
490
)
471
491
}
472
- Some ( Err ( _) ) => Ok ( EvaluatedToErr ) ,
473
492
None => Ok ( EvaluatedToAmbig ) ,
474
- }
475
- }
493
+ } ,
476
494
477
- ty:: PredicateAtom :: WellFormed ( arg) => match wf:: obligations (
478
- self . infcx ,
479
- obligation. param_env ,
480
- obligation. cause . body_id ,
481
- arg,
482
- obligation. cause . span ,
483
- ) {
484
- Some ( mut obligations) => {
485
- self . add_depth ( obligations. iter_mut ( ) , obligation. recursion_depth ) ;
486
- self . evaluate_predicates_recursively ( previous_stack, obligations. into_iter ( ) )
495
+ ty:: PredicateAtom :: TypeOutlives ( ..) | ty:: PredicateAtom :: RegionOutlives ( ..) => {
496
+ // We do not consider region relationships when evaluating trait matches.
497
+ Ok ( EvaluatedToOkModuloRegions )
487
498
}
488
- None => Ok ( EvaluatedToAmbig ) ,
489
- } ,
490
-
491
- ty:: PredicateAtom :: TypeOutlives ( ..) | ty:: PredicateAtom :: RegionOutlives ( ..) => {
492
- // We do not consider region relationships when evaluating trait matches.
493
- Ok ( EvaluatedToOkModuloRegions )
494
- }
495
499
496
- ty:: PredicateAtom :: ObjectSafe ( trait_def_id) => {
497
- if self . tcx ( ) . is_object_safe ( trait_def_id) {
498
- Ok ( EvaluatedToOk )
499
- } else {
500
- Ok ( EvaluatedToErr )
500
+ ty:: PredicateAtom :: ObjectSafe ( trait_def_id) => {
501
+ if self . tcx ( ) . is_object_safe ( trait_def_id) {
502
+ Ok ( EvaluatedToOk )
503
+ } else {
504
+ Ok ( EvaluatedToErr )
505
+ }
501
506
}
502
- }
503
507
504
- ty:: PredicateAtom :: Projection ( data) => {
505
- let data = ty:: Binder :: bind ( data) ;
506
- let project_obligation = obligation. with ( data) ;
507
- match project:: poly_project_and_unify_type ( self , & project_obligation) {
508
- Ok ( Ok ( Some ( mut subobligations) ) ) => {
509
- self . add_depth ( subobligations. iter_mut ( ) , obligation. recursion_depth ) ;
510
- let result = self . evaluate_predicates_recursively (
511
- previous_stack,
512
- subobligations. into_iter ( ) ,
513
- ) ;
514
- if let Some ( key) =
515
- ProjectionCacheKey :: from_poly_projection_predicate ( self , data)
516
- {
517
- self . infcx . inner . borrow_mut ( ) . projection_cache ( ) . complete ( key) ;
508
+ ty:: PredicateAtom :: Projection ( data) => {
509
+ let data = ty:: Binder :: bind ( data) ;
510
+ let project_obligation = obligation. with ( data) ;
511
+ match project:: poly_project_and_unify_type ( self , & project_obligation) {
512
+ Ok ( Ok ( Some ( mut subobligations) ) ) => {
513
+ self . add_depth ( subobligations. iter_mut ( ) , obligation. recursion_depth ) ;
514
+ let result = self . evaluate_predicates_recursively (
515
+ previous_stack,
516
+ subobligations. into_iter ( ) ,
517
+ ) ;
518
+ if let Some ( key) =
519
+ ProjectionCacheKey :: from_poly_projection_predicate ( self , data)
520
+ {
521
+ self . infcx . inner . borrow_mut ( ) . projection_cache ( ) . complete ( key) ;
522
+ }
523
+ result
518
524
}
519
- result
525
+ Ok ( Ok ( None ) ) => Ok ( EvaluatedToAmbig ) ,
526
+ // EvaluatedToRecur might also be acceptable here, but use
527
+ // Unknown for now because it means that we won't dismiss a
528
+ // selection candidate solely because it has a projection
529
+ // cycle. This is closest to the previous behavior of
530
+ // immediately erroring.
531
+ Ok ( Err ( project:: InProgress ) ) => Ok ( EvaluatedToUnknown ) ,
532
+ Err ( _) => Ok ( EvaluatedToErr ) ,
520
533
}
521
- Ok ( Ok ( None ) ) => Ok ( EvaluatedToAmbig ) ,
522
- // EvaluatedToRecur might also be acceptable here, but use
523
- // Unknown for now because it means that we won't dismiss a
524
- // selection candidate solely because it has a projection
525
- // cycle. This is closest to the previous behavior of
526
- // immediately erroring.
527
- Ok ( Err ( project:: InProgress ) ) => Ok ( EvaluatedToUnknown ) ,
528
- Err ( _) => Ok ( EvaluatedToErr ) ,
529
534
}
530
- }
531
535
532
- ty:: PredicateAtom :: ClosureKind ( _, closure_substs, kind) => {
533
- match self . infcx . closure_kind ( closure_substs) {
534
- Some ( closure_kind) => {
535
- if closure_kind. extends ( kind) {
536
- Ok ( EvaluatedToOk )
537
- } else {
538
- Ok ( EvaluatedToErr )
536
+ ty:: PredicateAtom :: ClosureKind ( _, closure_substs, kind) => {
537
+ match self . infcx . closure_kind ( closure_substs) {
538
+ Some ( closure_kind) => {
539
+ if closure_kind. extends ( kind) {
540
+ Ok ( EvaluatedToOk )
541
+ } else {
542
+ Ok ( EvaluatedToErr )
543
+ }
539
544
}
545
+ None => Ok ( EvaluatedToAmbig ) ,
540
546
}
541
- None => Ok ( EvaluatedToAmbig ) ,
542
547
}
543
- }
544
548
545
- ty:: PredicateAtom :: ConstEvaluatable ( def_id, substs) => {
546
- match const_evaluatable:: is_const_evaluatable (
547
- self . infcx ,
548
- def_id,
549
- substs,
550
- obligation. param_env ,
551
- obligation. cause . span ,
552
- ) {
553
- Ok ( ( ) ) => Ok ( EvaluatedToOk ) ,
554
- Err ( ErrorHandled :: TooGeneric ) => Ok ( EvaluatedToAmbig ) ,
555
- Err ( _) => Ok ( EvaluatedToErr ) ,
549
+ ty:: PredicateAtom :: ConstEvaluatable ( def_id, substs) => {
550
+ match const_evaluatable:: is_const_evaluatable (
551
+ self . infcx ,
552
+ def_id,
553
+ substs,
554
+ obligation. param_env ,
555
+ obligation. cause . span ,
556
+ ) {
557
+ Ok ( ( ) ) => Ok ( EvaluatedToOk ) ,
558
+ Err ( ErrorHandled :: TooGeneric ) => Ok ( EvaluatedToAmbig ) ,
559
+ Err ( _) => Ok ( EvaluatedToErr ) ,
560
+ }
556
561
}
557
- }
558
562
559
- ty:: PredicateAtom :: ConstEquate ( c1, c2) => {
560
- debug ! ( "evaluate_predicate_recursively: equating consts c1={:?} c2={:?}" , c1, c2) ;
561
-
562
- let evaluate = |c : & ' tcx ty:: Const < ' tcx > | {
563
- if let ty:: ConstKind :: Unevaluated ( def, substs, promoted) = c. val {
564
- self . infcx
565
- . const_eval_resolve (
566
- obligation. param_env ,
567
- def,
568
- substs,
569
- promoted,
570
- Some ( obligation. cause . span ) ,
571
- )
572
- . map ( |val| ty:: Const :: from_value ( self . tcx ( ) , val, c. ty ) )
573
- } else {
574
- Ok ( c)
575
- }
576
- } ;
563
+ ty:: PredicateAtom :: ConstEquate ( c1, c2) => {
564
+ debug ! (
565
+ "evaluate_predicate_recursively: equating consts c1={:?} c2={:?}" ,
566
+ c1, c2
567
+ ) ;
577
568
578
- match ( evaluate ( c1) , evaluate ( c2) ) {
579
- ( Ok ( c1) , Ok ( c2) ) => {
580
- match self . infcx ( ) . at ( & obligation. cause , obligation. param_env ) . eq ( c1, c2) {
581
- Ok ( _) => Ok ( EvaluatedToOk ) ,
582
- Err ( _) => Ok ( EvaluatedToErr ) ,
569
+ let evaluate = |c : & ' tcx ty:: Const < ' tcx > | {
570
+ if let ty:: ConstKind :: Unevaluated ( def, substs, promoted) = c. val {
571
+ self . infcx
572
+ . const_eval_resolve (
573
+ obligation. param_env ,
574
+ def,
575
+ substs,
576
+ promoted,
577
+ Some ( obligation. cause . span ) ,
578
+ )
579
+ . map ( |val| ty:: Const :: from_value ( self . tcx ( ) , val, c. ty ) )
580
+ } else {
581
+ Ok ( c)
582
+ }
583
+ } ;
584
+
585
+ match ( evaluate ( c1) , evaluate ( c2) ) {
586
+ ( Ok ( c1) , Ok ( c2) ) => {
587
+ match self
588
+ . infcx ( )
589
+ . at ( & obligation. cause , obligation. param_env )
590
+ . eq ( c1, c2)
591
+ {
592
+ Ok ( _) => Ok ( EvaluatedToOk ) ,
593
+ Err ( _) => Ok ( EvaluatedToErr ) ,
594
+ }
595
+ }
596
+ ( Err ( ErrorHandled :: Reported ( ErrorReported ) ) , _)
597
+ | ( _, Err ( ErrorHandled :: Reported ( ErrorReported ) ) ) => Ok ( EvaluatedToErr ) ,
598
+ ( Err ( ErrorHandled :: Linted ) , _) | ( _, Err ( ErrorHandled :: Linted ) ) => {
599
+ span_bug ! (
600
+ obligation. cause. span( self . tcx( ) ) ,
601
+ "ConstEquate: const_eval_resolve returned an unexpected error"
602
+ )
603
+ }
604
+ ( Err ( ErrorHandled :: TooGeneric ) , _) | ( _, Err ( ErrorHandled :: TooGeneric ) ) => {
605
+ Ok ( EvaluatedToAmbig )
583
606
}
584
- }
585
- ( Err ( ErrorHandled :: Reported ( ErrorReported ) ) , _)
586
- | ( _, Err ( ErrorHandled :: Reported ( ErrorReported ) ) ) => Ok ( EvaluatedToErr ) ,
587
- ( Err ( ErrorHandled :: Linted ) , _) | ( _, Err ( ErrorHandled :: Linted ) ) => span_bug ! (
588
- obligation. cause. span( self . tcx( ) ) ,
589
- "ConstEquate: const_eval_resolve returned an unexpected error"
590
- ) ,
591
- ( Err ( ErrorHandled :: TooGeneric ) , _) | ( _, Err ( ErrorHandled :: TooGeneric ) ) => {
592
- Ok ( EvaluatedToAmbig )
593
607
}
594
608
}
609
+ ty:: PredicateAtom :: TypeWellFormedFromEnv ( ..) => {
610
+ bug ! ( "TypeWellFormedFromEnv is only used for chalk" )
611
+ }
595
612
}
596
- ty:: PredicateAtom :: TypeWellFormedFromEnv ( ..) => {
597
- bug ! ( "TypeWellFormedFromEnv is only used for chalk" )
598
- }
599
- }
613
+ } )
600
614
}
601
615
602
616
fn evaluate_trait_predicate_recursively < ' o > (
0 commit comments