1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
macro_rules! stack_only_docs {
($item:item) => {
/// Types which contain no pointers or references and can thus live entirely
/// on the stack.
///
/// This trait is automatically implemented when the compiler determines
/// it's appropriate.
///
/// Note that this trait is *sealed*, i.e. you cannot implement it on your
/// own custom types.
///
/// Primitive types like [`u8`] and structs, tuples, and enums made only
/// from them implement [`StackOnly`].
///
/// In contrast, `&T`, `&mut T`, `*const T`, `*mut T`, and any type
/// containing a reference or a pointer do *not* implement [`StackOnly`].
///
/// # Examples
///
/// ```rust
/// # use rust_cuda::safety::StackOnly;
/// fn assert_stackonly(_x: impl StackOnly) {}
/// ```
/// ```rust
/// # use rust_cuda::safety::StackOnly;
/// # fn assert_stackonly(_x: impl StackOnly) {}
/// assert_stackonly(42); // ok
/// ```
/// ```rust
/// # use rust_cuda::safety::StackOnly;
/// # fn assert_stackonly(_x: impl StackOnly) {}
/// assert_stackonly([42; 42]); // ok
/// ```
/// ```rust,compile_fail
/// # use alloc::vec;
/// # use rust_cuda::safety::StackOnly;
/// # fn assert_stackonly(_x: impl StackOnly) {}
/// assert_stackonly(vec![42]); // error
/// ```
/// ```rust,compile_fail
/// # use alloc::vec;
/// # use rust_cuda::safety::StackOnly;
/// # fn assert_stackonly(_x: impl StackOnly) {}
/// assert_stackonly(&42); // error
/// ```
/// ```rust,compile_fail
/// # use alloc::vec;
/// # use rust_cuda::safety::StackOnly;
/// # fn assert_stackonly(_x: impl StackOnly) {}
/// # use crate::utils::shared::r#static::ThreadBlockShared;
/// assert_stackonly(ThreadBlockShared::new_uninit()); // error
/// ```
/// ```rust,compile_fail
/// # use alloc::vec;
/// # use rust_cuda::safety::StackOnly;
/// # fn assert_stackonly(_x: impl StackOnly) {}
/// # use crate::utils::shared::slice::ThreadBlockSharedSlice;
/// assert_stackonly(ThreadBlockSharedSlice::new_uninit_with_len(0)); // error
/// ```
$item
};
}
#[cfg(not(doc))]
stack_only_docs! {
pub trait StackOnly: sealed::StackOnly {}
}
#[cfg(doc)]
stack_only_docs! {
pub use sealed::StackOnly;
}
#[cfg(not(doc))]
impl<T: sealed::StackOnly> StackOnly for T {}
mod sealed {
pub auto trait StackOnly {}
impl<T: ?Sized> !StackOnly for &T {}
impl<T: ?Sized> !StackOnly for &mut T {}
impl<T: ?Sized> !StackOnly for *const T {}
impl<T: ?Sized> !StackOnly for *mut T {}
impl<T> StackOnly for core::marker::PhantomData<T> {}
}