diff --git a/Cargo.lock b/Cargo.lock index 5d313b93083..0204617d5df 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1167,7 +1167,6 @@ dependencies = [ "mbe", "memmap2", "object 0.29.0", - "once_cell", "paths", "proc-macro-api", "proc-macro-test", diff --git a/crates/proc-macro-srv/Cargo.toml b/crates/proc-macro-srv/Cargo.toml index 06348afdede..e39026ac70b 100644 --- a/crates/proc-macro-srv/Cargo.toml +++ b/crates/proc-macro-srv/Cargo.toml @@ -24,7 +24,6 @@ tt = { path = "../tt", version = "0.0.0" } mbe = { path = "../mbe", version = "0.0.0" } paths = { path = "../paths", version = "0.0.0" } proc-macro-api = { path = "../proc-macro-api", version = "0.0.0" } -once_cell = "1.13.0" [dev-dependencies] expect-test = "1.4.0" diff --git a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs index 69f1e13fb06..066e0e26ac8 100644 --- a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs +++ b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server.rs @@ -83,7 +83,7 @@ fn literal_from_str( s: &str, ) -> Result, ()> { // FIXME: keep track of LitKind and Suffix - let symbol = SYMBOL_INTERNER.lock().unwrap().intern(s); + let symbol = ThreadLocalSymbolInterner::intern(s); Ok(bridge::Literal { kind: bridge::LitKind::Err, symbol, @@ -124,7 +124,7 @@ fn from_token_tree( bridge::TokenTree::Ident(ident) => { // FIXME: handle raw idents - let text = SYMBOL_INTERNER.lock().unwrap().get(&ident.sym).clone(); + let text = ThreadLocalSymbolInterner::get_cloned(&ident.sym); let ident: tt::Ident = tt::Ident { text, id: ident.span }; let leaf = tt::Leaf::from(ident); let tree = TokenTree::from(leaf); @@ -132,10 +132,11 @@ fn from_token_tree( } bridge::TokenTree::Literal(literal) => { - let symbol = SYMBOL_INTERNER.lock().unwrap().get(&literal.symbol).clone(); + // FIXME: remove unnecessary clones here + let symbol = ThreadLocalSymbolInterner::get_cloned(&literal.symbol); let text: tt::SmolStr = if let Some(suffix) = literal.suffix { - let suffix = SYMBOL_INTERNER.lock().unwrap().get(&suffix).clone(); + let suffix = ThreadLocalSymbolInterner::get_cloned(&suffix); format!("{symbol}{suffix}").into() } else { symbol @@ -203,7 +204,7 @@ fn into_trees( .map(|tree| match tree { tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { bridge::TokenTree::Ident(bridge::Ident { - sym: SYMBOL_INTERNER.lock().unwrap().intern(&ident.text), + sym: ThreadLocalSymbolInterner::intern(&ident.text), // FIXME: handle raw idents is_raw: false, span: ident.id, @@ -213,7 +214,7 @@ fn into_trees( bridge::TokenTree::Literal(bridge::Literal { // FIXME: handle literal kinds kind: bridge::LitKind::Err, - symbol: SYMBOL_INTERNER.lock().unwrap().intern(&lit.text), + symbol: ThreadLocalSymbolInterner::intern(&lit.text), // FIXME: handle suffixes suffix: None, span: lit.id, @@ -407,11 +408,11 @@ fn globals(&mut self) -> bridge::ExpnGlobals { } fn intern_symbol(ident: &str) -> Self::Symbol { - SYMBOL_INTERNER.lock().unwrap().intern(&tt::SmolStr::from(ident)) + ThreadLocalSymbolInterner::intern(&tt::SmolStr::from(ident)) } fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) { - f(SYMBOL_INTERNER.lock().unwrap().get(symbol).as_str()) + ThreadLocalSymbolInterner::with(symbol, |s| f(s.as_str())) } } diff --git a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs index d16c2d22440..294ef76c24a 100644 --- a/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs +++ b/crates/proc-macro-srv/src/abis/abi_sysroot/ra_server/symbol.rs @@ -1,23 +1,24 @@ //! Symbol interner for proc-macro-srv -use once_cell::sync::Lazy; -use std::{collections::HashMap, sync::Mutex}; +use std::{cell::RefCell, collections::HashMap}; use tt::SmolStr; -pub(super) static SYMBOL_INTERNER: Lazy> = Lazy::new(|| Default::default()); +thread_local! { + static SYMBOL_INTERNER: RefCell = Default::default(); +} // ID for an interned symbol. #[derive(Hash, Eq, PartialEq, Copy, Clone)] pub struct Symbol(u32); #[derive(Default)] -pub(super) struct SymbolInterner { +struct SymbolInterner { idents: HashMap, ident_data: Vec, } impl SymbolInterner { - pub(super) fn intern(&mut self, data: &str) -> Symbol { + fn intern(&mut self, data: &str) -> Symbol { if let Some(index) = self.idents.get(data) { return Symbol(*index); } @@ -29,7 +30,23 @@ pub(super) fn intern(&mut self, data: &str) -> Symbol { Symbol(index) } - pub(super) fn get(&self, index: &Symbol) -> &SmolStr { - &self.ident_data[index.0 as usize] + fn get(&self, sym: &Symbol) -> &SmolStr { + &self.ident_data[sym.0 as usize] + } +} + +pub(super) struct ThreadLocalSymbolInterner; + +impl ThreadLocalSymbolInterner { + pub(super) fn intern(data: &str) -> Symbol { + SYMBOL_INTERNER.with(|i| i.borrow_mut().intern(data)) + } + + pub(super) fn with(sym: &Symbol, f: impl FnOnce(&SmolStr) -> T) -> T { + SYMBOL_INTERNER.with(|i| f(i.borrow().get(sym))) + } + + pub(super) fn get_cloned(sym: &Symbol) -> SmolStr { + Self::with(sym, |s| s.clone()) } }