diff --git a/src/cpu.rs b/src/cpu.rs index cdeea8f475..bd5833ab99 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -20,11 +20,13 @@ pub(crate) fn features() -> Features { } mod features { + use crate::polyfill::NotSend; + /// A witness indicating that CPU features have been detected and cached. /// /// This is a zero-sized type so that it can be "stored" wherever convenient. #[derive(Copy, Clone)] - pub(crate) struct Features(()); + pub(crate) struct Features(NotSend); cfg_if::cfg_if! { if #[cfg(any(target_arch = "aarch64", target_arch = "arm", @@ -33,19 +35,21 @@ mod features { // SAFETY: This must only be called after CPU features have been written // and synchronized. pub(super) unsafe fn new_after_feature_flags_written_and_synced_unchecked() -> Self { - Self(()) + Self(NotSend::VALUE) } } } else { impl Features { pub(super) fn new_no_features_to_detect() -> Self { - Self(()) + Self(NotSend::VALUE) } } } } } +const _: () = assert!(core::mem::size_of::() == 0); + cfg_if::cfg_if! { if #[cfg(any(target_arch = "aarch64", target_arch = "arm"))] { pub mod arm; diff --git a/src/polyfill.rs b/src/polyfill.rs index 42f455eb6b..4d5a0ec1f0 100644 --- a/src/polyfill.rs +++ b/src/polyfill.rs @@ -54,6 +54,7 @@ pub mod sliceutil; #[cfg(feature = "alloc")] mod leading_zeros_skipped; +mod notsend; pub mod ptr; pub mod slice; @@ -64,7 +65,8 @@ mod test; mod unwrap_const; pub use self::{ - array_flat_map::ArrayFlatMap, array_split_map::ArraySplitMap, unwrap_const::unwrap_const, + array_flat_map::ArrayFlatMap, array_split_map::ArraySplitMap, notsend::NotSend, + unwrap_const::unwrap_const, }; #[cfg(feature = "alloc")] diff --git a/src/polyfill/notsend.rs b/src/polyfill/notsend.rs new file mode 100644 index 0000000000..1200c99c8b --- /dev/null +++ b/src/polyfill/notsend.rs @@ -0,0 +1,28 @@ +// Copyright 2024 Brian Smith. +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY +// SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +// OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +// CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +use crate::test; +use core::marker::PhantomData; + +/// A ZST that can be added to any type to make the type `!Send`. +#[derive(Clone, Copy)] +pub struct NotSend(PhantomData<*mut ()>); + +impl NotSend { + pub const VALUE: Self = Self(PhantomData); +} + +const _: () = test::compile_time_assert_clone::(); +const _: () = test::compile_time_assert_copy::(); +const _: () = assert!(core::mem::size_of::() == 0);