@@ -3,6 +3,7 @@ pub(crate) mod overflow;
3
3
4
4
use self :: cache:: ProvisionalEntry ;
5
5
use super :: { CanonicalGoal , Certainty , MaybeCause , QueryResult } ;
6
+ use crate :: solve:: search_graph:: overflow:: OverflowHandler ;
6
7
use cache:: ProvisionalCache ;
7
8
use overflow:: OverflowData ;
8
9
use rustc_index:: vec:: IndexVec ;
@@ -13,7 +14,7 @@ rustc_index::newtype_index! {
13
14
pub struct StackDepth { }
14
15
}
15
16
16
- struct StackElem < ' tcx > {
17
+ pub ( crate ) struct StackElem < ' tcx > {
17
18
goal : CanonicalGoal < ' tcx > ,
18
19
has_been_used : bool ,
19
20
}
@@ -127,7 +128,8 @@ impl<'tcx> SearchGraph<'tcx> {
127
128
actual_goal : CanonicalGoal < ' tcx > ,
128
129
response : QueryResult < ' tcx > ,
129
130
) -> 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;
131
133
assert_eq ! ( goal, actual_goal) ;
132
134
133
135
let cache = & mut self . provisional_cache ;
@@ -156,18 +158,19 @@ impl<'tcx> SearchGraph<'tcx> {
156
158
self . stack . push ( StackElem { goal, has_been_used : false } ) ;
157
159
false
158
160
} else {
159
- self . try_move_finished_goal_to_global_cache ( tcx, & goal ) ;
161
+ self . try_move_finished_goal_to_global_cache ( tcx, stack_elem ) ;
160
162
true
161
163
}
162
164
}
163
165
164
166
pub ( super ) fn try_move_finished_goal_to_global_cache (
165
167
& mut self ,
166
168
tcx : TyCtxt < ' tcx > ,
167
- goal : & CanonicalGoal < ' tcx > ,
169
+ stack_elem : StackElem < ' tcx > ,
168
170
) {
171
+ let StackElem { goal, .. } = stack_elem;
169
172
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 ( ) ;
171
174
let provisional_entry = & mut cache. entries [ provisional_entry_index] ;
172
175
let depth = provisional_entry. depth ;
173
176
@@ -193,4 +196,34 @@ impl<'tcx> SearchGraph<'tcx> {
193
196
}
194
197
}
195
198
}
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
+ }
196
229
}
0 commit comments