Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/proc-macro-api/src/bidirectional_protocol.rs | 2 | ||||
| -rw-r--r-- | crates/proc-macro-srv-cli/src/main_loop.rs | 12 | ||||
| -rw-r--r-- | crates/proc-macro-srv/src/lib.rs | 25 |
3 files changed, 27 insertions, 12 deletions
diff --git a/crates/proc-macro-api/src/bidirectional_protocol.rs b/crates/proc-macro-api/src/bidirectional_protocol.rs index ffdc6fdd4d..ba59cb219b 100644 --- a/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/crates/proc-macro-api/src/bidirectional_protocol.rs @@ -56,6 +56,8 @@ pub fn run_conversation( return Ok(BidirectionalMessage::Response(response)); } BidirectionalMessage::SubRequest(sr) => { + // TODO: Avoid `AssertUnwindSafe` by making the callback `UnwindSafe` once `ExpandDatabase` + // becomes unwind-safe (currently blocked by `parking_lot::RwLock` in the VFS). let resp = match catch_unwind(AssertUnwindSafe(|| callback(sr))) { Ok(Ok(resp)) => BidirectionalMessage::SubResponse(resp), Ok(Err(err)) => BidirectionalMessage::SubResponse(SubResponse::Cancel { diff --git a/crates/proc-macro-srv-cli/src/main_loop.rs b/crates/proc-macro-srv-cli/src/main_loop.rs index af8c3cb39b..c19847b4b5 100644 --- a/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/crates/proc-macro-srv-cli/src/main_loop.rs @@ -11,7 +11,7 @@ use std::{ use legacy::Message; -use proc_macro_srv::{EnvSnapshot, ProcMacroCancelMarker, ProcMacroClientError, SpanId}; +use proc_macro_srv::{EnvSnapshot, ProcMacroClientError, ProcMacroPanicMarker, SpanId}; struct SpanTrans; @@ -199,13 +199,17 @@ impl<'a> ProcMacroClientHandle<'a> { fn handle_failure(failure: Result<bidirectional::SubResponse, ProcMacroClientError>) -> ! { match failure { Err(ProcMacroClientError::Cancelled { reason }) => { - panic_any(ProcMacroCancelMarker { reason }); + panic_any(ProcMacroPanicMarker::Cancelled { reason }); } Err(err) => { - panic!("proc-macro IPC failed: {err:?}"); + panic_any(ProcMacroPanicMarker::Internal { + reason: format!("proc-macro IPC error: {err:?}"), + }); } Ok(other) => { - panic!("unexpected SubResponse {other:?}"); + panic_any(ProcMacroPanicMarker::Internal { + reason: format!("unexpected SubResponse {other:?}"), + }); } } } diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs index 0462aafd00..c548dc620a 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs @@ -105,8 +105,9 @@ pub enum ProcMacroClientError { } #[derive(Debug)] -pub struct ProcMacroCancelMarker { - pub reason: String, +pub enum ProcMacroPanicMarker { + Cancelled { reason: String }, + Internal { reason: String }, } pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send); @@ -126,6 +127,7 @@ const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; pub enum ExpandError { Panic(PanicMessage), Cancelled { reason: Option<String> }, + Internal { reason: Option<String> }, } impl ExpandError { @@ -133,6 +135,7 @@ impl ExpandError { match self { ExpandError::Panic(panic_message) => panic_message.into_string(), ExpandError::Cancelled { reason } => reason, + ExpandError::Internal { reason } => reason, } } } @@ -152,10 +155,8 @@ impl ProcMacroSrv<'_> { callback: Option<ProcMacroClientHandle<'_>>, ) -> Result<token_stream::TokenStream<S>, ExpandError> { let snapped_env = self.env; - let expander = self.expander(lib.as_ref()).map_err(|err| { - ExpandError::Panic(PanicMessage { - message: Some(format!("failed to load macro: {err}")), - }) + let expander = self.expander(lib.as_ref()).map_err(|err| ExpandError::Internal { + reason: Some(format!("failed to load macro: {err}")), })?; let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref)); @@ -176,9 +177,17 @@ impl ProcMacroSrv<'_> { Ok(res) => res.map_err(ExpandError::Panic), Err(payload) => { - if let Some(cancel) = payload.downcast_ref::<ProcMacroCancelMarker>() { - return Err(ExpandError::Cancelled { reason: Some(cancel.reason.clone()) }); + if let Some(marker) = payload.downcast_ref::<ProcMacroPanicMarker>() { + return match marker { + ProcMacroPanicMarker::Cancelled { reason } => { + Err(ExpandError::Cancelled { reason: Some(reason.clone()) }) + } + ProcMacroPanicMarker::Internal { reason } => { + Err(ExpandError::Internal { reason: Some(reason.clone()) }) + } + }; } + std::panic::resume_unwind(payload) } } |