about summary refs log tree commit diff
path: root/src/tools/rust-analyzer/crates/proc-macro-api
diff options
context:
space:
mode:
authorjyn <github@jyn.dev>2025-04-19 11:42:38 -0400
committerjyn <github@jyn.dev>2025-04-19 12:15:22 -0400
commitfdcc2faaa206f2fcecd5a1ee40e1db6a116c9500 (patch)
tree18490bb3418d47c82fbe17f1d021f4d05661ae80 /src/tools/rust-analyzer/crates/proc-macro-api
parent53bd63400f223993adf036d180e42089dd9f2b48 (diff)
allow using `null` to unset an environment variable
this makes three changes:
- all callsites of `toolchain::command` are changed to use
  `command(path, extra_env)`, instead of manually adding the env after
  the fact.
- all `map<str, str>` are changed to `map<str, option<str>>`.
- `command` checks for None and calls `env_remove` if so.

this caught several places where environment variables weren't being
propagated:
- when running `rustc --print=target-libdir`
- when running `cargo rustc -- --print=target-spec-json`
- when running the custom DiscoverLinkedProjects config. I *think* this
  is for use with non-cargo build systems, so I didn't change it.
Diffstat (limited to 'src/tools/rust-analyzer/crates/proc-macro-api')
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs7
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs28
2 files changed, 23 insertions, 12 deletions
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
index d67d6058d50..25c30b6db4a 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/lib.rs
@@ -105,10 +105,11 @@ impl fmt::Display for ServerError {
 
 impl ProcMacroClient {
     /// Spawns an external process as the proc macro server and returns a client connected to it.
-    pub fn spawn(
+    pub fn spawn<'a>(
         process_path: &AbsPath,
-        env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>
-        + Clone,
+        env: impl IntoIterator<
+            Item = (impl AsRef<std::ffi::OsStr>, &'a Option<impl 'a + AsRef<std::ffi::OsStr>>),
+        > + Clone,
     ) -> io::Result<ProcMacroClient> {
         let process = ProcMacroServerProcess::run(process_path, env)?;
         Ok(ProcMacroClient { process: Arc::new(process), path: process_path.to_owned() })
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs
index 27bf751bde8..fcea75ef672 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/process.rs
@@ -43,10 +43,11 @@ struct ProcessSrvState {
 
 impl ProcMacroServerProcess {
     /// Starts the proc-macro server and performs a version check
-    pub(crate) fn run(
+    pub(crate) fn run<'a>(
         process_path: &AbsPath,
-        env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>
-        + Clone,
+        env: impl IntoIterator<
+            Item = (impl AsRef<std::ffi::OsStr>, &'a Option<impl 'a + AsRef<std::ffi::OsStr>>),
+        > + Clone,
     ) -> io::Result<ProcMacroServerProcess> {
         let create_srv = || {
             let mut process = Process::run(process_path, env.clone())?;
@@ -193,9 +194,11 @@ struct Process {
 
 impl Process {
     /// Runs a new proc-macro server process with the specified environment variables.
-    fn run(
+    fn run<'a>(
         path: &AbsPath,
-        env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>,
+        env: impl IntoIterator<
+            Item = (impl AsRef<std::ffi::OsStr>, &'a Option<impl 'a + AsRef<std::ffi::OsStr>>),
+        >,
     ) -> io::Result<Process> {
         let child = JodChild(mk_child(path, env)?);
         Ok(Process { child })
@@ -212,14 +215,21 @@ impl Process {
 }
 
 /// Creates and configures a new child process for the proc-macro server.
-fn mk_child(
+fn mk_child<'a>(
     path: &AbsPath,
-    env: impl IntoIterator<Item = (impl AsRef<std::ffi::OsStr>, impl AsRef<std::ffi::OsStr>)>,
+    extra_env: impl IntoIterator<
+        Item = (impl AsRef<std::ffi::OsStr>, &'a Option<impl 'a + AsRef<std::ffi::OsStr>>),
+    >,
 ) -> io::Result<Child> {
     #[allow(clippy::disallowed_methods)]
     let mut cmd = Command::new(path);
-    cmd.envs(env)
-        .env("RUST_ANALYZER_INTERNALS_DO_NOT_USE", "this is unstable")
+    for env in extra_env {
+        match env {
+            (key, Some(val)) => cmd.env(key, val),
+            (key, None) => cmd.env_remove(key),
+        };
+    }
+    cmd.env("RUST_ANALYZER_INTERNALS_DO_NOT_USE", "this is unstable")
         .stdin(Stdio::piped())
         .stdout(Stdio::piped())
         .stderr(Stdio::inherit());