diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index f220bd5688dae..4cc9d8fe93bd6 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -18,6 +18,7 @@ #![feature(crate_visibility_modifier)] #![feature(const_fn)] #![feature(const_panic)] +#![feature(hash_raw_entry)] #![feature(negative_impls)] #![feature(nll)] #![feature(min_specialization)] diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index b4937a68a5f53..83006c602d72d 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -5,7 +5,7 @@ //! type, and vice versa. use rustc_arena::DroplessArena; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey}; use rustc_macros::HashStable_Generic; use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; @@ -5051,6 +5051,12 @@ rustc_index::newtype_index! { pub struct SymbolIndex { .. } } +fn fx_hash(string: &str) -> u64 { + let mut hasher = FxHasher::default(); + string.hash(&mut hasher); + hasher.finish() +} + impl Symbol { const fn new(n: u32) -> Self { Symbol(SymbolIndex::from_u32(n)) @@ -5058,10 +5064,13 @@ impl Symbol { /// Maps a string to its interned representation. pub fn intern(string: &str) -> Self { - if let Some(symbol) = unsafe { STATIC_SYMBOLS.get(string) } { + let hash = fx_hash(string); + if let Some((_, symbol)) = + unsafe { &STATIC_SYMBOLS }.raw_entry().from_key_hashed_nocheck(hash, string) + { *symbol } else { - with_interner(|interner| interner.intern(string)) + with_interner(|interner| interner.intern_ext(hash, string)) } } @@ -5163,8 +5172,8 @@ impl Interner { } #[inline] - pub fn intern(&mut self, string: &str) -> Symbol { - if let Some(&name) = self.names.get(string) { + fn intern_ext(&mut self, hash: u64, string: &str) -> Symbol { + if let Some((_, &name)) = self.names.raw_entry().from_key_hashed_nocheck(hash, string) { return name; } @@ -5182,6 +5191,11 @@ impl Interner { name } + #[inline] + pub fn intern(&mut self, string: &str) -> Symbol { + self.intern_ext(fx_hash(string), string) + } + // Get the symbol as a string. `Symbol::as_str()` should be used in // preference to this function. pub fn get(&self, symbol: Symbol) -> &str {