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 {}