@@ -450,153 +450,167 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
450450 None => self . check_recursion_limit ( & obligation, & obligation) ?,
451451 }
452452
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+ }
460477
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) => {
466486 self . add_depth ( obligations. iter_mut ( ) , obligation. recursion_depth ) ;
467487 self . evaluate_predicates_recursively (
468488 previous_stack,
469489 obligations. into_iter ( ) ,
470490 )
471491 }
472- Some ( Err ( _) ) => Ok ( EvaluatedToErr ) ,
473492 None => Ok ( EvaluatedToAmbig ) ,
474- }
475- }
493+ } ,
476494
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 )
487498 }
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- }
495499
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+ }
501506 }
502- }
503507
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
518524 }
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 ) ,
520533 }
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 ) ,
529534 }
530- }
531535
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+ }
539544 }
545+ None => Ok ( EvaluatedToAmbig ) ,
540546 }
541- None => Ok ( EvaluatedToAmbig ) ,
542547 }
543- }
544548
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+ }
556561 }
557- }
558562
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+ ) ;
577568
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 )
583606 }
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 )
593607 }
594608 }
609+ ty:: PredicateAtom :: TypeWellFormedFromEnv ( ..) => {
610+ bug ! ( "TypeWellFormedFromEnv is only used for chalk" )
611+ }
595612 }
596- ty:: PredicateAtom :: TypeWellFormedFromEnv ( ..) => {
597- bug ! ( "TypeWellFormedFromEnv is only used for chalk" )
598- }
599- }
613+ } )
600614 }
601615
602616 fn evaluate_trait_predicate_recursively < ' o > (
0 commit comments