1- use crate :: solve :: FIXPOINT_STEP_LIMIT ;
1+ use std :: mem ;
22
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 } ;
84use rustc_index:: Idx ;
95use rustc_index:: IndexVec ;
106use rustc_middle:: dep_graph:: dep_kinds;
117use rustc_middle:: traits:: solve:: CacheData ;
12- use rustc_middle:: traits:: solve:: { CanonicalInput , Certainty , EvaluationCache , QueryResult } ;
8+ use rustc_middle:: traits:: solve:: EvaluationCache ;
139use rustc_middle:: ty:: TyCtxt ;
10+ use rustc_next_trait_solver:: solve:: { CanonicalInput , Certainty , QueryResult } ;
1411use 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 ;
1619
1720rustc_index:: newtype_index! {
1821 #[ orderable]
@@ -30,9 +33,10 @@ bitflags::bitflags! {
3033 }
3134}
3235
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 > ,
3640
3741 available_depth : Limit ,
3842
@@ -53,11 +57,11 @@ struct StackEntry<'tcx> {
5357 has_been_used : HasBeenUsed ,
5458 /// Starts out as `None` and gets set when rerunning this
5559 /// goal in case we encounter a cycle.
56- provisional_result : Option < QueryResult < ' tcx > > ,
60+ provisional_result : Option < QueryResult < I > > ,
5761}
5862
5963/// The provisional result for a goal which is not on the stack.
60- struct DetachedEntry < ' tcx > {
64+ struct DetachedEntry < I : Interner > {
6165 /// The head of the smallest non-trivial cycle involving this entry.
6266 ///
6367 /// Given the following rules, when proving `A` the head for
@@ -68,7 +72,7 @@ struct DetachedEntry<'tcx> {
6872 /// C :- A + B + C
6973 /// ```
7074 head : StackDepth ,
71- result : QueryResult < ' tcx > ,
75+ result : QueryResult < I > ,
7276}
7377
7478/// Stores the stack depth of a currently evaluated goal *and* already
@@ -83,40 +87,41 @@ struct DetachedEntry<'tcx> {
8387///
8488/// The provisional cache can theoretically result in changes to the observable behavior,
8589/// 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 > {
8893 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 > > ,
9196}
9297
93- impl < ' tcx > ProvisionalCacheEntry < ' tcx > {
98+ impl < I : Interner > ProvisionalCacheEntry < I > {
9499 fn is_empty ( & self ) -> bool {
95100 self . stack_depth . is_none ( )
96101 && self . with_inductive_stack . is_none ( )
97102 && self . with_coinductive_stack . is_none ( )
98103 }
99104}
100105
101- pub ( super ) struct SearchGraph < ' tcx > {
106+ pub ( super ) struct SearchGraph < I : Interner > {
102107 mode : SolverMode ,
103108 /// The stack of goals currently being computed.
104109 ///
105110 /// 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 > > ,
108113 /// We put only the root goal of a coinductive cycle into the global cache.
109114 ///
110115 /// If we were to use that result when later trying to prove another cycle
111116 /// participant, we can end up with unstable query results.
112117 ///
113118 /// See tests/ui/next-solver/coinduction/incompleteness-unstable-result.rs for
114119 /// an example of where this is needed.
115- cycle_participants : FxHashSet < CanonicalInput < ' tcx > > ,
120+ cycle_participants : FxHashSet < CanonicalInput < I > > ,
116121}
117122
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 > {
120125 Self {
121126 mode,
122127 stack : Default :: default ( ) ,
@@ -144,7 +149,7 @@ impl<'tcx> SearchGraph<'tcx> {
144149 ///
145150 /// Directly popping from the stack instead of using this method
146151 /// 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 > {
148153 let elem = self . stack . pop ( ) . unwrap ( ) ;
149154 if let Some ( last) = self . stack . raw . last_mut ( ) {
150155 last. reached_depth = last. reached_depth . max ( elem. reached_depth ) ;
@@ -153,17 +158,6 @@ impl<'tcx> SearchGraph<'tcx> {
153158 elem
154159 }
155160
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-
167161 pub ( super ) fn is_empty ( & self ) -> bool {
168162 if self . stack . is_empty ( ) {
169163 debug_assert ! ( self . provisional_cache. is_empty( ) ) ;
@@ -181,8 +175,8 @@ impl<'tcx> SearchGraph<'tcx> {
181175 /// the remaining depth of all nested goals to prevent hangs
182176 /// in case there is exponential blowup.
183177 fn allowed_depth_for_nested (
184- tcx : TyCtxt < ' tcx > ,
185- stack : & IndexVec < StackDepth , StackEntry < ' tcx > > ,
178+ tcx : I ,
179+ stack : & IndexVec < StackDepth , StackEntry < I > > ,
186180 ) -> Option < Limit > {
187181 if let Some ( last) = stack. raw . last ( ) {
188182 if last. available_depth . 0 == 0 {
@@ -195,13 +189,13 @@ impl<'tcx> SearchGraph<'tcx> {
195189 Limit ( last. available_depth . 0 - 1 )
196190 } )
197191 } else {
198- Some ( tcx. recursion_limit ( ) )
192+ Some ( Limit ( tcx. recursion_limit ( ) ) )
199193 }
200194 }
201195
202196 fn stack_coinductive_from (
203- tcx : TyCtxt < ' tcx > ,
204- stack : & IndexVec < StackDepth , StackEntry < ' tcx > > ,
197+ tcx : I ,
198+ stack : & IndexVec < StackDepth , StackEntry < I > > ,
205199 head : StackDepth ,
206200 ) -> bool {
207201 stack. raw [ head. index ( ) ..]
@@ -220,8 +214,8 @@ impl<'tcx> SearchGraph<'tcx> {
220214 // we reach a fixpoint and all other cycle participants to make sure that
221215 // their result does not get moved to the global cache.
222216 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 > > ,
225219 usage_kind : HasBeenUsed ,
226220 head : StackDepth ,
227221 ) {
@@ -234,7 +228,7 @@ impl<'tcx> SearchGraph<'tcx> {
234228 }
235229
236230 fn clear_dependent_provisional_results (
237- provisional_cache : & mut FxHashMap < CanonicalInput < ' tcx > , ProvisionalCacheEntry < ' tcx > > ,
231+ provisional_cache : & mut FxHashMap < CanonicalInput < I > , ProvisionalCacheEntry < I > > ,
238232 head : StackDepth ,
239233 ) {
240234 #[ allow( rustc:: potential_query_instability) ]
@@ -244,6 +238,19 @@ impl<'tcx> SearchGraph<'tcx> {
244238 !entry. is_empty ( )
245239 } ) ;
246240 }
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+ }
247254
248255 /// Probably the most involved method of the whole solver.
249256 ///
@@ -252,10 +259,13 @@ impl<'tcx> SearchGraph<'tcx> {
252259 pub ( super ) fn with_new_goal (
253260 & mut self ,
254261 tcx : TyCtxt < ' tcx > ,
255- input : CanonicalInput < ' tcx > ,
262+ input : CanonicalInput < TyCtxt < ' tcx > > ,
256263 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 > > {
259269 // Check for overflow.
260270 let Some ( available_depth) = Self :: allowed_depth_for_nested ( tcx, & self . stack ) else {
261271 if let Some ( last) = self . stack . raw . last_mut ( ) {
@@ -489,9 +499,9 @@ impl<'tcx> SearchGraph<'tcx> {
489499
490500 fn response_no_constraints (
491501 tcx : TyCtxt < ' tcx > ,
492- goal : CanonicalInput < ' tcx > ,
502+ goal : CanonicalInput < TyCtxt < ' tcx > > ,
493503 certainty : Certainty ,
494- ) -> QueryResult < ' tcx > {
504+ ) -> QueryResult < TyCtxt < ' tcx > > {
495505 Ok ( super :: response_no_constraints_raw ( tcx, goal. max_universe , goal. variables , certainty) )
496506 }
497507}
0 commit comments