@@ -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 ;
@@ -277,21 +277,35 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
277277 query_state : & ' cx mut OriginalQueryValues < ' tcx > ,
278278 // Note that indices is only used once `var_values` is big enough to be
279279 // heap-allocated.
280- indices : FxHashMap < Kind < ' tcx > , BoundTyIndex > ,
280+ indices : FxHashMap < Kind < ' tcx > , BoundVar > ,
281281 canonicalize_region_mode : & ' cx dyn CanonicalizeRegionMode ,
282282 needs_canonical_flags : TypeFlags ,
283+
284+ binder_index : ty:: DebruijnIndex ,
283285}
284286
285287impl < ' cx , ' gcx , ' tcx > TypeFolder < ' gcx , ' tcx > for Canonicalizer < ' cx , ' gcx , ' tcx > {
286288 fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' tcx > {
287289 self . tcx
288290 }
289291
292+ fn fold_binder < T > ( & mut self , t : & ty:: Binder < T > ) -> ty:: Binder < T >
293+ where T : TypeFoldable < ' tcx >
294+ {
295+ self . binder_index . shift_in ( 1 ) ;
296+ let t = t. super_fold_with ( self ) ;
297+ self . binder_index . shift_out ( 1 ) ;
298+ t
299+ }
300+
290301 fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
291302 match * r {
292- ty:: ReLateBound ( ..) => {
293- // leave bound regions alone
294- r
303+ ty:: ReLateBound ( index, ..) => {
304+ if index >= self . binder_index {
305+ bug ! ( "escaping late bound region during canonicalization" )
306+ } else {
307+ r
308+ }
295309 }
296310
297311 ty:: ReVar ( vid) => {
@@ -317,8 +331,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
317331 | ty:: ReErased => self . canonicalize_region_mode
318332 . canonicalize_free_region ( self , r) ,
319333
320- ty:: ReClosureBound ( ..) | ty :: ReCanonical ( _ ) => {
321- bug ! ( "canonical region encountered during canonicalization" )
334+ ty:: ReClosureBound ( ..) => {
335+ bug ! ( "closure bound region encountered during canonicalization" )
322336 }
323337 }
324338 }
@@ -337,8 +351,12 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
337351 bug ! ( "encountered a fresh type during canonicalization" )
338352 }
339353
340- ty:: Infer ( ty:: BoundTy ( _) ) => {
341- bug ! ( "encountered a canonical type during canonicalization" )
354+ ty:: Bound ( bound_ty) => {
355+ if bound_ty. index >= self . binder_index {
356+ bug ! ( "escaping bound type during canonicalization" )
357+ } else {
358+ t
359+ }
342360 }
343361
344362 ty:: Closure ( ..)
@@ -389,12 +407,6 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
389407 where
390408 V : TypeFoldable < ' tcx > + Lift < ' gcx > ,
391409 {
392- debug_assert ! (
393- !value. has_type_flags( TypeFlags :: HAS_CANONICAL_VARS ) ,
394- "canonicalizing a canonical value: {:?}" ,
395- value,
396- ) ;
397-
398410 let needs_canonical_flags = if canonicalize_region_mode. any ( ) {
399411 TypeFlags :: HAS_FREE_REGIONS | TypeFlags :: KEEP_IN_LOCAL_TCX
400412 } else {
@@ -422,6 +434,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
422434 variables : SmallVec :: new ( ) ,
423435 query_state,
424436 indices : FxHashMap :: default ( ) ,
437+ binder_index : ty:: INNERMOST ,
425438 } ;
426439 let out_value = value. fold_with ( & mut canonicalizer) ;
427440
@@ -455,7 +468,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
455468 /// or returns an existing variable if `kind` has already been
456469 /// seen. `kind` is expected to be an unbound variable (or
457470 /// potentially a free region).
458- fn canonical_var ( & mut self , info : CanonicalVarInfo , kind : Kind < ' tcx > ) -> BoundTy {
471+ fn canonical_var ( & mut self , info : CanonicalVarInfo , kind : Kind < ' tcx > ) -> BoundVar {
459472 let Canonicalizer {
460473 variables,
461474 query_state,
@@ -475,7 +488,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
475488 // direct linear search of `var_values`.
476489 if let Some ( idx) = var_values. iter ( ) . position ( |& k| k == kind) {
477490 // `kind` is already present in `var_values`.
478- BoundTyIndex :: new ( idx)
491+ BoundVar :: new ( idx)
479492 } else {
480493 // `kind` isn't present in `var_values`. Append it. Likewise
481494 // for `info` and `variables`.
@@ -490,26 +503,23 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
490503 * indices = var_values
491504 . iter ( )
492505 . enumerate ( )
493- . map ( |( i, & kind) | ( kind, BoundTyIndex :: new ( i) ) )
506+ . map ( |( i, & kind) | ( kind, BoundVar :: new ( i) ) )
494507 . collect ( ) ;
495508 }
496509 // The cv is the index of the appended element.
497- BoundTyIndex :: new ( var_values. len ( ) - 1 )
510+ BoundVar :: new ( var_values. len ( ) - 1 )
498511 }
499512 } else {
500513 // `var_values` is large. Do a hashmap search via `indices`.
501514 * indices. entry ( kind) . or_insert_with ( || {
502515 variables. push ( info) ;
503516 var_values. push ( kind) ;
504517 assert_eq ! ( variables. len( ) , var_values. len( ) ) ;
505- BoundTyIndex :: new ( variables. len ( ) - 1 )
518+ BoundVar :: new ( variables. len ( ) - 1 )
506519 } )
507520 } ;
508521
509- BoundTy {
510- level : ty:: INNERMOST ,
511- var,
512- }
522+ var
513523 }
514524
515525 /// Shorthand helper that creates a canonical region variable for
@@ -552,9 +562,12 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
552562 info : CanonicalVarInfo ,
553563 r : ty:: Region < ' tcx > ,
554564 ) -> ty:: Region < ' tcx > {
555- let b = self . canonical_var ( info, r. into ( ) ) ;
556- debug_assert_eq ! ( ty:: INNERMOST , b. level) ;
557- self . tcx ( ) . mk_region ( ty:: ReCanonical ( b. var ) )
565+ let var = self . canonical_var ( info, r. into ( ) ) ;
566+ let region = ty:: ReLateBound (
567+ self . binder_index ,
568+ ty:: BoundRegion :: BrAnon ( var. as_u32 ( ) )
569+ ) ;
570+ self . tcx ( ) . mk_region ( region)
558571 }
559572
560573 /// Given a type variable `ty_var` of the given kind, first check
@@ -570,9 +583,8 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
570583 let info = CanonicalVarInfo {
571584 kind : CanonicalVarKind :: Ty ( ty_kind) ,
572585 } ;
573- let b = self . canonical_var ( info, ty_var. into ( ) ) ;
574- debug_assert_eq ! ( ty:: INNERMOST , b. level) ;
575- self . tcx ( ) . mk_infer ( ty:: InferTy :: BoundTy ( b) )
586+ let var = self . canonical_var ( info, ty_var. into ( ) ) ;
587+ self . tcx ( ) . mk_ty ( ty:: Bound ( BoundTy :: new ( self . binder_index , var) ) )
576588 }
577589 }
578590}
0 commit comments