From e85722946af6ae7d6ba8b6c7459d6ae6c5554216 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 25 Mar 2022 16:11:27 +0100 Subject: [PATCH 1/6] Remove unused auto_traits feature gate --- library/proc_macro/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 5338cd077572c..fba3bec43d570 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -26,7 +26,6 @@ #![feature(decl_macro)] #![feature(extern_types)] #![feature(negative_impls)] -#![feature(auto_traits)] #![feature(restricted_std)] #![feature(rustc_attrs)] #![feature(min_specialization)] From 681ea25b2016723cac03bc4f1682f50860d560d3 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 25 Mar 2022 16:12:21 +0100 Subject: [PATCH 2/6] Remove usage of panic_update_hook feature gate --- library/proc_macro/src/bridge/client.rs | 5 +++-- library/proc_macro/src/lib.rs | 1 - 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index 9e9750eb8de40..83a2ac6f0d4f1 100644 --- a/library/proc_macro/src/bridge/client.rs +++ b/library/proc_macro/src/bridge/client.rs @@ -310,7 +310,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 +319,7 @@ impl Bridge<'_> { if show { prev(info) } - }); + })); }); BRIDGE_STATE.with(|state| state.set(BridgeState::Connected(self), f)) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index fba3bec43d570..088d32ed16f9b 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -29,7 +29,6 @@ #![feature(restricted_std)] #![feature(rustc_attrs)] #![feature(min_specialization)] -#![feature(panic_update_hook)] #![recursion_limit = "256"] #[unstable(feature = "proc_macro_internals", issue = "27812")] From 4b67506baa758d6937c765a9d99ca803dce2c5bd Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 25 Mar 2022 16:12:57 +0100 Subject: [PATCH 3/6] Remove usage of extern_types feature gate --- library/proc_macro/src/bridge/closure.rs | 15 ++++++++------- library/proc_macro/src/lib.rs | 1 - 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library/proc_macro/src/bridge/closure.rs b/library/proc_macro/src/bridge/closure.rs index 5bfe287d33ab7..04d30d82bd112 100644 --- a/library/proc_macro/src/bridge/closure.rs +++ b/library/proc_macro/src/bridge/closure.rs @@ -1,24 +1,25 @@ //! 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, + call: unsafe extern "C" fn(*mut Env, A) -> R, + env: *mut Env, + _marker: PhantomData<&'a mut ()>, } -extern "C" { - type Env; -} +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 { + 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/lib.rs b/library/proc_macro/src/lib.rs index 088d32ed16f9b..433fb1001dd78 100644 --- a/library/proc_macro/src/lib.rs +++ b/library/proc_macro/src/lib.rs @@ -24,7 +24,6 @@ #![cfg_attr(bootstrap, feature(const_fn_fn_ptr_basics))] #![feature(allow_internal_unstable)] #![feature(decl_macro)] -#![feature(extern_types)] #![feature(negative_impls)] #![feature(restricted_std)] #![feature(rustc_attrs)] From ec7efa75f90884f1c9c242d5654c3bb854555271 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 25 Mar 2022 16:17:32 +0100 Subject: [PATCH 4/6] Avoid negative impls in the bridge --- library/proc_macro/src/bridge/client.rs | 41 ++++++++++++++++-------- library/proc_macro/src/bridge/closure.rs | 6 ++-- library/proc_macro/src/bridge/mod.rs | 5 ++- 3 files changed, 32 insertions(+), 20 deletions(-) diff --git a/library/proc_macro/src/bridge/client.rs b/library/proc_macro/src/bridge/client.rs index 83a2ac6f0d4f1..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, + } } } )* diff --git a/library/proc_macro/src/bridge/closure.rs b/library/proc_macro/src/bridge/closure.rs index 04d30d82bd112..06f76d2fc9140 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 fbeb585095bbb..d1f7d84991d66 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 { From 6eab9802c9d43cc7b2340fd93c49881850cd3b20 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 25 Mar 2022 16:19:02 +0100 Subject: [PATCH 5/6] Add note about feature gates --- library/proc_macro/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs index 433fb1001dd78..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)] From 7eda975b06a0896139e6ab0d23df22c6d357e146 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Wed, 6 Apr 2022 18:53:19 +0200 Subject: [PATCH 6/6] Use PhantomData directly in Bridge --- library/proc_macro/src/bridge/mod.rs | 5 +++-- library/proc_macro/src/bridge/server.rs | 9 ++++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs index d1f7d84991d66..f7c9df6564f87 100644 --- a/library/proc_macro/src/bridge/mod.rs +++ b/library/proc_macro/src/bridge/mod.rs @@ -220,8 +220,6 @@ 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,6 +231,9 @@ pub struct Bridge<'a> { /// If 'true', always invoke the default panic hook force_show_panics: bool, + + // Prevent Send and Sync impls + _marker: marker::PhantomData<*mut ()>, } #[forbid(unsafe_code)] 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, );