@@ -34,7 +34,7 @@ use rustc_middle::ty::Instance;
3434use  rustc_middle:: ty:: { self ,  AdtKind ,  GeneratorSubsts ,  ParamEnv ,  Ty ,  TyCtxt } ; 
3535use  rustc_middle:: { bug,  span_bug} ; 
3636use  rustc_session:: config:: { self ,  DebugInfo } ; 
37- use  rustc_span:: symbol:: { Interner ,   Symbol } ; 
37+ use  rustc_span:: symbol:: Symbol ; 
3838use  rustc_span:: FileNameDisplayPreference ; 
3939use  rustc_span:: { self ,  SourceFile ,  SourceFileHash ,  Span } ; 
4040use  rustc_target:: abi:: { Abi ,  Align ,  HasDataLayout ,  Integer ,  TagEncoding } ; 
@@ -89,8 +89,54 @@ pub const UNKNOWN_COLUMN_NUMBER: c_uint = 0;
8989
9090pub  const  NO_SCOPE_METADATA :  Option < & DIScope >  = None ; 
9191
92- #[ derive( Copy ,  Debug ,  Hash ,  Eq ,  PartialEq ,  Clone ) ]  
93- pub  struct  UniqueTypeId ( Symbol ) ; 
92+ mod  unique_type_id { 
93+     use  super :: * ; 
94+     use  rustc_arena:: DroplessArena ; 
95+ 
96+     #[ derive( Copy ,  Hash ,  Eq ,  PartialEq ,  Clone ) ]  
97+     pub ( super )  struct  UniqueTypeId ( u32 ) ; 
98+ 
99+     // The `&'static str`s in this type actually point into the arena. 
100+     // 
101+     // The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278 
102+     // found that to regress performance up to 2% in some cases. This might be 
103+     // revisited after further improvements to `indexmap`. 
104+     #[ derive( Default ) ]  
105+     pub ( super )  struct  TypeIdInterner  { 
106+         arena :  DroplessArena , 
107+         names :  FxHashMap < & ' static  str ,  UniqueTypeId > , 
108+         strings :  Vec < & ' static  str > , 
109+     } 
110+ 
111+     impl  TypeIdInterner  { 
112+         #[ inline]  
113+         pub ( super )  fn  intern ( & mut  self ,  string :  & str )  -> UniqueTypeId  { 
114+             if  let  Some ( & name)  = self . names . get ( string)  { 
115+                 return  name; 
116+             } 
117+ 
118+             let  name = UniqueTypeId ( self . strings . len ( )  as  u32 ) ; 
119+ 
120+             // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be 
121+             // UTF-8. 
122+             let  string:  & str  =
123+                 unsafe  {  std:: str:: from_utf8_unchecked ( self . arena . alloc_slice ( string. as_bytes ( ) ) )  } ; 
124+             // It is safe to extend the arena allocation to `'static` because we only access 
125+             // these while the arena is still alive. 
126+             let  string:  & ' static  str  = unsafe  {  & * ( string as  * const  str )  } ; 
127+             self . strings . push ( string) ; 
128+             self . names . insert ( string,  name) ; 
129+             name
130+         } 
131+ 
132+         // Get the symbol as a string. `Symbol::as_str()` should be used in 
133+         // preference to this function. 
134+         pub ( super )  fn  get ( & self ,  symbol :  UniqueTypeId )  -> & str  { 
135+             self . strings [ symbol. 0  as  usize ] 
136+         } 
137+     } 
138+ } 
139+ use  unique_type_id:: * ; 
94140
95141/// The `TypeMap` is where the `CrateDebugContext` holds the type metadata nodes 
96142/// created so far. The metadata nodes are indexed by `UniqueTypeId`, and, for 
@@ -99,7 +145,7 @@ pub struct UniqueTypeId(Symbol);
99145#[ derive( Default ) ]  
100146pub  struct  TypeMap < ' ll ,  ' tcx >  { 
101147    /// The `UniqueTypeId`s created so far. 
102-      unique_id_interner :  Interner , 
148+      unique_id_interner :  TypeIdInterner , 
103149    /// A map from `UniqueTypeId` to debuginfo metadata for that type. This is a 1:1 mapping. 
104150     unique_id_to_metadata :  FxHashMap < UniqueTypeId ,  & ' ll  DIType > , 
105151    /// A map from types to debuginfo metadata. This is an N:1 mapping. 
@@ -166,8 +212,7 @@ impl TypeMap<'ll, 'tcx> {
166212    /// Gets the string representation of a `UniqueTypeId`. This method will fail if 
167213     /// the ID is unknown. 
168214     fn  get_unique_type_id_as_string ( & self ,  unique_type_id :  UniqueTypeId )  -> & str  { 
169-         let  UniqueTypeId ( interner_key)  = unique_type_id; 
170-         self . unique_id_interner . get ( interner_key) 
215+         self . unique_id_interner . get ( unique_type_id) 
171216    } 
172217
173218    /// Gets the `UniqueTypeId` for the given type. If the `UniqueTypeId` for the given 
@@ -197,9 +242,9 @@ impl TypeMap<'ll, 'tcx> {
197242        let  unique_type_id = hasher. finish :: < Fingerprint > ( ) . to_hex ( ) ; 
198243
199244        let  key = self . unique_id_interner . intern ( & unique_type_id) ; 
200-         self . type_to_unique_id . insert ( type_,  UniqueTypeId ( key) ) ; 
245+         self . type_to_unique_id . insert ( type_,  key) ; 
201246
202-         UniqueTypeId ( key) 
247+         key
203248    } 
204249
205250    /// Gets the `UniqueTypeId` for an enum variant. Enum variants are not really 
@@ -215,7 +260,7 @@ impl TypeMap<'ll, 'tcx> {
215260        let  enum_variant_type_id =
216261            format ! ( "{}::{}" ,  self . get_unique_type_id_as_string( enum_type_id) ,  variant_name) ; 
217262        let  interner_key = self . unique_id_interner . intern ( & enum_variant_type_id) ; 
218-         UniqueTypeId ( interner_key) 
263+         interner_key
219264    } 
220265
221266    /// Gets the unique type ID string for an enum variant part. 
0 commit comments