@@ -42,7 +42,7 @@ use rustc_data_structures::bit_set::GrowableBitSet;
4242use rustc_data_structures:: sync:: Lock ;
4343use rustc_target:: spec:: abi:: Abi ;
4444use std:: cmp;
45- use std:: fmt:: { self , Display } ;
45+ use std:: fmt;
4646use std:: iter;
4747use std:: rc:: Rc ;
4848use util:: nodemap:: { FxHashMap , FxHashSet } ;
@@ -573,9 +573,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
573573
574574 let stack = self . push_stack ( TraitObligationStackList :: empty ( ) , obligation) ;
575575
576- // 'select' is an entry point into SelectionContext - we never call it recursively
577- // from within SelectionContext. Therefore, we start our recursion depth at 0
578- let candidate = match self . candidate_from_obligation ( & stack, 0 ) {
576+ let candidate = match self . candidate_from_obligation ( & stack) {
579577 Err ( SelectionError :: Overflow ) => {
580578 // In standard mode, overflow must have been caught and reported
581579 // earlier.
@@ -631,9 +629,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
631629 obligation : & PredicateObligation < ' tcx > ,
632630 ) -> Result < EvaluationResult , OverflowError > {
633631 self . evaluation_probe ( |this| {
634- // Like 'select', 'evaluate_obligation_recursively' is an entry point into
635- // SelectionContext, so our recursion depth is 0
636- this. evaluate_predicate_recursively ( TraitObligationStackList :: empty ( ) , obligation, 0 )
632+ this. evaluate_predicate_recursively ( TraitObligationStackList :: empty ( ) , obligation. clone ( ) )
637633 } )
638634 }
639635
@@ -657,15 +653,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
657653 & mut self ,
658654 stack : TraitObligationStackList < ' o , ' tcx > ,
659655 predicates : I ,
660- recursion_depth : usize
661656 ) -> Result < EvaluationResult , OverflowError >
662657 where
663- I : IntoIterator < Item = & ' a PredicateObligation < ' tcx > > ,
658+ I : IntoIterator < Item = PredicateObligation < ' tcx > > ,
664659 ' tcx : ' a ,
665660 {
666661 let mut result = EvaluatedToOk ;
667662 for obligation in predicates {
668- let eval = self . evaluate_predicate_recursively ( stack, obligation, recursion_depth ) ?;
663+ let eval = self . evaluate_predicate_recursively ( stack, obligation) ?;
669664 debug ! (
670665 "evaluate_predicate_recursively({:?}) = {:?}" ,
671666 obligation, eval
@@ -684,32 +679,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
684679 fn evaluate_predicate_recursively < ' o > (
685680 & mut self ,
686681 previous_stack : TraitObligationStackList < ' o , ' tcx > ,
687- obligation : & PredicateObligation < ' tcx > ,
688- mut recursion_depth : usize
682+ obligation : PredicateObligation < ' tcx > ,
689683 ) -> Result < EvaluationResult , OverflowError > {
690- debug ! ( "evaluate_predicate_recursively({:?}, recursion_depth={:?})" , obligation,
691- recursion_depth) ;
692-
693- // We need to check for overflow here, since the normal
694- // recursion check uses the obligation from the stack.
695- // This is insufficient for two reasions:
696- // 1. That recursion depth is only incremented when a candidate is confirmed
697- // Since evaluation skips candidate confirmation, this will never happen
698- // 2. It relies on the trait obligation stack. However, it's possible for overflow
699- // to happen without involving the trait obligation stack. For example,
700- // we might end up trying to infinitely recurse with a projection predicate,
701- // which will never push anything onto the stack.
702- self . check_recursion_limit ( recursion_depth, obligation) ?;
703-
704- // Now that we know that the recursion check has passed, increment our depth
705- recursion_depth += 1 ;
684+ debug ! ( "evaluate_predicate_recursively({:?})" , obligation) ;
685+ self . check_recursion_limit ( obligation) ?;
706686
707687 match obligation. predicate {
708688 ty:: Predicate :: Trait ( ref t) => {
709689 debug_assert ! ( !t. has_escaping_bound_vars( ) ) ;
710- let obligation = obligation. with ( t. clone ( ) ) ;
711- self . evaluate_trait_predicate_recursively ( previous_stack , obligation ,
712- recursion_depth )
690+ let mut obligation = obligation. with ( t. clone ( ) ) ;
691+ obligation . recursion_depth += 1
692+ self . evaluate_trait_predicate_recursively ( previous_stack , obligation )
713693 }
714694
715695 ty:: Predicate :: Subtype ( ref p) => {
@@ -718,8 +698,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
718698 . subtype_predicate ( & obligation. cause , obligation. param_env , p)
719699 {
720700 Some ( Ok ( InferOk { obligations, .. } ) ) => {
721- self . evaluate_predicates_recursively ( previous_stack, & obligations,
722- recursion_depth)
701+ for o in obligations. iter_mut ( ) {
702+ o. recursion_depth += 1
703+ }
704+ self . evaluate_predicates_recursively ( previous_stack, obligation. into_iter ( ) )
723705 }
724706 Some ( Err ( _) ) => Ok ( EvaluatedToErr ) ,
725707 None => Ok ( EvaluatedToAmbig ) ,
@@ -734,8 +716,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
734716 obligation. cause . span ,
735717 ) {
736718 Some ( obligations) => {
737- self . evaluate_predicates_recursively ( previous_stack, obligations. iter ( ) ,
738- recursion_depth)
719+ for o in obligations. iter_mut ( ) {
720+ o. recursion_depth += 1
721+ }
722+ self . evaluate_predicates_recursively ( previous_stack, obligations. iter ( ) )
739723 }
740724 None => Ok ( EvaluatedToAmbig ) ,
741725 } ,
@@ -758,10 +742,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
758742 let project_obligation = obligation. with ( data. clone ( ) ) ;
759743 match project:: poly_project_and_unify_type ( self , & project_obligation) {
760744 Ok ( Some ( subobligations) ) => {
745+ for o in subobligations. iter_mut ( ) {
746+ o. recursion_depth += 1
747+ }
761748 let result = self . evaluate_predicates_recursively (
762749 previous_stack,
763- subobligations. iter ( ) ,
764- recursion_depth
750+ subobligations. into_iter ( ) ,
765751 ) ;
766752 if let Some ( key) =
767753 ProjectionCacheKey :: from_poly_projection_predicate ( self , data)
@@ -820,7 +806,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
820806 & mut self ,
821807 previous_stack : TraitObligationStackList < ' o , ' tcx > ,
822808 mut obligation : TraitObligation < ' tcx > ,
823- recursion_depth : usize
824809 ) -> Result < EvaluationResult , OverflowError > {
825810 debug ! ( "evaluate_trait_predicate_recursively({:?})" , obligation) ;
826811
@@ -848,7 +833,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
848833 return Ok ( result) ;
849834 }
850835
851- let ( result, dep_node) = self . in_task ( |this| this. evaluate_stack ( & stack, recursion_depth ) ) ;
836+ let ( result, dep_node) = self . in_task ( |this| this. evaluate_stack ( & stack) ) ;
852837 let result = result?;
853838
854839 debug ! ( "CACHE MISS: EVAL({:?})={:?}" , fresh_trait_ref, result) ;
@@ -860,7 +845,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
860845 fn evaluate_stack < ' o > (
861846 & mut self ,
862847 stack : & TraitObligationStack < ' o , ' tcx > ,
863- recursion_depth : usize
864848 ) -> Result < EvaluationResult , OverflowError > {
865849 // In intercrate mode, whenever any of the types are unbound,
866850 // there can always be an impl. Even if there are no impls in
@@ -901,7 +885,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
901885 // Heuristics: show the diagnostics when there are no candidates in crate.
902886 if self . intercrate_ambiguity_causes . is_some ( ) {
903887 debug ! ( "evaluate_stack: intercrate_ambiguity_causes is some" ) ;
904- if let Ok ( candidate_set) = self . assemble_candidates ( stack, recursion_depth ) {
888+ if let Ok ( candidate_set) = self . assemble_candidates ( stack) {
905889 if !candidate_set. ambiguous && candidate_set. vec . is_empty ( ) {
906890 let trait_ref = stack. obligation . predicate . skip_binder ( ) . trait_ref ;
907891 let self_ty = trait_ref. self_ty ( ) ;
@@ -982,8 +966,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
982966 }
983967 }
984968
985- match self . candidate_from_obligation ( stack, recursion_depth ) {
986- Ok ( Some ( c) ) => self . evaluate_candidate ( stack, & c, recursion_depth ) ,
969+ match self . candidate_from_obligation ( stack) {
970+ Ok ( Some ( c) ) => self . evaluate_candidate ( stack, & c) ,
987971 Ok ( None ) => Ok ( EvaluatedToAmbig ) ,
988972 Err ( Overflow ) => Err ( OverflowError ) ,
989973 Err ( ..) => Ok ( EvaluatedToErr ) ,
@@ -1022,7 +1006,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
10221006 & mut self ,
10231007 stack : & TraitObligationStack < ' o , ' tcx > ,
10241008 candidate : & SelectionCandidate < ' tcx > ,
1025- recursion_depth : usize
10261009 ) -> Result < EvaluationResult , OverflowError > {
10271010 debug ! (
10281011 "evaluate_candidate: depth={} candidate={:?}" ,
@@ -1034,7 +1017,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
10341017 Ok ( selection) => this. evaluate_predicates_recursively (
10351018 stack. list ( ) ,
10361019 selection. nested_obligations ( ) . iter ( ) ,
1037- recursion_depth
10381020 ) ,
10391021 Err ( ..) => Ok ( EvaluatedToErr ) ,
10401022 }
@@ -1109,13 +1091,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
11091091 . insert ( trait_ref, WithDepNode :: new ( dep_node, result) ) ;
11101092 }
11111093
1094+ // Check that the recursion limit has not been exceeded.
1095+ //
11121096 // The weird return type of this function allows it to be used with the 'try' (?)
11131097 // operator within certain functions
1114- fn check_recursion_limit < T : Display + TypeFoldable < ' tcx > > ( & self , recursion_depth : usize ,
1115- obligation : & Obligation < ' tcx , T > ,
1098+ fn check_recursion_limit < T : Display + TypeFoldable < ' tcx > > ( & self , obligation : & Obligation < ' tcx , T > ,
11161099 ) -> Result < ( ) , OverflowError > {
11171100 let recursion_limit = * self . infcx . tcx . sess . recursion_limit . get ( ) ;
1118- if recursion_depth >= recursion_limit {
1101+ if obligaton . recursion_depth >= recursion_limit {
11191102 match self . query_mode {
11201103 TraitQueryMode :: Standard => {
11211104 self . infcx ( ) . report_overflow_error ( obligation, true ) ;
@@ -1141,11 +1124,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
11411124 fn candidate_from_obligation < ' o > (
11421125 & mut self ,
11431126 stack : & TraitObligationStack < ' o , ' tcx > ,
1144- recursion_depth : usize
11451127 ) -> SelectionResult < ' tcx , SelectionCandidate < ' tcx > > {
11461128 // Watch out for overflow. This intentionally bypasses (and does
11471129 // not update) the cache.
1148- self . check_recursion_limit ( stack. obligation . recursion_depth , & stack. obligation ) ?;
1130+ self . check_recursion_limit ( & stack. obligation ) ?;
1131+
11491132
11501133 // Check the cache. Note that we freshen the trait-ref
11511134 // separately rather than using `stack.fresh_trait_ref` --
@@ -1167,7 +1150,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
11671150
11681151 // If no match, compute result and insert into cache.
11691152 let ( candidate, dep_node) =
1170- self . in_task ( |this| this. candidate_from_obligation_no_cache ( stack, recursion_depth ) ) ;
1153+ self . in_task ( |this| this. candidate_from_obligation_no_cache ( stack) ) ;
11711154
11721155 debug ! (
11731156 "CACHE MISS: SELECT({:?})={:?}" ,
@@ -1211,7 +1194,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
12111194 fn candidate_from_obligation_no_cache < ' o > (
12121195 & mut self ,
12131196 stack : & TraitObligationStack < ' o , ' tcx > ,
1214- recursion_depth : usize
12151197 ) -> SelectionResult < ' tcx , SelectionCandidate < ' tcx > > {
12161198 if stack. obligation . predicate . references_error ( ) {
12171199 // If we encounter a `Error`, we generally prefer the
@@ -1229,13 +1211,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
12291211 if self . intercrate_ambiguity_causes . is_some ( ) {
12301212 debug ! ( "evaluate_stack: intercrate_ambiguity_causes is some" ) ;
12311213 // Heuristics: show the diagnostics when there are no candidates in crate.
1232- if let Ok ( candidate_set) = self . assemble_candidates ( stack, recursion_depth ) {
1214+ if let Ok ( candidate_set) = self . assemble_candidates ( stack) {
12331215 let mut no_candidates_apply = true ;
12341216 {
12351217 let evaluated_candidates = candidate_set
12361218 . vec
12371219 . iter ( )
1238- . map ( |c| self . evaluate_candidate ( stack, & c, recursion_depth ) ) ;
1220+ . map ( |c| self . evaluate_candidate ( stack, & c) ) ;
12391221
12401222 for ec in evaluated_candidates {
12411223 match ec {
@@ -1281,7 +1263,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
12811263 return Ok ( None ) ;
12821264 }
12831265
1284- let candidate_set = self . assemble_candidates ( stack, recursion_depth ) ?;
1266+ let candidate_set = self . assemble_candidates ( stack) ?;
12851267
12861268 if candidate_set. ambiguous {
12871269 debug ! ( "candidate set contains ambig" ) ;
@@ -1328,7 +1310,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
13281310 // is needed for specialization. Propagate overflow if it occurs.
13291311 let mut candidates = candidates
13301312 . into_iter ( )
1331- . map ( |c| match self . evaluate_candidate ( stack, & c, recursion_depth ) {
1313+ . map ( |c| match self . evaluate_candidate ( stack, & c) {
13321314 Ok ( eval) if eval. may_apply ( ) => Ok ( Some ( EvaluatedCandidate {
13331315 candidate : c,
13341316 evaluation : eval,
@@ -1566,7 +1548,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
15661548 fn assemble_candidates < ' o > (
15671549 & mut self ,
15681550 stack : & TraitObligationStack < ' o , ' tcx > ,
1569- recursion_depth : usize
15701551 ) -> Result < SelectionCandidateSet < ' tcx > , SelectionError < ' tcx > > {
15711552 let TraitObligationStack { obligation, .. } = * stack;
15721553 let ref obligation = Obligation {
@@ -1642,7 +1623,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
16421623 }
16431624
16441625 self . assemble_candidates_from_projected_tys ( obligation, & mut candidates) ;
1645- self . assemble_candidates_from_caller_bounds ( stack, & mut candidates, recursion_depth ) ?;
1626+ self . assemble_candidates_from_caller_bounds ( stack, & mut candidates) ?;
16461627 // Auto implementations have lower priority, so we only
16471628 // consider triggering a default if there is no other impl that can apply.
16481629 if candidates. vec . is_empty ( ) {
@@ -1775,7 +1756,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
17751756 & mut self ,
17761757 stack : & TraitObligationStack < ' o , ' tcx > ,
17771758 candidates : & mut SelectionCandidateSet < ' tcx > ,
1778- recursion_depth : usize
17791759 ) -> Result < ( ) , SelectionError < ' tcx > > {
17801760 debug ! (
17811761 "assemble_candidates_from_caller_bounds({:?})" ,
@@ -1797,7 +1777,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
17971777 // keep only those bounds which may apply, and propagate overflow if it occurs
17981778 let mut param_candidates = vec ! [ ] ;
17991779 for bound in matching_bounds {
1800- let wc = self . evaluate_where_clause ( stack, bound. clone ( ) , recursion_depth ) ?;
1780+ let wc = self . evaluate_where_clause ( stack, bound. clone ( ) ) ?;
18011781 if wc. may_apply ( ) {
18021782 param_candidates. push ( ParamCandidate ( bound) ) ;
18031783 }
@@ -1812,13 +1792,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
18121792 & mut self ,
18131793 stack : & TraitObligationStack < ' o , ' tcx > ,
18141794 where_clause_trait_ref : ty:: PolyTraitRef < ' tcx > ,
1815- recursion_depth : usize
18161795 ) -> Result < EvaluationResult , OverflowError > {
18171796 self . evaluation_probe ( |this| {
18181797 match this. match_where_clause_trait_ref ( stack. obligation , where_clause_trait_ref) {
18191798 Ok ( obligations) => {
1820- this. evaluate_predicates_recursively ( stack. list ( ) , obligations. iter ( ) ,
1821- recursion_depth)
1799+ this. evaluate_predicates_recursively ( stack. list ( ) , obligations. iter ( ) )
18221800 }
18231801 Err ( ( ) ) => Ok ( EvaluatedToErr ) ,
18241802 }
0 commit comments