Skip to content

Commit 1bafbe1

Browse files
committed
Unload proc-macro dlls on changed timestamp
1 parent 536eea3 commit 1bafbe1

File tree

2 files changed

+31
-18
lines changed

2 files changed

+31
-18
lines changed

src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,12 @@
33
mod version;
44

55
use proc_macro::bridge;
6-
use std::{fmt, fs::File, io};
6+
use std::{
7+
fmt,
8+
fs::{self, File},
9+
io,
10+
time::SystemTime,
11+
};
712

813
use libloading::Library;
914
use memmap2::Mmap;
@@ -136,6 +141,7 @@ impl ProcMacroLibraryLibloading {
136141
pub(crate) struct Expander {
137142
inner: ProcMacroLibraryLibloading,
138143
path: Utf8PathBuf,
144+
modified_time: SystemTime,
139145
}
140146

141147
impl Drop for Expander {
@@ -151,12 +157,13 @@ impl Expander {
151157
// Some libraries for dynamic loading require canonicalized path even when it is
152158
// already absolute
153159
let lib = lib.canonicalize_utf8()?;
160+
let modified_time = fs::metadata(&lib).and_then(|it| it.modified())?;
154161

155162
let path = ensure_file_with_lock_free_access(&lib)?;
156163

157164
let library = ProcMacroLibraryLibloading::open(path.as_ref())?;
158165

159-
Ok(Expander { inner: library, path })
166+
Ok(Expander { inner: library, path, modified_time })
160167
}
161168

162169
pub(crate) fn expand<S: ProcMacroSrvSpan>(
@@ -181,6 +188,10 @@ impl Expander {
181188
pub(crate) fn list_macros(&self) -> Vec<(String, ProcMacroKind)> {
182189
self.inner.proc_macros.list_macros()
183190
}
191+
192+
pub(crate) fn modified_time(&self) -> SystemTime {
193+
self.modified_time
194+
}
184195
}
185196

186197
/// Copy the dylib to temp directory to prevent locking in Windows

src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ use std::{
3535
fs,
3636
path::{Path, PathBuf},
3737
thread,
38-
time::SystemTime,
3938
};
4039

4140
use paths::{Utf8Path, Utf8PathBuf};
@@ -53,7 +52,7 @@ use crate::server_impl::TokenStream;
5352
pub const RUSTC_VERSION_STRING: &str = env!("RUSTC_VERSION");
5453

5554
pub struct ProcMacroSrv<'env> {
56-
expanders: HashMap<(Utf8PathBuf, SystemTime), dylib::Expander>,
55+
expanders: HashMap<Utf8PathBuf, dylib::Expander>,
5756
span_mode: SpanMode,
5857
env: &'env EnvSnapshot,
5958
}
@@ -81,10 +80,9 @@ impl<'env> ProcMacroSrv<'env> {
8180
) -> Result<(msg::FlatTree, Vec<u32>), msg::PanicMessage> {
8281
let span_mode = self.span_mode;
8382
let snapped_env = self.env;
84-
let expander = self.expander(lib.as_ref()).map_err(|err| {
85-
debug_assert!(false, "should list macros before asking to expand");
86-
msg::PanicMessage(format!("failed to load macro: {err}"))
87-
})?;
83+
let expander = self
84+
.expander(lib.as_ref())
85+
.map_err(|err| msg::PanicMessage(format!("failed to load macro: {err}")))?;
8886

8987
let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref));
9088

@@ -107,16 +105,20 @@ impl<'env> ProcMacroSrv<'env> {
107105
}
108106

109107
fn expander(&mut self, path: &Utf8Path) -> Result<&dylib::Expander, String> {
110-
let time = fs::metadata(path)
111-
.and_then(|it| it.modified())
112-
.map_err(|err| format!("Failed to get file metadata for {path}: {err}",))?;
113-
114-
Ok(match self.expanders.entry((path.to_path_buf(), time)) {
115-
Entry::Vacant(v) => v.insert(
116-
dylib::Expander::new(path)
117-
.map_err(|err| format!("Cannot create expander for {path}: {err}",))?,
118-
),
119-
Entry::Occupied(e) => e.into_mut(),
108+
let expander = || {
109+
dylib::Expander::new(path)
110+
.map_err(|err| format!("Cannot create expander for {path}: {err}",))
111+
};
112+
113+
Ok(match self.expanders.entry(path.to_path_buf()) {
114+
Entry::Vacant(v) => v.insert(expander()?),
115+
Entry::Occupied(mut e) => {
116+
let time = fs::metadata(path).and_then(|it| it.modified()).ok();
117+
if Some(e.get().modified_time()) != time {
118+
e.insert(expander()?);
119+
}
120+
e.into_mut()
121+
}
120122
})
121123
}
122124
}

0 commit comments

Comments
 (0)