@@ -243,11 +243,20 @@ impl<'tcx> CtxtInterners<'tcx> {
243243 }
244244}
245245
246+ // For these preinterned values, an alternative would be to have
247+ // variable-length vectors that grow as needed. But that turned out to be
248+ // slightly more complex and no faster.
249+
246250const NUM_PREINTERNED_TY_VARS : u32 = 100 ;
247251const NUM_PREINTERNED_FRESH_TYS : u32 = 20 ;
248252const NUM_PREINTERNED_FRESH_INT_TYS : u32 = 3 ;
249253const NUM_PREINTERNED_FRESH_FLOAT_TYS : u32 = 3 ;
250254
255+ // This number may seem high, but it is reached in all but the smallest crates.
256+ const NUM_PREINTERNED_RE_VARS : u32 = 500 ;
257+ const NUM_PREINTERNED_RE_LATE_BOUNDS_I : u32 = 2 ;
258+ const NUM_PREINTERNED_RE_LATE_BOUNDS_V : u32 = 20 ;
259+
251260pub struct CommonTypes < ' tcx > {
252261 pub unit : Ty < ' tcx > ,
253262 pub bool : Ty < ' tcx > ,
@@ -295,6 +304,14 @@ pub struct CommonLifetimes<'tcx> {
295304
296305 /// Erased region, used outside of type inference.
297306 pub re_erased : Region < ' tcx > ,
307+
308+ /// Pre-interned `ReVar(ty::RegionVar(n))` for small values of `n`.
309+ pub re_vars : Vec < Region < ' tcx > > ,
310+
311+ /// Pre-interned values of the form:
312+ /// `ReLateBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon(v, None) })
313+ /// for small values of `i` and `v`.
314+ pub re_late_bounds : Vec < Vec < Region < ' tcx > > > ,
298315}
299316
300317pub struct CommonConsts < ' tcx > {
@@ -358,7 +375,31 @@ impl<'tcx> CommonLifetimes<'tcx> {
358375 ) )
359376 } ;
360377
361- CommonLifetimes { re_static : mk ( ty:: ReStatic ) , re_erased : mk ( ty:: ReErased ) }
378+ let re_vars =
379+ ( 0 ..NUM_PREINTERNED_RE_VARS ) . map ( |n| mk ( ty:: ReVar ( ty:: RegionVid :: from ( n) ) ) ) . collect ( ) ;
380+
381+ let re_late_bounds = ( 0 ..NUM_PREINTERNED_RE_LATE_BOUNDS_I )
382+ . map ( |i| {
383+ ( 0 ..NUM_PREINTERNED_RE_LATE_BOUNDS_V )
384+ . map ( |v| {
385+ mk ( ty:: ReLateBound (
386+ ty:: DebruijnIndex :: from ( i) ,
387+ ty:: BoundRegion {
388+ var : ty:: BoundVar :: from ( v) ,
389+ kind : ty:: BrAnon ( v, None ) ,
390+ } ,
391+ ) )
392+ } )
393+ . collect ( )
394+ } )
395+ . collect ( ) ;
396+
397+ CommonLifetimes {
398+ re_static : mk ( ty:: ReStatic ) ,
399+ re_erased : mk ( ty:: ReErased ) ,
400+ re_vars,
401+ re_late_bounds,
402+ }
362403 }
363404}
364405
@@ -2002,7 +2043,16 @@ impl<'tcx> TyCtxt<'tcx> {
20022043 debruijn : ty:: DebruijnIndex ,
20032044 bound_region : ty:: BoundRegion ,
20042045 ) -> Region < ' tcx > {
2005- self . intern_region ( ty:: ReLateBound ( debruijn, bound_region) )
2046+ // Use a pre-interned one when possible.
2047+ if let ty:: BoundRegion { var, kind : ty:: BrAnon ( v, None ) } = bound_region
2048+ && var. as_u32 ( ) == v
2049+ && let Some ( inner) = self . lifetimes . re_late_bounds . get ( debruijn. as_usize ( ) )
2050+ && let Some ( re) = inner. get ( v as usize ) . copied ( )
2051+ {
2052+ re
2053+ } else {
2054+ self . intern_region ( ty:: ReLateBound ( debruijn, bound_region) )
2055+ }
20062056 }
20072057
20082058 #[ inline]
@@ -2011,8 +2061,13 @@ impl<'tcx> TyCtxt<'tcx> {
20112061 }
20122062
20132063 #[ inline]
2014- pub fn mk_re_var ( self , vid : ty:: RegionVid ) -> Region < ' tcx > {
2015- self . intern_region ( ty:: ReVar ( vid) )
2064+ pub fn mk_re_var ( self , v : ty:: RegionVid ) -> Region < ' tcx > {
2065+ // Use a pre-interned one when possible.
2066+ self . lifetimes
2067+ . re_vars
2068+ . get ( v. as_usize ( ) )
2069+ . copied ( )
2070+ . unwrap_or_else ( || self . intern_region ( ty:: ReVar ( v) ) )
20162071 }
20172072
20182073 #[ inline]
0 commit comments