@@ -23,7 +23,7 @@ use infer::InferCtxt;
2323use std:: sync:: atomic:: Ordering ;
2424use ty:: fold:: { TypeFoldable , TypeFolder } ;
2525use ty:: subst:: Kind ;
26- use ty:: { self , BoundTy , BoundTyIndex , Lift , List , Ty , TyCtxt , TypeFlags } ;
26+ use ty:: { self , BoundTy , BoundVar , Lift , List , Ty , TyCtxt , TypeFlags } ;
2727
2828use rustc_data_structures:: fx:: FxHashMap ;
2929use rustc_data_structures:: indexed_vec:: Idx ;
@@ -225,21 +225,35 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
225225 query_state : & ' cx mut OriginalQueryValues < ' tcx > ,
226226 // Note that indices is only used once `var_values` is big enough to be
227227 // heap-allocated.
228- indices : FxHashMap < Kind < ' tcx > , BoundTyIndex > ,
228+ indices : FxHashMap < Kind < ' tcx > , BoundVar > ,
229229 canonicalize_region_mode : & ' cx dyn CanonicalizeRegionMode ,
230230 needs_canonical_flags : TypeFlags ,
231+
232+ binder_index : ty:: DebruijnIndex ,
231233}
232234
233235impl < ' cx , ' gcx , ' tcx > TypeFolder < ' gcx , ' tcx > for Canonicalizer < ' cx , ' gcx , ' tcx > {
234236 fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' tcx > {
235237 self . tcx
236238 }
237239
240+ fn fold_binder < T > ( & mut self , t : & ty:: Binder < T > ) -> ty:: Binder < T >
241+ where T : TypeFoldable < ' tcx >
242+ {
243+ self . binder_index . shift_in ( 1 ) ;
244+ let t = t. super_fold_with ( self ) ;
245+ self . binder_index . shift_out ( 1 ) ;
246+ t
247+ }
248+
238249 fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
239250 match * r {
240- ty:: ReLateBound ( ..) => {
241- // leave bound regions alone
242- r
251+ ty:: ReLateBound ( index, ..) => {
252+ if index >= self . binder_index {
253+ bug ! ( "escaping late bound region during canonicalization" )
254+ } else {
255+ r
256+ }
243257 }
244258
245259 ty:: ReVar ( vid) => {
@@ -263,8 +277,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
263277 | ty:: ReEmpty
264278 | ty:: ReErased => self . canonicalize_region_mode . canonicalize_free_region ( self , r) ,
265279
266- ty:: ReClosureBound ( ..) | ty :: ReCanonical ( _ ) => {
267- bug ! ( "canonical region encountered during canonicalization" )
280+ ty:: ReClosureBound ( ..) => {
281+ bug ! ( "closure bound region encountered during canonicalization" )
268282 }
269283 }
270284 }
@@ -283,8 +297,12 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
283297 bug ! ( "encountered a fresh type during canonicalization" )
284298 }
285299
286- ty:: Infer ( ty:: BoundTy ( _) ) => {
287- bug ! ( "encountered a canonical type during canonicalization" )
300+ ty:: Bound ( bound_ty) => {
301+ if bound_ty. index >= self . binder_index {
302+ bug ! ( "escaping bound type during canonicalization" )
303+ } else {
304+ t
305+ }
288306 }
289307
290308 ty:: Closure ( ..)
@@ -335,12 +353,6 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
335353 where
336354 V : TypeFoldable < ' tcx > + Lift < ' gcx > ,
337355 {
338- debug_assert ! (
339- !value. has_type_flags( TypeFlags :: HAS_CANONICAL_VARS ) ,
340- "canonicalizing a canonical value: {:?}" ,
341- value,
342- ) ;
343-
344356 let needs_canonical_flags = if canonicalize_region_mode. any ( ) {
345357 TypeFlags :: HAS_FREE_REGIONS | TypeFlags :: KEEP_IN_LOCAL_TCX
346358 } else {
@@ -367,6 +379,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
367379 variables : SmallVec :: new ( ) ,
368380 query_state,
369381 indices : FxHashMap :: default ( ) ,
382+ binder_index : ty:: INNERMOST ,
370383 } ;
371384 let out_value = value. fold_with ( & mut canonicalizer) ;
372385
@@ -393,7 +406,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
393406 /// or returns an existing variable if `kind` has already been
394407 /// seen. `kind` is expected to be an unbound variable (or
395408 /// potentially a free region).
396- fn canonical_var ( & mut self , info : CanonicalVarInfo , kind : Kind < ' tcx > ) -> BoundTy {
409+ fn canonical_var ( & mut self , info : CanonicalVarInfo , kind : Kind < ' tcx > ) -> BoundVar {
397410 let Canonicalizer {
398411 variables,
399412 query_state,
@@ -413,7 +426,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
413426 // direct linear search of `var_values`.
414427 if let Some ( idx) = var_values. iter ( ) . position ( |& k| k == kind) {
415428 // `kind` is already present in `var_values`.
416- BoundTyIndex :: new ( idx)
429+ BoundVar :: new ( idx)
417430 } else {
418431 // `kind` isn't present in `var_values`. Append it. Likewise
419432 // for `info` and `variables`.
@@ -428,35 +441,35 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
428441 * indices = var_values
429442 . iter ( )
430443 . enumerate ( )
431- . map ( |( i, & kind) | ( kind, BoundTyIndex :: new ( i) ) )
444+ . map ( |( i, & kind) | ( kind, BoundVar :: new ( i) ) )
432445 . collect ( ) ;
433446 }
434447 // The cv is the index of the appended element.
435- BoundTyIndex :: new ( var_values. len ( ) - 1 )
448+ BoundVar :: new ( var_values. len ( ) - 1 )
436449 }
437450 } else {
438451 // `var_values` is large. Do a hashmap search via `indices`.
439452 * indices. entry ( kind) . or_insert_with ( || {
440453 variables. push ( info) ;
441454 var_values. push ( kind) ;
442455 assert_eq ! ( variables. len( ) , var_values. len( ) ) ;
443- BoundTyIndex :: new ( variables. len ( ) - 1 )
456+ BoundVar :: new ( variables. len ( ) - 1 )
444457 } )
445458 } ;
446459
447- BoundTy {
448- level : ty:: INNERMOST ,
449- var,
450- }
460+ var
451461 }
452462
453463 fn canonical_var_for_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
454464 let info = CanonicalVarInfo {
455465 kind : CanonicalVarKind :: Region ,
456466 } ;
457- let b = self . canonical_var ( info, r. into ( ) ) ;
458- debug_assert_eq ! ( ty:: INNERMOST , b. level) ;
459- self . tcx ( ) . mk_region ( ty:: ReCanonical ( b. var ) )
467+ let var = self . canonical_var ( info, r. into ( ) ) ;
468+ let region = ty:: ReLateBound (
469+ self . binder_index ,
470+ ty:: BoundRegion :: BrAnon ( var. as_u32 ( ) )
471+ ) ;
472+ self . tcx ( ) . mk_region ( region)
460473 }
461474
462475 /// Given a type variable `ty_var` of the given kind, first check
@@ -472,9 +485,8 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
472485 let info = CanonicalVarInfo {
473486 kind : CanonicalVarKind :: Ty ( ty_kind) ,
474487 } ;
475- let b = self . canonical_var ( info, ty_var. into ( ) ) ;
476- debug_assert_eq ! ( ty:: INNERMOST , b. level) ;
477- self . tcx ( ) . mk_infer ( ty:: InferTy :: BoundTy ( b) )
488+ let var = self . canonical_var ( info, ty_var. into ( ) ) ;
489+ self . tcx ( ) . mk_ty ( ty:: Bound ( BoundTy :: new ( self . binder_index , var) ) )
478490 }
479491 }
480492}
0 commit comments