Skip to content

Commit ca47cdd

Browse files
authored
Merge pull request #19099 from Veykril/push-qxylslwltsqy
Use interior mutability for loaded `ProcMacrorv::expanders`
2 parents fc726ce + 5ec0057 commit ca47cdd

File tree

3 files changed

+29
-22
lines changed

3 files changed

+29
-22
lines changed

crates/proc-macro-srv-cli/src/main_loop.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -21,18 +21,16 @@ pub(crate) fn run() -> io::Result<()> {
2121
}
2222
}
2323

24-
let read_request =
25-
|buf: &mut String| msg::Request::read(read_json, &mut io::stdin().lock(), buf);
26-
24+
let mut buf = String::new();
25+
let mut read_request = || msg::Request::read(read_json, &mut io::stdin().lock(), &mut buf);
2726
let write_response = |msg: msg::Response| msg.write(write_json, &mut io::stdout().lock());
2827

2928
let env = EnvSnapshot::default();
30-
let mut srv = proc_macro_srv::ProcMacroSrv::new(&env);
31-
let mut buf = String::new();
29+
let srv = proc_macro_srv::ProcMacroSrv::new(&env);
3230

3331
let mut span_mode = SpanMode::Id;
3432

35-
while let Some(req) = read_request(&mut buf)? {
33+
while let Some(req) = read_request()? {
3634
let res = match req {
3735
msg::Request::ListMacros { dylib_path } => {
3836
msg::Response::ListMacros(srv.list_macros(&dylib_path).map(|macros| {

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

+24-15
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use std::{
3535
ffi::OsString,
3636
fs,
3737
path::{Path, PathBuf},
38+
sync::{Arc, Mutex, PoisonError},
3839
thread,
3940
};
4041

@@ -53,7 +54,7 @@ pub enum ProcMacroKind {
5354
pub const RUSTC_VERSION_STRING: &str = env!("RUSTC_VERSION");
5455

5556
pub struct ProcMacroSrv<'env> {
56-
expanders: HashMap<Utf8PathBuf, dylib::Expander>,
57+
expanders: Mutex<HashMap<Utf8PathBuf, Arc<dylib::Expander>>>,
5758
env: &'env EnvSnapshot,
5859
}
5960

@@ -67,7 +68,7 @@ const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024;
6768

6869
impl ProcMacroSrv<'_> {
6970
pub fn expand<S: ProcMacroSrvSpan>(
70-
&mut self,
71+
&self,
7172
lib: impl AsRef<Utf8Path>,
7273
env: Vec<(String, String)>,
7374
current_dir: Option<impl AsRef<Path>>,
@@ -118,29 +119,37 @@ impl ProcMacroSrv<'_> {
118119
}
119120

120121
pub fn list_macros(
121-
&mut self,
122+
&self,
122123
dylib_path: &Utf8Path,
123124
) -> Result<Vec<(String, ProcMacroKind)>, String> {
124125
let expander = self.expander(dylib_path)?;
125126
Ok(expander.list_macros())
126127
}
127128

128-
fn expander(&mut self, path: &Utf8Path) -> Result<&dylib::Expander, String> {
129+
fn expander(&self, path: &Utf8Path) -> Result<Arc<dylib::Expander>, String> {
129130
let expander = || {
130-
dylib::Expander::new(path)
131-
.map_err(|err| format!("Cannot create expander for {path}: {err}",))
131+
let expander = dylib::Expander::new(path)
132+
.map_err(|err| format!("Cannot create expander for {path}: {err}",));
133+
expander.map(Arc::new)
132134
};
133135

134-
Ok(match self.expanders.entry(path.to_path_buf()) {
135-
Entry::Vacant(v) => v.insert(expander()?),
136-
Entry::Occupied(mut e) => {
137-
let time = fs::metadata(path).and_then(|it| it.modified()).ok();
138-
if Some(e.get().modified_time()) != time {
139-
e.insert(expander()?);
136+
Ok(
137+
match self
138+
.expanders
139+
.lock()
140+
.unwrap_or_else(PoisonError::into_inner)
141+
.entry(path.to_path_buf())
142+
{
143+
Entry::Vacant(v) => v.insert(expander()?).clone(),
144+
Entry::Occupied(mut e) => {
145+
let time = fs::metadata(path).and_then(|it| it.modified()).ok();
146+
if Some(e.get().modified_time()) != time {
147+
e.insert(expander()?);
148+
}
149+
e.get().clone()
140150
}
141-
e.into_mut()
142-
}
143-
})
151+
},
152+
)
144153
}
145154
}
146155

crates/proc-macro-srv/src/tests/utils.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ fn assert_expand_impl(
107107
pub(crate) fn list() -> Vec<String> {
108108
let dylib_path = proc_macro_test_dylib_path();
109109
let env = EnvSnapshot::default();
110-
let mut srv = ProcMacroSrv::new(&env);
110+
let srv = ProcMacroSrv::new(&env);
111111
let res = srv.list_macros(&dylib_path).unwrap();
112112
res.into_iter().map(|(name, kind)| format!("{name} [{kind:?}]")).collect()
113113
}

0 commit comments

Comments
 (0)