@@ -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