@@ -23,7 +23,7 @@ use infer::InferCtxt;
23
23
use std:: sync:: atomic:: Ordering ;
24
24
use ty:: fold:: { TypeFoldable , TypeFolder } ;
25
25
use 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 } ;
27
27
28
28
use rustc_data_structures:: fx:: FxHashMap ;
29
29
use rustc_data_structures:: indexed_vec:: Idx ;
@@ -277,21 +277,35 @@ struct Canonicalizer<'cx, 'gcx: 'tcx, 'tcx: 'cx> {
277
277
query_state : & ' cx mut OriginalQueryValues < ' tcx > ,
278
278
// Note that indices is only used once `var_values` is big enough to be
279
279
// heap-allocated.
280
- indices : FxHashMap < Kind < ' tcx > , BoundTyIndex > ,
280
+ indices : FxHashMap < Kind < ' tcx > , BoundVar > ,
281
281
canonicalize_region_mode : & ' cx dyn CanonicalizeRegionMode ,
282
282
needs_canonical_flags : TypeFlags ,
283
+
284
+ binder_index : ty:: DebruijnIndex ,
283
285
}
284
286
285
287
impl < ' cx , ' gcx , ' tcx > TypeFolder < ' gcx , ' tcx > for Canonicalizer < ' cx , ' gcx , ' tcx > {
286
288
fn tcx < ' b > ( & ' b self ) -> TyCtxt < ' b , ' gcx , ' tcx > {
287
289
self . tcx
288
290
}
289
291
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
+
290
301
fn fold_region ( & mut self , r : ty:: Region < ' tcx > ) -> ty:: Region < ' tcx > {
291
302
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
+ }
295
309
}
296
310
297
311
ty:: ReVar ( vid) => {
@@ -317,8 +331,8 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
317
331
| ty:: ReErased => self . canonicalize_region_mode
318
332
. canonicalize_free_region ( self , r) ,
319
333
320
- ty:: ReClosureBound ( ..) | ty :: ReCanonical ( _ ) => {
321
- bug ! ( "canonical region encountered during canonicalization" )
334
+ ty:: ReClosureBound ( ..) => {
335
+ bug ! ( "closure bound region encountered during canonicalization" )
322
336
}
323
337
}
324
338
}
@@ -337,8 +351,12 @@ impl<'cx, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for Canonicalizer<'cx, 'gcx, 'tcx>
337
351
bug ! ( "encountered a fresh type during canonicalization" )
338
352
}
339
353
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
+ }
342
360
}
343
361
344
362
ty:: Closure ( ..)
@@ -389,12 +407,6 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
389
407
where
390
408
V : TypeFoldable < ' tcx > + Lift < ' gcx > ,
391
409
{
392
- debug_assert ! (
393
- !value. has_type_flags( TypeFlags :: HAS_CANONICAL_VARS ) ,
394
- "canonicalizing a canonical value: {:?}" ,
395
- value,
396
- ) ;
397
-
398
410
let needs_canonical_flags = if canonicalize_region_mode. any ( ) {
399
411
TypeFlags :: HAS_FREE_REGIONS | TypeFlags :: KEEP_IN_LOCAL_TCX
400
412
} else {
@@ -422,6 +434,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
422
434
variables : SmallVec :: new ( ) ,
423
435
query_state,
424
436
indices : FxHashMap :: default ( ) ,
437
+ binder_index : ty:: INNERMOST ,
425
438
} ;
426
439
let out_value = value. fold_with ( & mut canonicalizer) ;
427
440
@@ -455,7 +468,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
455
468
/// or returns an existing variable if `kind` has already been
456
469
/// seen. `kind` is expected to be an unbound variable (or
457
470
/// 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 {
459
472
let Canonicalizer {
460
473
variables,
461
474
query_state,
@@ -475,7 +488,7 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
475
488
// direct linear search of `var_values`.
476
489
if let Some ( idx) = var_values. iter ( ) . position ( |& k| k == kind) {
477
490
// `kind` is already present in `var_values`.
478
- BoundTyIndex :: new ( idx)
491
+ BoundVar :: new ( idx)
479
492
} else {
480
493
// `kind` isn't present in `var_values`. Append it. Likewise
481
494
// for `info` and `variables`.
@@ -490,26 +503,23 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
490
503
* indices = var_values
491
504
. iter ( )
492
505
. enumerate ( )
493
- . map ( |( i, & kind) | ( kind, BoundTyIndex :: new ( i) ) )
506
+ . map ( |( i, & kind) | ( kind, BoundVar :: new ( i) ) )
494
507
. collect ( ) ;
495
508
}
496
509
// The cv is the index of the appended element.
497
- BoundTyIndex :: new ( var_values. len ( ) - 1 )
510
+ BoundVar :: new ( var_values. len ( ) - 1 )
498
511
}
499
512
} else {
500
513
// `var_values` is large. Do a hashmap search via `indices`.
501
514
* indices. entry ( kind) . or_insert_with ( || {
502
515
variables. push ( info) ;
503
516
var_values. push ( kind) ;
504
517
assert_eq ! ( variables. len( ) , var_values. len( ) ) ;
505
- BoundTyIndex :: new ( variables. len ( ) - 1 )
518
+ BoundVar :: new ( variables. len ( ) - 1 )
506
519
} )
507
520
} ;
508
521
509
- BoundTy {
510
- level : ty:: INNERMOST ,
511
- var,
512
- }
522
+ var
513
523
}
514
524
515
525
/// Shorthand helper that creates a canonical region variable for
@@ -552,9 +562,12 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
552
562
info : CanonicalVarInfo ,
553
563
r : ty:: Region < ' tcx > ,
554
564
) -> 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)
558
571
}
559
572
560
573
/// Given a type variable `ty_var` of the given kind, first check
@@ -570,9 +583,8 @@ impl<'cx, 'gcx, 'tcx> Canonicalizer<'cx, 'gcx, 'tcx> {
570
583
let info = CanonicalVarInfo {
571
584
kind : CanonicalVarKind :: Ty ( ty_kind) ,
572
585
} ;
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) ) )
576
588
}
577
589
}
578
590
}
0 commit comments