From 50e2330dce8a9d7a9adfeee2c219fc00487b4dbd Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 11 Jan 2026 18:27:30 +0530 Subject: [PATCH] add suggested changes: have a internal error variant, comment on unwindsafe --- .../src/bidirectional_protocol.rs | 2 ++ .../proc-macro-srv-cli/src/main_loop.rs | 12 ++++++--- .../crates/proc-macro-srv/src/lib.rs | 25 +++++++++++++------ 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs index ffdc6fdd4dec..ba59cb219b9a 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol.rs +++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs b/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs index af8c3cb39ba2..c19847b4b53d 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/src/tools/rust-analyzer/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) -> ! { 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/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs index 0462aafd00e7..c548dc620ad1 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs +++ b/src/tools/rust-analyzer/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 }, + Internal { reason: Option }, } 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>, ) -> Result, 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::() { - return Err(ExpandError::Cancelled { reason: Some(cancel.reason.clone()) }); + if let Some(marker) = payload.downcast_ref::() { + 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) } }