diff --git a/src/lib.rs b/src/lib.rs index 1b5fa52..abd00c5 100755 --- a/src/lib.rs +++ b/src/lib.rs @@ -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, @@ -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, + } } } @@ -114,13 +111,13 @@ fn enum_from_usize(ident: &Ident, variants: impl IntoIterator) - 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}`]. @@ -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)), + } } } } @@ -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()) } } } @@ -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); } } } @@ -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()) } } } @@ -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)) } } } @@ -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) } } } @@ -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)) } } } @@ -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 @@ -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), @@ -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), @@ -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() { @@ -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);