Skip to content

Commit 0522503

Browse files
committed
Thread global symbol interner through as if it was a local
1 parent c4582f6 commit 0522503

File tree

3 files changed

+39
-26
lines changed

3 files changed

+39
-26
lines changed

crates/proc-macro-srv/src/proc_macros.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use libloading::Library;
44
use proc_macro_api::{ProcMacroKind, RustCInfo};
55

6-
use crate::{dylib::LoadProcMacroDylibError, tt};
6+
use crate::{dylib::LoadProcMacroDylibError, server::SYMBOL_INTERNER, tt};
77

88
pub(crate) struct ProcMacros {
99
exported_macros: Vec<proc_macro::bridge::client::ProcMacro>,
@@ -59,7 +59,7 @@ impl ProcMacros {
5959
} if *trait_name == macro_name => {
6060
let res = client.run(
6161
&proc_macro::bridge::server::SameThread,
62-
crate::server::RustAnalyzer::default(),
62+
crate::server::RustAnalyzer { interner: &SYMBOL_INTERNER },
6363
parsed_body,
6464
true,
6565
);
@@ -70,7 +70,7 @@ impl ProcMacros {
7070
{
7171
let res = client.run(
7272
&proc_macro::bridge::server::SameThread,
73-
crate::server::RustAnalyzer::default(),
73+
crate::server::RustAnalyzer { interner: &SYMBOL_INTERNER },
7474
parsed_body,
7575
true,
7676
);
@@ -81,7 +81,7 @@ impl ProcMacros {
8181
{
8282
let res = client.run(
8383
&proc_macro::bridge::server::SameThread,
84-
crate::server::RustAnalyzer::default(),
84+
crate::server::RustAnalyzer { interner: &SYMBOL_INTERNER },
8585
parsed_attributes,
8686
parsed_body,
8787
true,

crates/proc-macro-srv/src/server.rs

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use proc_macro::{
1414
};
1515

1616
mod token_stream;
17-
pub(crate) use token_stream::TokenStream;
17+
pub use token_stream::TokenStream;
1818
use token_stream::TokenStreamBuilder;
1919

2020
mod symbol;
@@ -40,9 +40,9 @@ pub struct SourceFile {
4040

4141
pub struct FreeFunctions;
4242

43-
#[derive(Default)]
4443
pub struct RustAnalyzer {
4544
// FIXME: store span information here.
45+
pub(crate) interner: SymbolInternerRef,
4646
}
4747

4848
impl server::Types for RustAnalyzer {
@@ -67,7 +67,7 @@ impl server::FreeFunctions for RustAnalyzer {
6767
// FIXME: keep track of LitKind and Suffix
6868
Ok(bridge::Literal {
6969
kind: bridge::LitKind::Err,
70-
symbol: Symbol::intern(s),
70+
symbol: Symbol::intern(self.interner, s),
7171
suffix: None,
7272
span: tt::TokenId::unspecified(),
7373
})
@@ -108,7 +108,7 @@ impl server::TokenStream for RustAnalyzer {
108108
}
109109

110110
bridge::TokenTree::Ident(ident) => {
111-
let text = ident.sym.text();
111+
let text = ident.sym.text(self.interner);
112112
let text =
113113
if ident.is_raw { ::tt::SmolStr::from_iter(["r#", &text]) } else { text };
114114
let ident: tt::Ident = tt::Ident { text, span: ident.span };
@@ -119,8 +119,9 @@ impl server::TokenStream for RustAnalyzer {
119119

120120
bridge::TokenTree::Literal(literal) => {
121121
let literal = LiteralFormatter(literal);
122-
let text = literal
123-
.with_stringify_parts(|parts| ::tt::SmolStr::from_iter(parts.iter().copied()));
122+
let text = literal.with_stringify_parts(self.interner, |parts| {
123+
::tt::SmolStr::from_iter(parts.iter().copied())
124+
});
124125

125126
let literal = tt::Literal { text, span: literal.0.span };
126127
let leaf = tt::Leaf::from(literal);
@@ -184,7 +185,7 @@ impl server::TokenStream for RustAnalyzer {
184185
.map(|tree| match tree {
185186
tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => {
186187
bridge::TokenTree::Ident(bridge::Ident {
187-
sym: Symbol::intern(ident.text.trim_start_matches("r#")),
188+
sym: Symbol::intern(self.interner, ident.text.trim_start_matches("r#")),
188189
is_raw: ident.text.starts_with("r#"),
189190
span: ident.span,
190191
})
@@ -193,7 +194,7 @@ impl server::TokenStream for RustAnalyzer {
193194
bridge::TokenTree::Literal(bridge::Literal {
194195
// FIXME: handle literal kinds
195196
kind: bridge::LitKind::Err,
196-
symbol: Symbol::intern(&lit.text),
197+
symbol: Symbol::intern(self.interner, &lit.text),
197198
// FIXME: handle suffixes
198199
suffix: None,
199200
span: lit.span,
@@ -351,11 +352,13 @@ impl server::Server for RustAnalyzer {
351352
}
352353

353354
fn intern_symbol(ident: &str) -> Self::Symbol {
354-
Symbol::intern(&::tt::SmolStr::from(ident))
355+
// FIXME: should be self.interner once the proc-macro api allows is
356+
Symbol::intern(&SYMBOL_INTERNER, &::tt::SmolStr::from(ident))
355357
}
356358

357359
fn with_symbol_string(symbol: &Self::Symbol, f: impl FnOnce(&str)) {
358-
f(symbol.text().as_str())
360+
// FIXME: should be self.interner once the proc-macro api allows is
361+
f(symbol.text(&SYMBOL_INTERNER).as_str())
359362
}
360363
}
361364

@@ -366,7 +369,11 @@ impl LiteralFormatter {
366369
/// literal's representation. This is done to allow the `ToString` and
367370
/// `Display` implementations to borrow references to symbol values, and
368371
/// both be optimized to reduce overhead.
369-
fn with_stringify_parts<R>(&self, f: impl FnOnce(&[&str]) -> R) -> R {
372+
fn with_stringify_parts<R>(
373+
&self,
374+
interner: SymbolInternerRef,
375+
f: impl FnOnce(&[&str]) -> R,
376+
) -> R {
370377
/// Returns a string containing exactly `num` '#' characters.
371378
/// Uses a 256-character source string literal which is always safe to
372379
/// index with a `u8` index.
@@ -381,7 +388,7 @@ impl LiteralFormatter {
381388
&HASHES[..num as usize]
382389
}
383390

384-
self.with_symbol_and_suffix(|symbol, suffix| match self.0.kind {
391+
self.with_symbol_and_suffix(interner, |symbol, suffix| match self.0.kind {
385392
bridge::LitKind::Byte => f(&["b'", symbol, "'", suffix]),
386393
bridge::LitKind::Char => f(&["'", symbol, "'", suffix]),
387394
bridge::LitKind::Str => f(&["\"", symbol, "\"", suffix]),
@@ -398,9 +405,13 @@ impl LiteralFormatter {
398405
})
399406
}
400407

401-
fn with_symbol_and_suffix<R>(&self, f: impl FnOnce(&str, &str) -> R) -> R {
402-
let symbol = self.0.symbol.text();
403-
let suffix = self.0.suffix.map(|s| s.text()).unwrap_or_default();
408+
fn with_symbol_and_suffix<R>(
409+
&self,
410+
interner: SymbolInternerRef,
411+
f: impl FnOnce(&str, &str) -> R,
412+
) -> R {
413+
let symbol = self.0.symbol.text(interner);
414+
let suffix = self.0.suffix.map(|s| s.text(interner)).unwrap_or_default();
404415
f(symbol.as_str(), suffix.as_str())
405416
}
406417
}

crates/proc-macro-srv/src/server/symbol.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,30 @@
11
//! Symbol interner for proc-macro-srv
22
3-
use std::{cell::RefCell, collections::HashMap};
3+
use std::{cell::RefCell, collections::HashMap, thread::LocalKey};
44
use tt::SmolStr;
55

66
thread_local! {
7-
static SYMBOL_INTERNER: RefCell<SymbolInterner> = Default::default();
7+
pub(crate) static SYMBOL_INTERNER: RefCell<SymbolInterner> = Default::default();
88
}
99

1010
// ID for an interned symbol.
1111
#[derive(Hash, Eq, PartialEq, Copy, Clone)]
1212
pub struct Symbol(u32);
1313

14+
pub(crate) type SymbolInternerRef = &'static LocalKey<RefCell<SymbolInterner>>;
15+
1416
impl Symbol {
15-
pub(super) fn intern(data: &str) -> Symbol {
16-
SYMBOL_INTERNER.with(|i| i.borrow_mut().intern(data))
17+
pub(super) fn intern(interner: SymbolInternerRef, data: &str) -> Symbol {
18+
interner.with(|i| i.borrow_mut().intern(data))
1719
}
1820

19-
pub(super) fn text(&self) -> SmolStr {
20-
SYMBOL_INTERNER.with(|i| i.borrow().get(self).clone())
21+
pub(super) fn text(&self, interner: SymbolInternerRef) -> SmolStr {
22+
interner.with(|i| i.borrow().get(self).clone())
2123
}
2224
}
2325

2426
#[derive(Default)]
25-
struct SymbolInterner {
27+
pub(crate) struct SymbolInterner {
2628
idents: HashMap<SmolStr, u32>,
2729
ident_data: Vec<SmolStr>,
2830
}

0 commit comments

Comments
 (0)