Skip to content

Commit 1fc7767

Browse files
Use cfg(target_has_atomic) to conditionally compile impls
This makes this crate a lot more useful to targets where not all atomic sizes were supported. Previously, this crate would simply not compile on those targets, because (e.g.) `AtomicU64` was not found. With this commit, `u64` just does not implement `Atom` or `PrimitiveAtom` on those targets. (And neither does `f64` implement `Atom` anymore.) This is not yet an optimal solution, as platform support for atomics are not just differentiated by size, but also by whether they support some features. Sadly, for those, there are no `cfg` flags available on stable yet. This commit raises the MSRV to 1.60
1 parent 1c5ebbf commit 1fc7767

File tree

2 files changed

+31
-22
lines changed

2 files changed

+31
-22
lines changed

src/impls.rs

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -247,12 +247,16 @@ macro_rules! integer_pass_through_methods {
247247
}
248248

249249
// ----- `*mut T` and `AtomicPtr` -----
250+
#[cfg(target_has_atomic = "ptr")]
250251
impl<T> Atom for *mut T {
251252
type Repr = Self;
252253
id_pack_unpack!();
253254
}
254255

256+
#[cfg(target_has_atomic = "ptr")]
255257
impl<T> sealed::Sealed for *mut T {}
258+
259+
#[cfg(target_has_atomic = "ptr")]
256260
impl<T> PrimitiveAtom for *mut T {
257261
type Impl = atomic::AtomicPtr<T>;
258262
pass_through_methods!(atomic::AtomicPtr<T>);
@@ -305,19 +309,20 @@ macro_rules! impl_std_atomics {
305309
(@int_methods $ty:ty, $non_zero_ty:ident, $impl_ty:ident, false) => {};
306310
}
307311

308-
impl_std_atomics!(bool, _Dummy, AtomicBool, false);
309-
impl_std_atomics!(u8, NonZeroU8, AtomicU8, true);
310-
impl_std_atomics!(i8, NonZeroI8, AtomicI8, true);
311-
impl_std_atomics!(u16, NonZeroU16, AtomicU16, true);
312-
impl_std_atomics!(i16, NonZeroI16, AtomicI16, true);
313-
impl_std_atomics!(u32, NonZeroU32, AtomicU32, true);
314-
impl_std_atomics!(i32, NonZeroI32, AtomicI32, true);
315-
impl_std_atomics!(u64, NonZeroU64, AtomicU64, true);
316-
impl_std_atomics!(i64, NonZeroI64, AtomicI64, true);
317-
impl_std_atomics!(usize, NonZeroUsize, AtomicUsize, true);
318-
impl_std_atomics!(isize, NonZeroIsize, AtomicIsize, true);
312+
#[cfg(target_has_atomic = "8")] impl_std_atomics!(bool, _Dummy, AtomicBool, false);
313+
#[cfg(target_has_atomic = "8")] impl_std_atomics!(u8, NonZeroU8, AtomicU8, true);
314+
#[cfg(target_has_atomic = "8")] impl_std_atomics!(i8, NonZeroI8, AtomicI8, true);
315+
#[cfg(target_has_atomic = "16")] impl_std_atomics!(u16, NonZeroU16, AtomicU16, true);
316+
#[cfg(target_has_atomic = "16")] impl_std_atomics!(i16, NonZeroI16, AtomicI16, true);
317+
#[cfg(target_has_atomic = "32")] impl_std_atomics!(u32, NonZeroU32, AtomicU32, true);
318+
#[cfg(target_has_atomic = "32")] impl_std_atomics!(i32, NonZeroI32, AtomicI32, true);
319+
#[cfg(target_has_atomic = "64")] impl_std_atomics!(u64, NonZeroU64, AtomicU64, true);
320+
#[cfg(target_has_atomic = "64")] impl_std_atomics!(i64, NonZeroI64, AtomicI64, true);
321+
#[cfg(target_has_atomic = "ptr")] impl_std_atomics!(usize, NonZeroUsize, AtomicUsize, true);
322+
#[cfg(target_has_atomic = "ptr")] impl_std_atomics!(isize, NonZeroIsize, AtomicIsize, true);
319323

320324
// ----- Implementations for non-atomic primitive types ------------------------------------------
325+
#[cfg(target_has_atomic = "32")]
321326
impl Atom for f32 {
322327
type Repr = u32;
323328
fn pack(self) -> Self::Repr {
@@ -328,6 +333,7 @@ impl Atom for f32 {
328333
}
329334
}
330335

336+
#[cfg(target_has_atomic = "64")]
331337
impl Atom for f64 {
332338
type Repr = u64;
333339
fn pack(self) -> Self::Repr {
@@ -338,6 +344,7 @@ impl Atom for f64 {
338344
}
339345
}
340346

347+
#[cfg(target_has_atomic = "32")]
341348
impl Atom for char {
342349
type Repr = u32;
343350
fn pack(self) -> Self::Repr {
@@ -362,6 +369,7 @@ impl<T: Atom> Atom for Wrapping<T> {
362369
impl<T: AtomLogic> AtomLogic for Wrapping<T> where T::Repr: PrimitiveAtomLogic {}
363370

364371

372+
#[cfg(target_has_atomic = "ptr")]
365373
impl<T> Atom for core::ptr::NonNull<T> {
366374
type Repr = *mut T;
367375
fn pack(self) -> Self::Repr {
@@ -373,6 +381,7 @@ impl<T> Atom for core::ptr::NonNull<T> {
373381
}
374382
}
375383

384+
#[cfg(target_has_atomic = "ptr")]
376385
impl<T> Atom for Option<core::ptr::NonNull<T>> {
377386
type Repr = *mut T;
378387
fn pack(self) -> Self::Repr {
@@ -409,16 +418,16 @@ macro_rules! impl_option_non_zero {
409418
};
410419
}
411420

412-
impl_option_non_zero!(NonZeroU8 = u8);
413-
impl_option_non_zero!(NonZeroI8 = i8);
414-
impl_option_non_zero!(NonZeroU16 = u16);
415-
impl_option_non_zero!(NonZeroI16 = i16);
416-
impl_option_non_zero!(NonZeroU32 = u32);
417-
impl_option_non_zero!(NonZeroI32 = i32);
418-
impl_option_non_zero!(NonZeroU64 = u64);
419-
impl_option_non_zero!(NonZeroI64 = i64);
420-
impl_option_non_zero!(NonZeroUsize = usize);
421-
impl_option_non_zero!(NonZeroIsize = isize);
421+
#[cfg(target_has_atomic = "8")] impl_option_non_zero!(NonZeroU8 = u8);
422+
#[cfg(target_has_atomic = "8")] impl_option_non_zero!(NonZeroI8 = i8);
423+
#[cfg(target_has_atomic = "16")] impl_option_non_zero!(NonZeroU16 = u16);
424+
#[cfg(target_has_atomic = "16")] impl_option_non_zero!(NonZeroI16 = i16);
425+
#[cfg(target_has_atomic = "32")] impl_option_non_zero!(NonZeroU32 = u32);
426+
#[cfg(target_has_atomic = "32")] impl_option_non_zero!(NonZeroI32 = i32);
427+
#[cfg(target_has_atomic = "64")] impl_option_non_zero!(NonZeroU64 = u64);
428+
#[cfg(target_has_atomic = "64")] impl_option_non_zero!(NonZeroI64 = i64);
429+
#[cfg(target_has_atomic = "ptr")] impl_option_non_zero!(NonZeroUsize = usize);
430+
#[cfg(target_has_atomic = "ptr")] impl_option_non_zero!(NonZeroIsize = isize);
422431

423432
/// This is just a dummy module to have doc tests.
424433
///

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ pub trait Atom {
206206
/// If your type also implements `AtomLogic` or `AtomInteger`, results of
207207
/// those operations might get passed to `unpack`. Furthermore, this method
208208
/// can be called by anyone. So at the very least, you have to make sure
209-
/// that invalid input values do not lead to undefined behavior(e.g. memory
209+
/// that invalid input values do not lead to undefined behavior (e.g. memory
210210
/// unsafety)!
211211
fn unpack(src: Self::Repr) -> Self;
212212
}

0 commit comments

Comments
 (0)