@@ -42,7 +42,7 @@ use rustc_data_structures::bit_set::GrowableBitSet;
42
42
use rustc_data_structures:: sync:: Lock ;
43
43
use rustc_target:: spec:: abi:: Abi ;
44
44
use std:: cmp;
45
- use std:: fmt:: { self , Display } ;
45
+ use std:: fmt;
46
46
use std:: iter;
47
47
use std:: rc:: Rc ;
48
48
use util:: nodemap:: { FxHashMap , FxHashSet } ;
@@ -573,9 +573,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
573
573
574
574
let stack = self . push_stack ( TraitObligationStackList :: empty ( ) , obligation) ;
575
575
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) {
579
577
Err ( SelectionError :: Overflow ) => {
580
578
// In standard mode, overflow must have been caught and reported
581
579
// earlier.
@@ -631,9 +629,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
631
629
obligation : & PredicateObligation < ' tcx > ,
632
630
) -> Result < EvaluationResult , OverflowError > {
633
631
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 ( ) )
637
633
} )
638
634
}
639
635
@@ -657,15 +653,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
657
653
& mut self ,
658
654
stack : TraitObligationStackList < ' o , ' tcx > ,
659
655
predicates : I ,
660
- recursion_depth : usize
661
656
) -> Result < EvaluationResult , OverflowError >
662
657
where
663
- I : IntoIterator < Item = & ' a PredicateObligation < ' tcx > > ,
658
+ I : IntoIterator < Item = PredicateObligation < ' tcx > > ,
664
659
' tcx : ' a ,
665
660
{
666
661
let mut result = EvaluatedToOk ;
667
662
for obligation in predicates {
668
- let eval = self . evaluate_predicate_recursively ( stack, obligation, recursion_depth ) ?;
663
+ let eval = self . evaluate_predicate_recursively ( stack, obligation) ?;
669
664
debug ! (
670
665
"evaluate_predicate_recursively({:?}) = {:?}" ,
671
666
obligation, eval
@@ -684,32 +679,17 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
684
679
fn evaluate_predicate_recursively < ' o > (
685
680
& mut self ,
686
681
previous_stack : TraitObligationStackList < ' o , ' tcx > ,
687
- obligation : & PredicateObligation < ' tcx > ,
688
- mut recursion_depth : usize
682
+ obligation : PredicateObligation < ' tcx > ,
689
683
) -> 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) ?;
706
686
707
687
match obligation. predicate {
708
688
ty:: Predicate :: Trait ( ref t) => {
709
689
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 )
713
693
}
714
694
715
695
ty:: Predicate :: Subtype ( ref p) => {
@@ -718,8 +698,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
718
698
. subtype_predicate ( & obligation. cause , obligation. param_env , p)
719
699
{
720
700
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 ( ) )
723
705
}
724
706
Some ( Err ( _) ) => Ok ( EvaluatedToErr ) ,
725
707
None => Ok ( EvaluatedToAmbig ) ,
@@ -734,8 +716,10 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
734
716
obligation. cause . span ,
735
717
) {
736
718
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 ( ) )
739
723
}
740
724
None => Ok ( EvaluatedToAmbig ) ,
741
725
} ,
@@ -758,10 +742,12 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
758
742
let project_obligation = obligation. with ( data. clone ( ) ) ;
759
743
match project:: poly_project_and_unify_type ( self , & project_obligation) {
760
744
Ok ( Some ( subobligations) ) => {
745
+ for o in subobligations. iter_mut ( ) {
746
+ o. recursion_depth += 1
747
+ }
761
748
let result = self . evaluate_predicates_recursively (
762
749
previous_stack,
763
- subobligations. iter ( ) ,
764
- recursion_depth
750
+ subobligations. into_iter ( ) ,
765
751
) ;
766
752
if let Some ( key) =
767
753
ProjectionCacheKey :: from_poly_projection_predicate ( self , data)
@@ -820,7 +806,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
820
806
& mut self ,
821
807
previous_stack : TraitObligationStackList < ' o , ' tcx > ,
822
808
mut obligation : TraitObligation < ' tcx > ,
823
- recursion_depth : usize
824
809
) -> Result < EvaluationResult , OverflowError > {
825
810
debug ! ( "evaluate_trait_predicate_recursively({:?})" , obligation) ;
826
811
@@ -848,7 +833,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
848
833
return Ok ( result) ;
849
834
}
850
835
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) ) ;
852
837
let result = result?;
853
838
854
839
debug ! ( "CACHE MISS: EVAL({:?})={:?}" , fresh_trait_ref, result) ;
@@ -860,7 +845,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
860
845
fn evaluate_stack < ' o > (
861
846
& mut self ,
862
847
stack : & TraitObligationStack < ' o , ' tcx > ,
863
- recursion_depth : usize
864
848
) -> Result < EvaluationResult , OverflowError > {
865
849
// In intercrate mode, whenever any of the types are unbound,
866
850
// 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> {
901
885
// Heuristics: show the diagnostics when there are no candidates in crate.
902
886
if self . intercrate_ambiguity_causes . is_some ( ) {
903
887
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) {
905
889
if !candidate_set. ambiguous && candidate_set. vec . is_empty ( ) {
906
890
let trait_ref = stack. obligation . predicate . skip_binder ( ) . trait_ref ;
907
891
let self_ty = trait_ref. self_ty ( ) ;
@@ -982,8 +966,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
982
966
}
983
967
}
984
968
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) ,
987
971
Ok ( None ) => Ok ( EvaluatedToAmbig ) ,
988
972
Err ( Overflow ) => Err ( OverflowError ) ,
989
973
Err ( ..) => Ok ( EvaluatedToErr ) ,
@@ -1022,7 +1006,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1022
1006
& mut self ,
1023
1007
stack : & TraitObligationStack < ' o , ' tcx > ,
1024
1008
candidate : & SelectionCandidate < ' tcx > ,
1025
- recursion_depth : usize
1026
1009
) -> Result < EvaluationResult , OverflowError > {
1027
1010
debug ! (
1028
1011
"evaluate_candidate: depth={} candidate={:?}" ,
@@ -1034,7 +1017,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1034
1017
Ok ( selection) => this. evaluate_predicates_recursively (
1035
1018
stack. list ( ) ,
1036
1019
selection. nested_obligations ( ) . iter ( ) ,
1037
- recursion_depth
1038
1020
) ,
1039
1021
Err ( ..) => Ok ( EvaluatedToErr ) ,
1040
1022
}
@@ -1109,13 +1091,14 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1109
1091
. insert ( trait_ref, WithDepNode :: new ( dep_node, result) ) ;
1110
1092
}
1111
1093
1094
+ // Check that the recursion limit has not been exceeded.
1095
+ //
1112
1096
// The weird return type of this function allows it to be used with the 'try' (?)
1113
1097
// 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 > ,
1116
1099
) -> Result < ( ) , OverflowError > {
1117
1100
let recursion_limit = * self . infcx . tcx . sess . recursion_limit . get ( ) ;
1118
- if recursion_depth >= recursion_limit {
1101
+ if obligaton . recursion_depth >= recursion_limit {
1119
1102
match self . query_mode {
1120
1103
TraitQueryMode :: Standard => {
1121
1104
self . infcx ( ) . report_overflow_error ( obligation, true ) ;
@@ -1141,11 +1124,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1141
1124
fn candidate_from_obligation < ' o > (
1142
1125
& mut self ,
1143
1126
stack : & TraitObligationStack < ' o , ' tcx > ,
1144
- recursion_depth : usize
1145
1127
) -> SelectionResult < ' tcx , SelectionCandidate < ' tcx > > {
1146
1128
// Watch out for overflow. This intentionally bypasses (and does
1147
1129
// not update) the cache.
1148
- self . check_recursion_limit ( stack. obligation . recursion_depth , & stack. obligation ) ?;
1130
+ self . check_recursion_limit ( & stack. obligation ) ?;
1131
+
1149
1132
1150
1133
// Check the cache. Note that we freshen the trait-ref
1151
1134
// separately rather than using `stack.fresh_trait_ref` --
@@ -1167,7 +1150,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1167
1150
1168
1151
// If no match, compute result and insert into cache.
1169
1152
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) ) ;
1171
1154
1172
1155
debug ! (
1173
1156
"CACHE MISS: SELECT({:?})={:?}" ,
@@ -1211,7 +1194,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1211
1194
fn candidate_from_obligation_no_cache < ' o > (
1212
1195
& mut self ,
1213
1196
stack : & TraitObligationStack < ' o , ' tcx > ,
1214
- recursion_depth : usize
1215
1197
) -> SelectionResult < ' tcx , SelectionCandidate < ' tcx > > {
1216
1198
if stack. obligation . predicate . references_error ( ) {
1217
1199
// If we encounter a `Error`, we generally prefer the
@@ -1229,13 +1211,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1229
1211
if self . intercrate_ambiguity_causes . is_some ( ) {
1230
1212
debug ! ( "evaluate_stack: intercrate_ambiguity_causes is some" ) ;
1231
1213
// 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) {
1233
1215
let mut no_candidates_apply = true ;
1234
1216
{
1235
1217
let evaluated_candidates = candidate_set
1236
1218
. vec
1237
1219
. iter ( )
1238
- . map ( |c| self . evaluate_candidate ( stack, & c, recursion_depth ) ) ;
1220
+ . map ( |c| self . evaluate_candidate ( stack, & c) ) ;
1239
1221
1240
1222
for ec in evaluated_candidates {
1241
1223
match ec {
@@ -1281,7 +1263,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1281
1263
return Ok ( None ) ;
1282
1264
}
1283
1265
1284
- let candidate_set = self . assemble_candidates ( stack, recursion_depth ) ?;
1266
+ let candidate_set = self . assemble_candidates ( stack) ?;
1285
1267
1286
1268
if candidate_set. ambiguous {
1287
1269
debug ! ( "candidate set contains ambig" ) ;
@@ -1328,7 +1310,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1328
1310
// is needed for specialization. Propagate overflow if it occurs.
1329
1311
let mut candidates = candidates
1330
1312
. into_iter ( )
1331
- . map ( |c| match self . evaluate_candidate ( stack, & c, recursion_depth ) {
1313
+ . map ( |c| match self . evaluate_candidate ( stack, & c) {
1332
1314
Ok ( eval) if eval. may_apply ( ) => Ok ( Some ( EvaluatedCandidate {
1333
1315
candidate : c,
1334
1316
evaluation : eval,
@@ -1566,7 +1548,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1566
1548
fn assemble_candidates < ' o > (
1567
1549
& mut self ,
1568
1550
stack : & TraitObligationStack < ' o , ' tcx > ,
1569
- recursion_depth : usize
1570
1551
) -> Result < SelectionCandidateSet < ' tcx > , SelectionError < ' tcx > > {
1571
1552
let TraitObligationStack { obligation, .. } = * stack;
1572
1553
let ref obligation = Obligation {
@@ -1642,7 +1623,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1642
1623
}
1643
1624
1644
1625
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) ?;
1646
1627
// Auto implementations have lower priority, so we only
1647
1628
// consider triggering a default if there is no other impl that can apply.
1648
1629
if candidates. vec . is_empty ( ) {
@@ -1775,7 +1756,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1775
1756
& mut self ,
1776
1757
stack : & TraitObligationStack < ' o , ' tcx > ,
1777
1758
candidates : & mut SelectionCandidateSet < ' tcx > ,
1778
- recursion_depth : usize
1779
1759
) -> Result < ( ) , SelectionError < ' tcx > > {
1780
1760
debug ! (
1781
1761
"assemble_candidates_from_caller_bounds({:?})" ,
@@ -1797,7 +1777,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1797
1777
// keep only those bounds which may apply, and propagate overflow if it occurs
1798
1778
let mut param_candidates = vec ! [ ] ;
1799
1779
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 ( ) ) ?;
1801
1781
if wc. may_apply ( ) {
1802
1782
param_candidates. push ( ParamCandidate ( bound) ) ;
1803
1783
}
@@ -1812,13 +1792,11 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
1812
1792
& mut self ,
1813
1793
stack : & TraitObligationStack < ' o , ' tcx > ,
1814
1794
where_clause_trait_ref : ty:: PolyTraitRef < ' tcx > ,
1815
- recursion_depth : usize
1816
1795
) -> Result < EvaluationResult , OverflowError > {
1817
1796
self . evaluation_probe ( |this| {
1818
1797
match this. match_where_clause_trait_ref ( stack. obligation , where_clause_trait_ref) {
1819
1798
Ok ( obligations) => {
1820
- this. evaluate_predicates_recursively ( stack. list ( ) , obligations. iter ( ) ,
1821
- recursion_depth)
1799
+ this. evaluate_predicates_recursively ( stack. list ( ) , obligations. iter ( ) )
1822
1800
}
1823
1801
Err ( ( ) ) => Ok ( EvaluatedToErr ) ,
1824
1802
}
0 commit comments