1 use super::*; 2 3 /// A trait which indicates that a type is a `#[repr(transparent)]` wrapper 4 /// around the `Inner` value. 5 /// 6 /// This allows safely copy transmuting between the `Inner` type and the 7 /// `TransparentWrapper` type. Functions like `wrap_{}` convert from the inner 8 /// type to the wrapper type and `peel_{}` functions do the inverse conversion 9 /// from the wrapper type to the inner type. We deliberately do not call the 10 /// wrapper-removing methods "unwrap" because at this point that word is too 11 /// strongly tied to the Option/ Result methods. 12 /// 13 /// # Safety 14 /// 15 /// The safety contract of `TransparentWrapper` is relatively simple: 16 /// 17 /// For a given `Wrapper` which implements `TransparentWrapper<Inner>`: 18 /// 19 /// 1. `Wrapper` must be a wrapper around `Inner` with an identical data 20 /// representations. This either means that it must be a 21 /// `#[repr(transparent)]` struct which contains a either a field of type 22 /// `Inner` (or a field of some other transparent wrapper for `Inner`) as 23 /// the only non-ZST field. 24 /// 25 /// 2. Any fields *other* than the `Inner` field must be trivially constructable 26 /// ZSTs, for example `PhantomData`, `PhantomPinned`, etc. (When deriving 27 /// `TransparentWrapper` on a type with ZST fields, the ZST fields must be 28 /// [`Zeroable`]). 29 /// 30 /// 3. The `Wrapper` may not impose additional alignment requirements over 31 /// `Inner`. 32 /// - Note: this is currently guaranteed by `repr(transparent)`, but there 33 /// have been discussions of lifting it, so it's stated here explicitly. 34 /// 35 /// 4. All functions on `TransparentWrapper` **may not** be overridden. 36 /// 37 /// ## Caveats 38 /// 39 /// If the wrapper imposes additional constraints upon the inner type which are 40 /// required for safety, it's responsible for ensuring those still hold -- this 41 /// generally requires preventing access to instances of the inner type, as 42 /// implementing `TransparentWrapper<U> for T` means anybody can call 43 /// `T::cast_ref(any_instance_of_u)`. 44 /// 45 /// For example, it would be invalid to implement TransparentWrapper for `str` 46 /// to implement `TransparentWrapper` around `[u8]` because of this. 47 /// 48 /// # Examples 49 /// 50 /// ## Basic 51 /// 52 /// ``` 53 /// use bytemuck::TransparentWrapper; 54 /// # #[derive(Default)] 55 /// # struct SomeStruct(u32); 56 /// 57 /// #[repr(transparent)] 58 /// struct MyWrapper(SomeStruct); 59 /// 60 /// unsafe impl TransparentWrapper<SomeStruct> for MyWrapper {} 61 /// 62 /// // interpret a reference to &SomeStruct as a &MyWrapper 63 /// let thing = SomeStruct::default(); 64 /// let inner_ref: &MyWrapper = MyWrapper::wrap_ref(&thing); 65 /// 66 /// // Works with &mut too. 67 /// let mut mut_thing = SomeStruct::default(); 68 /// let inner_mut: &mut MyWrapper = MyWrapper::wrap_mut(&mut mut_thing); 69 /// 70 /// # let _ = (inner_ref, inner_mut); // silence warnings 71 /// ``` 72 /// 73 /// ## Use with dynamically sized types 74 /// 75 /// ``` 76 /// use bytemuck::TransparentWrapper; 77 /// 78 /// #[repr(transparent)] 79 /// struct Slice<T>([T]); 80 /// 81 /// unsafe impl<T> TransparentWrapper<[T]> for Slice<T> {} 82 /// 83 /// let s = Slice::wrap_ref(&[1u32, 2, 3]); 84 /// assert_eq!(&s.0, &[1, 2, 3]); 85 /// 86 /// let mut buf = [1, 2, 3u8]; 87 /// let sm = Slice::wrap_mut(&mut buf); 88 /// ``` 89 /// 90 /// ## Deriving 91 /// 92 /// When deriving, the non-wrapped fields must uphold all the normal 93 /// requirements, and must also be `Zeroable`. 94 #[cfg_attr(feature = "derive", doc = "```")] 95 #[cfg_attr( 96 not(feature = "derive"), 97 doc = "```ignore 98 // This example requires the `derive` feature." 99 )] 100 /// use bytemuck::TransparentWrapper; 101 /// use std::marker::PhantomData; 102 /// 103 /// #[derive(TransparentWrapper)] 104 /// #[repr(transparent)] 105 /// #[transparent(usize)] 106 /// struct Wrapper<T: ?Sized>(usize, PhantomData<T>); // PhantomData<T> implements Zeroable for all T 107 /// ``` 108 /// 109 /// Here, an error will occur, because `MyZst` does not implement `Zeroable`. 110 #[cfg_attr(feature = "derive", doc = "```compile_fail")] 111 #[cfg_attr( 112 not(feature = "derive"), 113 doc = "```ignore 114 // This example requires the `derive` feature." 115 )] 116 /// use bytemuck::TransparentWrapper; 117 /// struct MyZst; 118 /// 119 /// #[derive(TransparentWrapper)] 120 /// #[repr(transparent)] 121 /// #[transparent(usize)] 122 /// struct Wrapper(usize, MyZst); // MyZst does not implement Zeroable 123 /// ``` 124 pub unsafe trait TransparentWrapper<Inner: ?Sized> { 125 /// Convert the inner type into the wrapper type. 126 #[inline] wrap(s: Inner) -> Self where Self: Sized, Inner: Sized,127 fn wrap(s: Inner) -> Self 128 where 129 Self: Sized, 130 Inner: Sized, 131 { 132 assert!(size_of::<Inner>() == size_of::<Self>()); 133 assert!(align_of::<Inner>() == align_of::<Self>()); 134 // SAFETY: The unsafe contract requires that `Self` and `Inner` have 135 // identical representations. 136 unsafe { transmute!(s) } 137 } 138 139 /// Convert a reference to the inner type into a reference to the wrapper 140 /// type. 141 #[inline] wrap_ref(s: &Inner) -> &Self142 fn wrap_ref(s: &Inner) -> &Self { 143 // The unsafe contract requires that these two have 144 // identical representations, and thus identical pointer metadata. 145 // Assert that Self and Inner have the same pointer size, 146 // which is the best we can do to assert their metadata is the same type 147 // on stable. 148 assert!(size_of::<*const Inner>() == size_of::<*const Self>()); 149 unsafe { 150 // A pointer cast doesn't work here because rustc can't tell that 151 // the vtables match (because of the `?Sized` restriction relaxation). 152 // A `transmute` doesn't work because the sizes are unspecified. 153 // 154 // SAFETY: The unsafe contract requires that these two have 155 // identical representations. 156 let inner_ptr = s as *const Inner; 157 let wrapper_ptr: *const Self = transmute!(inner_ptr); 158 &*wrapper_ptr 159 } 160 } 161 162 /// Convert a mutable reference to the inner type into a mutable reference to 163 /// the wrapper type. 164 #[inline] wrap_mut(s: &mut Inner) -> &mut Self165 fn wrap_mut(s: &mut Inner) -> &mut Self { 166 // The unsafe contract requires that these two have 167 // identical representations, and thus identical pointer metadata. 168 // Assert that Self and Inner have the same pointer size, 169 // which is about the best we can do on stable. 170 assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); 171 unsafe { 172 // A pointer cast doesn't work here because rustc can't tell that 173 // the vtables match (because of the `?Sized` restriction relaxation). 174 // A `transmute` doesn't work because the sizes are unspecified. 175 // 176 // SAFETY: The unsafe contract requires that these two have 177 // identical representations. 178 let inner_ptr = s as *mut Inner; 179 let wrapper_ptr: *mut Self = transmute!(inner_ptr); 180 &mut *wrapper_ptr 181 } 182 } 183 184 /// Convert a slice to the inner type into a slice to the wrapper type. 185 #[inline] wrap_slice(s: &[Inner]) -> &[Self] where Self: Sized, Inner: Sized,186 fn wrap_slice(s: &[Inner]) -> &[Self] 187 where 188 Self: Sized, 189 Inner: Sized, 190 { 191 assert!(size_of::<Inner>() == size_of::<Self>()); 192 assert!(align_of::<Inner>() == align_of::<Self>()); 193 // SAFETY: The unsafe contract requires that these two have 194 // identical representations (size and alignment). 195 unsafe { core::slice::from_raw_parts(s.as_ptr() as *const Self, s.len()) } 196 } 197 198 /// Convert a mutable slice to the inner type into a mutable slice to the 199 /// wrapper type. 200 #[inline] wrap_slice_mut(s: &mut [Inner]) -> &mut [Self] where Self: Sized, Inner: Sized,201 fn wrap_slice_mut(s: &mut [Inner]) -> &mut [Self] 202 where 203 Self: Sized, 204 Inner: Sized, 205 { 206 assert!(size_of::<Inner>() == size_of::<Self>()); 207 assert!(align_of::<Inner>() == align_of::<Self>()); 208 // SAFETY: The unsafe contract requires that these two have 209 // identical representations (size and alignment). 210 unsafe { 211 core::slice::from_raw_parts_mut(s.as_mut_ptr() as *mut Self, s.len()) 212 } 213 } 214 215 /// Convert the wrapper type into the inner type. 216 #[inline] peel(s: Self) -> Inner where Self: Sized, Inner: Sized,217 fn peel(s: Self) -> Inner 218 where 219 Self: Sized, 220 Inner: Sized, 221 { 222 assert!(size_of::<Inner>() == size_of::<Self>()); 223 assert!(align_of::<Inner>() == align_of::<Self>()); 224 // SAFETY: The unsafe contract requires that `Self` and `Inner` have 225 // identical representations. 226 unsafe { transmute!(s) } 227 } 228 229 /// Convert a reference to the wrapper type into a reference to the inner 230 /// type. 231 #[inline] peel_ref(s: &Self) -> &Inner232 fn peel_ref(s: &Self) -> &Inner { 233 // The unsafe contract requires that these two have 234 // identical representations, and thus identical pointer metadata. 235 // Assert that Self and Inner have the same pointer size, 236 // which is about the best we can do on stable. 237 assert!(size_of::<*const Inner>() == size_of::<*const Self>()); 238 unsafe { 239 // A pointer cast doesn't work here because rustc can't tell that 240 // the vtables match (because of the `?Sized` restriction relaxation). 241 // A `transmute` doesn't work because the sizes are unspecified. 242 // 243 // SAFETY: The unsafe contract requires that these two have 244 // identical representations. 245 let wrapper_ptr = s as *const Self; 246 let inner_ptr: *const Inner = transmute!(wrapper_ptr); 247 &*inner_ptr 248 } 249 } 250 251 /// Convert a mutable reference to the wrapper type into a mutable reference 252 /// to the inner type. 253 #[inline] peel_mut(s: &mut Self) -> &mut Inner254 fn peel_mut(s: &mut Self) -> &mut Inner { 255 // The unsafe contract requires that these two have 256 // identical representations, and thus identical pointer metadata. 257 // Assert that Self and Inner have the same pointer size, 258 // which is about the best we can do on stable. 259 assert!(size_of::<*mut Inner>() == size_of::<*mut Self>()); 260 unsafe { 261 // A pointer cast doesn't work here because rustc can't tell that 262 // the vtables match (because of the `?Sized` restriction relaxation). 263 // A `transmute` doesn't work because the sizes are unspecified. 264 // 265 // SAFETY: The unsafe contract requires that these two have 266 // identical representations. 267 let wrapper_ptr = s as *mut Self; 268 let inner_ptr: *mut Inner = transmute!(wrapper_ptr); 269 &mut *inner_ptr 270 } 271 } 272 273 /// Convert a slice to the wrapped type into a slice to the inner type. 274 #[inline] peel_slice(s: &[Self]) -> &[Inner] where Self: Sized, Inner: Sized,275 fn peel_slice(s: &[Self]) -> &[Inner] 276 where 277 Self: Sized, 278 Inner: Sized, 279 { 280 assert!(size_of::<Inner>() == size_of::<Self>()); 281 assert!(align_of::<Inner>() == align_of::<Self>()); 282 // SAFETY: The unsafe contract requires that these two have 283 // identical representations (size and alignment). 284 unsafe { core::slice::from_raw_parts(s.as_ptr() as *const Inner, s.len()) } 285 } 286 287 /// Convert a mutable slice to the wrapped type into a mutable slice to the 288 /// inner type. 289 #[inline] peel_slice_mut(s: &mut [Self]) -> &mut [Inner] where Self: Sized, Inner: Sized,290 fn peel_slice_mut(s: &mut [Self]) -> &mut [Inner] 291 where 292 Self: Sized, 293 Inner: Sized, 294 { 295 assert!(size_of::<Inner>() == size_of::<Self>()); 296 assert!(align_of::<Inner>() == align_of::<Self>()); 297 // SAFETY: The unsafe contract requires that these two have 298 // identical representations (size and alignment). 299 unsafe { 300 core::slice::from_raw_parts_mut(s.as_mut_ptr() as *mut Inner, s.len()) 301 } 302 } 303 } 304 305 unsafe impl<T> TransparentWrapper<T> for core::num::Wrapping<T> {} 306