@@ -3,6 +3,7 @@ pub(crate) mod overflow;
33
44use self :: cache:: ProvisionalEntry ;
55use super :: { CanonicalGoal , Certainty , MaybeCause , QueryResult } ;
6+ use crate :: solve:: search_graph:: overflow:: OverflowHandler ;
67use cache:: ProvisionalCache ;
78use overflow:: OverflowData ;
89use rustc_index:: vec:: IndexVec ;
@@ -13,7 +14,7 @@ rustc_index::newtype_index! {
1314 pub struct StackDepth { }
1415}
1516
16- struct StackElem < ' tcx > {
17+ pub ( crate ) struct StackElem < ' tcx > {
1718 goal : CanonicalGoal < ' tcx > ,
1819 has_been_used : bool ,
1920}
@@ -127,7 +128,8 @@ impl<'tcx> SearchGraph<'tcx> {
127128 actual_goal : CanonicalGoal < ' tcx > ,
128129 response : QueryResult < ' tcx > ,
129130 ) -> bool {
130- let StackElem { goal, has_been_used } = self . stack . pop ( ) . unwrap ( ) ;
131+ let stack_elem = self . stack . pop ( ) . unwrap ( ) ;
132+ let StackElem { goal, has_been_used } = stack_elem;
131133 assert_eq ! ( goal, actual_goal) ;
132134
133135 let cache = & mut self . provisional_cache ;
@@ -156,18 +158,19 @@ impl<'tcx> SearchGraph<'tcx> {
156158 self . stack . push ( StackElem { goal, has_been_used : false } ) ;
157159 false
158160 } else {
159- self . try_move_finished_goal_to_global_cache ( tcx, & goal ) ;
161+ self . try_move_finished_goal_to_global_cache ( tcx, stack_elem ) ;
160162 true
161163 }
162164 }
163165
164166 pub ( super ) fn try_move_finished_goal_to_global_cache (
165167 & mut self ,
166168 tcx : TyCtxt < ' tcx > ,
167- goal : & CanonicalGoal < ' tcx > ,
169+ stack_elem : StackElem < ' tcx > ,
168170 ) {
171+ let StackElem { goal, .. } = stack_elem;
169172 let cache = & mut self . provisional_cache ;
170- let provisional_entry_index = * cache. lookup_table . get ( goal) . unwrap ( ) ;
173+ let provisional_entry_index = * cache. lookup_table . get ( & goal) . unwrap ( ) ;
171174 let provisional_entry = & mut cache. entries [ provisional_entry_index] ;
172175 let depth = provisional_entry. depth ;
173176
@@ -193,4 +196,34 @@ impl<'tcx> SearchGraph<'tcx> {
193196 }
194197 }
195198 }
199+
200+ pub ( super ) fn with_new_goal (
201+ & mut self ,
202+ tcx : TyCtxt < ' tcx > ,
203+ canonical_goal : CanonicalGoal < ' tcx > ,
204+ mut loop_body : impl FnMut ( & mut Self ) -> QueryResult < ' tcx > ,
205+ ) -> QueryResult < ' tcx > {
206+ match self . try_push_stack ( tcx, canonical_goal) {
207+ Ok ( ( ) ) => { }
208+ // Our goal is already on the stack, eager return.
209+ Err ( response) => return response,
210+ }
211+
212+ self . repeat_while_none (
213+ |this| {
214+ let result = this. deal_with_overflow ( tcx, canonical_goal) ;
215+ let stack_elem = this. stack . pop ( ) . unwrap ( ) ;
216+ this. try_move_finished_goal_to_global_cache ( tcx, stack_elem) ;
217+ result
218+ } ,
219+ |this| {
220+ let result = loop_body ( this) ;
221+ if this. try_finalize_goal ( tcx, canonical_goal, result) {
222+ Some ( result)
223+ } else {
224+ None
225+ }
226+ } ,
227+ )
228+ }
196229}
0 commit comments