From 5c8d7dbe8ee508b35c033d25b115f164c7c72307 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Tue, 6 Jan 2026 09:32:02 +0530 Subject: [PATCH 01/11] add cancel variant to SubResponse --- .../crates/proc-macro-api/src/bidirectional_protocol/msg.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs index 1df0c68379a5..3f0422dc5bc8 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-api/src/bidirectional_protocol/msg.rs @@ -42,6 +42,9 @@ pub enum SubResponse { ByteRangeResult { range: Range, }, + Cancel { + reason: String, + }, } #[derive(Debug, Serialize, Deserialize)] From fb2cb46ea873f90c5a0a237772d4a42a2b7e4188 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Tue, 6 Jan 2026 09:32:43 +0530 Subject: [PATCH 02/11] catch unwind on client side, and accordingly send Cancel subResponse to server --- .../proc-macro-api/src/bidirectional_protocol.rs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 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 8311df23d718..ffdc6fdd4dec 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 @@ -2,6 +2,7 @@ use std::{ io::{self, BufRead, Write}, + panic::{AssertUnwindSafe, catch_unwind}, sync::Arc, }; @@ -55,9 +56,17 @@ pub fn run_conversation( return Ok(BidirectionalMessage::Response(response)); } BidirectionalMessage::SubRequest(sr) => { - let resp = callback(sr)?; - let reply = BidirectionalMessage::SubResponse(resp); - let encoded = postcard::encode(&reply).map_err(wrap_encode)?; + let resp = match catch_unwind(AssertUnwindSafe(|| callback(sr))) { + Ok(Ok(resp)) => BidirectionalMessage::SubResponse(resp), + Ok(Err(err)) => BidirectionalMessage::SubResponse(SubResponse::Cancel { + reason: err.to_string(), + }), + Err(_) => BidirectionalMessage::SubResponse(SubResponse::Cancel { + reason: "callback panicked or was cancelled".into(), + }), + }; + + let encoded = postcard::encode(&resp).map_err(wrap_encode)?; postcard::write(writer, &encoded) .map_err(wrap_io("failed to write sub-response"))?; } From d2ac252cf258f7d2d1962e31382e17363c8ff7ee Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Tue, 6 Jan 2026 09:33:07 +0530 Subject: [PATCH 03/11] add proc-macro-client error variant --- src/tools/rust-analyzer/crates/proc-macro-srv/src/lib.rs | 8 ++++++++ 1 file changed, 8 insertions(+) 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 e04f744ae2b0..a6090253d3af 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 @@ -96,6 +96,14 @@ impl<'env> ProcMacroSrv<'env> { } } +#[derive(Debug)] +pub enum ProcMacroClientError { + Cancelled { reason: String }, + Io(std::io::Error), + Protocol(String), + Eof, +} + pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send); pub trait ProcMacroClientInterface { From 26bc8cbc7797d8a988c5b096b14f121dac22035a Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Tue, 6 Jan 2026 09:43:19 +0530 Subject: [PATCH 04/11] make sure we panic in callback so the srv panics and stops --- .../proc-macro-srv-cli/src/main_loop.rs | 84 +++++++++++++------ 1 file changed, 60 insertions(+), 24 deletions(-) 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 758629fd1fd6..869c5f93927c 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 @@ -10,7 +10,7 @@ use std::{ use legacy::Message; -use proc_macro_srv::{EnvSnapshot, SpanId}; +use proc_macro_srv::{EnvSnapshot, ProcMacroClientError, SpanId}; struct SpanTrans; @@ -172,16 +172,26 @@ impl<'a> ProcMacroClientHandle<'a> { fn roundtrip( &mut self, req: bidirectional::SubRequest, - ) -> Option { + ) -> Result { let msg = bidirectional::BidirectionalMessage::SubRequest(req); - if msg.write(&mut *self.stdout).is_err() { - return None; - } + msg.write(&mut *self.stdout).map_err(ProcMacroClientError::Io)?; - match bidirectional::BidirectionalMessage::read(&mut *self.stdin, self.buf) { - Ok(Some(msg)) => Some(msg), - _ => None, + let msg = + bidirectional::BidirectionalMessage::read(&mut *self.stdin, self.buf) + .map_err(ProcMacroClientError::Io)? + .ok_or(ProcMacroClientError::Eof)?; + + match msg { + bidirectional::BidirectionalMessage::SubResponse(resp) => match resp { + bidirectional::SubResponse::Cancel { reason } => { + Err(ProcMacroClientError::Cancelled { reason }) + } + other => Ok(other), + }, + other => { + Err(ProcMacroClientError::Protocol(format!("expected SubResponse, got {other:?}"))) + } } } } @@ -189,10 +199,16 @@ impl<'a> ProcMacroClientHandle<'a> { impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { fn file(&mut self, file_id: proc_macro_srv::span::FileId) -> String { match self.roundtrip(bidirectional::SubRequest::FilePath { file_id: file_id.index() }) { - Some(bidirectional::BidirectionalMessage::SubResponse( - bidirectional::SubResponse::FilePathResult { name }, - )) => name, - _ => String::new(), + Ok(bidirectional::SubResponse::FilePathResult { name }) => name, + Err(ProcMacroClientError::Cancelled { reason }) => { + panic!("proc-macro expansion cancelled by client: {reason}"); + } + Err(err) => { + panic!("proc-macro IPC failed: {err:?}"); + } + Ok(other) => { + panic!("unexpected SubResponse in file(): {other:?}"); + } } } @@ -206,20 +222,32 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { start: range.start().into(), end: range.end().into(), }) { - Some(bidirectional::BidirectionalMessage::SubResponse( - bidirectional::SubResponse::SourceTextResult { text }, - )) => text, - _ => None, + Ok(bidirectional::SubResponse::SourceTextResult { text }) => text, + Err(ProcMacroClientError::Cancelled { reason }) => { + panic!("proc-macro expansion cancelled by client: {reason}"); + } + Err(err) => { + panic!("proc-macro IPC failed: {err:?}"); + } + Ok(other) => { + panic!("unexpected SubResponse in source_text: {other:?}"); + } } } fn local_file(&mut self, file_id: proc_macro_srv::span::FileId) -> Option { match self.roundtrip(bidirectional::SubRequest::LocalFilePath { file_id: file_id.index() }) { - Some(bidirectional::BidirectionalMessage::SubResponse( - bidirectional::SubResponse::LocalFilePathResult { name }, - )) => name, - _ => None, + Ok(bidirectional::SubResponse::LocalFilePathResult { name }) => name, + Err(ProcMacroClientError::Cancelled { reason }) => { + panic!("proc-macro expansion cancelled by client: {reason}"); + } + Err(err) => { + panic!("proc-macro IPC failed: {err:?}"); + } + Ok(other) => { + panic!("unexpected SubResponse in local_file(): {other:?}"); + } } } @@ -230,10 +258,18 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { ast_id: anchor.ast_id.into_raw(), offset: range.start().into(), }) { - Some(bidirectional::BidirectionalMessage::SubResponse( - bidirectional::SubResponse::LineColumnResult { line, column }, - )) => Some((line, column)), - _ => None, + Ok(bidirectional::SubResponse::LineColumnResult { line, column }) => { + Some((line, column)) + } + Err(ProcMacroClientError::Cancelled { reason }) => { + panic!("proc-macro expansion cancelled by client: {reason}"); + } + Err(err) => { + panic!("proc-macro IPC failed: {err:?}"); + } + Ok(other) => { + panic!("unexpected SubResponse in local_file(): {other:?}"); + } } } From 489245903e30492055a479b7e36b8efa505207e6 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Tue, 6 Jan 2026 21:12:39 +0530 Subject: [PATCH 05/11] don't kill server on cancellation --- .../crates/proc-macro-srv-cli/src/main_loop.rs | 11 ++++++----- .../rust-analyzer/crates/proc-macro-srv/src/lib.rs | 13 ++++++++++++- 2 files changed, 18 insertions(+), 6 deletions(-) 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 869c5f93927c..cae6d31f1a29 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 @@ -7,10 +7,11 @@ use std::{ io::{self, BufRead, Write}, ops::Range, }; +use std::panic::panic_any; use legacy::Message; -use proc_macro_srv::{EnvSnapshot, ProcMacroClientError, SpanId}; +use proc_macro_srv::{EnvSnapshot, ProcMacroCancelMarker, ProcMacroClientError, SpanId}; struct SpanTrans; @@ -201,7 +202,7 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { match self.roundtrip(bidirectional::SubRequest::FilePath { file_id: file_id.index() }) { Ok(bidirectional::SubResponse::FilePathResult { name }) => name, Err(ProcMacroClientError::Cancelled { reason }) => { - panic!("proc-macro expansion cancelled by client: {reason}"); + panic_any(ProcMacroCancelMarker { reason }); } Err(err) => { panic!("proc-macro IPC failed: {err:?}"); @@ -224,7 +225,7 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { }) { Ok(bidirectional::SubResponse::SourceTextResult { text }) => text, Err(ProcMacroClientError::Cancelled { reason }) => { - panic!("proc-macro expansion cancelled by client: {reason}"); + panic_any(ProcMacroCancelMarker { reason }); } Err(err) => { panic!("proc-macro IPC failed: {err:?}"); @@ -240,7 +241,7 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { { Ok(bidirectional::SubResponse::LocalFilePathResult { name }) => name, Err(ProcMacroClientError::Cancelled { reason }) => { - panic!("proc-macro expansion cancelled by client: {reason}"); + panic_any(ProcMacroCancelMarker { reason }); } Err(err) => { panic!("proc-macro IPC failed: {err:?}"); @@ -262,7 +263,7 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { Some((line, column)) } Err(ProcMacroClientError::Cancelled { reason }) => { - panic!("proc-macro expansion cancelled by client: {reason}"); + panic_any(ProcMacroCancelMarker { reason }); } Err(err) => { panic!("proc-macro IPC failed: {err:?}"); 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 a6090253d3af..99dfa24ca412 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 @@ -104,6 +104,11 @@ pub enum ProcMacroClientError { Eof, } +#[derive(Debug)] +pub struct ProcMacroCancelMarker { + pub reason: String, +} + pub type ProcMacroClientHandle<'a> = &'a mut (dyn ProcMacroClientInterface + Sync + Send); pub trait ProcMacroClientInterface { @@ -153,7 +158,13 @@ impl ProcMacroSrv<'_> { }); match thread.unwrap().join() { Ok(res) => res, - Err(e) => std::panic::resume_unwind(e), + + Err(payload) => { + if let Some(cancel) = payload.downcast_ref::() { + return Err(PanicMessage { message: Some(cancel.reason.clone()) }); + } + std::panic::resume_unwind(payload) + } } }); prev_env.rollback(); From 8d2811a7c312135c832432af94953c16cdf97f4c Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 10 Jan 2026 03:03:36 +0530 Subject: [PATCH 06/11] remove repititive error block in callbacks --- .../proc-macro-srv-cli/src/main_loop.rs | 56 +++++++------------ 1 file changed, 19 insertions(+), 37 deletions(-) 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 cae6d31f1a29..534697c68684 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 @@ -197,19 +197,25 @@ impl<'a> ProcMacroClientHandle<'a> { } } -impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { +fn handle_failure(failure: Result) -> ! { + match failure { + Err(ProcMacroClientError::Cancelled { reason }) => { + panic_any(ProcMacroCancelMarker { reason }); + } + Err(err) => { + panic!("proc-macro IPC failed: {err:?}"); + } + Ok(other) => { + panic!("unexpected SubResponse {other:?}"); + } + } +} + +impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> { fn file(&mut self, file_id: proc_macro_srv::span::FileId) -> String { match self.roundtrip(bidirectional::SubRequest::FilePath { file_id: file_id.index() }) { Ok(bidirectional::SubResponse::FilePathResult { name }) => name, - Err(ProcMacroClientError::Cancelled { reason }) => { - panic_any(ProcMacroCancelMarker { reason }); - } - Err(err) => { - panic!("proc-macro IPC failed: {err:?}"); - } - Ok(other) => { - panic!("unexpected SubResponse in file(): {other:?}"); - } + other => handle_failure(other), } } @@ -224,15 +230,7 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { end: range.end().into(), }) { Ok(bidirectional::SubResponse::SourceTextResult { text }) => text, - Err(ProcMacroClientError::Cancelled { reason }) => { - panic_any(ProcMacroCancelMarker { reason }); - } - Err(err) => { - panic!("proc-macro IPC failed: {err:?}"); - } - Ok(other) => { - panic!("unexpected SubResponse in source_text: {other:?}"); - } + other => handle_failure(other), } } @@ -240,15 +238,7 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { match self.roundtrip(bidirectional::SubRequest::LocalFilePath { file_id: file_id.index() }) { Ok(bidirectional::SubResponse::LocalFilePathResult { name }) => name, - Err(ProcMacroClientError::Cancelled { reason }) => { - panic_any(ProcMacroCancelMarker { reason }); - } - Err(err) => { - panic!("proc-macro IPC failed: {err:?}"); - } - Ok(other) => { - panic!("unexpected SubResponse in local_file(): {other:?}"); - } + other => handle_failure(other), } } @@ -262,15 +252,7 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { Ok(bidirectional::SubResponse::LineColumnResult { line, column }) => { Some((line, column)) } - Err(ProcMacroClientError::Cancelled { reason }) => { - panic_any(ProcMacroCancelMarker { reason }); - } - Err(err) => { - panic!("proc-macro IPC failed: {err:?}"); - } - Ok(other) => { - panic!("unexpected SubResponse in local_file(): {other:?}"); - } + other => handle_failure(other), } } From 724606d3491faff9a4edb1b88ec7c3b1b4af923e Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 10 Jan 2026 03:04:02 +0530 Subject: [PATCH 07/11] add error variant for cancelled expansion --- .../proc-macro-srv-cli/src/main_loop.rs | 9 +++---- .../crates/proc-macro-srv/src/lib.rs | 26 +++++++++++++++---- 2 files changed, 25 insertions(+), 10 deletions(-) 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 534697c68684..bb94d33ac102 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 @@ -3,11 +3,11 @@ use proc_macro_api::{ ProtocolFormat, bidirectional_protocol::msg as bidirectional, legacy_protocol::msg as legacy, version::CURRENT_API_VERSION, }; +use std::panic::panic_any; use std::{ io::{self, BufRead, Write}, ops::Range, }; -use std::panic::panic_any; use legacy::Message; @@ -178,10 +178,9 @@ impl<'a> ProcMacroClientHandle<'a> { msg.write(&mut *self.stdout).map_err(ProcMacroClientError::Io)?; - let msg = - bidirectional::BidirectionalMessage::read(&mut *self.stdin, self.buf) - .map_err(ProcMacroClientError::Io)? - .ok_or(ProcMacroClientError::Eof)?; + let msg = bidirectional::BidirectionalMessage::read(&mut *self.stdin, self.buf) + .map_err(ProcMacroClientError::Io)? + .ok_or(ProcMacroClientError::Eof)?; match msg { bidirectional::BidirectionalMessage::SubResponse(resp) => match resp { 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 99dfa24ca412..0462aafd00e7 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 @@ -123,6 +123,20 @@ pub trait ProcMacroClientInterface { const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; +pub enum ExpandError { + Panic(PanicMessage), + Cancelled { reason: Option }, +} + +impl ExpandError { + pub fn into_string(self) -> Option { + match self { + ExpandError::Panic(panic_message) => panic_message.into_string(), + ExpandError::Cancelled { reason } => reason, + } + } +} + impl ProcMacroSrv<'_> { pub fn expand( &self, @@ -136,10 +150,12 @@ impl ProcMacroSrv<'_> { call_site: S, mixed_site: S, callback: Option>, - ) -> Result, PanicMessage> { + ) -> Result, ExpandError> { let snapped_env = self.env; - let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage { - message: Some(format!("failed to load macro: {err}")), + let expander = self.expander(lib.as_ref()).map_err(|err| { + ExpandError::Panic(PanicMessage { + message: Some(format!("failed to load macro: {err}")), + }) })?; let prev_env = EnvChange::apply(snapped_env, env, current_dir.as_ref().map(<_>::as_ref)); @@ -157,11 +173,11 @@ impl ProcMacroSrv<'_> { ) }); match thread.unwrap().join() { - Ok(res) => res, + Ok(res) => res.map_err(ExpandError::Panic), Err(payload) => { if let Some(cancel) = payload.downcast_ref::() { - return Err(PanicMessage { message: Some(cancel.reason.clone()) }); + return Err(ExpandError::Cancelled { reason: Some(cancel.reason.clone()) }); } std::panic::resume_unwind(payload) } From a37aa50bca6a7f424907e9f3f638a15935963ef8 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 11 Jan 2026 16:49:22 +0530 Subject: [PATCH 08/11] adapt ByteRange to new roundtrip --- .../crates/proc-macro-srv-cli/src/main_loop.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) 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 bb94d33ac102..af8c3cb39ba2 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 @@ -265,10 +265,8 @@ impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandl start: range.start().into(), end: range.end().into(), }) { - Some(bidirectional::BidirectionalMessage::SubResponse( - bidirectional::SubResponse::ByteRangeResult { range }, - )) => range, - _ => Range { start: range.start().into(), end: range.end().into() }, + Ok(bidirectional::SubResponse::ByteRangeResult { range }) => range, + other => handle_failure(other), } } } From 50e2330dce8a9d7a9adfeee2c219fc00487b4dbd Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 11 Jan 2026 18:27:30 +0530 Subject: [PATCH 09/11] 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) } } From 98380734814667ba50ad748d8130a77b06ebaa3f Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 18 Jan 2026 21:10:32 +0530 Subject: [PATCH 10/11] replace panic_any with resume_unwind on Client panic cancelled message --- .../rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 c19847b4b53d..1e956f91e6b9 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 @@ -3,7 +3,7 @@ use proc_macro_api::{ ProtocolFormat, bidirectional_protocol::msg as bidirectional, legacy_protocol::msg as legacy, version::CURRENT_API_VERSION, }; -use std::panic::panic_any; +use std::panic::{panic_any, resume_unwind}; use std::{ io::{self, BufRead, Write}, ops::Range, @@ -199,7 +199,7 @@ impl<'a> ProcMacroClientHandle<'a> { fn handle_failure(failure: Result) -> ! { match failure { Err(ProcMacroClientError::Cancelled { reason }) => { - panic_any(ProcMacroPanicMarker::Cancelled { reason }); + resume_unwind(Box::new(ProcMacroPanicMarker::Cancelled { reason })); } Err(err) => { panic_any(ProcMacroPanicMarker::Internal { From fcb55722d4ef6623f36a9787c7724bd364adb413 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sun, 1 Feb 2026 15:19:03 +0530 Subject: [PATCH 11/11] correct handler generic input --- .../rust-analyzer/crates/proc-macro-srv-cli/src/main_loop.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 1e956f91e6b9..9be3199a3836 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 @@ -214,7 +214,7 @@ fn handle_failure(failure: Result proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_, C> { +impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle<'_> { fn file(&mut self, file_id: proc_macro_srv::span::FileId) -> String { match self.roundtrip(bidirectional::SubRequest::FilePath { file_id: file_id.index() }) { Ok(bidirectional::SubResponse::FilePathResult { name }) => name,