Skip to content
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
8 changes: 6 additions & 2 deletions library/alloc/src/sync.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,8 +389,12 @@ struct ArcInner<T: ?Sized> {
strong: Atomic<usize>,

// the value usize::MAX acts as a sentinel for temporarily "locking" the
// ability to upgrade weak pointers or downgrade strong ones; this is used
// to avoid races in `make_mut` and `get_mut`.
// weak count, preventing `Arc::downgrade` from racing to create new
// `Weak` references. `Arc::is_unique` (which backs `Arc::get_mut`)
// needs to observe both the strong and weak counts as indicating
// uniqueness in one logical atomic step; since they live in separate
// atomic words, it locks the weak count while reading the strong
// count to keep the two reads consistent.
weak: Atomic<usize>,

data: T,
Expand Down
10 changes: 8 additions & 2 deletions library/proc_macro/src/bridge/client.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
//! Client-side types.

use std::cell::RefCell;

use super::*;
use std::ops::{Bound, Range};
use std::sync::Once;
use std::{fmt, mem, panic};

use crate::bridge::{
ApiTags, BridgeConfig, Buffer, Decode, Diagnostic, Encode, ExpnGlobals, Literal, PanicMessage,
TokenTree, closure, handle,
};

pub(crate) struct TokenStream {
handle: handle::Handle,
Expand Down
7 changes: 4 additions & 3 deletions library/proc_macro/src/bridge/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,8 @@
#![deny(unsafe_code)]

use std::hash::Hash;
use std::marker;
use std::ops::{Bound, Range};
use std::sync::Once;
use std::{fmt, marker, mem, panic, thread};

use crate::{Delimiter, Level};

Expand Down Expand Up @@ -100,6 +99,8 @@ mod handle;
#[macro_use]
#[forbid(unsafe_code)]
mod rpc;
#[forbid(unsafe_code)]
mod panic_message;
#[allow(unsafe_code)]
mod selfless_reify;
#[forbid(unsafe_code)]
Expand All @@ -108,7 +109,7 @@ pub mod server;
mod symbol;

use buffer::Buffer;
pub use rpc::PanicMessage;
pub use panic_message::PanicMessage;
use rpc::{Decode, Encode};

/// Configuration for establishing an active connection between a server and a
Expand Down
71 changes: 71 additions & 0 deletions library/proc_macro/src/bridge/panic_message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
use std::any::Any;

use crate::bridge::{Buffer, Decode, Encode};

/// Simplified version of panic payloads, ignoring
/// types other than `&'static str` and `String`.
pub enum PanicMessage {
StaticStr(&'static str),
String(String),
Unknown,
}

impl From<Box<dyn Any + Send>> for PanicMessage {
fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
if let Some(s) = payload.downcast_ref::<&'static str>() {
return PanicMessage::StaticStr(s);
}
if let Ok(s) = payload.downcast::<String>() {
return PanicMessage::String(*s);
}
PanicMessage::Unknown
}
}

impl From<PanicMessage> for Box<dyn Any + Send> {
fn from(val: PanicMessage) -> Self {
match val {
PanicMessage::StaticStr(s) => Box::new(s),
PanicMessage::String(s) => Box::new(s),
PanicMessage::Unknown => {
struct UnknownPanicMessage;
Box::new(UnknownPanicMessage)
}
}
}
}

impl PanicMessage {
pub fn as_str(&self) -> Option<&str> {
match self {
PanicMessage::StaticStr(s) => Some(s),
PanicMessage::String(s) => Some(s),
PanicMessage::Unknown => None,
}
}

pub fn into_string(self) -> Option<String> {
match self {
PanicMessage::StaticStr(s) => Some(s.into()),
PanicMessage::String(s) => Some(s),
PanicMessage::Unknown => None,
}
}
}

impl<S> Encode<S> for PanicMessage {
#[inline]
fn encode(self, w: &mut Buffer, s: &mut S) {
self.as_str().encode(w, s);
}
}

impl<S> Decode<'_, '_, S> for PanicMessage {
#[inline]
fn decode(r: &mut &[u8], s: &mut S) -> Self {
match Option::<String>::decode(r, s) {
Some(s) => PanicMessage::String(s),
None => PanicMessage::Unknown,
}
}
}
69 changes: 0 additions & 69 deletions library/proc_macro/src/bridge/rpc.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
//! Serialization for client-server communication.

use std::any::Any;
use std::io::Write;
use std::num::NonZero;

Expand Down Expand Up @@ -259,71 +258,3 @@ impl<'a, S, T: for<'s> Decode<'a, 's, S>> Decode<'a, '_, S> for Vec<T> {
vec
}
}

/// Simplified version of panic payloads, ignoring
/// types other than `&'static str` and `String`.
pub enum PanicMessage {
StaticStr(&'static str),
String(String),
Unknown,
}

impl From<Box<dyn Any + Send>> for PanicMessage {
fn from(payload: Box<dyn Any + Send + 'static>) -> Self {
if let Some(s) = payload.downcast_ref::<&'static str>() {
return PanicMessage::StaticStr(s);
}
if let Ok(s) = payload.downcast::<String>() {
return PanicMessage::String(*s);
}
PanicMessage::Unknown
}
}

impl From<PanicMessage> for Box<dyn Any + Send> {
fn from(val: PanicMessage) -> Self {
match val {
PanicMessage::StaticStr(s) => Box::new(s),
PanicMessage::String(s) => Box::new(s),
PanicMessage::Unknown => {
struct UnknownPanicMessage;
Box::new(UnknownPanicMessage)
}
}
}
}

impl PanicMessage {
pub fn as_str(&self) -> Option<&str> {
match self {
PanicMessage::StaticStr(s) => Some(s),
PanicMessage::String(s) => Some(s),
PanicMessage::Unknown => None,
}
}

pub fn into_string(self) -> Option<String> {
match self {
PanicMessage::StaticStr(s) => Some(s.into()),
PanicMessage::String(s) => Some(s),
PanicMessage::Unknown => None,
}
}
}

impl<S> Encode<S> for PanicMessage {
#[inline]
fn encode(self, w: &mut Buffer, s: &mut S) {
self.as_str().encode(w, s);
}
}

impl<S> Decode<'_, '_, S> for PanicMessage {
#[inline]
fn decode(r: &mut &[u8], s: &mut S) -> Self {
match Option::<String>::decode(r, s) {
Some(s) => PanicMessage::String(s),
None => PanicMessage::Unknown,
}
}
}
8 changes: 7 additions & 1 deletion library/proc_macro/src/bridge/server.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
//! Server-side traits.

use std::cell::Cell;
use std::hash::Hash;
use std::ops::{Bound, Range};
use std::sync::atomic::AtomicU32;
use std::sync::mpsc;
use std::{panic, thread};

use super::*;
use crate::bridge::{
ApiTags, BridgeConfig, Buffer, Decode, Diagnostic, Encode, ExpnGlobals, Literal, Mark, Marked,
PanicMessage, TokenTree, client, handle,
};

pub(super) struct HandleStore<S: Server> {
token_stream: handle::OwnedStore<MarkedTokenStream<S>>,
Expand Down
3 changes: 2 additions & 1 deletion library/proc_macro/src/bridge/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@
//! proc_macro, this module should probably be removed or simplified.

use std::cell::RefCell;
use std::fmt;
use std::num::NonZero;

use super::*;
use crate::bridge::{Buffer, Decode, Encode, Mark, arena, client, fxhash, server};

/// Handle for a symbol string stored within the Interner.
#[derive(Copy, Clone, PartialEq, Eq, Hash)]
Expand Down
Loading