1
- use crate :: solve :: FIXPOINT_STEP_LIMIT ;
1
+ use std :: mem ;
2
2
3
- use super :: inspect;
4
- use super :: inspect:: ProofTreeBuilder ;
5
- use super :: SolverMode ;
6
- use rustc_data_structures:: fx:: FxHashMap ;
7
- use rustc_data_structures:: fx:: FxHashSet ;
3
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
8
4
use rustc_index:: Idx ;
9
5
use rustc_index:: IndexVec ;
10
6
use rustc_middle:: dep_graph:: dep_kinds;
11
7
use rustc_middle:: traits:: solve:: CacheData ;
12
- use rustc_middle:: traits:: solve:: { CanonicalInput , Certainty , EvaluationCache , QueryResult } ;
8
+ use rustc_middle:: traits:: solve:: EvaluationCache ;
13
9
use rustc_middle:: ty:: TyCtxt ;
10
+ use rustc_next_trait_solver:: solve:: { CanonicalInput , Certainty , QueryResult } ;
14
11
use rustc_session:: Limit ;
15
- use std:: mem;
12
+ use rustc_type_ir:: inherent:: * ;
13
+ use rustc_type_ir:: Interner ;
14
+
15
+ use super :: inspect;
16
+ use super :: inspect:: ProofTreeBuilder ;
17
+ use super :: SolverMode ;
18
+ use crate :: solve:: FIXPOINT_STEP_LIMIT ;
16
19
17
20
rustc_index:: newtype_index! {
18
21
#[ orderable]
@@ -30,9 +33,10 @@ bitflags::bitflags! {
30
33
}
31
34
}
32
35
33
- #[ derive( Debug ) ]
34
- struct StackEntry < ' tcx > {
35
- input : CanonicalInput < ' tcx > ,
36
+ #[ derive( derivative:: Derivative ) ]
37
+ #[ derivative( Debug ( bound = "" ) ) ]
38
+ struct StackEntry < I : Interner > {
39
+ input : CanonicalInput < I > ,
36
40
37
41
available_depth : Limit ,
38
42
@@ -53,11 +57,11 @@ struct StackEntry<'tcx> {
53
57
has_been_used : HasBeenUsed ,
54
58
/// Starts out as `None` and gets set when rerunning this
55
59
/// goal in case we encounter a cycle.
56
- provisional_result : Option < QueryResult < ' tcx > > ,
60
+ provisional_result : Option < QueryResult < I > > ,
57
61
}
58
62
59
63
/// The provisional result for a goal which is not on the stack.
60
- struct DetachedEntry < ' tcx > {
64
+ struct DetachedEntry < I : Interner > {
61
65
/// The head of the smallest non-trivial cycle involving this entry.
62
66
///
63
67
/// Given the following rules, when proving `A` the head for
@@ -68,7 +72,7 @@ struct DetachedEntry<'tcx> {
68
72
/// C :- A + B + C
69
73
/// ```
70
74
head : StackDepth ,
71
- result : QueryResult < ' tcx > ,
75
+ result : QueryResult < I > ,
72
76
}
73
77
74
78
/// Stores the stack depth of a currently evaluated goal *and* already
@@ -83,40 +87,41 @@ struct DetachedEntry<'tcx> {
83
87
///
84
88
/// The provisional cache can theoretically result in changes to the observable behavior,
85
89
/// see tests/ui/traits/next-solver/cycles/provisional-cache-impacts-behavior.rs.
86
- #[ derive( Default ) ]
87
- struct ProvisionalCacheEntry < ' tcx > {
90
+ #[ derive( derivative:: Derivative ) ]
91
+ #[ derivative( Default ( bound = "" ) ) ]
92
+ struct ProvisionalCacheEntry < I : Interner > {
88
93
stack_depth : Option < StackDepth > ,
89
- with_inductive_stack : Option < DetachedEntry < ' tcx > > ,
90
- with_coinductive_stack : Option < DetachedEntry < ' tcx > > ,
94
+ with_inductive_stack : Option < DetachedEntry < I > > ,
95
+ with_coinductive_stack : Option < DetachedEntry < I > > ,
91
96
}
92
97
93
- impl < ' tcx > ProvisionalCacheEntry < ' tcx > {
98
+ impl < I : Interner > ProvisionalCacheEntry < I > {
94
99
fn is_empty ( & self ) -> bool {
95
100
self . stack_depth . is_none ( )
96
101
&& self . with_inductive_stack . is_none ( )
97
102
&& self . with_coinductive_stack . is_none ( )
98
103
}
99
104
}
100
105
101
- pub ( super ) struct SearchGraph < ' tcx > {
106
+ pub ( super ) struct SearchGraph < I : Interner > {
102
107
mode : SolverMode ,
103
108
/// The stack of goals currently being computed.
104
109
///
105
110
/// An element is *deeper* in the stack if its index is *lower*.
106
- stack : IndexVec < StackDepth , StackEntry < ' tcx > > ,
107
- provisional_cache : FxHashMap < CanonicalInput < ' tcx > , ProvisionalCacheEntry < ' tcx > > ,
111
+ stack : IndexVec < StackDepth , StackEntry < I > > ,
112
+ provisional_cache : FxHashMap < CanonicalInput < I > , ProvisionalCacheEntry < I > > ,
108
113
/// We put only the root goal of a coinductive cycle into the global cache.
109
114
///
110
115
/// If we were to use that result when later trying to prove another cycle
111
116
/// participant, we can end up with unstable query results.
112
117
///
113
118
/// See tests/ui/next-solver/coinduction/incompleteness-unstable-result.rs for
114
119
/// an example of where this is needed.
115
- cycle_participants : FxHashSet < CanonicalInput < ' tcx > > ,
120
+ cycle_participants : FxHashSet < CanonicalInput < I > > ,
116
121
}
117
122
118
- impl < ' tcx > SearchGraph < ' tcx > {
119
- pub ( super ) fn new ( mode : SolverMode ) -> SearchGraph < ' tcx > {
123
+ impl < I : Interner > SearchGraph < I > {
124
+ pub ( super ) fn new ( mode : SolverMode ) -> SearchGraph < I > {
120
125
Self {
121
126
mode,
122
127
stack : Default :: default ( ) ,
@@ -144,7 +149,7 @@ impl<'tcx> SearchGraph<'tcx> {
144
149
///
145
150
/// Directly popping from the stack instead of using this method
146
151
/// would cause us to not track overflow and recursion depth correctly.
147
- fn pop_stack ( & mut self ) -> StackEntry < ' tcx > {
152
+ fn pop_stack ( & mut self ) -> StackEntry < I > {
148
153
let elem = self . stack . pop ( ) . unwrap ( ) ;
149
154
if let Some ( last) = self . stack . raw . last_mut ( ) {
150
155
last. reached_depth = last. reached_depth . max ( elem. reached_depth ) ;
@@ -153,17 +158,6 @@ impl<'tcx> SearchGraph<'tcx> {
153
158
elem
154
159
}
155
160
156
- /// The trait solver behavior is different for coherence
157
- /// so we use a separate cache. Alternatively we could use
158
- /// a single cache and share it between coherence and ordinary
159
- /// trait solving.
160
- pub ( super ) fn global_cache ( & self , tcx : TyCtxt < ' tcx > ) -> & ' tcx EvaluationCache < ' tcx > {
161
- match self . mode {
162
- SolverMode :: Normal => & tcx. new_solver_evaluation_cache ,
163
- SolverMode :: Coherence => & tcx. new_solver_coherence_evaluation_cache ,
164
- }
165
- }
166
-
167
161
pub ( super ) fn is_empty ( & self ) -> bool {
168
162
if self . stack . is_empty ( ) {
169
163
debug_assert ! ( self . provisional_cache. is_empty( ) ) ;
@@ -181,8 +175,8 @@ impl<'tcx> SearchGraph<'tcx> {
181
175
/// the remaining depth of all nested goals to prevent hangs
182
176
/// in case there is exponential blowup.
183
177
fn allowed_depth_for_nested (
184
- tcx : TyCtxt < ' tcx > ,
185
- stack : & IndexVec < StackDepth , StackEntry < ' tcx > > ,
178
+ tcx : I ,
179
+ stack : & IndexVec < StackDepth , StackEntry < I > > ,
186
180
) -> Option < Limit > {
187
181
if let Some ( last) = stack. raw . last ( ) {
188
182
if last. available_depth . 0 == 0 {
@@ -195,13 +189,13 @@ impl<'tcx> SearchGraph<'tcx> {
195
189
Limit ( last. available_depth . 0 - 1 )
196
190
} )
197
191
} else {
198
- Some ( tcx. recursion_limit ( ) )
192
+ Some ( Limit ( tcx. recursion_limit ( ) ) )
199
193
}
200
194
}
201
195
202
196
fn stack_coinductive_from (
203
- tcx : TyCtxt < ' tcx > ,
204
- stack : & IndexVec < StackDepth , StackEntry < ' tcx > > ,
197
+ tcx : I ,
198
+ stack : & IndexVec < StackDepth , StackEntry < I > > ,
205
199
head : StackDepth ,
206
200
) -> bool {
207
201
stack. raw [ head. index ( ) ..]
@@ -220,8 +214,8 @@ impl<'tcx> SearchGraph<'tcx> {
220
214
// we reach a fixpoint and all other cycle participants to make sure that
221
215
// their result does not get moved to the global cache.
222
216
fn tag_cycle_participants (
223
- stack : & mut IndexVec < StackDepth , StackEntry < ' tcx > > ,
224
- cycle_participants : & mut FxHashSet < CanonicalInput < ' tcx > > ,
217
+ stack : & mut IndexVec < StackDepth , StackEntry < I > > ,
218
+ cycle_participants : & mut FxHashSet < CanonicalInput < I > > ,
225
219
usage_kind : HasBeenUsed ,
226
220
head : StackDepth ,
227
221
) {
@@ -234,7 +228,7 @@ impl<'tcx> SearchGraph<'tcx> {
234
228
}
235
229
236
230
fn clear_dependent_provisional_results (
237
- provisional_cache : & mut FxHashMap < CanonicalInput < ' tcx > , ProvisionalCacheEntry < ' tcx > > ,
231
+ provisional_cache : & mut FxHashMap < CanonicalInput < I > , ProvisionalCacheEntry < I > > ,
238
232
head : StackDepth ,
239
233
) {
240
234
#[ allow( rustc:: potential_query_instability) ]
@@ -244,6 +238,19 @@ impl<'tcx> SearchGraph<'tcx> {
244
238
!entry. is_empty ( )
245
239
} ) ;
246
240
}
241
+ }
242
+
243
+ impl < ' tcx > SearchGraph < TyCtxt < ' tcx > > {
244
+ /// The trait solver behavior is different for coherence
245
+ /// so we use a separate cache. Alternatively we could use
246
+ /// a single cache and share it between coherence and ordinary
247
+ /// trait solving.
248
+ pub ( super ) fn global_cache ( & self , tcx : TyCtxt < ' tcx > ) -> & ' tcx EvaluationCache < ' tcx > {
249
+ match self . mode {
250
+ SolverMode :: Normal => & tcx. new_solver_evaluation_cache ,
251
+ SolverMode :: Coherence => & tcx. new_solver_coherence_evaluation_cache ,
252
+ }
253
+ }
247
254
248
255
/// Probably the most involved method of the whole solver.
249
256
///
@@ -252,10 +259,13 @@ impl<'tcx> SearchGraph<'tcx> {
252
259
pub ( super ) fn with_new_goal (
253
260
& mut self ,
254
261
tcx : TyCtxt < ' tcx > ,
255
- input : CanonicalInput < ' tcx > ,
262
+ input : CanonicalInput < TyCtxt < ' tcx > > ,
256
263
inspect : & mut ProofTreeBuilder < TyCtxt < ' tcx > > ,
257
- mut prove_goal : impl FnMut ( & mut Self , & mut ProofTreeBuilder < TyCtxt < ' tcx > > ) -> QueryResult < ' tcx > ,
258
- ) -> QueryResult < ' tcx > {
264
+ mut prove_goal : impl FnMut (
265
+ & mut Self ,
266
+ & mut ProofTreeBuilder < TyCtxt < ' tcx > > ,
267
+ ) -> QueryResult < TyCtxt < ' tcx > > ,
268
+ ) -> QueryResult < TyCtxt < ' tcx > > {
259
269
// Check for overflow.
260
270
let Some ( available_depth) = Self :: allowed_depth_for_nested ( tcx, & self . stack ) else {
261
271
if let Some ( last) = self . stack . raw . last_mut ( ) {
@@ -489,9 +499,9 @@ impl<'tcx> SearchGraph<'tcx> {
489
499
490
500
fn response_no_constraints (
491
501
tcx : TyCtxt < ' tcx > ,
492
- goal : CanonicalInput < ' tcx > ,
502
+ goal : CanonicalInput < TyCtxt < ' tcx > > ,
493
503
certainty : Certainty ,
494
- ) -> QueryResult < ' tcx > {
504
+ ) -> QueryResult < TyCtxt < ' tcx > > {
495
505
Ok ( super :: response_no_constraints_raw ( tcx, goal. max_universe , goal. variables , certainty) )
496
506
}
497
507
}
0 commit comments