From 5ac7a90089dbe3807934deebc6d7b403e60eba05 Mon Sep 17 00:00:00 2001 From: yvt Date: Sun, 7 Jun 2020 14:42:46 +0900 Subject: [PATCH 1/2] Implement an alternative solution for the variance issue not involving `Mutex` --- src/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 3d6da24..6f2bec5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -72,7 +72,6 @@ //! } //! ``` -use std::sync::Mutex; use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use std::marker::PhantomData; use std::fmt; @@ -82,7 +81,8 @@ use std::default::Default; #[repr(C)] pub struct AtomicRef<'a, T: 'a> { data: AtomicUsize, - _marker: PhantomData>, + // Make `AtomicRef` invariant over `'a` and `T` + _marker: PhantomData<&'a mut &'a mut T>, } /// You will probably never need to use this type. It exists mostly for internal From cb4e7c5cb94ef83374bfd31073f230e288880211 Mon Sep 17 00:00:00 2001 From: yvt Date: Sun, 7 Jun 2020 14:48:03 +0900 Subject: [PATCH 2/2] Get rid of dependency on `std` --- src/lib.rs | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 6f2bec5..777475a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,11 +71,12 @@ //! assert!(res); //! } //! ``` +#![no_std] -use std::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; -use std::marker::PhantomData; -use std::fmt; -use std::default::Default; +use core::sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; +use core::marker::PhantomData; +use core::fmt; +use core::default::Default; /// A mutable Option<&'a, T> type which can be safely shared between threads. #[repr(C)] @@ -104,6 +105,11 @@ pub const ATOMIC_U8_REF_INIT: AtomicRef<'static, u8> = AtomicRef { _marker: PhantomData, }; +/// Re-export `core` for `static_atomic_ref!` (which may be used in a +/// non-`no_std` crate, where `core` is unavailable). +#[doc(hidden)] +pub use core::{mem as core_mem, ops as core_ops}; + /// A macro to define a statically allocated `AtomicRef<'static, T>` which is /// initialized to `None`. /// @@ -134,12 +140,12 @@ macro_rules! static_atomic_ref { }; (@$VIS:ident, $(#[$attr:meta])* static $N:ident : $T:ty; $($t:tt)*) => { static_atomic_ref!(@MAKE TY, $VIS, $(#[$attr])*, $N); - impl ::std::ops::Deref for $N { + impl $crate::core_ops::Deref for $N { type Target = $crate::AtomicRef<'static, $T>; #[allow(unsafe_code)] fn deref<'a>(&'a self) -> &'a $crate::AtomicRef<'static, $T> { static STORAGE: $crate::AtomicRef<'static, u8> = $crate::ATOMIC_U8_REF_INIT; - unsafe { ::std::mem::transmute(&STORAGE) } + unsafe { $crate::core_mem::transmute(&STORAGE) } } } static_atomic_ref!($($t)*); @@ -403,7 +409,7 @@ impl<'a, T> Default for AtomicRef<'a, T> { #[cfg(test)] mod tests { - use std::sync::atomic::Ordering; + use core::sync::atomic::Ordering; static_atomic_ref! { static FOO: AtomicRef;