@@ -16,7 +16,9 @@ mod abis;
16
16
17
17
use std:: {
18
18
collections:: { hash_map:: Entry , HashMap } ,
19
- env, fs,
19
+ env,
20
+ ffi:: OsString ,
21
+ fs,
20
22
path:: { Path , PathBuf } ,
21
23
time:: SystemTime ,
22
24
} ;
@@ -38,9 +40,8 @@ impl ProcMacroSrv {
38
40
PanicMessage ( format ! ( "failed to load macro: {}" , err) )
39
41
} ) ?;
40
42
41
- let mut prev_env = HashMap :: new ( ) ;
43
+ let prev_env = EnvSnapshot :: new ( ) ;
42
44
for ( k, v) in & task. env {
43
- prev_env. insert ( k. as_str ( ) , env:: var_os ( k) ) ;
44
45
env:: set_var ( k, v) ;
45
46
}
46
47
let prev_working_dir = match task. current_dir {
@@ -60,12 +61,8 @@ impl ProcMacroSrv {
60
61
. expand ( & task. macro_name , & macro_body, attributes. as_ref ( ) )
61
62
. map ( |it| FlatTree :: new ( & it) ) ;
62
63
63
- for ( k, _) in & task. env {
64
- match & prev_env[ k. as_str ( ) ] {
65
- Some ( v) => env:: set_var ( k, v) ,
66
- None => env:: remove_var ( k) ,
67
- }
68
- }
64
+ prev_env. rollback ( ) ;
65
+
69
66
if let Some ( dir) = prev_working_dir {
70
67
if let Err ( err) = std:: env:: set_current_dir ( & dir) {
71
68
eprintln ! (
@@ -101,6 +98,32 @@ impl ProcMacroSrv {
101
98
}
102
99
}
103
100
101
+ struct EnvSnapshot {
102
+ vars : Vec < ( OsString , OsString ) > ,
103
+ }
104
+
105
+ impl EnvSnapshot {
106
+ fn new ( ) -> EnvSnapshot {
107
+ EnvSnapshot { vars : env:: vars_os ( ) . collect ( ) }
108
+ }
109
+
110
+ fn rollback ( self ) {
111
+ let mut old_vars = self . vars . into_iter ( ) . collect :: < HashMap < OsString , OsString > > ( ) ;
112
+ for ( name, value) in env:: vars_os ( ) {
113
+ let old_value = old_vars. remove ( & name) ;
114
+ if old_value != Some ( value) {
115
+ match old_value {
116
+ None => env:: remove_var ( name) ,
117
+ Some ( old_value) => env:: set_var ( name, old_value) ,
118
+ }
119
+ }
120
+ }
121
+ for ( name, old_value) in old_vars {
122
+ env:: set_var ( name, old_value)
123
+ }
124
+ }
125
+ }
126
+
104
127
pub mod cli;
105
128
106
129
#[ cfg( test) ]
0 commit comments