@@ -243,11 +243,20 @@ impl<'tcx> CtxtInterners<'tcx> {
243
243
}
244
244
}
245
245
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
+
246
250
const NUM_PREINTERNED_TY_VARS : u32 = 100 ;
247
251
const NUM_PREINTERNED_FRESH_TYS : u32 = 20 ;
248
252
const NUM_PREINTERNED_FRESH_INT_TYS : u32 = 3 ;
249
253
const NUM_PREINTERNED_FRESH_FLOAT_TYS : u32 = 3 ;
250
254
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
+
251
260
pub struct CommonTypes < ' tcx > {
252
261
pub unit : Ty < ' tcx > ,
253
262
pub bool : Ty < ' tcx > ,
@@ -295,6 +304,14 @@ pub struct CommonLifetimes<'tcx> {
295
304
296
305
/// Erased region, used outside of type inference.
297
306
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 > > > ,
298
315
}
299
316
300
317
pub struct CommonConsts < ' tcx > {
@@ -358,7 +375,31 @@ impl<'tcx> CommonLifetimes<'tcx> {
358
375
) )
359
376
} ;
360
377
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
+ }
362
403
}
363
404
}
364
405
@@ -2002,7 +2043,16 @@ impl<'tcx> TyCtxt<'tcx> {
2002
2043
debruijn : ty:: DebruijnIndex ,
2003
2044
bound_region : ty:: BoundRegion ,
2004
2045
) -> 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
+ }
2006
2056
}
2007
2057
2008
2058
#[ inline]
@@ -2011,8 +2061,13 @@ impl<'tcx> TyCtxt<'tcx> {
2011
2061
}
2012
2062
2013
2063
#[ 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) ) )
2016
2071
}
2017
2072
2018
2073
#[ inline]
0 commit comments