castaway/
lifetime_free.rs

1/// Marker trait for types that do not contain any lifetime parameters. Such
2/// types are safe to cast from non-static type parameters if their types are
3/// equal.
4///
5/// This trait is used by [`cast!`](crate::cast) to determine what casts are legal on values
6/// without a `'static` type constraint.
7///
8/// # Safety
9///
10/// When implementing this trait for a type, you must ensure that the type is
11/// free of any lifetime parameters. Failure to meet **all** of the requirements
12/// below may result in undefined behavior.
13///
14/// - The type must be `'static`.
15/// - The type must be free of lifetime parameters. In other words, the type
16///   must be an "owned" type and not contain *any* lifetime parameters.
17/// - All contained fields must also be `LifetimeFree`.
18///
19/// # Examples
20///
21/// ```
22/// use castaway::LifetimeFree;
23///
24/// struct Container<T>(T);
25///
26/// // UNDEFINED BEHAVIOR!!
27/// // unsafe impl LifetimeFree for Container<&'static str> {}
28///
29/// // UNDEFINED BEHAVIOR!!
30/// // unsafe impl<T> LifetimeFree for Container<T> {}
31///
32/// // This is safe.
33/// unsafe impl<T: LifetimeFree> LifetimeFree for Container<T> {}
34///
35/// struct PlainOldData {
36///     foo: u8,
37///     bar: bool,
38/// }
39///
40/// // This is also safe, since all fields are known to be `LifetimeFree`.
41/// unsafe impl LifetimeFree for PlainOldData {}
42/// ```
43pub unsafe trait LifetimeFree {}
44
45unsafe impl LifetimeFree for () {}
46unsafe impl LifetimeFree for bool {}
47unsafe impl LifetimeFree for char {}
48unsafe impl LifetimeFree for f32 {}
49unsafe impl LifetimeFree for f64 {}
50unsafe impl LifetimeFree for i8 {}
51unsafe impl LifetimeFree for i16 {}
52unsafe impl LifetimeFree for i32 {}
53unsafe impl LifetimeFree for i64 {}
54unsafe impl LifetimeFree for i128 {}
55unsafe impl LifetimeFree for isize {}
56unsafe impl LifetimeFree for str {}
57unsafe impl LifetimeFree for u8 {}
58unsafe impl LifetimeFree for u16 {}
59unsafe impl LifetimeFree for u32 {}
60unsafe impl LifetimeFree for u64 {}
61unsafe impl LifetimeFree for u128 {}
62unsafe impl LifetimeFree for usize {}
63
64unsafe impl LifetimeFree for core::num::NonZeroI8 {}
65unsafe impl LifetimeFree for core::num::NonZeroI16 {}
66unsafe impl LifetimeFree for core::num::NonZeroI32 {}
67unsafe impl LifetimeFree for core::num::NonZeroI64 {}
68unsafe impl LifetimeFree for core::num::NonZeroI128 {}
69unsafe impl LifetimeFree for core::num::NonZeroIsize {}
70unsafe impl LifetimeFree for core::num::NonZeroU8 {}
71unsafe impl LifetimeFree for core::num::NonZeroU16 {}
72unsafe impl LifetimeFree for core::num::NonZeroU32 {}
73unsafe impl LifetimeFree for core::num::NonZeroU64 {}
74unsafe impl LifetimeFree for core::num::NonZeroU128 {}
75unsafe impl LifetimeFree for core::num::NonZeroUsize {}
76
77unsafe impl<T: LifetimeFree> LifetimeFree for [T] {}
78#[rustversion::since(1.51)]
79unsafe impl<T: LifetimeFree, const SIZE: usize> LifetimeFree for [T; SIZE] {}
80unsafe impl<T: LifetimeFree> LifetimeFree for Option<T> {}
81unsafe impl<T: LifetimeFree, E: LifetimeFree> LifetimeFree for Result<T, E> {}
82unsafe impl<T: LifetimeFree> LifetimeFree for core::num::Wrapping<T> {}
83unsafe impl<T: LifetimeFree> LifetimeFree for core::cell::Cell<T> {}
84unsafe impl<T: LifetimeFree> LifetimeFree for core::cell::RefCell<T> {}
85
86macro_rules! tuple_impls {
87    ($( $( $name:ident )+, )+) => {
88        $(
89            unsafe impl<$($name: LifetimeFree),+> LifetimeFree for ($($name,)+) {}
90        )+
91    };
92}
93
94tuple_impls! {
95    T0,
96    T0 T1,
97    T0 T1 T2,
98    T0 T1 T2 T3,
99    T0 T1 T2 T3 T4,
100    T0 T1 T2 T3 T4 T5,
101    T0 T1 T2 T3 T4 T5 T6,
102    T0 T1 T2 T3 T4 T5 T6 T7,
103    T0 T1 T2 T3 T4 T5 T6 T7 T8,
104    T0 T1 T2 T3 T4 T5 T6 T7 T8 T9,
105}
106
107#[cfg(feature = "alloc")]
108mod alloc_impls {
109    use super::LifetimeFree;
110
111    unsafe impl LifetimeFree for alloc::string::String {}
112
113    unsafe impl<T: LifetimeFree> LifetimeFree for alloc::boxed::Box<T> {}
114    unsafe impl<T: LifetimeFree> LifetimeFree for alloc::vec::Vec<T> {}
115
116    #[rustversion::attr(since(1.60), cfg(target_has_atomic = "ptr"))]
117    unsafe impl<T: LifetimeFree> LifetimeFree for alloc::sync::Arc<T> {}
118}