Properly clean proc-macro-srv proc-macro temp dir
diff --git a/Cargo.lock b/Cargo.lock
index 0cbbb5d..53c2d04 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -51,6 +51,15 @@
checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
+name = "atomic-polyfill"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cf2bce30dfe09ef0bfaef228b9d414faaf7e563035494d7fe092dba54b300f4"
+dependencies = [
+ "critical-section",
+]
+
+[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -126,6 +135,12 @@
checksum = "26c4925bc979b677330a8c7fe7a8c94af2dbb4a2d37b4a20a80d884400f46baa"
[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
name = "camino"
version = "1.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -319,6 +334,15 @@
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
[[package]]
+name = "cobs"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fa961b519f0b462e3a3b4a34b64d119eeaca1d59af726fe450bbba07a9fc0a1"
+dependencies = [
+ "thiserror 2.0.12",
+]
+
+[[package]]
name = "countme"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -340,6 +364,12 @@
]
[[package]]
+name = "critical-section"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b"
+
+[[package]]
name = "crossbeam-channel"
version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -597,6 +627,15 @@
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
+name = "hash32"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b0c35f58762feb77d74ebe43bdbc3210f09be9fe6742234d573bacc26ed92b67"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -623,6 +662,20 @@
]
[[package]]
+name = "heapless"
+version = "0.7.17"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f"
+dependencies = [
+ "atomic-polyfill",
+ "hash32",
+ "rustc_version",
+ "serde",
+ "spin",
+ "stable_deref_trait",
+]
+
+[[package]]
name = "hermit-abi"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1593,6 +1646,17 @@
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
[[package]]
+name = "postcard"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6764c3b5dd454e283a30e6dfe78e9b31096d9e32036b5d1eaac7a6119ccb9a24"
+dependencies = [
+ "cobs",
+ "heapless",
+ "serde",
+]
+
+[[package]]
name = "potential_utf"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1639,6 +1703,7 @@
"ra-ap-rustc_lexer 0.122.0",
"span",
"syntax-bridge",
+ "temp-dir",
"tt",
]
@@ -1647,6 +1712,7 @@
version = "0.0.0"
dependencies = [
"clap",
+ "postcard",
"proc-macro-api",
"proc-macro-srv",
"tt",
@@ -2024,6 +2090,15 @@
]
[[package]]
+name = "rustc_version"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92"
+dependencies = [
+ "semver",
+]
+
+[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2241,6 +2316,15 @@
]
[[package]]
+name = "spin"
+version = "0.9.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
+dependencies = [
+ "lock_api",
+]
+
+[[package]]
name = "stable_deref_trait"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/crates/proc-macro-srv-cli/Cargo.toml b/crates/proc-macro-srv-cli/Cargo.toml
index 16ec3b0..91e9e62 100644
--- a/crates/proc-macro-srv-cli/Cargo.toml
+++ b/crates/proc-macro-srv-cli/Cargo.toml
@@ -15,10 +15,13 @@
proc-macro-api.workspace = true
tt.workspace = true
clap = {version = "4.5.42", default-features = false, features = ["std"]}
+postcard = { version = "1.1.3", optional = true }
[features]
+default = ["postcard"]
sysroot-abi = ["proc-macro-srv/sysroot-abi"]
in-rust-tree = ["proc-macro-srv/in-rust-tree", "sysroot-abi"]
+postcard = ["dep:postcard"]
[[bin]]
diff --git a/crates/proc-macro-srv-cli/src/main.rs b/crates/proc-macro-srv-cli/src/main.rs
index b6ebc56..97a622e 100644
--- a/crates/proc-macro-srv-cli/src/main.rs
+++ b/crates/proc-macro-srv-cli/src/main.rs
@@ -39,6 +39,7 @@
#[derive(Copy, Clone)]
enum ProtocolFormat {
Json,
+ #[cfg(feature = "postcard")]
Postcard,
}
@@ -50,12 +51,14 @@
fn to_possible_value(&self) -> Option<clap::builder::PossibleValue> {
match self {
ProtocolFormat::Json => Some(clap::builder::PossibleValue::new("json")),
+ #[cfg(feature = "postcard")]
ProtocolFormat::Postcard => Some(clap::builder::PossibleValue::new("postcard")),
}
}
fn from_str(input: &str, _ignore_case: bool) -> Result<Self, String> {
match input {
"json" => Ok(ProtocolFormat::Json),
+ #[cfg(feature = "postcard")]
"postcard" => Ok(ProtocolFormat::Postcard),
_ => Err(format!("unknown protocol format: {input}")),
}
diff --git a/crates/proc-macro-srv-cli/src/main_loop.rs b/crates/proc-macro-srv-cli/src/main_loop.rs
index 6bf58ee..46be8a2 100644
--- a/crates/proc-macro-srv-cli/src/main_loop.rs
+++ b/crates/proc-macro-srv-cli/src/main_loop.rs
@@ -37,6 +37,7 @@
pub(crate) fn run(format: ProtocolFormat) -> io::Result<()> {
match format {
ProtocolFormat::Json => run_json(),
+ #[cfg(feature = "postcard")]
ProtocolFormat::Postcard => unimplemented!(),
}
}
@@ -96,7 +97,7 @@
srv.expand(
lib,
- env,
+ &env,
current_dir,
macro_name,
macro_body,
@@ -127,7 +128,7 @@
});
srv.expand(
lib,
- env,
+ &env,
current_dir,
macro_name,
macro_body,
diff --git a/crates/proc-macro-srv/Cargo.toml b/crates/proc-macro-srv/Cargo.toml
index 4034f24..d037e71 100644
--- a/crates/proc-macro-srv/Cargo.toml
+++ b/crates/proc-macro-srv/Cargo.toml
@@ -16,6 +16,7 @@
object.workspace = true
libloading.workspace = true
memmap2.workspace = true
+temp-dir.workspace = true
tt.workspace = true
syntax-bridge.workspace = true
@@ -26,6 +27,7 @@
ra-ap-rustc_lexer.workspace = true
+
[target.'cfg(unix)'.dependencies]
libc.workspace = true
diff --git a/crates/proc-macro-srv/src/dylib.rs b/crates/proc-macro-srv/src/dylib.rs
index c49159d..095e9fa 100644
--- a/crates/proc-macro-srv/src/dylib.rs
+++ b/crates/proc-macro-srv/src/dylib.rs
@@ -4,6 +4,7 @@
use proc_macro::bridge;
use std::{fmt, fs, io, time::SystemTime};
+use temp_dir::TempDir;
use libloading::Library;
use object::Object;
@@ -141,13 +142,16 @@
}
impl Expander {
- pub(crate) fn new(lib: &Utf8Path) -> Result<Expander, LoadProcMacroDylibError> {
+ pub(crate) fn new(
+ temp_dir: &TempDir,
+ lib: &Utf8Path,
+ ) -> Result<Expander, LoadProcMacroDylibError> {
// Some libraries for dynamic loading require canonicalized path even when it is
// already absolute
let lib = lib.canonicalize_utf8()?;
let modified_time = fs::metadata(&lib).and_then(|it| it.modified())?;
- let path = ensure_file_with_lock_free_access(&lib)?;
+ let path = ensure_file_with_lock_free_access(temp_dir, &lib)?;
let library = ProcMacroLibrary::open(path.as_ref())?;
Ok(Expander { inner: library, _remove_on_drop: RemoveFileOnDrop(path), modified_time })
@@ -221,7 +225,10 @@
/// Copy the dylib to temp directory to prevent locking in Windows
#[cfg(windows)]
-fn ensure_file_with_lock_free_access(path: &Utf8Path) -> io::Result<Utf8PathBuf> {
+fn ensure_file_with_lock_free_access(
+ temp_dir: &TempDir,
+ path: &Utf8Path,
+) -> io::Result<Utf8PathBuf> {
use std::collections::hash_map::RandomState;
use std::hash::{BuildHasher, Hasher};
@@ -229,9 +236,7 @@
return Ok(path.to_path_buf());
}
- let mut to = Utf8PathBuf::from_path_buf(std::env::temp_dir()).unwrap();
- to.push("rust-analyzer-proc-macros");
- _ = fs::create_dir(&to);
+ let mut to = Utf8Path::from_path(temp_dir.path()).unwrap().to_owned();
let file_name = path.file_stem().ok_or_else(|| {
io::Error::new(io::ErrorKind::InvalidInput, format!("File path is invalid: {path}"))
@@ -248,6 +253,9 @@
}
#[cfg(unix)]
-fn ensure_file_with_lock_free_access(path: &Utf8Path) -> io::Result<Utf8PathBuf> {
+fn ensure_file_with_lock_free_access(
+ _temp_dir: &TempDir,
+ path: &Utf8Path,
+) -> io::Result<Utf8PathBuf> {
Ok(path.to_owned())
}
diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs
index 0f7c839..29fe5ae 100644
--- a/crates/proc-macro-srv/src/lib.rs
+++ b/crates/proc-macro-srv/src/lib.rs
@@ -42,6 +42,7 @@
use paths::{Utf8Path, Utf8PathBuf};
use span::Span;
+use temp_dir::TempDir;
use crate::server_impl::TokenStream;
@@ -59,11 +60,16 @@
pub struct ProcMacroSrv<'env> {
expanders: Mutex<HashMap<Utf8PathBuf, Arc<dylib::Expander>>>,
env: &'env EnvSnapshot,
+ temp_dir: TempDir,
}
impl<'env> ProcMacroSrv<'env> {
pub fn new(env: &'env EnvSnapshot) -> Self {
- Self { expanders: Default::default(), env }
+ Self {
+ expanders: Default::default(),
+ env,
+ temp_dir: TempDir::with_prefix("proc-macro-srv").unwrap(),
+ }
}
}
@@ -73,7 +79,7 @@
pub fn expand<S: ProcMacroSrvSpan>(
&self,
lib: impl AsRef<Utf8Path>,
- env: Vec<(String, String)>,
+ env: &[(String, String)],
current_dir: Option<impl AsRef<Path>>,
macro_name: String,
macro_body: tt::TopSubtree<S>,
@@ -131,7 +137,7 @@
fn expander(&self, path: &Utf8Path) -> Result<Arc<dylib::Expander>, String> {
let expander = || {
- let expander = dylib::Expander::new(path)
+ let expander = dylib::Expander::new(&self.temp_dir, path)
.map_err(|err| format!("Cannot create expander for {path}: {err}",));
expander.map(Arc::new)
};
@@ -203,7 +209,7 @@
static ENV_LOCK: std::sync::Mutex<()> = std::sync::Mutex::new(());
struct EnvChange<'snap> {
- changed_vars: Vec<String>,
+ changed_vars: Vec<&'snap str>,
prev_working_dir: Option<PathBuf>,
snap: &'snap EnvSnapshot,
_guard: std::sync::MutexGuard<'snap, ()>,
@@ -212,7 +218,7 @@
impl<'snap> EnvChange<'snap> {
fn apply(
snap: &'snap EnvSnapshot,
- new_vars: Vec<(String, String)>,
+ new_vars: &'snap [(String, String)],
current_dir: Option<&Path>,
) -> EnvChange<'snap> {
let guard = ENV_LOCK.lock().unwrap_or_else(std::sync::PoisonError::into_inner);
@@ -232,11 +238,11 @@
EnvChange {
snap,
changed_vars: new_vars
- .into_iter()
+ .iter()
.map(|(k, v)| {
// SAFETY: We have acquired the environment lock
- unsafe { env::set_var(&k, v) };
- k
+ unsafe { env::set_var(k, v) };
+ &**k
})
.collect(),
prev_working_dir,
diff --git a/crates/proc-macro-srv/src/tests/utils.rs b/crates/proc-macro-srv/src/tests/utils.rs
index 7aa3857..f5a76e3 100644
--- a/crates/proc-macro-srv/src/tests/utils.rs
+++ b/crates/proc-macro-srv/src/tests/utils.rs
@@ -55,7 +55,7 @@
expect_spanned: Expect,
) {
let path = proc_macro_test_dylib_path();
- let expander = dylib::Expander::new(&path).unwrap();
+ let expander = dylib::Expander::new(&temp_dir::TempDir::new().unwrap(), &path).unwrap();
let def_site = SpanId(0);
let call_site = SpanId(1);