Skip to content

Commit 9242c12

Browse files
committed
proc_macro/bridge: remove Closure.
1 parent 4689fbe commit 9242c12

File tree

5 files changed

+58
-67
lines changed

5 files changed

+58
-67
lines changed

library/proc_macro/src/bridge/client.rs

+43-26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
use super::*;
44

5+
use std::cell::Cell;
56
use std::marker::PhantomData;
67

78
macro_rules! define_handles {
@@ -256,7 +257,7 @@ macro_rules! define_client_side {
256257
api_tags::Method::$name(api_tags::$name::$method).encode(&mut b, &mut ());
257258
reverse_encode!(b; $($arg),*);
258259

259-
b = bridge.dispatch.call(b);
260+
b = (bridge.dispatch)(b);
260261

261262
let r = Result::<_, PanicMessage>::decode(&mut &b[..], &mut ());
262263

@@ -270,48 +271,64 @@ macro_rules! define_client_side {
270271
}
271272
with_api!(self, self, define_client_side);
272273

273-
enum BridgeState<'a> {
274+
enum BridgeState {
274275
/// No server is currently connected to this client.
275276
NotConnected,
276277

277278
/// A server is connected and available for requests.
278-
Connected(Bridge<'a>),
279+
Connected(Bridge),
279280

280281
/// Access to the bridge is being exclusively acquired
281282
/// (e.g., during `BridgeState::with`).
282283
InUse,
283284
}
284285

285-
enum BridgeStateL {}
286+
impl BridgeState {
287+
/// Sets the thread-local `BridgeState` to `replacement` while
288+
/// running `f`, which gets the old `BridgeState`, mutably.
289+
///
290+
/// The state will be restored after `f` exits, even
291+
/// by panic, including modifications made to it by `f`.
292+
fn replace_during<R>(replacement: Self, f: impl FnOnce(&mut Self) -> R) -> R {
293+
/// Wrapper that ensures that a cell always gets filled
294+
/// (with the original state, optionally changed by `f`),
295+
/// even if `f` had panicked.
296+
struct PutBackOnDrop<'a, T> {
297+
cell: &'a Cell<T>,
298+
value: Option<T>,
299+
}
286300

287-
impl<'a> scoped_cell::ApplyL<'a> for BridgeStateL {
288-
type Out = BridgeState<'a>;
289-
}
301+
impl<'a, T> Drop for PutBackOnDrop<'a, T> {
302+
fn drop(&mut self) {
303+
self.cell.set(self.value.take().unwrap());
304+
}
305+
}
290306

291-
thread_local! {
292-
static BRIDGE_STATE: scoped_cell::ScopedCell<BridgeStateL> =
293-
scoped_cell::ScopedCell::new(BridgeState::NotConnected);
294-
}
307+
thread_local! {
308+
static BRIDGE_STATE: Cell<BridgeState> = Cell::new(BridgeState::NotConnected);
309+
}
310+
BRIDGE_STATE.with(|state| {
311+
let mut put_back_on_drop =
312+
PutBackOnDrop { cell: state, value: Some(state.replace(replacement)) };
313+
314+
f(put_back_on_drop.value.as_mut().unwrap())
315+
})
316+
}
295317

296-
impl BridgeState<'_> {
297318
/// Take exclusive control of the thread-local
298319
/// `BridgeState`, and pass it to `f`, mutably.
320+
///
299321
/// The state will be restored after `f` exits, even
300322
/// by panic, including modifications made to it by `f`.
301323
///
302324
/// N.B., while `f` is running, the thread-local state
303325
/// is `BridgeState::InUse`.
304-
fn with<R>(f: impl FnOnce(&mut BridgeState<'_>) -> R) -> R {
305-
BRIDGE_STATE.with(|state| {
306-
state.replace(BridgeState::InUse, |mut state| {
307-
// FIXME(#52812) pass `f` directly to `replace` when `RefMutL` is gone
308-
f(&mut *state)
309-
})
310-
})
326+
fn with<R>(f: impl FnOnce(&mut Self) -> R) -> R {
327+
Self::replace_during(BridgeState::InUse, f)
311328
}
312329
}
313330

314-
impl Bridge<'_> {
331+
impl Bridge {
315332
pub(crate) fn is_available() -> bool {
316333
BridgeState::with(|state| match state {
317334
BridgeState::Connected(_) | BridgeState::InUse => true,
@@ -337,10 +354,10 @@ impl Bridge<'_> {
337354
}));
338355
});
339356

340-
BRIDGE_STATE.with(|state| state.set(BridgeState::Connected(self), f))
357+
BridgeState::replace_during(BridgeState::Connected(self), |_| f())
341358
}
342359

343-
fn with<R>(f: impl FnOnce(&mut Bridge<'_>) -> R) -> R {
360+
fn with<R>(f: impl FnOnce(&mut Self) -> R) -> R {
344361
BridgeState::with(|state| match state {
345362
BridgeState::NotConnected => {
346363
panic!("procedural macro API is used outside of a procedural macro");
@@ -367,15 +384,15 @@ pub struct Client<F> {
367384
// FIXME(eddyb) use a reference to the `static COUNTERS`, instead of
368385
// a wrapper `fn` pointer, once `const fn` can reference `static`s.
369386
pub(super) get_handle_counters: extern "C" fn() -> &'static HandleCounters,
370-
pub(super) run: extern "C" fn(Bridge<'_>, F) -> Buffer<u8>,
387+
pub(super) run: extern "C" fn(Bridge, F) -> Buffer<u8>,
371388
pub(super) f: F,
372389
}
373390

374391
/// Client-side helper for handling client panics, entering the bridge,
375392
/// deserializing input and serializing output.
376393
// FIXME(eddyb) maybe replace `Bridge::enter` with this?
377394
fn run_client<A: for<'a, 's> DecodeMut<'a, 's, ()>, R: Encode<()>>(
378-
mut bridge: Bridge<'_>,
395+
mut bridge: Bridge,
379396
f: impl FnOnce(A) -> R,
380397
) -> Buffer<u8> {
381398
// The initial `cached_buffer` contains the input.
@@ -418,7 +435,7 @@ fn run_client<A: for<'a, 's> DecodeMut<'a, 's, ()>, R: Encode<()>>(
418435
impl Client<fn(crate::TokenStream) -> crate::TokenStream> {
419436
pub const fn expand1(f: fn(crate::TokenStream) -> crate::TokenStream) -> Self {
420437
extern "C" fn run(
421-
bridge: Bridge<'_>,
438+
bridge: Bridge,
422439
f: impl FnOnce(crate::TokenStream) -> crate::TokenStream,
423440
) -> Buffer<u8> {
424441
run_client(bridge, |input| f(crate::TokenStream(input)).0)
@@ -432,7 +449,7 @@ impl Client<fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream> {
432449
f: fn(crate::TokenStream, crate::TokenStream) -> crate::TokenStream,
433450
) -> Self {
434451
extern "C" fn run(
435-
bridge: Bridge<'_>,
452+
bridge: Bridge,
436453
f: impl FnOnce(crate::TokenStream, crate::TokenStream) -> crate::TokenStream,
437454
) -> Buffer<u8> {
438455
run_client(bridge, |(input, input2)| {

library/proc_macro/src/bridge/closure.rs

-28
This file was deleted.

library/proc_macro/src/bridge/mod.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -199,8 +199,6 @@ macro_rules! reverse_decode {
199199
mod buffer;
200200
#[forbid(unsafe_code)]
201201
pub mod client;
202-
#[allow(unsafe_code)]
203-
mod closure;
204202
#[forbid(unsafe_code)]
205203
mod handle;
206204
#[macro_use]
@@ -221,13 +219,13 @@ use rpc::{Decode, DecodeMut, Encode, Reader, Writer};
221219
/// field of `client::Client`. The client holds its copy of the `Bridge`
222220
/// in TLS during its execution (`Bridge::{enter, with}` in `client.rs`).
223221
#[repr(C)]
224-
pub struct Bridge<'a> {
222+
pub struct Bridge {
225223
/// Reusable buffer (only `clear`-ed, never shrunk), primarily
226224
/// used for making requests, but also for passing input to client.
227225
cached_buffer: Buffer<u8>,
228226

229227
/// Server-side function that the client uses to make requests.
230-
dispatch: closure::Closure<'a, Buffer<u8>, Buffer<u8>>,
228+
dispatch: extern "C" fn(Buffer<u8>) -> Buffer<u8>,
231229

232230
/// If 'true', always invoke the default panic hook
233231
force_show_panics: bool,

library/proc_macro/src/bridge/scoped_cell.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@ impl<T: LambdaL> ScopedCell<T> {
4141

4242
/// Sets the value in `self` to `replacement` while
4343
/// running `f`, which gets the old value, mutably.
44+
///
4445
/// The old value will be restored after `f` exits, even
4546
/// by panic, including modifications made to it by `f`.
46-
pub fn replace<'a, R>(
47+
pub fn replace_during<'a, R>(
4748
&self,
4849
replacement: <T as ApplyL<'a>>::Out,
4950
f: impl for<'b, 'c> FnOnce(RefMutL<'b, 'c, T>) -> R,
@@ -76,6 +77,6 @@ impl<T: LambdaL> ScopedCell<T> {
7677

7778
/// Sets the value in `self` to `value` while running `f`.
7879
pub fn set<R>(&self, value: <T as ApplyL<'_>>::Out, f: impl FnOnce() -> R) -> R {
79-
self.replace(value, |_| f())
80+
self.replace_during(value, |_| f())
8081
}
8182
}

library/proc_macro/src/bridge/server.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ fn run_bridge_and_client<D: Copy + Send + 'static>(
243243
strategy: &impl ExecutionStrategy,
244244
server_thread_dispatch: impl FnMut(Buffer<u8>) -> Buffer<u8>,
245245
input: Buffer<u8>,
246-
run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>,
246+
run_client: extern "C" fn(Bridge, D) -> Buffer<u8>,
247247
client_data: D,
248248
force_show_panics: bool,
249249
) -> Buffer<u8> {
@@ -268,18 +268,21 @@ fn run_bridge_and_client<D: Copy + Send + 'static>(
268268
strategy.cross_thread_dispatch(server_thread_dispatch, move |client_thread_dispatch| {
269269
CLIENT_THREAD_DISPATCH.with(|dispatch_slot| {
270270
dispatch_slot.set(Some(client_thread_dispatch), || {
271-
let mut dispatch = |b| {
271+
extern "C" fn dispatch(b: Buffer<u8>) -> Buffer<u8> {
272272
CLIENT_THREAD_DISPATCH.with(|dispatch_slot| {
273-
dispatch_slot.replace(None, |mut client_thread_dispatch| {
274-
client_thread_dispatch.as_mut().unwrap()(b)
273+
dispatch_slot.replace_during(None, |mut client_thread_dispatch| {
274+
client_thread_dispatch.as_mut().expect(
275+
"proc_macro::bridge::server: dispatch used on \
276+
thread lacking an active server-side dispatcher",
277+
)(b)
275278
})
276279
})
277-
};
280+
}
278281

279282
run_client(
280283
Bridge {
281284
cached_buffer: input,
282-
dispatch: (&mut dispatch).into(),
285+
dispatch,
283286
force_show_panics,
284287
_marker: marker::PhantomData,
285288
},
@@ -300,7 +303,7 @@ fn run_server<
300303
handle_counters: &'static client::HandleCounters,
301304
server: S,
302305
input: I,
303-
run_client: extern "C" fn(Bridge<'_>, D) -> Buffer<u8>,
306+
run_client: extern "C" fn(Bridge, D) -> Buffer<u8>,
304307
client_data: D,
305308
force_show_panics: bool,
306309
) -> Result<O, PanicMessage> {

0 commit comments

Comments
 (0)