55use rustc_arena:: DroplessArena ;
66use rustc_data_structures:: fx:: FxHashMap ;
77use rustc_data_structures:: stable_hasher:: { HashStable , StableHasher , ToStableHashKey } ;
8+ use rustc_data_structures:: sync:: Lock ;
89use rustc_macros:: HashStable_Generic ;
910use rustc_serialize:: { Decodable , Decoder , Encodable , Encoder } ;
1011
@@ -1623,14 +1624,15 @@ impl Symbol {
16231624
16241625 /// Maps a string to its interned representation.
16251626 pub fn intern ( string : & str ) -> Self {
1626- with_interner ( |interner| interner . intern ( string) )
1627+ with_session_globals ( |session_globals| session_globals . symbol_interner . intern ( string) )
16271628 }
16281629
16291630 /// Convert to a `SymbolStr`. This is a slowish operation because it
16301631 /// requires locking the symbol interner.
16311632 pub fn as_str ( self ) -> SymbolStr {
1632- with_interner ( |interner| unsafe {
1633- SymbolStr { string : std:: mem:: transmute :: < & str , & str > ( interner. get ( self ) ) }
1633+ with_session_globals ( |session_globals| {
1634+ let symbol_str = session_globals. symbol_interner . get ( self ) ;
1635+ unsafe { SymbolStr { string : std:: mem:: transmute :: < & str , & str > ( symbol_str) } }
16341636 } )
16351637 }
16361638
@@ -1639,7 +1641,7 @@ impl Symbol {
16391641 }
16401642
16411643 pub fn len ( self ) -> usize {
1642- with_interner ( |interner| interner . get ( self ) . len ( ) )
1644+ with_session_globals ( |session_globals| session_globals . symbol_interner . get ( self ) . len ( ) )
16431645 }
16441646
16451647 pub fn is_empty ( self ) -> bool {
@@ -1696,6 +1698,9 @@ impl<CTX> ToStableHashKey<CTX> for Symbol {
16961698 }
16971699}
16981700
1701+ #[ derive( Default ) ]
1702+ pub ( crate ) struct Interner ( Lock < InternerInner > ) ;
1703+
16991704// The `&'static str`s in this type actually point into the arena.
17001705//
17011706// The `FxHashMap`+`Vec` pair could be replaced by `FxIndexSet`, but #75278
@@ -1705,45 +1710,46 @@ impl<CTX> ToStableHashKey<CTX> for Symbol {
17051710// This type is private to prevent accidentally constructing more than one `Interner` on the same
17061711// thread, which makes it easy to mixup `Symbol`s between `Interner`s.
17071712#[ derive( Default ) ]
1708- pub ( crate ) struct Interner {
1713+ struct InternerInner {
17091714 arena : DroplessArena ,
17101715 names : FxHashMap < & ' static str , Symbol > ,
17111716 strings : Vec < & ' static str > ,
17121717}
17131718
17141719impl Interner {
17151720 fn prefill ( init : & [ & ' static str ] ) -> Self {
1716- Interner {
1721+ Interner ( Lock :: new ( InternerInner {
17171722 strings : init. into ( ) ,
17181723 names : init. iter ( ) . copied ( ) . zip ( ( 0 ..) . map ( Symbol :: new) ) . collect ( ) ,
17191724 ..Default :: default ( )
1720- }
1725+ } ) )
17211726 }
17221727
17231728 #[ inline]
1724- pub fn intern ( & mut self , string : & str ) -> Symbol {
1725- if let Some ( & name) = self . names . get ( string) {
1729+ fn intern ( & self , string : & str ) -> Symbol {
1730+ let mut inner = self . 0 . lock ( ) ;
1731+ if let Some ( & name) = inner. names . get ( string) {
17261732 return name;
17271733 }
17281734
1729- let name = Symbol :: new ( self . strings . len ( ) as u32 ) ;
1735+ let name = Symbol :: new ( inner . strings . len ( ) as u32 ) ;
17301736
17311737 // `from_utf8_unchecked` is safe since we just allocated a `&str` which is known to be
17321738 // UTF-8.
17331739 let string: & str =
1734- unsafe { str:: from_utf8_unchecked ( self . arena . alloc_slice ( string. as_bytes ( ) ) ) } ;
1740+ unsafe { str:: from_utf8_unchecked ( inner . arena . alloc_slice ( string. as_bytes ( ) ) ) } ;
17351741 // It is safe to extend the arena allocation to `'static` because we only access
17361742 // these while the arena is still alive.
17371743 let string: & ' static str = unsafe { & * ( string as * const str ) } ;
1738- self . strings . push ( string) ;
1739- self . names . insert ( string, name) ;
1744+ inner . strings . push ( string) ;
1745+ inner . names . insert ( string, name) ;
17401746 name
17411747 }
17421748
17431749 // Get the symbol as a string. `Symbol::as_str()` should be used in
17441750 // preference to this function.
1745- pub fn get ( & self , symbol : Symbol ) -> & str {
1746- self . strings [ symbol. 0 . as_usize ( ) ]
1751+ fn get ( & self , symbol : Symbol ) -> & str {
1752+ self . 0 . lock ( ) . strings [ symbol. 0 . as_usize ( ) ]
17471753 }
17481754}
17491755
@@ -1874,11 +1880,6 @@ impl Ident {
18741880 }
18751881}
18761882
1877- #[ inline]
1878- fn with_interner < T , F : FnOnce ( & mut Interner ) -> T > ( f : F ) -> T {
1879- with_session_globals ( |session_globals| f ( & mut * session_globals. symbol_interner . lock ( ) ) )
1880- }
1881-
18821883/// An alternative to [`Symbol`], useful when the chars within the symbol need to
18831884/// be accessed. It deliberately has limited functionality and should only be
18841885/// used for temporary values.
0 commit comments