memapi/
marker.rs

1use core::ffi::CStr;
2#[cfg(feature = "metadata")]
3use core::ptr::Pointee;
4#[cfg(feature = "std")]
5use std::{ffi::OsStr, path::Path};
6
7/// Unsafe marker trait for types that can be copied, including unsized types such as slices.
8///
9/// # Safety
10///
11/// Implementing `UnsizedCopy` indicates the type's memory representation can be duplicated without
12/// violating soundness or causing double frees.
13pub unsafe trait UnsizedCopy {}
14
15// Any `T` which is `Copy` is also `UnsizedCopy`.
16unsafe impl<T: Copy> UnsizedCopy for T {}
17// And so are slices containing copyable T.    ↰
18unsafe impl<T: Copy> UnsizedCopy for [T] {} // |
19// `str == [u8]` and `u8: Copy`.               ┤
20unsafe impl UnsizedCopy for str {} //          |
21// `CStr == [u8]` and `u8: Copy`               ┤
22unsafe impl UnsizedCopy for CStr {} //         |
23#[cfg(feature = "std")] //                     |
24// `OsStr == [u8]` and `[u8]: UnsizedCopy`     ┤
25unsafe impl UnsizedCopy for OsStr {} //        |
26#[cfg(feature = "std")] //                     |
27// `Path == OsStr` and `OsStr: UnsizedCopy`.   ┘
28unsafe impl UnsizedCopy for Path {}
29
30#[cfg(feature = "metadata")]
31/// Trait indicating that a type has no metadata.
32///
33/// This usually means `Self: Sized` or `Self` is `extern`.
34///
35/// # Example
36///
37/// ```rust
38/// # use memapi::{SizedProps, Thin};
39///
40/// fn safe<T: Thin>() {
41///     assert_eq!(<&T>::SZ, usize::SZ)
42/// }
43/// ```
44pub trait Thin: Pointee<Metadata = ()> {}
45
46#[cfg(feature = "metadata")]
47impl<P: Pointee<Metadata = ()>> Thin for P {}