Skip to content

Commit

Permalink
Make into_inner const fn on Rust 1.56+
Browse files Browse the repository at this point in the history
  • Loading branch information
taiki-e committed Apr 7, 2024
1 parent 7e70c47 commit dee1f89
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 99 deletions.
5 changes: 0 additions & 5 deletions bench/benches/imp/spinlock_fallback.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,6 @@ macro_rules! atomic_int {
unsafe { &mut *self.v.get() }
}

#[inline]
pub(crate) fn into_inner(self) -> $int_type {
self.v.into_inner()
}

#[inline]
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
pub(crate) fn load(&self, order: Ordering) -> $int_type {
Expand Down
4 changes: 4 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,10 @@ fn main() {
if !version.probe(52, 2021, 3, 10) {
println!("cargo:rustc-cfg=portable_atomic_no_unsafe_op_in_unsafe_fn");
}
// const_transmute stabilized in Rust 1.56 (nightly-2021-07-29): https://github.com/rust-lang/rust/pull/85769
if !version.probe(56, 2021, 7, 28) {
println!("cargo:rustc-cfg=portable_atomic_no_const_transmute");
}
// https://github.com/rust-lang/rust/pull/84662 merged in Rust 1.56 (nightly-2021-08-02).
if !version.probe(56, 2021, 8, 1) {
println!("cargo:rustc-cfg=portable_atomic_no_core_unwind_safe");
Expand Down
5 changes: 0 additions & 5 deletions src/imp/arm_linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,6 @@ macro_rules! atomic64 {
unsafe { &mut *self.v.get() }
}

#[inline]
pub(crate) fn into_inner(self) -> $int_type {
self.v.into_inner()
}

#[inline]
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
pub(crate) fn load(&self, order: Ordering) -> $int_type {
Expand Down
5 changes: 0 additions & 5 deletions src/imp/atomic128/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,6 @@ macro_rules! atomic128 {
unsafe { &mut *self.v.get() }
}

#[inline]
pub(crate) fn into_inner(self) -> $int_type {
self.v.into_inner()
}

#[inline]
#[cfg_attr(
any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),
Expand Down
8 changes: 0 additions & 8 deletions src/imp/core_atomic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,6 @@ impl<T> AtomicPtr<T> {
self.inner.get_mut()
}
#[inline]
pub(crate) fn into_inner(self) -> *mut T {
self.inner.into_inner()
}
#[inline]
#[cfg_attr(
any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),
track_caller
Expand Down Expand Up @@ -174,10 +170,6 @@ macro_rules! atomic_int {
self.inner.get_mut()
}
#[inline]
pub(crate) fn into_inner(self) -> $int_type {
self.inner.into_inner()
}
#[inline]
#[cfg_attr(
any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),
track_caller
Expand Down
5 changes: 0 additions & 5 deletions src/imp/fallback/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,6 @@ macro_rules! atomic {
unsafe { &mut *self.v.get() }
}

#[inline]
pub(crate) fn into_inner(self) -> $int_type {
self.v.into_inner()
}

#[inline]
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
pub(crate) fn load(&self, order: Ordering) -> $int_type {
Expand Down
5 changes: 0 additions & 5 deletions src/imp/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,6 @@ macro_rules! atomic_float {
unsafe { &mut *self.v.get() }
}

#[inline]
pub(crate) fn into_inner(self) -> $float_type {
self.v.into_inner()
}

#[inline]
#[cfg_attr(
any(all(debug_assertions, not(portable_atomic_no_track_caller)), miri),
Expand Down
10 changes: 0 additions & 10 deletions src/imp/interrupt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -139,11 +139,6 @@ impl<T> AtomicPtr<T> {
unsafe { &mut *self.p.get() }
}

#[inline]
pub(crate) fn into_inner(self) -> *mut T {
self.p.into_inner()
}

#[inline]
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
pub(crate) fn load(&self, order: Ordering) -> *mut T {
Expand Down Expand Up @@ -276,11 +271,6 @@ macro_rules! atomic_int {
unsafe { &mut *self.v.get() }
}

#[inline]
pub(crate) fn into_inner(self) -> $int_type {
self.v.into_inner()
}

#[inline]
pub(crate) const fn as_ptr(&self) -> *mut $int_type {
self.v.get()
Expand Down
6 changes: 0 additions & 6 deletions src/imp/msp430.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,6 @@ macro_rules! atomic {
unsafe { &mut *self.v.get() }
}

#[cfg(test)]
#[inline]
pub(crate) fn into_inner(self) -> $value_type {
self.v.into_inner()
}

#[inline]
#[cfg_attr(all(debug_assertions, not(portable_atomic_no_track_caller)), track_caller)]
pub(crate) fn load(&self, order: Ordering) -> $value_type {
Expand Down
5 changes: 0 additions & 5 deletions src/imp/riscv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -153,11 +153,6 @@ macro_rules! atomic_load_store {
unsafe { &mut *self.v.get() }
}

#[inline]
pub(crate) fn into_inner(self) -> $value_type {
self.v.into_inner()
}

#[inline]
pub(crate) const fn as_ptr(&self) -> *mut $value_type {
self.v.get()
Expand Down
137 changes: 96 additions & 41 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,22 +686,30 @@ impl AtomicBool {
// TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types.
// https://github.com/rust-lang/rust/issues/76314

/// Consumes the atomic and returns the contained value.
///
/// This is safe because passing `self` by value guarantees that no other threads are
/// concurrently accessing the atomic data.
///
/// # Examples
///
/// ```
/// use portable_atomic::AtomicBool;
///
/// let some_bool = AtomicBool::new(true);
/// assert_eq!(some_bool.into_inner(), true);
/// ```
#[inline]
pub fn into_inner(self) -> bool {
self.v.into_inner() != 0
const_fn! {
const_if: #[cfg(not(portable_atomic_no_const_transmute))];
/// Consumes the atomic and returns the contained value.
///
/// This is safe because passing `self` by value guarantees that no other threads are
/// concurrently accessing the atomic data.
///
/// This is `const fn` on Rust 1.56+.
///
/// # Examples
///
/// ```
/// use portable_atomic::AtomicBool;
///
/// let some_bool = AtomicBool::new(true);
/// assert_eq!(some_bool.into_inner(), true);
/// ```
#[inline]
pub const fn into_inner(self) -> bool {
// SAFETY: AtomicBool and u8 have the same size and in-memory representations,
// so they can be safely transmuted.
// (const UnsafeCell::into_inner is unstable)
unsafe { core::mem::transmute::<AtomicBool, u8>(self) != 0 }
}
}

/// Loads a value from the bool.
Expand Down Expand Up @@ -1544,23 +1552,31 @@ impl<T> AtomicPtr<T> {
// TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types.
// https://github.com/rust-lang/rust/issues/76314

/// Consumes the atomic and returns the contained value.
///
/// This is safe because passing `self` by value guarantees that no other threads are
/// concurrently accessing the atomic data.
///
/// # Examples
///
/// ```
/// use portable_atomic::AtomicPtr;
///
/// let mut data = 5;
/// let atomic_ptr = AtomicPtr::new(&mut data);
/// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5);
/// ```
#[inline]
pub fn into_inner(self) -> *mut T {
self.inner.into_inner()
const_fn! {
const_if: #[cfg(not(portable_atomic_no_const_transmute))];
/// Consumes the atomic and returns the contained value.
///
/// This is safe because passing `self` by value guarantees that no other threads are
/// concurrently accessing the atomic data.
///
/// This is `const fn` on Rust 1.56+.
///
/// # Examples
///
/// ```
/// use portable_atomic::AtomicPtr;
///
/// let mut data = 5;
/// let atomic_ptr = AtomicPtr::new(&mut data);
/// assert_eq!(unsafe { *atomic_ptr.into_inner() }, 5);
/// ```
#[inline]
pub const fn into_inner(self) -> *mut T {
// SAFETY: AtomicPtr<T> and *mut T have the same size and in-memory representations,
// so they can be safely transmuted.
// (const UnsafeCell::into_inner is unstable)
unsafe { core::mem::transmute(self) }
}
}

/// Loads a value from the pointer.
Expand Down Expand Up @@ -2539,12 +2555,40 @@ assert_eq!(some_var.load(Ordering::SeqCst), 5);
// TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types.
// https://github.com/rust-lang/rust/issues/76314

#[cfg(not(portable_atomic_no_const_transmute))]
doc_comment! {
concat!("Consumes the atomic and returns the contained value.
This is safe because passing `self` by value guarantees that no other threads are
concurrently accessing the atomic data.
This is `const fn` on Rust 1.56+.
# Examples
```
use portable_atomic::", stringify!($atomic_type), ";
let some_var = ", stringify!($atomic_type), "::new(5);
assert_eq!(some_var.into_inner(), 5);
```"),
#[inline]
pub const fn into_inner(self) -> $int_type {
// SAFETY: $atomic_type and $int_type have the same size and in-memory representations,
// so they can be safely transmuted.
// (const UnsafeCell::into_inner is unstable)
unsafe { core::mem::transmute(self) }
}
}
#[cfg(portable_atomic_no_const_transmute)]
doc_comment! {
concat!("Consumes the atomic and returns the contained value.
This is safe because passing `self` by value guarantees that no other threads are
concurrently accessing the atomic data.
This is `const fn` on Rust 1.56+.
# Examples
```
Expand All @@ -2555,7 +2599,10 @@ assert_eq!(some_var.into_inner(), 5);
```"),
#[inline]
pub fn into_inner(self) -> $int_type {
self.inner.into_inner()
// SAFETY: $atomic_type and $int_type have the same size and in-memory representations,
// so they can be safely transmuted.
// (const UnsafeCell::into_inner is unstable)
unsafe { core::mem::transmute(self) }
}
}

Expand Down Expand Up @@ -3607,13 +3654,21 @@ This type has the same in-memory representation as the underlying floating point
// TODO: Add from_mut/get_mut_slice/from_mut_slice once it is stable on std atomic types.
// https://github.com/rust-lang/rust/issues/76314

/// Consumes the atomic and returns the contained value.
///
/// This is safe because passing `self` by value guarantees that no other threads are
/// concurrently accessing the atomic data.
#[inline]
pub fn into_inner(self) -> $float_type {
self.inner.into_inner()
const_fn! {
const_if: #[cfg(not(portable_atomic_no_const_transmute))];
/// Consumes the atomic and returns the contained value.
///
/// This is safe because passing `self` by value guarantees that no other threads are
/// concurrently accessing the atomic data.
///
/// This is `const fn` on Rust 1.56+.
#[inline]
pub const fn into_inner(self) -> $float_type {
// SAFETY: $atomic_type and $float_type have the same size and in-memory representations,
// so they can be safely transmuted.
// (const UnsafeCell::into_inner is unstable)
unsafe { core::mem::transmute(self) }
}
}

/// Loads a value from the atomic float.
Expand Down
Loading

0 comments on commit dee1f89

Please sign in to comment.