Skip to content
Open
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
51 changes: 22 additions & 29 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
#![forbid(
rust_2018_idioms,
future_incompatible,
elided_lifetimes_in_paths,
unsafe_code
)]
#![forbid(rust_2018_idioms, future_incompatible, elided_lifetimes_in_paths, unsafe_code)]
#![warn(
missing_debug_implementations,
missing_docs,
Expand Down Expand Up @@ -78,7 +73,9 @@ This type uses an `AtomicUsize` to store the enum value.

quote! {
#[doc = #atomic_ident_docs]
#vis struct #atomic_ident(core::sync::atomic::AtomicUsize);
#vis struct #atomic_ident {
inner_do_not_use_directly: core::sync::atomic::AtomicUsize,
}
}
}

Expand Down Expand Up @@ -114,13 +111,13 @@ fn enum_from_usize(ident: &Ident, variants: impl IntoIterator<Item = Variant>) -

match val {
#(#variants_back)*
_ => panic!("Invalid enum discriminant"),
_ => unsafe { core::hint::unreachable_unchecked() },
}
}
}
}

fn atomic_enum_new(ident: &Ident, atomic_ident: &Ident) -> TokenStream2 {
fn atomic_enum_new(ident: &Ident) -> TokenStream2 {
let atomic_ident_docs = format!(
"Creates a new atomic [`{0}`].

Expand All @@ -130,8 +127,10 @@ fn atomic_enum_new(ident: &Ident, atomic_ident: &Ident) -> TokenStream2 {

quote! {
#[doc = #atomic_ident_docs]
pub const fn new(v: #ident) -> #atomic_ident {
#atomic_ident(core::sync::atomic::AtomicUsize::new(Self::to_usize(v)))
pub const fn new(v: #ident) -> Self {
Self {
inner_do_not_use_directly: core::sync::atomic::AtomicUsize::new(Self::to_usize(v)),
}
}
}
}
Expand All @@ -142,7 +141,7 @@ fn atomic_enum_into_inner(ident: &Ident) -> TokenStream2 {
///
/// This is safe because passing self by value guarantees that no other threads are concurrently accessing the atomic data.
pub fn into_inner(self) -> #ident {
Self::from_usize(self.0.into_inner())
Self::from_usize(self.inner_do_not_use_directly.into_inner())
}
}
}
Expand All @@ -153,7 +152,7 @@ fn atomic_enum_set(ident: &Ident) -> TokenStream2 {
///
/// This is safe because the mutable reference guarantees that no other threads are concurrently accessing the atomic data.
pub fn set(&mut self, v: #ident) {
*self.0.get_mut() = Self::to_usize(v);
*self.inner_do_not_use_directly.get_mut() = Self::to_usize(v);
}
}
}
Expand All @@ -164,7 +163,7 @@ fn atomic_enum_get(ident: &Ident) -> TokenStream2 {
///
/// This is safe because the mutable reference guarantees that no other threads are concurrently accessing the atomic data.
pub fn get(&mut self) -> #ident {
Self::from_usize(*self.0.get_mut())
Self::from_usize(*self.inner_do_not_use_directly.get_mut())
}
}
}
Expand Down Expand Up @@ -192,7 +191,7 @@ fn atomic_enum_load(ident: &Ident) -> TokenStream2 {
///
/// Panics if order is `Release` or `AcqRel`.
pub fn load(&self, order: core::sync::atomic::Ordering) -> #ident {
Self::from_usize(self.0.load(order))
Self::from_usize(self.inner_do_not_use_directly.load(order))
}
}
}
Expand All @@ -207,7 +206,7 @@ fn atomic_enum_store(ident: &Ident) -> TokenStream2 {
///
/// Panics if order is `Acquire` or `AcqRel`.
pub fn store(&self, val: #ident, order: core::sync::atomic::Ordering) {
self.0.store(Self::to_usize(val), order)
self.inner_do_not_use_directly.store(Self::to_usize(val), order)
}
}
}
Expand All @@ -221,7 +220,7 @@ fn atomic_enum_swap(ident: &Ident) -> TokenStream2 {
/// All ordering modes are possible. Note that using `Acquire` makes the store part of this operation `Relaxed`,
/// and using `Release` makes the load part `Relaxed`.
pub fn swap(&self, val: #ident, order: core::sync::atomic::Ordering) -> #ident {
Self::from_usize(self.0.swap(Self::to_usize(val), order))
Self::from_usize(self.inner_do_not_use_directly.swap(Self::to_usize(val), order))
}
}
}
Expand All @@ -245,7 +244,7 @@ fn atomic_enum_compare_and_swap(ident: &Ident) -> TokenStream2 {
new: #ident,
order: core::sync::atomic::Ordering
) -> #ident {
Self::from_usize(self.0.compare_and_swap(
Self::from_usize(self.inner_do_not_use_directly.compare_and_swap(
Self::to_usize(current),
Self::to_usize(new),
order
Expand Down Expand Up @@ -274,7 +273,7 @@ fn atomic_enum_compare_exchange(ident: &Ident) -> TokenStream2 {
success: core::sync::atomic::Ordering,
failure: core::sync::atomic::Ordering
) -> core::result::Result<#ident, #ident> {
self.0
self.inner_do_not_use_directly
.compare_exchange(
Self::to_usize(current),
Self::to_usize(new),
Expand Down Expand Up @@ -308,7 +307,7 @@ fn atomic_enum_compare_exchange_weak(ident: &Ident) -> TokenStream2 {
success: core::sync::atomic::Ordering,
failure: core::sync::atomic::Ordering
) -> core::result::Result<#ident, #ident> {
self.0
self.inner_do_not_use_directly
.compare_exchange_weak(
Self::to_usize(current),
Self::to_usize(new),
Expand Down Expand Up @@ -378,14 +377,8 @@ fn debug_impl(atomic_ident: &Ident) -> TokenStream2 {
/// ```
pub fn atomic_enum(args: TokenStream, input: TokenStream) -> TokenStream {
// Parse the input
let ItemEnum {
attrs,
vis,
ident,
generics,
variants,
..
} = parse_macro_input!(input as ItemEnum);
let ItemEnum { attrs, vis, ident, generics, variants, .. } =
parse_macro_input!(input as ItemEnum);

// We only support C-style enums: No generics, no fields
if !generics.params.is_empty() {
Expand Down Expand Up @@ -414,7 +407,7 @@ pub fn atomic_enum(args: TokenStream, input: TokenStream) -> TokenStream {
// Write the impl block for the atomic wrapper
let enum_to_usize = enum_to_usize(&ident);
let enum_from_usize = enum_from_usize(&ident, variants);
let atomic_enum_new = atomic_enum_new(&ident, &atomic_ident);
let atomic_enum_new = atomic_enum_new(&ident);
let atomic_enum_into_inner = atomic_enum_into_inner(&ident);
let atomic_enum_set = atomic_enum_set(&ident);
let atomic_enum_get = atomic_enum_get(&ident);
Expand Down