Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce the amount of unstable features used in libproc_macro #95308

Merged
merged 6 commits into from
Apr 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 31 additions & 15 deletions library/proc_macro/src/bridge/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

use super::*;

use std::marker::PhantomData;

macro_rules! define_handles {
(
'owned: $($oty:ident,)*
Expand Down Expand Up @@ -45,20 +47,25 @@ macro_rules! define_handles {

$(
#[repr(C)]
pub(crate) struct $oty(handle::Handle);
impl !Send for $oty {}
impl !Sync for $oty {}
Mark-Simulacrum marked this conversation as resolved.
Show resolved Hide resolved
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<S> Encode<S> 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);
}
Expand All @@ -74,7 +81,7 @@ macro_rules! define_handles {

impl<S> Encode<S> for &$oty {
fn encode(self, w: &mut Writer, s: &mut S) {
self.0.encode(w, s);
self.handle.encode(w, s);
}
}

Expand All @@ -88,7 +95,7 @@ macro_rules! define_handles {

impl<S> Encode<S> for &mut $oty {
fn encode(self, w: &mut Writer, s: &mut S) {
self.0.encode(w, s);
self.handle.encode(w, s);
}
}

Expand All @@ -113,21 +120,26 @@ macro_rules! define_handles {

impl<S> 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,
}
}
}
)*

$(
#[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<S> Encode<S> for $ity {
fn encode(self, w: &mut Writer, s: &mut S) {
self.0.encode(w, s);
self.handle.encode(w, s);
}
}

Expand All @@ -149,7 +161,10 @@ macro_rules! define_handles {

impl<S> 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,
}
}
}
)*
Expand Down Expand Up @@ -310,15 +325,16 @@ 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,
});
if show {
prev(info)
}
});
}));
});

BRIDGE_STATE.with(|state| state.set(BridgeState::Connected(self), f))
Expand Down
19 changes: 9 additions & 10 deletions library/proc_macro/src/bridge/closure.rs
Original file line number Diff line number Diff line change
@@ -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;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The rust-analyzer copies turn Env into a regular struct too, but don't replace &mut Env with *mut Env, which is UB according to stacked borrows.


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<A, R, F: FnMut(A) -> R>(env: &mut Env, arg: A) -> R {
unsafe extern "C" fn call<A, R, F: FnMut(A) -> R>(env: *mut Env, arg: A) -> R {
(*(env as *mut _ as *mut F))(arg)
}
Closure { call: call::<A, R, F>, env: unsafe { &mut *(f as *mut _ as *mut Env) } }
Closure { call: call::<A, R, F>, env: f as *mut _ as *mut Env, _marker: PhantomData }
}
}

Expand Down
6 changes: 3 additions & 3 deletions library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
9 changes: 8 additions & 1 deletion library/proc_macro/src/bridge/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
)
}
Expand Down Expand Up @@ -189,6 +194,7 @@ impl ExecutionStrategy for CrossThread1 {
cached_buffer: input,
dispatch: (&mut dispatch).into(),
force_show_panics,
_marker: marker::PhantomData,
},
client_data,
)
Expand Down Expand Up @@ -241,6 +247,7 @@ impl ExecutionStrategy for CrossThread2 {
cached_buffer: input,
dispatch: (&mut dispatch).into(),
force_show_panics,
_marker: marker::PhantomData,
},
client_data,
);
Expand Down
6 changes: 3 additions & 3 deletions library/proc_macro/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,20 @@
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)]
#![cfg_attr(bootstrap, feature(const_fn_trait_bound))]
#![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")]
Expand Down