Skip to content

Commit f9e29cf

Browse files
authored
Merge pull request #21340 from Shourya742/2025-12-26-better-bm-ergonomics
Refactor: Bidirectional messages
2 parents 8c5a68e + 6ae410c commit f9e29cf

8 files changed

Lines changed: 59 additions & 72 deletions

File tree

Cargo.lock

Lines changed: 0 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

crates/proc-macro-srv-cli/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ publish = false
1414
proc-macro-srv.workspace = true
1515
proc-macro-api.workspace = true
1616
postcard.workspace = true
17-
crossbeam-channel.workspace = true
1817
clap = {version = "4.5.42", default-features = false, features = ["std"]}
1918

2019
[features]

crates/proc-macro-srv-cli/src/main_loop.rs

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
//! The main loop of the proc-macro server.
2-
use std::io;
3-
42
use proc_macro_api::{
53
Codec,
64
bidirectional_protocol::msg as bidirectional,
75
legacy_protocol::msg as legacy,
86
transport::codec::{json::JsonProtocol, postcard::PostcardProtocol},
97
version::CURRENT_API_VERSION,
108
};
9+
use std::{io, sync::mpsc};
1110

1211
use legacy::Message;
1312

@@ -170,6 +169,21 @@ fn handle_expand_id<W: std::io::Write, C: Codec>(
170169
send_response::<_, C>(stdout, bidirectional::Response::ExpandMacro(res))
171170
}
172171

172+
struct ProcMacroClientHandle {
173+
subreq_tx: mpsc::Sender<bidirectional::SubRequest>,
174+
subresp_rx: mpsc::Receiver<bidirectional::SubResponse>,
175+
}
176+
177+
impl proc_macro_srv::ProcMacroClientInterface for ProcMacroClientHandle {
178+
fn source_text(&self, file_id: u32, start: u32, end: u32) -> Option<String> {
179+
self.subreq_tx.send(bidirectional::SubRequest::SourceText { file_id, start, end }).ok()?;
180+
181+
match self.subresp_rx.recv().ok()? {
182+
bidirectional::SubResponse::SourceTextResult { text } => text,
183+
}
184+
}
185+
}
186+
173187
fn handle_expand_ra<W: io::Write, R: io::BufRead, C: Codec>(
174188
srv: &proc_macro_srv::ProcMacroSrv<'_>,
175189
stdin: &mut R,
@@ -201,22 +215,20 @@ fn handle_expand_ra<W: io::Write, R: io::BufRead, C: Codec>(
201215
macro_body.to_tokenstream_resolved(CURRENT_API_VERSION, &span_data_table, |a, b| {
202216
srv.join_spans(a, b).unwrap_or(b)
203217
});
218+
204219
let attributes = attributes.map(|it| {
205220
it.to_tokenstream_resolved(CURRENT_API_VERSION, &span_data_table, |a, b| {
206221
srv.join_spans(a, b).unwrap_or(b)
207222
})
208223
});
209224

210-
let (subreq_tx, subreq_rx) = crossbeam_channel::unbounded();
211-
let (subresp_tx, subresp_rx) = crossbeam_channel::unbounded();
212-
let (result_tx, result_rx) = crossbeam_channel::bounded(1);
225+
let (subreq_tx, subreq_rx) = mpsc::channel();
226+
let (subresp_tx, subresp_rx) = mpsc::channel();
227+
let (result_tx, result_rx) = mpsc::channel();
213228

214-
std::thread::scope(|scope| {
215-
scope.spawn(|| {
216-
let callback = Box::new(move |req: proc_macro_srv::SubRequest| {
217-
subreq_tx.send(req).unwrap();
218-
subresp_rx.recv().unwrap()
219-
});
229+
std::thread::scope(|s| {
230+
s.spawn(|| {
231+
let callback = ProcMacroClientHandle { subreq_tx, subresp_rx };
220232

221233
let res = srv
222234
.expand(
@@ -229,7 +241,7 @@ fn handle_expand_ra<W: io::Write, R: io::BufRead, C: Codec>(
229241
def_site,
230242
call_site,
231243
mixed_site,
232-
Some(callback),
244+
Some(Box::new(callback)),
233245
)
234246
.map(|it| {
235247
(
@@ -253,27 +265,31 @@ fn handle_expand_ra<W: io::Write, R: io::BufRead, C: Codec>(
253265

254266
loop {
255267
if let Ok(res) = result_rx.try_recv() {
256-
send_response::<_, C>(stdout, bidirectional::Response::ExpandMacroExtended(res))
257-
.unwrap();
268+
let _ = send_response::<_, C>(
269+
stdout,
270+
bidirectional::Response::ExpandMacroExtended(res),
271+
);
258272
break;
259273
}
260274

261-
let subreq = match subreq_rx.recv() {
275+
let sub_req = match subreq_rx.recv() {
262276
Ok(r) => r,
263277
Err(_) => break,
264278
};
265279

266-
let api_req = from_srv_req(subreq);
267-
bidirectional::BidirectionalMessage::SubRequest(api_req).write::<_, C>(stdout).unwrap();
268-
269-
let resp = bidirectional::BidirectionalMessage::read::<_, C>(stdin, buf)
270-
.unwrap()
271-
.expect("client closed connection");
272-
280+
if bidirectional::BidirectionalMessage::SubRequest(sub_req)
281+
.write::<_, C>(stdout)
282+
.is_err()
283+
{
284+
break;
285+
}
286+
let resp = match bidirectional::BidirectionalMessage::read::<_, C>(stdin, buf) {
287+
Ok(Some(r)) => r,
288+
_ => break,
289+
};
273290
match resp {
274-
bidirectional::BidirectionalMessage::SubResponse(api_resp) => {
275-
let srv_resp = from_client_res(api_resp);
276-
subresp_tx.send(srv_resp).unwrap();
291+
bidirectional::BidirectionalMessage::SubResponse(resp) => {
292+
let _ = subresp_tx.send(resp);
277293
}
278294
other => panic!("expected SubResponse, got {other:?}"),
279295
}
@@ -425,22 +441,6 @@ fn run_<C: Codec>() -> io::Result<()> {
425441
Ok(())
426442
}
427443

428-
fn from_srv_req(value: proc_macro_srv::SubRequest) -> bidirectional::SubRequest {
429-
match value {
430-
proc_macro_srv::SubRequest::SourceText { file_id, start, end } => {
431-
bidirectional::SubRequest::SourceText { file_id: file_id.file_id().index(), start, end }
432-
}
433-
}
434-
}
435-
436-
fn from_client_res(value: bidirectional::SubResponse) -> proc_macro_srv::SubResponse {
437-
match value {
438-
bidirectional::SubResponse::SourceTextResult { text } => {
439-
proc_macro_srv::SubResponse::SourceTextResult { text }
440-
}
441-
}
442-
}
443-
444444
fn send_response<W: std::io::Write, C: Codec>(
445445
stdout: &mut W,
446446
resp: bidirectional::Response,

crates/proc-macro-srv/src/dylib.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ use object::Object;
1212
use paths::{Utf8Path, Utf8PathBuf};
1313

1414
use crate::{
15-
PanicMessage, ProcMacroKind, ProcMacroSrvSpan, SubCallback, dylib::proc_macros::ProcMacros,
16-
token_stream::TokenStream,
15+
PanicMessage, ProcMacroClientHandle, ProcMacroKind, ProcMacroSrvSpan,
16+
dylib::proc_macros::ProcMacros, token_stream::TokenStream,
1717
};
1818

1919
pub(crate) struct Expander {
@@ -45,7 +45,7 @@ impl Expander {
4545
def_site: S,
4646
call_site: S,
4747
mixed_site: S,
48-
callback: Option<SubCallback>,
48+
callback: Option<ProcMacroClientHandle>,
4949
) -> Result<TokenStream<S>, PanicMessage>
5050
where
5151
<S::Server as bridge::server::Types>::TokenStream: Default,

crates/proc-macro-srv/src/dylib/proc_macros.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Proc macro ABI
2-
use crate::{ProcMacroKind, ProcMacroSrvSpan, SubCallback, token_stream::TokenStream};
2+
use crate::{ProcMacroClientHandle, ProcMacroKind, ProcMacroSrvSpan, token_stream::TokenStream};
33
use proc_macro::bridge;
44

55
#[repr(transparent)]
@@ -20,7 +20,7 @@ impl ProcMacros {
2020
def_site: S,
2121
call_site: S,
2222
mixed_site: S,
23-
callback: Option<SubCallback>,
23+
callback: Option<ProcMacroClientHandle>,
2424
) -> Result<TokenStream<S>, crate::PanicMessage> {
2525
let parsed_attributes = attribute.unwrap_or_default();
2626

crates/proc-macro-srv/src/lib.rs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ use std::{
4747
};
4848

4949
use paths::{Utf8Path, Utf8PathBuf};
50-
use span::{EditionedFileId, Span};
50+
use span::Span;
5151
use temp_dir::TempDir;
5252

5353
pub use crate::server_impl::token_id::SpanId;
@@ -91,14 +91,10 @@ impl<'env> ProcMacroSrv<'env> {
9191
}
9292
}
9393

94-
pub type SubCallback = Box<dyn Fn(SubRequest) -> SubResponse + Send + Sync + 'static>;
94+
pub type ProcMacroClientHandle = Box<dyn ProcMacroClientInterface + Send>;
9595

96-
pub enum SubRequest {
97-
SourceText { file_id: EditionedFileId, start: u32, end: u32 },
98-
}
99-
100-
pub enum SubResponse {
101-
SourceTextResult { text: Option<String> },
96+
pub trait ProcMacroClientInterface {
97+
fn source_text(&self, file_id: u32, start: u32, end: u32) -> Option<String>;
10298
}
10399

104100
const EXPANDER_STACK_SIZE: usize = 8 * 1024 * 1024;
@@ -115,7 +111,7 @@ impl ProcMacroSrv<'_> {
115111
def_site: S,
116112
call_site: S,
117113
mixed_site: S,
118-
callback: Option<SubCallback>,
114+
callback: Option<ProcMacroClientHandle>,
119115
) -> Result<token_stream::TokenStream<S>, PanicMessage> {
120116
let snapped_env = self.env;
121117
let expander = self.expander(lib.as_ref()).map_err(|err| PanicMessage {
@@ -187,7 +183,7 @@ pub trait ProcMacroSrvSpan: Copy + Send + Sync {
187183
call_site: Self,
188184
def_site: Self,
189185
mixed_site: Self,
190-
callback: Option<SubCallback>,
186+
callback: Option<ProcMacroClientHandle>,
191187
) -> Self::Server;
192188
}
193189

@@ -198,7 +194,7 @@ impl ProcMacroSrvSpan for SpanId {
198194
call_site: Self,
199195
def_site: Self,
200196
mixed_site: Self,
201-
callback: Option<SubCallback>,
197+
callback: Option<ProcMacroClientHandle>,
202198
) -> Self::Server {
203199
Self::Server {
204200
call_site,
@@ -217,7 +213,7 @@ impl ProcMacroSrvSpan for Span {
217213
call_site: Self,
218214
def_site: Self,
219215
mixed_site: Self,
220-
callback: Option<SubCallback>,
216+
callback: Option<ProcMacroClientHandle>,
221217
) -> Self::Server {
222218
Self::Server {
223219
call_site,

crates/proc-macro-srv/src/server_impl/rust_analyzer_span.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use proc_macro::bridge::server;
1414
use span::{FIXUP_ERASED_FILE_AST_ID_MARKER, Span, TextRange, TextSize};
1515

1616
use crate::{
17-
SubCallback, SubRequest, SubResponse,
17+
ProcMacroClientHandle,
1818
bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree},
1919
server_impl::literal_from_str,
2020
};
@@ -29,7 +29,7 @@ pub struct RaSpanServer {
2929
pub call_site: Span,
3030
pub def_site: Span,
3131
pub mixed_site: Span,
32-
pub callback: Option<SubCallback>,
32+
pub callback: Option<ProcMacroClientHandle>,
3333
}
3434

3535
impl server::Types for RaSpanServer {
@@ -156,14 +156,7 @@ impl server::Span for RaSpanServer {
156156
let start: u32 = span.range.start().into();
157157
let end: u32 = span.range.end().into();
158158

159-
let req = SubRequest::SourceText { file_id, start, end };
160-
161-
let cb = self.callback.as_mut()?;
162-
let response = cb(req);
163-
164-
match response {
165-
SubResponse::SourceTextResult { text } => text,
166-
}
159+
self.callback.as_ref()?.source_text(file_id.file_id().index(), start, end)
167160
}
168161

169162
fn parent(&mut self, _span: Self::Span) -> Option<Self::Span> {

crates/proc-macro-srv/src/server_impl/token_id.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use intern::Symbol;
99
use proc_macro::bridge::server;
1010

1111
use crate::{
12-
SubCallback,
12+
ProcMacroClientHandle,
1313
bridge::{Diagnostic, ExpnGlobals, Literal, TokenTree},
1414
server_impl::literal_from_str,
1515
};
@@ -35,7 +35,7 @@ pub struct SpanIdServer {
3535
pub call_site: Span,
3636
pub def_site: Span,
3737
pub mixed_site: Span,
38-
pub callback: Option<SubCallback>,
38+
pub callback: Option<ProcMacroClientHandle>,
3939
}
4040

4141
impl server::Types for SpanIdServer {

0 commit comments

Comments
 (0)