From f601b29825f874ba05e67631ddb80a2b830cc03c Mon Sep 17 00:00:00 2001 From: cyrgani Date: Fri, 13 Feb 2026 11:24:50 +0000 Subject: [PATCH] inline `SameThread` and `CrossThread` --- compiler/rustc_expand/src/proc_macro.rs | 6 +- library/proc_macro/src/bridge/server.rs | 92 +++++++------------ .../proc-macro-srv/src/dylib/proc_macros.rs | 6 +- 3 files changed, 40 insertions(+), 64 deletions(-) diff --git a/compiler/rustc_expand/src/proc_macro.rs b/compiler/rustc_expand/src/proc_macro.rs index 530e7b998d41..e67855700813 100644 --- a/compiler/rustc_expand/src/proc_macro.rs +++ b/compiler/rustc_expand/src/proc_macro.rs @@ -12,10 +12,10 @@ use crate::base::{self, *}; use crate::{errors, proc_macro_server}; fn exec_strategy(sess: &Session) -> impl pm::bridge::server::ExecutionStrategy + 'static { - pm::bridge::server::MaybeCrossThread::new( - sess.opts.unstable_opts.proc_macro_execution_strategy + pm::bridge::server::MaybeCrossThread { + cross_thread: sess.opts.unstable_opts.proc_macro_execution_strategy == ProcMacroExecutionStrategy::CrossThread, - ) + } } pub struct BangProcMacro { diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs index b5b63ead4464..1151798fccf4 100644 --- a/library/proc_macro/src/bridge/server.rs +++ b/library/proc_macro/src/bridge/server.rs @@ -121,10 +121,13 @@ macro_rules! define_dispatcher { } with_api!(define_dispatcher, MarkedTokenStream, MarkedSpan, MarkedSymbol); +// This trait is currently only implemented and used once, inside of this crate. +// We keep it public to allow implementing more complex execution strategies in +// the future, such as wasm proc-macros. pub trait ExecutionStrategy { - fn run_bridge_and_client( + fn run_bridge_and_client( &self, - dispatcher: &mut Dispatcher, + dispatcher: &mut Dispatcher, input: Buffer, run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer, force_show_panics: bool, @@ -164,82 +167,55 @@ impl Drop for RunningSameThreadGuard { } pub struct MaybeCrossThread { - cross_thread: bool, + pub cross_thread: bool, } -impl MaybeCrossThread { - pub const fn new(cross_thread: bool) -> Self { - MaybeCrossThread { cross_thread } - } -} +pub const SAME_THREAD: MaybeCrossThread = MaybeCrossThread { cross_thread: false }; +pub const CROSS_THREAD: MaybeCrossThread = MaybeCrossThread { cross_thread: true }; impl ExecutionStrategy for MaybeCrossThread { - fn run_bridge_and_client( + fn run_bridge_and_client( &self, - dispatcher: &mut Dispatcher, + dispatcher: &mut Dispatcher, input: Buffer, run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer, force_show_panics: bool, ) -> Buffer { if self.cross_thread || ALREADY_RUNNING_SAME_THREAD.get() { - CrossThread.run_bridge_and_client(dispatcher, input, run_client, force_show_panics) + let (mut server, mut client) = MessagePipe::new(); + + let join_handle = thread::spawn(move || { + let mut dispatch = |b: Buffer| -> Buffer { + client.send(b); + client.recv().expect("server died while client waiting for reply") + }; + + run_client(BridgeConfig { + input, + dispatch: (&mut dispatch).into(), + force_show_panics, + }) + }); + + while let Some(b) = server.recv() { + server.send(dispatcher.dispatch(b)); + } + + join_handle.join().unwrap() } else { - SameThread.run_bridge_and_client(dispatcher, input, run_client, force_show_panics) - } - } -} + let _guard = RunningSameThreadGuard::new(); -pub struct SameThread; - -impl ExecutionStrategy for SameThread { - fn run_bridge_and_client( - &self, - dispatcher: &mut Dispatcher, - input: Buffer, - run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer, - force_show_panics: bool, - ) -> Buffer { - let _guard = RunningSameThreadGuard::new(); - - let mut dispatch = |buf| dispatcher.dispatch(buf); - - run_client(BridgeConfig { input, dispatch: (&mut dispatch).into(), force_show_panics }) - } -} - -pub struct CrossThread; - -impl ExecutionStrategy for CrossThread { - fn run_bridge_and_client( - &self, - dispatcher: &mut Dispatcher, - input: Buffer, - run_client: extern "C" fn(BridgeConfig<'_>) -> Buffer, - force_show_panics: bool, - ) -> Buffer { - let (mut server, mut client) = MessagePipe::new(); - - let join_handle = thread::spawn(move || { - let mut dispatch = |b: Buffer| -> Buffer { - client.send(b); - client.recv().expect("server died while client waiting for reply") - }; + let mut dispatch = |buf| dispatcher.dispatch(buf); run_client(BridgeConfig { input, dispatch: (&mut dispatch).into(), force_show_panics }) - }); - - while let Some(b) = server.recv() { - server.send(dispatcher.dispatch(b)); } - - join_handle.join().unwrap() } } /// A message pipe used for communicating between server and client threads. struct MessagePipe { - tx: std::sync::mpsc::SyncSender, - rx: std::sync::mpsc::Receiver, + tx: mpsc::SyncSender, + rx: mpsc::Receiver, } impl MessagePipe { diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs index 76c5097101c7..4065dbd0b49b 100644 --- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs +++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/proc_macros.rs @@ -30,7 +30,7 @@ impl ProcMacros { if *trait_name == macro_name => { let res = client.run( - &bridge::server::SameThread, + &bridge::server::SAME_THREAD, S::make_server(call_site, def_site, mixed_site, callback), macro_body, cfg!(debug_assertions), @@ -39,7 +39,7 @@ impl ProcMacros { } bridge::client::ProcMacro::Bang { name, client } if *name == macro_name => { let res = client.run( - &bridge::server::SameThread, + &bridge::server::SAME_THREAD, S::make_server(call_site, def_site, mixed_site, callback), macro_body, cfg!(debug_assertions), @@ -48,7 +48,7 @@ impl ProcMacros { } bridge::client::ProcMacro::Attr { name, client } if *name == macro_name => { let res = client.run( - &bridge::server::SameThread, + &bridge::server::SAME_THREAD, S::make_server(call_site, def_site, mixed_site, callback), parsed_attributes, macro_body,