diff options
Diffstat (limited to 'crates/proc_macro_srv')
-rw-r--r-- | crates/proc_macro_srv/src/dylib.rs | 3 | ||||
-rw-r--r-- | crates/proc_macro_srv/src/lib.rs | 20 | ||||
-rw-r--r-- | crates/proc_macro_srv/src/proc_macro/bridge/client.rs | 12 | ||||
-rw-r--r-- | crates/proc_macro_srv/src/proc_macro/bridge/mod.rs | 3 | ||||
-rw-r--r-- | crates/proc_macro_srv/src/proc_macro/bridge/server.rs | 34 |
5 files changed, 62 insertions, 10 deletions
diff --git a/crates/proc_macro_srv/src/dylib.rs b/crates/proc_macro_srv/src/dylib.rs index 2afb973cc..4e719f3aa 100644 --- a/crates/proc_macro_srv/src/dylib.rs +++ b/crates/proc_macro_srv/src/dylib.rs | |||
@@ -136,6 +136,7 @@ impl Expander { | |||
136 | &crate::proc_macro::bridge::server::SameThread, | 136 | &crate::proc_macro::bridge::server::SameThread, |
137 | crate::rustc_server::Rustc::default(), | 137 | crate::rustc_server::Rustc::default(), |
138 | parsed_body, | 138 | parsed_body, |
139 | false, | ||
139 | ); | 140 | ); |
140 | return res.map(|it| it.subtree); | 141 | return res.map(|it| it.subtree); |
141 | } | 142 | } |
@@ -144,6 +145,7 @@ impl Expander { | |||
144 | &crate::proc_macro::bridge::server::SameThread, | 145 | &crate::proc_macro::bridge::server::SameThread, |
145 | crate::rustc_server::Rustc::default(), | 146 | crate::rustc_server::Rustc::default(), |
146 | parsed_body, | 147 | parsed_body, |
148 | false, | ||
147 | ); | 149 | ); |
148 | return res.map(|it| it.subtree); | 150 | return res.map(|it| it.subtree); |
149 | } | 151 | } |
@@ -153,6 +155,7 @@ impl Expander { | |||
153 | crate::rustc_server::Rustc::default(), | 155 | crate::rustc_server::Rustc::default(), |
154 | parsed_attributes, | 156 | parsed_attributes, |
155 | parsed_body, | 157 | parsed_body, |
158 | false, | ||
156 | ); | 159 | ); |
157 | return res.map(|it| it.subtree); | 160 | return res.map(|it| it.subtree); |
158 | } | 161 | } |
diff --git a/crates/proc_macro_srv/src/lib.rs b/crates/proc_macro_srv/src/lib.rs index 9cca96994..d4f04ee06 100644 --- a/crates/proc_macro_srv/src/lib.rs +++ b/crates/proc_macro_srv/src/lib.rs | |||
@@ -24,7 +24,7 @@ use proc_macro::bridge::client::TokenStream; | |||
24 | use proc_macro_api::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; | 24 | use proc_macro_api::{ExpansionResult, ExpansionTask, ListMacrosResult, ListMacrosTask}; |
25 | use std::{ | 25 | use std::{ |
26 | collections::{hash_map::Entry, HashMap}, | 26 | collections::{hash_map::Entry, HashMap}, |
27 | fs, | 27 | env, fs, |
28 | path::{Path, PathBuf}, | 28 | path::{Path, PathBuf}, |
29 | time::SystemTime, | 29 | time::SystemTime, |
30 | }; | 30 | }; |
@@ -37,7 +37,23 @@ pub(crate) struct ProcMacroSrv { | |||
37 | impl ProcMacroSrv { | 37 | impl ProcMacroSrv { |
38 | pub fn expand(&mut self, task: &ExpansionTask) -> Result<ExpansionResult, String> { | 38 | pub fn expand(&mut self, task: &ExpansionTask) -> Result<ExpansionResult, String> { |
39 | let expander = self.expander(&task.lib)?; | 39 | let expander = self.expander(&task.lib)?; |
40 | match expander.expand(&task.macro_name, &task.macro_body, task.attributes.as_ref()) { | 40 | |
41 | let mut prev_env = HashMap::new(); | ||
42 | for (k, v) in &task.env { | ||
43 | prev_env.insert(k.as_str(), env::var_os(k)); | ||
44 | env::set_var(k, v); | ||
45 | } | ||
46 | |||
47 | let result = expander.expand(&task.macro_name, &task.macro_body, task.attributes.as_ref()); | ||
48 | |||
49 | for (k, _) in &task.env { | ||
50 | match &prev_env[k.as_str()] { | ||
51 | Some(v) => env::set_var(k, v), | ||
52 | None => env::remove_var(k), | ||
53 | } | ||
54 | } | ||
55 | |||
56 | match result { | ||
41 | Ok(expansion) => Ok(ExpansionResult { expansion }), | 57 | Ok(expansion) => Ok(ExpansionResult { expansion }), |
42 | Err(msg) => { | 58 | Err(msg) => { |
43 | let msg = msg.as_str().unwrap_or("<unknown error>"); | 59 | let msg = msg.as_str().unwrap_or("<unknown error>"); |
diff --git a/crates/proc_macro_srv/src/proc_macro/bridge/client.rs b/crates/proc_macro_srv/src/proc_macro/bridge/client.rs index 55d6330cc..ca6749b9b 100644 --- a/crates/proc_macro_srv/src/proc_macro/bridge/client.rs +++ b/crates/proc_macro_srv/src/proc_macro/bridge/client.rs | |||
@@ -303,17 +303,21 @@ impl BridgeState<'_> { | |||
303 | 303 | ||
304 | impl Bridge<'_> { | 304 | impl Bridge<'_> { |
305 | fn enter<R>(self, f: impl FnOnce() -> R) -> R { | 305 | fn enter<R>(self, f: impl FnOnce() -> R) -> R { |
306 | let force_show_panics = self.force_show_panics; | ||
307 | |||
306 | // Hide the default panic output within `proc_macro` expansions. | 308 | // Hide the default panic output within `proc_macro` expansions. |
307 | // NB. the server can't do this because it may use a different libstd. | 309 | // NB. the server can't do this because it may use a different libstd. |
308 | static HIDE_PANICS_DURING_EXPANSION: Once = Once::new(); | 310 | static HIDE_PANICS_DURING_EXPANSION: Once = Once::new(); |
309 | HIDE_PANICS_DURING_EXPANSION.call_once(|| { | 311 | HIDE_PANICS_DURING_EXPANSION.call_once(|| { |
310 | let prev = panic::take_hook(); | 312 | let prev = panic::take_hook(); |
311 | panic::set_hook(Box::new(move |info| { | 313 | panic::set_hook(Box::new(move |info| { |
312 | let hide = BridgeState::with(|state| match state { | 314 | let show = BridgeState::with(|state| match state { |
313 | BridgeState::NotConnected => false, | 315 | BridgeState::NotConnected => true, |
314 | BridgeState::Connected(_) | BridgeState::InUse => true, | 316 | // Something weird is going on, so don't suppress any backtraces |
317 | BridgeState::InUse => true, | ||
318 | BridgeState::Connected(bridge) => force_show_panics, | ||
315 | }); | 319 | }); |
316 | if !hide { | 320 | if show { |
317 | prev(info) | 321 | prev(info) |
318 | } | 322 | } |
319 | })); | 323 | })); |
diff --git a/crates/proc_macro_srv/src/proc_macro/bridge/mod.rs b/crates/proc_macro_srv/src/proc_macro/bridge/mod.rs index b97886eb9..e4006a5ab 100644 --- a/crates/proc_macro_srv/src/proc_macro/bridge/mod.rs +++ b/crates/proc_macro_srv/src/proc_macro/bridge/mod.rs | |||
@@ -225,6 +225,9 @@ pub struct Bridge<'a> { | |||
225 | 225 | ||
226 | /// Server-side function that the client uses to make requests. | 226 | /// Server-side function that the client uses to make requests. |
227 | dispatch: closure::Closure<'a, Buffer<u8>, Buffer<u8>>, | 227 | dispatch: closure::Closure<'a, Buffer<u8>, Buffer<u8>>, |
228 | |||
229 | /// If 'true', always invoke the default panic hook | ||
230 | force_show_panics: bool, | ||
228 | } | 231 | } |
229 | 232 | ||
230 | // impl<'a> !Sync for Bridge<'a> {} | 233 | // impl<'a> !Sync for Bridge<'a> {} |
diff --git a/crates/proc_macro_srv/src/proc_macro/bridge/server.rs b/crates/proc_macro_srv/src/proc_macro/bridge/server.rs index 3acb239af..88fbdc078 100644 --- a/crates/proc_macro_srv/src/proc_macro/bridge/server.rs +++ b/crates/proc_macro_srv/src/proc_macro/bridge/server.rs | |||
@@ -138,6 +138,7 @@ pub trait ExecutionStrategy { | |||
138 | input: Buffer<u8>, | 138 | input: Buffer<u8>, |
139 | run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, | 139 | run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, |
140 | client_data: D, | 140 | client_data: D, |
141 | force_show_panics: bool, | ||
141 | ) -> Buffer<u8>; | 142 | ) -> Buffer<u8>; |
142 | } | 143 | } |
143 | 144 | ||
@@ -150,10 +151,14 @@ impl ExecutionStrategy for SameThread { | |||
150 | input: Buffer<u8>, | 151 | input: Buffer<u8>, |
151 | run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, | 152 | run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, |
152 | client_data: D, | 153 | client_data: D, |
154 | force_show_panics: bool, | ||
153 | ) -> Buffer<u8> { | 155 | ) -> Buffer<u8> { |
154 | let mut dispatch = |b| dispatcher.dispatch(b); | 156 | let mut dispatch = |b| dispatcher.dispatch(b); |
155 | 157 | ||
156 | run_client(Bridge { cached_buffer: input, dispatch: (&mut dispatch).into() }, client_data) | 158 | run_client( |
159 | Bridge { cached_buffer: input, dispatch: (&mut dispatch).into(), force_show_panics }, | ||
160 | client_data, | ||
161 | ) | ||
157 | } | 162 | } |
158 | } | 163 | } |
159 | 164 | ||
@@ -169,6 +174,7 @@ impl ExecutionStrategy for CrossThread1 { | |||
169 | input: Buffer<u8>, | 174 | input: Buffer<u8>, |
170 | run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, | 175 | run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, |
171 | client_data: D, | 176 | client_data: D, |
177 | force_show_panics: bool, | ||
172 | ) -> Buffer<u8> { | 178 | ) -> Buffer<u8> { |
173 | use std::sync::mpsc::channel; | 179 | use std::sync::mpsc::channel; |
174 | 180 | ||
@@ -182,7 +188,11 @@ impl ExecutionStrategy for CrossThread1 { | |||
182 | }; | 188 | }; |
183 | 189 | ||
184 | run_client( | 190 | run_client( |
185 | Bridge { cached_buffer: input, dispatch: (&mut dispatch).into() }, | 191 | Bridge { |
192 | cached_buffer: input, | ||
193 | dispatch: (&mut dispatch).into(), | ||
194 | force_show_panics, | ||
195 | }, | ||
186 | client_data, | 196 | client_data, |
187 | ) | 197 | ) |
188 | }); | 198 | }); |
@@ -204,6 +214,7 @@ impl ExecutionStrategy for CrossThread2 { | |||
204 | input: Buffer<u8>, | 214 | input: Buffer<u8>, |
205 | run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, | 215 | run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, |
206 | client_data: D, | 216 | client_data: D, |
217 | force_show_panics: bool, | ||
207 | ) -> Buffer<u8> { | 218 | ) -> Buffer<u8> { |
208 | use std::sync::{Arc, Mutex}; | 219 | use std::sync::{Arc, Mutex}; |
209 | 220 | ||
@@ -229,7 +240,11 @@ impl ExecutionStrategy for CrossThread2 { | |||
229 | }; | 240 | }; |
230 | 241 | ||
231 | let r = run_client( | 242 | let r = run_client( |
232 | Bridge { cached_buffer: input, dispatch: (&mut dispatch).into() }, | 243 | Bridge { |
244 | cached_buffer: input, | ||
245 | dispatch: (&mut dispatch).into(), | ||
246 | force_show_panics, | ||
247 | }, | ||
233 | client_data, | 248 | client_data, |
234 | ); | 249 | ); |
235 | 250 | ||
@@ -268,6 +283,7 @@ fn run_server< | |||
268 | input: I, | 283 | input: I, |
269 | run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, | 284 | run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>, |
270 | client_data: D, | 285 | client_data: D, |
286 | force_show_panics: bool, | ||
271 | ) -> Result<O, PanicMessage> { | 287 | ) -> Result<O, PanicMessage> { |
272 | let mut dispatcher = | 288 | let mut dispatcher = |
273 | Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) }; | 289 | Dispatcher { handle_store: HandleStore::new(handle_counters), server: MarkedTypes(server) }; |
@@ -275,7 +291,13 @@ fn run_server< | |||
275 | let mut b = Buffer::new(); | 291 | let mut b = Buffer::new(); |
276 | input.encode(&mut b, &mut dispatcher.handle_store); | 292 | input.encode(&mut b, &mut dispatcher.handle_store); |
277 | 293 | ||
278 | b = strategy.run_bridge_and_client(&mut dispatcher, b, run_client, client_data); | 294 | b = strategy.run_bridge_and_client( |
295 | &mut dispatcher, | ||
296 | b, | ||
297 | run_client, | ||
298 | client_data, | ||
299 | force_show_panics, | ||
300 | ); | ||
279 | 301 | ||
280 | Result::decode(&mut &b[..], &mut dispatcher.handle_store) | 302 | Result::decode(&mut &b[..], &mut dispatcher.handle_store) |
281 | } | 303 | } |
@@ -286,6 +308,7 @@ impl client::Client<fn(crate::TokenStream) -> crate::TokenStream> { | |||
286 | strategy: &impl ExecutionStrategy, | 308 | strategy: &impl ExecutionStrategy, |
287 | server: S, | 309 | server: S, |
288 | input: S::TokenStream, | 310 | input: S::TokenStream, |
311 | force_show_panics: bool, | ||
289 | ) -> Result<S::TokenStream, PanicMessage> { | 312 | ) -> Result<S::TokenStream, PanicMessage> { |
290 | let client::Client { get_handle_counters, run, f } = *self; | 313 | let client::Client { get_handle_counters, run, f } = *self; |
291 | run_server( | 314 | run_server( |
@@ -295,6 +318,7 @@ impl client::Client<fn(crate::TokenStream) -> crate::TokenStream> { | |||
295 | <MarkedTypes<S> as Types>::TokenStream::mark(input), | 318 | <MarkedTypes<S> as Types>::TokenStream::mark(input), |
296 | run, | 319 | run, |
297 | f, | 320 | f, |
321 | force_show_panics, | ||
298 | ) | 322 | ) |
299 | .map(<MarkedTypes<S> as Types>::TokenStream::unmark) | 323 | .map(<MarkedTypes<S> as Types>::TokenStream::unmark) |
300 | } | 324 | } |
@@ -307,6 +331,7 @@ impl client::Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenSt | |||
307 | server: S, | 331 | server: S, |
308 | input: S::TokenStream, | 332 | input: S::TokenStream, |
309 | input2: S::TokenStream, | 333 | input2: S::TokenStream, |
334 | force_show_panics: bool, | ||
310 | ) -> Result<S::TokenStream, PanicMessage> { | 335 | ) -> Result<S::TokenStream, PanicMessage> { |
311 | let client::Client { get_handle_counters, run, f } = *self; | 336 | let client::Client { get_handle_counters, run, f } = *self; |
312 | run_server( | 337 | run_server( |
@@ -319,6 +344,7 @@ impl client::Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenSt | |||
319 | ), | 344 | ), |
320 | run, | 345 | run, |
321 | f, | 346 | f, |
347 | force_show_panics, | ||
322 | ) | 348 | ) |
323 | .map(<MarkedTypes<S> as Types>::TokenStream::unmark) | 349 | .map(<MarkedTypes<S> as Types>::TokenStream::unmark) |
324 | } | 350 | } |