@@ -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;
45+ use std:: fmt:: { self , Display } ;
4646use std:: iter;
4747use std:: rc:: Rc ;
4848use util:: nodemap:: { FxHashMap , FxHashSet } ;
@@ -660,7 +660,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
660660 {
661661 let mut result = EvaluatedToOk ;
662662 for obligation in predicates {
663- let eval = self . evaluate_predicate_recursively ( stack, obligation) ?;
663+ let eval = self . evaluate_predicate_recursively ( stack, obligation. clone ( ) ) ?;
664664 debug ! (
665665 "evaluate_predicate_recursively({:?}) = {:?}" ,
666666 obligation, eval
@@ -682,13 +682,13 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
682682 obligation : PredicateObligation < ' tcx > ,
683683 ) -> Result < EvaluationResult , OverflowError > {
684684 debug ! ( "evaluate_predicate_recursively({:?})" , obligation) ;
685- self . check_recursion_limit ( obligation) ?;
685+ self . check_recursion_limit ( & obligation) ?;
686686
687687 match obligation. predicate {
688688 ty:: Predicate :: Trait ( ref t) => {
689689 debug_assert ! ( !t. has_escaping_bound_vars( ) ) ;
690690 let mut obligation = obligation. with ( t. clone ( ) ) ;
691- obligation. recursion_depth += 1
691+ obligation. recursion_depth += 1 ;
692692 self . evaluate_trait_predicate_recursively ( previous_stack, obligation)
693693 }
694694
@@ -697,11 +697,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
697697 match self . infcx
698698 . subtype_predicate ( & obligation. cause , obligation. param_env , p)
699699 {
700- Some ( Ok ( InferOk { obligations, .. } ) ) => {
701- for o in obligations. iter_mut ( ) {
702- o. recursion_depth += 1
703- }
704- self . evaluate_predicates_recursively ( previous_stack, obligation. into_iter ( ) )
700+ Some ( Ok ( InferOk { mut obligations, .. } ) ) => {
701+ self . add_depth ( obligations. iter_mut ( ) , obligation. recursion_depth ) ;
702+ self . evaluate_predicates_recursively ( previous_stack, obligations. into_iter ( ) )
705703 }
706704 Some ( Err ( _) ) => Ok ( EvaluatedToErr ) ,
707705 None => Ok ( EvaluatedToAmbig ) ,
@@ -715,11 +713,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
715713 ty,
716714 obligation. cause . span ,
717715 ) {
718- Some ( obligations) => {
719- for o in obligations. iter_mut ( ) {
720- o. recursion_depth += 1
721- }
722- self . evaluate_predicates_recursively ( previous_stack, obligations. iter ( ) )
716+ Some ( mut obligations) => {
717+ self . add_depth ( obligations. iter_mut ( ) , obligation. recursion_depth ) ;
718+ self . evaluate_predicates_recursively ( previous_stack, obligations. into_iter ( ) )
723719 }
724720 None => Ok ( EvaluatedToAmbig ) ,
725721 } ,
@@ -741,10 +737,8 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
741737 ty:: Predicate :: Projection ( ref data) => {
742738 let project_obligation = obligation. with ( data. clone ( ) ) ;
743739 match project:: poly_project_and_unify_type ( self , & project_obligation) {
744- Ok ( Some ( subobligations) ) => {
745- for o in subobligations. iter_mut ( ) {
746- o. recursion_depth += 1
747- }
740+ Ok ( Some ( mut subobligations) ) => {
741+ self . add_depth ( subobligations. iter_mut ( ) , obligation. recursion_depth ) ;
748742 let result = self . evaluate_predicates_recursively (
749743 previous_stack,
750744 subobligations. into_iter ( ) ,
@@ -1016,7 +1010,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
10161010 match this. confirm_candidate ( stack. obligation , candidate) {
10171011 Ok ( selection) => this. evaluate_predicates_recursively (
10181012 stack. list ( ) ,
1019- selection. nested_obligations ( ) . iter ( ) ,
1013+ selection. nested_obligations ( ) . into_iter ( ) ,
10201014 ) ,
10211015 Err ( ..) => Ok ( EvaluatedToErr ) ,
10221016 }
@@ -1091,14 +1085,23 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
10911085 . insert ( trait_ref, WithDepNode :: new ( dep_node, result) ) ;
10921086 }
10931087
1088+ // Due to caching of projection results, it's possible for a subobligation
1089+ // to have a *lower* recursion_depth than the obligation used to create it.
1090+ // To ensure that obligation_depth never decreasees, we force all subobligations
1091+ // to have at least the depth of the original obligation.
1092+ fn add_depth < T : ' cx , I : Iterator < Item = & ' cx mut Obligation < ' tcx , T > > > ( & self , it : I ,
1093+ min_depth : usize ) {
1094+ it. for_each ( |o| o. recursion_depth = cmp:: max ( min_depth, o. recursion_depth ) + 1 ) ;
1095+ }
1096+
10941097 // Check that the recursion limit has not been exceeded.
10951098 //
10961099 // The weird return type of this function allows it to be used with the 'try' (?)
10971100 // operator within certain functions
10981101 fn check_recursion_limit < T : Display + TypeFoldable < ' tcx > > ( & self , obligation : & Obligation < ' tcx , T > ,
10991102 ) -> Result < ( ) , OverflowError > {
11001103 let recursion_limit = * self . infcx . tcx . sess . recursion_limit . get ( ) ;
1101- if obligaton . recursion_depth >= recursion_limit {
1104+ if obligation . recursion_depth >= recursion_limit {
11021105 match self . query_mode {
11031106 TraitQueryMode :: Standard => {
11041107 self . infcx ( ) . report_overflow_error ( obligation, true ) ;
@@ -1796,7 +1799,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
17961799 self . evaluation_probe ( |this| {
17971800 match this. match_where_clause_trait_ref ( stack. obligation , where_clause_trait_ref) {
17981801 Ok ( obligations) => {
1799- this. evaluate_predicates_recursively ( stack. list ( ) , obligations. iter ( ) )
1802+ this. evaluate_predicates_recursively ( stack. list ( ) , obligations. into_iter ( ) )
18001803 }
18011804 Err ( ( ) ) => Ok ( EvaluatedToErr ) ,
18021805 }
0 commit comments