Skip to content

Commit

Permalink
cpu: Make cpu::Features be !Send.
Browse files Browse the repository at this point in the history
We don't intend to put `cpu::Features` in any type that could be sent
across threads. Enforce this in the type system. This way, we can
potentially change the representation of `cpu::Features` to one that
really couldn't be `Send` in the future.
  • Loading branch information
briansmith committed Jun 14, 2024
1 parent e3593b4 commit c5f7b8b
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 9 deletions.
8 changes: 6 additions & 2 deletions src/cpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -33,7 +35,7 @@ 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 {
Expand All @@ -46,6 +48,8 @@ mod features {
}
}

const _: () = assert!(core::mem::size_of::<Features>() == 0);

cfg_if::cfg_if! {
if #[cfg(any(target_arch = "aarch64", target_arch = "arm"))] {
pub mod arm;
Expand Down
4 changes: 3 additions & 1 deletion src/polyfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ pub mod sliceutil;
#[cfg(feature = "alloc")]
mod leading_zeros_skipped;

mod notsend;
pub mod ptr;

pub mod slice;
Expand All @@ -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")]
Expand Down
12 changes: 6 additions & 6 deletions src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,28 +128,28 @@ extern crate std;

/// `compile_time_assert_clone::<T>();` fails to compile if `T` doesn't
/// implement `Clone`.
pub fn compile_time_assert_clone<T: Clone>() {}
pub const fn compile_time_assert_clone<T: Clone>() {}

/// `compile_time_assert_copy::<T>();` fails to compile if `T` doesn't
/// implement `Copy`.
pub fn compile_time_assert_copy<T: Copy>() {}
pub const fn compile_time_assert_copy<T: Copy>() {}

/// `compile_time_assert_eq::<T>();` fails to compile if `T` doesn't
/// implement `Eq`.
pub fn compile_time_assert_eq<T: Eq>() {}
pub const fn compile_time_assert_eq<T: Eq>() {}

/// `compile_time_assert_send::<T>();` fails to compile if `T` doesn't
/// implement `Send`.
pub fn compile_time_assert_send<T: Send>() {}
pub const fn compile_time_assert_send<T: Send>() {}

/// `compile_time_assert_sync::<T>();` fails to compile if `T` doesn't
/// implement `Sync`.
pub fn compile_time_assert_sync<T: Sync>() {}
pub const fn compile_time_assert_sync<T: Sync>() {}

/// `compile_time_assert_std_error_error::<T>();` fails to compile if `T`
/// doesn't implement `std::error::Error`.
#[cfg(feature = "std")]
pub fn compile_time_assert_std_error_error<T: std::error::Error>() {}
pub const fn compile_time_assert_std_error_error<T: std::error::Error>() {}

/// A test case. A test case consists of a set of named attributes. Every
/// attribute in the test case must be consumed exactly once; this helps catch
Expand Down

0 comments on commit c5f7b8b

Please sign in to comment.