about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2022-01-30 08:05:55 +0000
committerGitHub <noreply@github.com>2022-01-30 08:05:55 +0000
commit6010431a0b19bbb0be0b3f1bf321d4aa9ce95dfb (patch)
tree6c16657612c89f5c1f901535cb38de9d12bc3f2b
parent6634eaf13a7e3a2b30f98f6e69af952f2d760df4 (diff)
parente93386f6ce989464c8de00d51cc31a72e831989f (diff)
downloadrust-6010431a0b19bbb0be0b3f1bf321d4aa9ce95dfb.tar.gz
rust-6010431a0b19bbb0be0b3f1bf321d4aa9ce95dfb.zip
Merge #11356
11356: Rollback env vars changed by a proc macro r=vlad20012 a=vlad20012

Fixes #11355

Co-authored-by: vlad20012 <beskvlad@gmail.com>
-rw-r--r--crates/proc_macro_srv/src/lib.rs41
1 files changed, 32 insertions, 9 deletions
diff --git a/crates/proc_macro_srv/src/lib.rs b/crates/proc_macro_srv/src/lib.rs
index 1698bc967d7..52693547e59 100644
--- a/crates/proc_macro_srv/src/lib.rs
+++ b/crates/proc_macro_srv/src/lib.rs
@@ -16,7 +16,9 @@ mod abis;
 
 use std::{
     collections::{hash_map::Entry, HashMap},
-    env, fs,
+    env,
+    ffi::OsString,
+    fs,
     path::{Path, PathBuf},
     time::SystemTime,
 };
@@ -38,9 +40,8 @@ impl ProcMacroSrv {
             PanicMessage(format!("failed to load macro: {}", err))
         })?;
 
-        let mut prev_env = HashMap::new();
+        let prev_env = EnvSnapshot::new();
         for (k, v) in &task.env {
-            prev_env.insert(k.as_str(), env::var_os(k));
             env::set_var(k, v);
         }
         let prev_working_dir = match task.current_dir {
@@ -60,12 +61,8 @@ impl ProcMacroSrv {
             .expand(&task.macro_name, &macro_body, attributes.as_ref())
             .map(|it| FlatTree::new(&it));
 
-        for (k, _) in &task.env {
-            match &prev_env[k.as_str()] {
-                Some(v) => env::set_var(k, v),
-                None => env::remove_var(k),
-            }
-        }
+        prev_env.rollback();
+
         if let Some(dir) = prev_working_dir {
             if let Err(err) = std::env::set_current_dir(&dir) {
                 eprintln!(
@@ -101,6 +98,32 @@ impl ProcMacroSrv {
     }
 }
 
+struct EnvSnapshot {
+    vars: HashMap<OsString, OsString>,
+}
+
+impl EnvSnapshot {
+    fn new() -> EnvSnapshot {
+        EnvSnapshot { vars: env::vars_os().collect() }
+    }
+
+    fn rollback(self) {
+        let mut old_vars = self.vars;
+        for (name, value) in env::vars_os() {
+            let old_value = old_vars.remove(&name);
+            if old_value != Some(value) {
+                match old_value {
+                    None => env::remove_var(name),
+                    Some(old_value) => env::set_var(name, old_value),
+                }
+            }
+        }
+        for (name, old_value) in old_vars {
+            env::set_var(name, old_value)
+        }
+    }
+}
+
 pub mod cli;
 
 #[cfg(test)]