diff --git a/crossbeam-utils/Cargo.toml b/crossbeam-utils/Cargo.toml index 1bd0323d6..29bdc7b6f 100644 --- a/crossbeam-utils/Cargo.toml +++ b/crossbeam-utils/Cargo.toml @@ -31,7 +31,6 @@ nightly = [] [dependencies] cfg-if = "1" -const_fn = "0.4" lazy_static = { version = "1.4.0", optional = true } [build-dependencies] @@ -39,4 +38,3 @@ autocfg = "1.0.0" [dev-dependencies] rand = "0.7.3" -rustversion = "1.0" diff --git a/crossbeam-utils/src/atomic/atomic_cell.rs b/crossbeam-utils/src/atomic/atomic_cell.rs index 82936e701..e8f6804cf 100644 --- a/crossbeam-utils/src/atomic/atomic_cell.rs +++ b/crossbeam-utils/src/atomic/atomic_cell.rs @@ -12,7 +12,6 @@ use core::sync::atomic::{self, AtomicBool, Ordering}; use std::panic::{RefUnwindSafe, UnwindSafe}; use super::seq_lock::SeqLock; -use const_fn::const_fn; /// A thread-safe mutable memory location. /// @@ -106,7 +105,6 @@ impl AtomicCell { /// // operations on them will have to use global locks for synchronization. /// assert_eq!(AtomicCell::<[u8; 1000]>::is_lock_free(), false); /// ``` - #[const_fn("1.46")] pub const fn is_lock_free() -> bool { atomic_is_lock_free::() } @@ -611,10 +609,9 @@ impl fmt::Debug for AtomicCell { } /// Returns `true` if values of type `A` can be transmuted into values of type `B`. -#[const_fn("1.46")] const fn can_transmute() -> bool { // Sizes must be equal, but alignment of `A` must be greater or equal than that of `B`. - mem::size_of::() == mem::size_of::() && mem::align_of::() >= mem::align_of::() + (mem::size_of::() == mem::size_of::()) & (mem::align_of::() >= mem::align_of::()) } /// Returns a reference to the global lock associated with the `AtomicCell` at address `addr`. @@ -810,6 +807,8 @@ macro_rules! atomic { atomic!(@check, $t, atomic::AtomicU32, $a, $atomic_op); #[cfg(has_atomic_u64)] atomic!(@check, $t, atomic::AtomicU64, $a, $atomic_op); + #[cfg(has_atomic_u128)] + atomic!(@check, $t, atomic::AtomicU128, $a, $atomic_op); break $fallback_op; } @@ -817,9 +816,20 @@ macro_rules! atomic { } /// Returns `true` if operations on `AtomicCell` are lock-free. -#[const_fn("1.46")] const fn atomic_is_lock_free() -> bool { - atomic! { T, _a, true, false } + // HACK(taiki-e): This is equivalent to `atomic! { T, _a, true, false }`, but can be used in const fn even in Rust 1.36. + let is_lock_free = can_transmute::() | can_transmute::(); + #[cfg(has_atomic_u8)] + let is_lock_free = is_lock_free | can_transmute::(); + #[cfg(has_atomic_u16)] + let is_lock_free = is_lock_free | can_transmute::(); + #[cfg(has_atomic_u32)] + let is_lock_free = is_lock_free | can_transmute::(); + #[cfg(has_atomic_u64)] + let is_lock_free = is_lock_free | can_transmute::(); + #[cfg(has_atomic_u128)] + let is_lock_free = is_lock_free | can_transmute::(); + is_lock_free } /// Atomically reads data from `src`. diff --git a/crossbeam-utils/tests/atomic_cell.rs b/crossbeam-utils/tests/atomic_cell.rs index 349fdf057..3d91d81d6 100644 --- a/crossbeam-utils/tests/atomic_cell.rs +++ b/crossbeam-utils/tests/atomic_cell.rs @@ -22,11 +22,10 @@ fn is_lock_free() { assert_eq!(AtomicCell::::is_lock_free(), cfg!(has_atomic_u128)); } -#[rustversion::since(1.46)] #[test] fn const_is_lock_free() { - const _: bool = AtomicCell::::is_lock_free(); - const _: bool = AtomicCell::::is_lock_free(); + const _U: bool = AtomicCell::::is_lock_free(); + const _I: bool = AtomicCell::::is_lock_free(); } #[test]