@@ -9,6 +9,7 @@ use rustc_middle::bug;
99use rustc_middle:: ty:: {
1010 self , Ty , TyCtxt , TypeFoldable , TypeFolder , TypeSuperFoldable , TypeVisitableExt ,
1111} ;
12+ pub use rustc_next_trait_solver:: placeholder:: BoundVarReplacer ;
1213use rustc_span:: Span ;
1314use smallvec:: { SmallVec , smallvec} ;
1415use tracing:: debug;
@@ -212,152 +213,6 @@ pub fn with_replaced_escaping_bound_vars<
212213 }
213214}
214215
215- pub struct BoundVarReplacer < ' a , ' tcx > {
216- infcx : & ' a InferCtxt < ' tcx > ,
217- // These three maps track the bound variable that were replaced by placeholders. It might be
218- // nice to remove these since we already have the `kind` in the placeholder; we really just need
219- // the `var` (but we *could* bring that into scope if we were to track them as we pass them).
220- mapped_regions : FxIndexMap < ty:: PlaceholderRegion , ty:: BoundRegion > ,
221- mapped_types : FxIndexMap < ty:: PlaceholderType , ty:: BoundTy > ,
222- mapped_consts : FxIndexMap < ty:: PlaceholderConst , ty:: BoundVar > ,
223- // The current depth relative to *this* folding, *not* the entire normalization. In other words,
224- // the depth of binders we've passed here.
225- current_index : ty:: DebruijnIndex ,
226- // The `UniverseIndex` of the binding levels above us. These are optional, since we are lazy:
227- // we don't actually create a universe until we see a bound var we have to replace.
228- universe_indices : & ' a mut Vec < Option < ty:: UniverseIndex > > ,
229- }
230-
231- impl < ' a , ' tcx > BoundVarReplacer < ' a , ' tcx > {
232- /// Returns `Some` if we *were* able to replace bound vars. If there are any bound vars that
233- /// use a binding level above `universe_indices.len()`, we fail.
234- pub fn replace_bound_vars < T : TypeFoldable < TyCtxt < ' tcx > > > (
235- infcx : & ' a InferCtxt < ' tcx > ,
236- universe_indices : & ' a mut Vec < Option < ty:: UniverseIndex > > ,
237- value : T ,
238- ) -> (
239- T ,
240- FxIndexMap < ty:: PlaceholderRegion , ty:: BoundRegion > ,
241- FxIndexMap < ty:: PlaceholderType , ty:: BoundTy > ,
242- FxIndexMap < ty:: PlaceholderConst , ty:: BoundVar > ,
243- ) {
244- let mapped_regions: FxIndexMap < ty:: PlaceholderRegion , ty:: BoundRegion > =
245- FxIndexMap :: default ( ) ;
246- let mapped_types: FxIndexMap < ty:: PlaceholderType , ty:: BoundTy > = FxIndexMap :: default ( ) ;
247- let mapped_consts: FxIndexMap < ty:: PlaceholderConst , ty:: BoundVar > = FxIndexMap :: default ( ) ;
248-
249- let mut replacer = BoundVarReplacer {
250- infcx,
251- mapped_regions,
252- mapped_types,
253- mapped_consts,
254- current_index : ty:: INNERMOST ,
255- universe_indices,
256- } ;
257-
258- let value = value. fold_with ( & mut replacer) ;
259-
260- ( value, replacer. mapped_regions , replacer. mapped_types , replacer. mapped_consts )
261- }
262-
263- fn universe_for ( & mut self , debruijn : ty:: DebruijnIndex ) -> ty:: UniverseIndex {
264- let infcx = self . infcx ;
265- let index =
266- self . universe_indices . len ( ) + self . current_index . as_usize ( ) - debruijn. as_usize ( ) - 1 ;
267- let universe = self . universe_indices [ index] . unwrap_or_else ( || {
268- for i in self . universe_indices . iter_mut ( ) . take ( index + 1 ) {
269- * i = i. or_else ( || Some ( infcx. create_next_universe ( ) ) )
270- }
271- self . universe_indices [ index] . unwrap ( )
272- } ) ;
273- universe
274- }
275- }
276-
277- impl < ' tcx > TypeFolder < TyCtxt < ' tcx > > for BoundVarReplacer < ' _ , ' tcx > {
278- fn cx ( & self ) -> TyCtxt < ' tcx > {
279- self . infcx . tcx
280- }
281-
282- fn fold_binder < T : TypeFoldable < TyCtxt < ' tcx > > > (
283- & mut self ,
284- t : ty:: Binder < ' tcx , T > ,
285- ) -> ty:: Binder < ' tcx , T > {
286- self . current_index . shift_in ( 1 ) ;
287- let t = t. super_fold_with ( self ) ;
288- self . current_index . shift_out ( 1 ) ;
289- t
290- }
291-
292- fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
293- match r. kind ( ) {
294- ty:: ReBound ( debruijn, _)
295- if debruijn. as_usize ( )
296- >= self . current_index . as_usize ( ) + self . universe_indices . len ( ) =>
297- {
298- bug ! (
299- "Bound vars {r:#?} outside of `self.universe_indices`: {:#?}" ,
300- self . universe_indices
301- ) ;
302- }
303- ty:: ReBound ( debruijn, br) if debruijn >= self . current_index => {
304- let universe = self . universe_for ( debruijn) ;
305- let p = ty:: PlaceholderRegion { universe, bound : br } ;
306- self . mapped_regions . insert ( p, br) ;
307- ty:: Region :: new_placeholder ( self . infcx . tcx , p)
308- }
309- _ => r,
310- }
311- }
312-
313- fn fold_ty ( & mut self , t : Ty < ' tcx > ) -> Ty < ' tcx > {
314- match * t. kind ( ) {
315- ty:: Bound ( debruijn, _)
316- if debruijn. as_usize ( ) + 1
317- > self . current_index . as_usize ( ) + self . universe_indices . len ( ) =>
318- {
319- bug ! (
320- "Bound vars {t:#?} outside of `self.universe_indices`: {:#?}" ,
321- self . universe_indices
322- ) ;
323- }
324- ty:: Bound ( debruijn, bound_ty) if debruijn >= self . current_index => {
325- let universe = self . universe_for ( debruijn) ;
326- let p = ty:: PlaceholderType { universe, bound : bound_ty } ;
327- self . mapped_types . insert ( p, bound_ty) ;
328- Ty :: new_placeholder ( self . infcx . tcx , p)
329- }
330- _ if t. has_vars_bound_at_or_above ( self . current_index ) => t. super_fold_with ( self ) ,
331- _ => t,
332- }
333- }
334-
335- fn fold_const ( & mut self , ct : ty:: Const < ' tcx > ) -> ty:: Const < ' tcx > {
336- match ct. kind ( ) {
337- ty:: ConstKind :: Bound ( debruijn, _)
338- if debruijn. as_usize ( ) + 1
339- > self . current_index . as_usize ( ) + self . universe_indices . len ( ) =>
340- {
341- bug ! (
342- "Bound vars {ct:#?} outside of `self.universe_indices`: {:#?}" ,
343- self . universe_indices
344- ) ;
345- }
346- ty:: ConstKind :: Bound ( debruijn, bound_const) if debruijn >= self . current_index => {
347- let universe = self . universe_for ( debruijn) ;
348- let p = ty:: PlaceholderConst { universe, bound : bound_const } ;
349- self . mapped_consts . insert ( p, bound_const) ;
350- ty:: Const :: new_placeholder ( self . infcx . tcx , p)
351- }
352- _ => ct. super_fold_with ( self ) ,
353- }
354- }
355-
356- fn fold_predicate ( & mut self , p : ty:: Predicate < ' tcx > ) -> ty:: Predicate < ' tcx > {
357- if p. has_vars_bound_at_or_above ( self . current_index ) { p. super_fold_with ( self ) } else { p }
358- }
359- }
360-
361216/// The inverse of [`BoundVarReplacer`]: replaces placeholders with the bound vars from which they came.
362217pub struct PlaceholderReplacer < ' a , ' tcx > {
363218 infcx : & ' a InferCtxt < ' tcx > ,
0 commit comments