From af0e2988182e3b7cdba19ace0b968ac5916ee7d9 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 26 Dec 2025 23:03:42 +0530 Subject: [PATCH 1/7] add bidirectionalHandler trait --- crates/proc-macro-srv/src/lib.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs index 705ac930ed..c35bb2ba8d 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs @@ -93,12 +93,8 @@ impl<'env> ProcMacroSrv<'env> { pub type SubCallback = Box SubResponse + Send + Sync + 'static>; -pub enum SubRequest { - SourceText { file_id: EditionedFileId, start: u32, end: u32 }, -} - -pub enum SubResponse { - SourceTextResult { text: Option }, +pub trait BidirectionalHandler { + fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; From 3441c230e3b0de7da00f87b476b11dd77cb51cd4 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 26 Dec 2025 23:04:04 +0530 Subject: [PATCH 2/7] remove old subreq/resp constructs --- crates/proc-macro-srv/src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs index c35bb2ba8d..5f0273d7bc 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs @@ -47,7 +47,7 @@ use std::{ }; use paths::{Utf8Path, Utf8PathBuf}; -use span::{EditionedFileId, Span}; +use span::Span; use temp_dir::TempDir; pub use crate::server_impl::token_id::SpanId; @@ -91,7 +91,7 @@ impl<'env> ProcMacroSrv<'env> { } } -pub type SubCallback = Box SubResponse + Send + Sync + 'static>; +pub type SubCallback = Box; pub trait BidirectionalHandler { fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option; From 346625f5f8467b6f7c250c13f0f6522b76600432 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Fri, 26 Dec 2025 23:04:19 +0530 Subject: [PATCH 3/7] adapt source_text to new handler --- .../src/server_impl/rust_analyzer_span.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 0bce67fcd9..ee834e37c1 100644 --- a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -14,7 +14,7 @@ use proc_macro::bridge::server; use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span, TextRange, TextSize}; use crate::{ - SubCallback, SubRequest, SubResponse, + SubCallback, bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree}, server_impl::literal_from_str, }; @@ -156,14 +156,7 @@ impl server::Span for RaSpanServer { let start: u32 = span.range.start().into(); let end: u32 = span.range.end().into(); - let req = SubRequest::SourceText { file_id, start, end }; - - let cb = self.callback.as_mut()?; - let response = cb(req); - - match response { - SubResponse::SourceTextResult { text } => text, - } + self.callback.as_mut()?.source_text(file_id.file_id().index(), start, end) } fn parent(&mut self, _span: Self::Span) -> Option { From 91b5c3c664a045ad07e69d1a8c1021b0d429c657 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 27 Dec 2025 09:07:08 +0530 Subject: [PATCH 4/7] add bidirectional handle in proc-macro-srv-cli to interact with client and srv --- crates/proc-macro-srv-cli/src/main_loop.rs | 82 +++++++++++----------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/crates/proc-macro-srv-cli/src/main_loop.rs b/crates/proc-macro-srv-cli/src/main_loop.rs index 99e3d79ef2..bd2fd2df79 100644 --- a/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/crates/proc-macro-srv-cli/src/main_loop.rs @@ -1,6 +1,4 @@ //! The main loop of the proc-macro server. -use std::io; - use proc_macro_api::{ Codec, bidirectional_protocol::msg as bidirectional, @@ -8,6 +6,7 @@ use proc_macro_api::{ transport::codec::{json::JsonProtocol, postcard::PostcardProtocol}, version::CURRENT_API_VERSION, }; +use std::{io, sync::mpsc}; use legacy::Message; @@ -170,6 +169,21 @@ fn handle_expand_id( send_response::<_, C>(stdout, bidirectional::Response::ExpandMacro(res)) } +struct BidirectionalProxy { + subreq_tx: mpsc::Sender, + subresp_rx: mpsc::Receiver, +} + +impl proc_macro_srv::BidirectionalHandler for BidirectionalProxy { + fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option { + self.subreq_tx.send(bidirectional::SubRequest::SourceText { file_id, start, end }).ok()?; + + match self.subresp_rx.recv().ok()? { + bidirectional::SubResponse::SourceTextResult { text } => text, + } + } +} + fn handle_expand_ra( srv: &proc_macro_srv::ProcMacroSrv<'_>, stdin: &mut R, @@ -201,22 +215,20 @@ fn handle_expand_ra( macro_body.to_tokenstream_resolved(CURRENT_API_VERSION, &span_data_table, |a, b| { srv.join_spans(a, b).unwrap_or(b) }); + let attributes = attributes.map(|it| { it.to_tokenstream_resolved(CURRENT_API_VERSION, &span_data_table, |a, b| { srv.join_spans(a, b).unwrap_or(b) }) }); - let (subreq_tx, subreq_rx) = crossbeam_channel::unbounded(); - let (subresp_tx, subresp_rx) = crossbeam_channel::unbounded(); - let (result_tx, result_rx) = crossbeam_channel::bounded(1); + let (subreq_tx, subreq_rx) = mpsc::channel(); + let (subresp_tx, subresp_rx) = mpsc::channel(); + let (result_tx, result_rx) = mpsc::channel(); - std::thread::scope(|scope| { - scope.spawn(|| { - let callback = Box::new(move |req: proc_macro_srv::SubRequest| { - subreq_tx.send(req).unwrap(); - subresp_rx.recv().unwrap() - }); + std::thread::scope(|s| { + s.spawn(|| { + let callback = BidirectionalProxy { subreq_tx, subresp_rx }; let res = srv .expand( @@ -229,7 +241,7 @@ fn handle_expand_ra( def_site, call_site, mixed_site, - Some(callback), + Some(Box::new(callback)), ) .map(|it| { ( @@ -253,27 +265,31 @@ fn handle_expand_ra( loop { if let Ok(res) = result_rx.try_recv() { - send_response::<_, C>(stdout, bidirectional::Response::ExpandMacroExtended(res)) - .unwrap(); + let _ = send_response::<_, C>( + stdout, + bidirectional::Response::ExpandMacroExtended(res), + ); break; } - let subreq = match subreq_rx.recv() { + let sub_req = match subreq_rx.recv() { Ok(r) => r, Err(_) => break, }; - let api_req = from_srv_req(subreq); - bidirectional::BidirectionalMessage::SubRequest(api_req).write::<_, C>(stdout).unwrap(); - - let resp = bidirectional::BidirectionalMessage::read::<_, C>(stdin, buf) - .unwrap() - .expect("client closed connection"); - + if bidirectional::BidirectionalMessage::SubRequest(sub_req) + .write::<_, C>(stdout) + .is_err() + { + break; + } + let resp = match bidirectional::BidirectionalMessage::read::<_, C>(stdin, buf) { + Ok(Some(r)) => r, + _ => break, + }; match resp { - bidirectional::BidirectionalMessage::SubResponse(api_resp) => { - let srv_resp = from_client_res(api_resp); - subresp_tx.send(srv_resp).unwrap(); + bidirectional::BidirectionalMessage::SubResponse(resp) => { + let _ = subresp_tx.send(resp); } other => panic!("expected SubResponse, got {other:?}"), } @@ -425,22 +441,6 @@ fn run_() -> io::Result<()> { Ok(()) } -fn from_srv_req(value: proc_macro_srv::SubRequest) -> bidirectional::SubRequest { - match value { - proc_macro_srv::SubRequest::SourceText { file_id, start, end } => { - bidirectional::SubRequest::SourceText { file_id: file_id.file_id().index(), start, end } - } - } -} - -fn from_client_res(value: bidirectional::SubResponse) -> proc_macro_srv::SubResponse { - match value { - bidirectional::SubResponse::SourceTextResult { text } => { - proc_macro_srv::SubResponse::SourceTextResult { text } - } - } -} - fn send_response( stdout: &mut W, resp: bidirectional::Response, From 76ea9828a7e70a17832f5802017cbe08ecb7beb1 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 27 Dec 2025 09:21:32 +0530 Subject: [PATCH 5/7] rename handler's to be context specific --- crates/proc-macro-srv-cli/src/main_loop.rs | 6 +++--- crates/proc-macro-srv/src/dylib.rs | 6 +++--- crates/proc-macro-srv/src/dylib/proc_macros.rs | 4 ++-- crates/proc-macro-srv/src/lib.rs | 12 ++++++------ .../src/server_impl/rust_analyzer_span.rs | 4 ++-- crates/proc-macro-srv/src/server_impl/token_id.rs | 4 ++-- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/crates/proc-macro-srv-cli/src/main_loop.rs b/crates/proc-macro-srv-cli/src/main_loop.rs index bd2fd2df79..d0f3a2b15d 100644 --- a/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/crates/proc-macro-srv-cli/src/main_loop.rs @@ -169,12 +169,12 @@ fn handle_expand_id( send_response::<_, C>(stdout, bidirectional::Response::ExpandMacro(res)) } -struct BidirectionalProxy { +struct ProcMacroClientHandle { subreq_tx: mpsc::Sender, subresp_rx: mpsc::Receiver, } -impl proc_macro_srv::BidirectionalHandler for BidirectionalProxy { +impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle { fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option { self.subreq_tx.send(bidirectional::SubRequest::SourceText { file_id, start, end }).ok()?; @@ -228,7 +228,7 @@ fn handle_expand_ra( std::thread::scope(|s| { s.spawn(|| { - let callback = BidirectionalProxy { subreq_tx, subresp_rx }; + let callback = ProcMacroClientHandle { subreq_tx, subresp_rx }; let res = srv .expand( diff --git a/crates/proc-macro-srv/src/dylib.rs b/crates/proc-macro-srv/src/dylib.rs index 082a1d77b5..d34f37b16a 100644 --- a/crates/proc-macro-srv/src/dylib.rs +++ b/crates/proc-macro-srv/src/dylib.rs @@ -12,8 +12,8 @@ use object::Object; use paths::{Utf8Path, Utf8PathBuf}; use crate::{ - PanicMessage, ProcMacroKind, ProcMacroSrvSpan, SubCallback, dylib::proc_macros::ProcMacros, - token_stream::TokenStream, + PanicMessage, ProcMacroClientHandle, ProcMacroKind, ProcMacroSrvSpan, + dylib::proc_macros::ProcMacros, token_stream::TokenStream, }; pub(crate) struct Expander { @@ -45,7 +45,7 @@ impl Expander { def_site: S, call_site: S, mixed_site: S, - callback: Option, + callback: Option, ) -> Result, PanicMessage> where ::TokenStream: Default, diff --git a/crates/proc-macro-srv/src/dylib/proc_macros.rs b/crates/proc-macro-srv/src/dylib/proc_macros.rs index 6f6bd086de..ddbb0128f5 100644 --- a/crates/proc-macro-srv/src/dylib/proc_macros.rs +++ b/crates/proc-macro-srv/src/dylib/proc_macros.rs @@ -1,5 +1,5 @@ //! Proc macro ABI -use crate::{ProcMacroKind, ProcMacroSrvSpan, SubCallback, token_stream::TokenStream}; +use crate::{ProcMacroClientHandle, ProcMacroKind, ProcMacroSrvSpan, token_stream::TokenStream}; use proc_macro::bridge; #[repr(transparent)] @@ -20,7 +20,7 @@ impl ProcMacros { def_site: S, call_site: S, mixed_site: S, - callback: Option, + callback: Option, ) -> Result, crate::PanicMessage> { let parsed_attributes = attribute.unwrap_or_default(); diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs index 5f0273d7bc..9fb81afdee 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs @@ -91,9 +91,9 @@ impl<'env> ProcMacroSrv<'env> { } } -pub type SubCallback = Box; +pub type ProcMacroClientHandle = Box; -pub trait BidirectionalHandler { +pub trait ProcMacroClientInterface { fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option; } @@ -111,7 +111,7 @@ impl ProcMacroSrv<'_> { def_site: S, call_site: S, mixed_site: S, - callback: Option, + callback: Option, ) -> Result, PanicMessage> { let snapped_env = self.env; let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage { @@ -183,7 +183,7 @@ pub trait ProcMacroSrvSpan: Copy + Send + Sync { call_site: Self, def_site: Self, mixed_site: Self, - callback: Option, + callback: Option, ) -> Self::Server; } @@ -194,7 +194,7 @@ impl ProcMacroSrvSpan for SpanId { call_site: Self, def_site: Self, mixed_site: Self, - callback: Option, + callback: Option, ) -> Self::Server { Self::Server { call_site, @@ -213,7 +213,7 @@ impl ProcMacroSrvSpan for Span { call_site: Self, def_site: Self, mixed_site: Self, - callback: Option, + callback: Option, ) -> Self::Server { Self::Server { call_site, diff --git a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index ee834e37c1..1b496950df 100644 --- a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -14,7 +14,7 @@ use proc_macro::bridge::server; use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span, TextRange, TextSize}; use crate::{ - SubCallback, + ProcMacroClientHandle, bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree}, server_impl::literal_from_str, }; @@ -29,7 +29,7 @@ pub struct RaSpanServer { pub call_site: Span, pub def_site: Span, pub mixed_site: Span, - pub callback: Option, + pub callback: Option, } impl server::Types for RaSpanServer { diff --git a/crates/proc-macro-srv/src/server_impl/token_id.rs b/crates/proc-macro-srv/src/server_impl/token_id.rs index 9db7597d84..646dde7952 100644 --- a/crates/proc-macro-srv/src/server_impl/token_id.rs +++ b/crates/proc-macro-srv/src/server_impl/token_id.rs @@ -9,7 +9,7 @@ use intern::Symbol; use proc_macro::bridge::server; use crate::{ - SubCallback, + ProcMacroClientHandle, bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree}, server_impl::literal_from_str, }; @@ -35,7 +35,7 @@ pub struct SpanIdServer { pub call_site: Span, pub def_site: Span, pub mixed_site: Span, - pub callback: Option, + pub callback: Option, } impl server::Types for SpanIdServer { From 5a91849218260d9098cae6df03e996fcedcd150c Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 27 Dec 2025 09:43:01 +0530 Subject: [PATCH 6/7] make source_text take non mutable reference of self --- crates/proc-macro-srv-cli/src/main_loop.rs | 2 +- crates/proc-macro-srv/src/lib.rs | 2 +- crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/crates/proc-macro-srv-cli/src/main_loop.rs b/crates/proc-macro-srv-cli/src/main_loop.rs index d0f3a2b15d..6ed42204df 100644 --- a/crates/proc-macro-srv-cli/src/main_loop.rs +++ b/crates/proc-macro-srv-cli/src/main_loop.rs @@ -175,7 +175,7 @@ struct ProcMacroClientHandle { } impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle { - fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option { + fn source_text(&self, file_id: u32, start: u32, end: u32) -> Option { self.subreq_tx.send(bidirectional::SubRequest::SourceText { file_id, start, end }).ok()?; match self.subresp_rx.recv().ok()? { diff --git a/crates/proc-macro-srv/src/lib.rs b/crates/proc-macro-srv/src/lib.rs index 9fb81afdee..ff5623f39e 100644 --- a/crates/proc-macro-srv/src/lib.rs +++ b/crates/proc-macro-srv/src/lib.rs @@ -94,7 +94,7 @@ impl<'env> ProcMacroSrv<'env> { pub type ProcMacroClientHandle = Box; pub trait ProcMacroClientInterface { - fn source_text(&mut self, file_id: u32, start: u32, end: u32) -> Option; + fn source_text(&self, file_id: u32, start: u32, end: u32) -> Option; } const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024; diff --git a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs index 1b496950df..5f7c0a5202 100644 --- a/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs +++ b/crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs @@ -156,7 +156,7 @@ impl server::Span for RaSpanServer { let start: u32 = span.range.start().into(); let end: u32 = span.range.end().into(); - self.callback.as_mut()?.source_text(file_id.file_id().index(), start, end) + self.callback.as_ref()?.source_text(file_id.file_id().index(), start, end) } fn parent(&mut self, _span: Self::Span) -> Option { From 6ae410ccc7a87a97c9d3128239e2c46b497ece31 Mon Sep 17 00:00:00 2001 From: bit-aloo Date: Sat, 27 Dec 2025 10:40:42 +0530 Subject: [PATCH 7/7] remove crossbeam-channel from proc-macro-srv-cli --- Cargo.lock | 1 - crates/proc-macro-srv-cli/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb76f51cd3..a2eb8b1397 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1877,7 +1877,6 @@ name = "proc-macro-srv-cli" version = "0.0.0" dependencies = [ "clap", - "crossbeam-channel", "postcard", "proc-macro-api", "proc-macro-srv", diff --git a/crates/proc-macro-srv-cli/Cargo.toml b/crates/proc-macro-srv-cli/Cargo.toml index df3d21aefc..2c6e5a16ee 100644 --- a/crates/proc-macro-srv-cli/Cargo.toml +++ b/crates/proc-macro-srv-cli/Cargo.toml @@ -14,7 +14,6 @@ publish = false proc-macro-srv.workspace = true proc-macro-api.workspace = true postcard.workspace = true -crossbeam-channel.workspace = true clap = {version = "4.5.42", default-features = false, features = ["std"]} [features]