diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index 83a2ac6f0d4..cf51d8da16d 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -2,6 +2,8 @@ use super::*; +use std::marker::PhantomData; + macro_rules! define_handles { ( 'owned: $($oty:ident,)* @@ -45,20 +47,25 @@ macro_rules! define_handles { $( #[repr(C)] - pub(crate) struct $oty(handle::Handle); - impl !Send for $oty {} - impl !Sync for $oty {} + pub(crate) struct $oty { + handle: handle::Handle, + // Prevent Send and Sync impls + _marker: PhantomData<*mut ()>, + } // Forward `Drop::drop` to the inherent `drop` method. impl Drop for $oty { fn drop(&mut self) { - $oty(self.0).drop(); + $oty { + handle: self.handle, + _marker: PhantomData, + }.drop(); } } impl Encode for $oty { fn encode(self, w: &mut Writer, s: &mut S) { - let handle = self.0; + let handle = self.handle; mem::forget(self); handle.encode(w, s); } @@ -74,7 +81,7 @@ macro_rules! define_handles { impl Encode for &$oty { fn encode(self, w: &mut Writer, s: &mut S) { - self.0.encode(w, s); + self.handle.encode(w, s); } } @@ -88,7 +95,7 @@ macro_rules! define_handles { impl Encode for &mut $oty { fn encode(self, w: &mut Writer, s: &mut S) { - self.0.encode(w, s); + self.handle.encode(w, s); } } @@ -113,7 +120,10 @@ macro_rules! define_handles { impl DecodeMut<'_, '_, S> for $oty { fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { - $oty(handle::Handle::decode(r, s)) + $oty { + handle: handle::Handle::decode(r, s), + _marker: PhantomData, + } } } )* @@ -121,13 +131,15 @@ macro_rules! define_handles { $( #[repr(C)] #[derive(Copy, Clone, PartialEq, Eq, Hash)] - pub(crate) struct $ity(handle::Handle); - impl !Send for $ity {} - impl !Sync for $ity {} + pub(crate) struct $ity { + handle: handle::Handle, + // Prevent Send and Sync impls + _marker: PhantomData<*mut ()>, + } impl Encode for $ity { fn encode(self, w: &mut Writer, s: &mut S) { - self.0.encode(w, s); + self.handle.encode(w, s); } } @@ -149,7 +161,10 @@ macro_rules! define_handles { impl DecodeMut<'_, '_, S> for $ity { fn decode(r: &mut Reader<'_>, s: &mut S) -> Self { - $ity(handle::Handle::decode(r, s)) + $ity { + handle: handle::Handle::decode(r, s), + _marker: PhantomData, + } } } )* diff --git a/library/proc_macro/src/bridge/closure.rs b/library/proc_macro/src/bridge/closure.rs index 04d30d82bd1..06f76d2fc91 100644 --- a/library/proc_macro/src/bridge/closure.rs +++ b/library/proc_macro/src/bridge/closure.rs @@ -6,14 +6,12 @@ use std::marker::PhantomData; pub struct Closure<'a, A, R> { call: unsafe extern "C" fn(*mut Env, A) -> R, env: *mut Env, - _marker: PhantomData<&'a mut ()>, + // Ensure Closure is !Send and !Sync + _marker: PhantomData<*mut &'a mut ()>, } struct Env; -impl<'a, A, R> !Sync for Closure<'a, A, R> {} -impl<'a, A, R> !Send for Closure<'a, A, R> {} - impl<'a, A, R, F: FnMut(A) -> R> From<&'a mut F> for Closure<'a, A, R> { fn from(f: &'a mut F) -> Self { unsafe extern "C" fn call R>(env: *mut Env, arg: A) -> R { diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index fbeb585095b..d1f7d84991d 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -220,6 +220,8 @@ use rpc::{Decode, DecodeMut, Encode, Reader, Writer}; /// then passes it to the client through the function pointer in the `run` /// field of `client::Client`. The client holds its copy of the `Bridge` /// in TLS during its execution (`Bridge::{enter, with}` in `client.rs`). +// Note: Bridge is !Send and !Sync due to containg a `Closure`. If this +// ever changes, make sure to preserve the !Send and !Sync property. #[repr(C)] pub struct Bridge<'a> { /// Reusable buffer (only `clear`-ed, never shrunk), primarily @@ -233,9 +235,6 @@ pub struct Bridge<'a> { force_show_panics: bool, } -impl<'a> !Sync for Bridge<'a> {} -impl<'a> !Send for Bridge<'a> {} - #[forbid(unsafe_code)] #[allow(non_camel_case_types)] mod api_tags {