diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index 9e9750eb8de40..cf51d8da16db5 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, + } } } )* @@ -310,7 +325,8 @@ impl Bridge<'_> { // NB. the server can't do this because it may use a different libstd. static HIDE_PANICS_DURING_EXPANSION: Once = Once::new(); HIDE_PANICS_DURING_EXPANSION.call_once(|| { - panic::update_hook(move |prev, info| { + let prev = panic::take_hook(); + panic::set_hook(Box::new(move |info| { let show = BridgeState::with(|state| match state { BridgeState::NotConnected => true, BridgeState::Connected(_) | BridgeState::InUse => force_show_panics, @@ -318,7 +334,7 @@ impl Bridge<'_> { if show { prev(info) } - }); + })); }); BRIDGE_STATE.with(|state| state.set(BridgeState::Connected(self), f)) diff --git a/library/proc_macro/src/bridge/closure.rs b/library/proc_macro/src/bridge/closure.rs index 5bfe287d33ab7..06f76d2fc9140 100644 --- a/library/proc_macro/src/bridge/closure.rs +++ b/library/proc_macro/src/bridge/closure.rs @@ -1,24 +1,23 @@ //! Closure type (equivalent to `&mut dyn FnMut(A) -> R`) that's `repr(C)`. +use std::marker::PhantomData; + #[repr(C)] pub struct Closure<'a, A, R> { - call: unsafe extern "C" fn(&mut Env, A) -> R, - env: &'a mut Env, -} - -extern "C" { - type Env; + call: unsafe extern "C" fn(*mut Env, A) -> R, + env: *mut Env, + // Ensure Closure is !Send and !Sync + _marker: PhantomData<*mut &'a mut ()>, } -impl<'a, A, R> !Sync for Closure<'a, A, R> {} -impl<'a, A, R> !Send for Closure<'a, A, R> {} +struct Env; 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 { + unsafe extern "C" fn call R>(env: *mut Env, arg: A) -> R { (*(env as *mut _ as *mut F))(arg) } - Closure { call: call::, env: unsafe { &mut *(f as *mut _ as *mut Env) } } + Closure { call: call::, env: f as *mut _ as *mut Env, _marker: PhantomData } } } diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index fbeb585095bbb..f7c9df6564f87 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -231,10 +231,10 @@ pub struct Bridge<'a> { /// If 'true', always invoke the default panic hook force_show_panics: bool, -} -impl<'a> !Sync for Bridge<'a> {} -impl<'a> !Send for Bridge<'a> {} + // Prevent Send and Sync impls + _marker: marker::PhantomData<*mut ()>, +} #[forbid(unsafe_code)] #[allow(non_camel_case_types)] diff --git a/library/proc_macro/src/bridge/server.rs b/library/proc_macro/src/bridge/server.rs index 1b3ccf4c18e70..2e0400d32a0af 100644 --- a/library/proc_macro/src/bridge/server.rs +++ b/library/proc_macro/src/bridge/server.rs @@ -153,7 +153,12 @@ impl ExecutionStrategy for SameThread { let mut dispatch = |b| dispatcher.dispatch(b); run_client( - Bridge { cached_buffer: input, dispatch: (&mut dispatch).into(), force_show_panics }, + Bridge { + cached_buffer: input, + dispatch: (&mut dispatch).into(), + force_show_panics, + _marker: marker::PhantomData, + }, client_data, ) } @@ -189,6 +194,7 @@ impl ExecutionStrategy for CrossThread1 { cached_buffer: input, dispatch: (&mut dispatch).into(), force_show_panics, + _marker: marker::PhantomData, }, client_data, ) @@ -241,6 +247,7 @@ impl ExecutionStrategy for CrossThread2 { cached_buffer: input, dispatch: (&mut dispatch).into(), force_show_panics, + _marker: marker::PhantomData, }, client_data, ); diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 5338cd077572c..762eafc8099d9 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -17,6 +17,9 @@ test(no_crate_inject, attr(deny(warnings))), test(attr(allow(dead_code, deprecated, unused_variables, unused_mut))) )] +// This library is copied into rust-analyzer to allow loading rustc compiled proc macros. +// Please avoid unstable features where possible to minimize the amount of changes necessary +// to make it compile with rust-analyzer on stable. #![feature(rustc_allow_const_fn_unstable)] #![feature(nll)] #![feature(staged_api)] @@ -24,13 +27,10 @@ #![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))] #![feature(allow_internal_unstable)] #![feature(decl_macro)] -#![feature(extern_types)] #![feature(negative_impls)] -#![feature(auto_traits)] #![feature(restricted_std)] #![feature(rustc_attrs)] #![feature(min_specialization)] -#![feature(panic_update_hook)] #![recursion_limit = "256"] #[unstable(feature = "proc_macro_internals", issue = "27812")]