munge/impls.rs
1use core::{
2 cell::{Cell, UnsafeCell},
3 mem::{transmute, ManuallyDrop, MaybeUninit},
4 ptr::read,
5};
6
7use crate::{Borrow, Destructure, Move, Restructure};
8
9// MaybeUninit<T>
10
11// SAFETY:
12// - `MaybeUninit<T>` is destructured by move, so its `Destructuring` type is
13// `Move`.
14// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
15// non-null, properly aligned, and valid for reads.
16unsafe impl<T> Destructure for MaybeUninit<T> {
17 type Underlying = T;
18 type Destructuring = Move;
19
20 fn underlying(&mut self) -> *mut Self::Underlying {
21 self.as_ptr() as *mut Self::Underlying
22 }
23}
24
25// SAFETY: `restructure` returns a `MaybeUninit<U>` that takes ownership of the
26// restructured field because `MaybeUninit<T>` is destructured by mvoe.
27unsafe impl<T, U> Restructure<U> for MaybeUninit<T> {
28 type Restructured = MaybeUninit<U>;
29
30 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
31 // SAFETY: The caller has guaranteed that `ptr` is a pointer to a
32 // subfield of some `T`, so it must be properly aligned, valid for
33 // reads, and initialized. We may move the fields because the
34 // destructuring type for `MaybeUninit<T>` is `Move`.
35 unsafe { read(ptr.cast()) }
36 }
37}
38
39// &MaybeUninit<T>
40
41// SAFETY:
42// - `&MaybeUninit<T>` is destructured by borrow, so its `Destructuring` type is
43// `Borrow`.
44// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
45// non-null, properly aligned, and valid for reads.
46unsafe impl<'a, T> Destructure for &'a MaybeUninit<T> {
47 type Underlying = T;
48 type Destructuring = Borrow;
49
50 fn underlying(&mut self) -> *mut Self::Underlying {
51 self.as_ptr() as *mut Self::Underlying
52 }
53}
54
55// SAFETY: `restructure` returns a `&MaybeUninit<U>` that borrows the
56// restructured field because `&MaybeUninit<T>` is destructured by borrow.
57unsafe impl<'a, T, U: 'a> Restructure<U> for &'a MaybeUninit<T> {
58 type Restructured = &'a MaybeUninit<U>;
59
60 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
61 // SAFETY: The caller has guaranteed that `ptr` points to a subfield of
62 // some `MaybeUninit<T>`, so it's safe to dereference. Because the
63 // destructuring type for `&MaybeUninit<T>` is `Borrow`, we may create a
64 // disjoint borrow of it for `'a`.
65 unsafe { &*ptr.cast() }
66 }
67}
68
69// &mut MaybeUninit<T>
70
71// SAFETY:
72// - `&mut MaybeUninit<T>` is destructured by borrow, so its `Destructuring`
73// type is `Borrow`.
74// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
75// non-null, properly aligned, and valid for reads.
76unsafe impl<'a, T> Destructure for &'a mut MaybeUninit<T> {
77 type Underlying = T;
78 type Destructuring = Borrow;
79
80 fn underlying(&mut self) -> *mut Self::Underlying {
81 MaybeUninit::as_mut_ptr(self)
82 }
83}
84
85// SAFETY: `restructure` returns a `&mut MaybeUninit<U>` that borrows the
86// restructured field because `&mut MaybeUninit<T>` is destructured by borrow.
87unsafe impl<'a, T, U: 'a> Restructure<U> for &'a mut MaybeUninit<T> {
88 type Restructured = &'a mut MaybeUninit<U>;
89
90 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
91 // SAFETY: The caller has guaranteed that `ptr` points to a subfield of
92 // some `MaybeUninit<T>`, so it's safe to dereference. Because the
93 // destructuring type for `&mut MaybeUninit<T>` is `Borrow`, we may
94 // create a disjoint borrow of it for `'a`.
95 unsafe { &mut *ptr.cast() }
96 }
97}
98
99// Cell<T>
100
101// SAFETY:
102// - `Cell<T>` is destructured by move, so its `Destructuring` type is `Move`.
103// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
104// non-null, properly aligned, and valid for reads.
105unsafe impl<T> Destructure for Cell<T> {
106 type Underlying = T;
107 type Destructuring = Move;
108
109 fn underlying(&mut self) -> *mut Self::Underlying {
110 self.as_ptr()
111 }
112}
113
114// SAFETY: `restructure` returns a `Cell<U>` that takes ownership of the
115// restructured field because `Cell<T>` is destructured by move.
116unsafe impl<T, U> Restructure<U> for Cell<T> {
117 type Restructured = Cell<U>;
118
119 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
120 // SAFETY: The caller has guaranteed that `ptr` is a pointer to a
121 // subfield of some `T`, so it must be properly aligned, valid for
122 // reads, and initialized. We may move the fields because the
123 // destructuring type for `Cell<T>` is `Move`.
124 unsafe { read(ptr.cast_const().cast()) }
125 }
126}
127
128// &Cell<T>
129
130// SAFETY:
131// - `&Cell<T>` is destructured by borrow, so its `Destructuring` type is
132// `Borrow`.
133// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
134// non-null, properly aligned, and valid for reads.
135unsafe impl<'a, T: ?Sized> Destructure for &'a Cell<T> {
136 type Underlying = T;
137 type Destructuring = Borrow;
138
139 fn underlying(&mut self) -> *mut Self::Underlying {
140 self.as_ptr()
141 }
142}
143
144// SAFETY: `restructure` returns a `&Cell<U>` that borrows the restructured
145// field because `&Cell<T>` is destructured by borrow.
146unsafe impl<'a, T: ?Sized, U: 'a + ?Sized> Restructure<U> for &'a Cell<T> {
147 type Restructured = &'a Cell<U>;
148
149 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
150 // SAFETY: `Cell<U>` is `repr(transparent)` and so guaranteed to have
151 // the same representation as the `U` it contains. Therefore, the
152 // pointer metadata for `*const Cell<U>` is the same as the metadata for
153 // `*mut U`, and transmuting between the two types is sound.
154 let ptr = unsafe { transmute::<*mut U, *const Cell<U>>(ptr) };
155 // SAFETY: The caller has guaranteed that `ptr` points to a subfield of
156 // some `Cell<T>`, so it's safe to dereference. Because the
157 // destructuring type for `&Cell<T>` is `Borrow`, we may create a
158 // disjoint borrow of it for `'a`.
159 unsafe { &*ptr }
160 }
161}
162
163// &mut Cell<T>
164
165// SAFETY:
166// - `&mut Cell<T>` is destructured by borrow, so its `Destructuring` type is
167// `Borrow`.
168// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
169// non-null, properly aligned, and valid for reads.
170unsafe impl<'a, T: ?Sized> Destructure for &'a mut Cell<T> {
171 type Underlying = T;
172 type Destructuring = Borrow;
173
174 fn underlying(&mut self) -> *mut Self::Underlying {
175 self.as_ptr()
176 }
177}
178
179// SAFETY: `restructure` returns a `&mut Cell<U>` that borrows the restructured
180// field because `&mut Cell<T>` is destructured by borrow.
181unsafe impl<'a, T: ?Sized, U: 'a + ?Sized> Restructure<U> for &'a mut Cell<T> {
182 type Restructured = &'a mut Cell<U>;
183
184 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
185 // SAFETY: `Cell<U>` is `repr(transparent)` and so guaranteed to have
186 // the same representation as the `U` it contains. Therefore, the
187 // pointer metadata for `*mut Cell<U>` is the same as the metadata for
188 // `*mut U`, and transmuting between the two types is sound.
189 let ptr = unsafe { transmute::<*mut U, *mut Cell<U>>(ptr) };
190 // SAFETY: The caller has guaranteed that `ptr` points to a subfield of
191 // some `Cell<T>`, so it's safe to dereference. Because the
192 // destructuring type for `&mut Cell<T>` is `Borrow`, we may create a
193 // disjoint borrow of it for `'a`.
194 unsafe { &mut *ptr }
195 }
196}
197
198// UnsafeCell<T>
199
200// SAFETY:
201// - `UnsafeCell<T>` is destructured by move, so its `Destructuring` type is
202// `Move`.
203// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
204// non-null, properly aligned, and valid for reads.
205unsafe impl<T> Destructure for UnsafeCell<T> {
206 type Underlying = T;
207 type Destructuring = Move;
208
209 fn underlying(&mut self) -> *mut Self::Underlying {
210 self.get()
211 }
212}
213
214// SAFETY: `restructure` returns a `UnsafeCell<U>` that takes ownership of the
215// restructured field because `UnsafeCell<T>` is destructured by move.
216unsafe impl<T, U> Restructure<U> for UnsafeCell<T> {
217 type Restructured = UnsafeCell<U>;
218
219 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
220 // SAFETY: The caller has guaranteed that `ptr` is a pointer to a
221 // subfield of some `T`, so it must be properly aligned, valid for
222 // reads, and initialized. We may move the fields because the
223 // destructuring type for `UnsafeCell<T>` is `Move`.
224 unsafe { read(ptr.cast()) }
225 }
226}
227
228// &UnsafeCell<T>
229
230// SAFETY:
231// - `&UnsafeCell<T>` is destructured by borrow, so its `Destructuring` type is
232// `Borrow`.
233// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
234// non-null, properly aligned, and valid for reads.
235unsafe impl<'a, T: ?Sized> Destructure for &'a UnsafeCell<T> {
236 type Underlying = T;
237 type Destructuring = Borrow;
238
239 fn underlying(&mut self) -> *mut Self::Underlying {
240 self.get()
241 }
242}
243
244// SAFETY: `restructure` returns a `&UnsafeCell<U>` that borrows the
245// restructured field because `&UnsafeCell<T>` is destructured by borrow.
246unsafe impl<'a, T, U> Restructure<U> for &'a UnsafeCell<T>
247where
248 T: ?Sized,
249 U: 'a + ?Sized,
250{
251 type Restructured = &'a UnsafeCell<U>;
252
253 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
254 // SAFETY: `UnsafeCell<U>` is `repr(transparent)` and so guaranteed to
255 // have the same representation as the `U` it contains. Therefore, the
256 // pointer metadata for `*const UnsafeCell<U>` is the same as the
257 // metadata for `*mut U`, and transmuting between the two types is
258 // sound.
259 let ptr = unsafe { transmute::<*mut U, *const UnsafeCell<U>>(ptr) };
260 // SAFETY: The caller has guaranteed that `ptr` points to a subfield of
261 // some `UnsafeCell<T>`, so it's safe to dereference. Because the
262 // destructuring type for `&UnsafeCell<T>` is `Borrow`, we may create a
263 // disjoint borrow of it for `'a`.
264 unsafe { &*ptr }
265 }
266}
267
268// &mut UnsafeCell<T>
269
270// SAFETY:
271// - `&mut UnsafeCell<T>` is destructured by borrow, so its `Destructuring` type
272// is `Borrow`.
273// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
274// non-null, properly aligned, and valid for reads.
275unsafe impl<'a, T: ?Sized> Destructure for &'a mut UnsafeCell<T> {
276 type Underlying = T;
277 type Destructuring = Borrow;
278
279 fn underlying(&mut self) -> *mut Self::Underlying {
280 self.get()
281 }
282}
283
284// SAFETY: `restructure` returns a `&mut UnsafeCell<U>` that borrows the
285// restructured field because `&mut UnsafeCell<T>` is destructured by borrow.
286unsafe impl<'a, T, U> Restructure<U> for &'a mut UnsafeCell<T>
287where
288 T: ?Sized,
289 U: 'a + ?Sized,
290{
291 type Restructured = &'a mut UnsafeCell<U>;
292
293 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
294 // SAFETY: `UnsafeCell<U>` is `repr(transparent)` and so guaranteed to
295 // have the same representation as the `U` it contains. Therefore, the
296 // pointer metadata for `*mut UnsafeCell<U>` is the same as the metadata
297 // for `*mut U`, and transmuting between the two types is sound.
298 let ptr = unsafe { transmute::<*mut U, *mut UnsafeCell<U>>(ptr) };
299 // SAFETY: The caller has guaranteed that `ptr` points to a subfield of
300 // some `UnsafeCell<T>`, so it's safe to dereference. Because the
301 // destructuring type for `&mut UnsafeCell<T>` is `Borrow`, we may
302 // create a disjoint borrow of it for `'a`.
303 unsafe { &mut *ptr }
304 }
305}
306
307// ManuallyDrop<T>
308
309// SAFETY:
310// - `ManuallyDrop<T>` is destructured by move, so its `Destructuring` type is
311// `Move`.
312// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
313// non-null, properly aligned, and valid for reads.
314unsafe impl<T> Destructure for ManuallyDrop<T> {
315 type Underlying = T;
316 type Destructuring = Move;
317
318 fn underlying(&mut self) -> *mut Self::Underlying {
319 &mut **self as *mut Self::Underlying
320 }
321}
322
323// SAFETY: `restructure` returns a `ManuallyDrop<U>` that takes ownership of the
324// restructured field because `ManuallyDrop<T>` is destructured by move.
325unsafe impl<T, U> Restructure<U> for ManuallyDrop<T> {
326 type Restructured = ManuallyDrop<U>;
327
328 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
329 // SAFETY: The caller has guaranteed that `ptr` is a pointer to a
330 // subfield of some `T`, so it must be properly aligned, valid for
331 // reads, and initialized. We may move the fields because the
332 // destructuring type for `ManuallyDrop<T>` is `Move`.
333 unsafe { read(ptr.cast()) }
334 }
335}
336
337// &ManuallyDrop<T>
338
339// SAFETY:
340// - `&ManuallyDrop<T>` is destructured by borrow, so its `Destructuring` type
341// is `Borrow`.
342// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
343// non-null, properly aligned, and valid for reads.
344unsafe impl<'a, T: ?Sized> Destructure for &'a ManuallyDrop<T> {
345 type Underlying = T;
346 type Destructuring = Borrow;
347
348 fn underlying(&mut self) -> *mut Self::Underlying {
349 (&***self as *const Self::Underlying).cast_mut()
350 }
351}
352
353// SAFETY: `restructure` returns a `&ManuallyDrop<U>` that borrows the
354// restructured field because `&ManuallyDrop<T>` is destructured by borrow.
355unsafe impl<'a, T, U> Restructure<U> for &'a ManuallyDrop<T>
356where
357 T: ?Sized,
358 U: 'a + ?Sized,
359{
360 type Restructured = &'a ManuallyDrop<U>;
361
362 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
363 // SAFETY: `ManuallyDrop<U>` is `repr(transparent)` and so guaranteed to
364 // have the same representation as the `U` it contains. Therefore, the
365 // pointer metadata for `*const ManuallyDrop<U>` is the same as the
366 // metadata for `*mut U`, and transmuting between the two types is
367 // sound.
368 let ptr = unsafe { transmute::<*mut U, *const ManuallyDrop<U>>(ptr) };
369 // SAFETY: The caller has guaranteed that `ptr` points to a subfield of
370 // some `ManuallyDrop<T>`, so it's safe to dereference. Because the
371 // destructuring type for `&ManuallyDrop<T>` is `Borrow`, we may create
372 // a disjoint borrow of it for `'a`.
373 unsafe { &*ptr }
374 }
375}
376
377// &mut ManuallyDrop<T>
378
379// SAFETY:
380// - `&mut ManuallyDrop<T>` is destructured by borrow, so its `Destructuring`
381// type is `Borrow`.
382// - `underlying` returns a pointer to its inner type, so it is guaranteed to be
383// non-null, properly aligned, and valid for reads.
384unsafe impl<'a, T: ?Sized> Destructure for &'a mut ManuallyDrop<T> {
385 type Underlying = T;
386 type Destructuring = Borrow;
387
388 fn underlying(&mut self) -> *mut Self::Underlying {
389 &mut ***self as *mut Self::Underlying
390 }
391}
392
393// SAFETY: `restructure` returns a `&mut ManuallyDrop<U>` that borrows the
394// restructured field because `&mut ManuallyDrop<T>` is destructured by
395// borrow.
396unsafe impl<'a, T, U> Restructure<U> for &'a mut ManuallyDrop<T>
397where
398 T: ?Sized,
399 U: 'a + ?Sized,
400{
401 type Restructured = &'a mut ManuallyDrop<U>;
402
403 unsafe fn restructure(&self, ptr: *mut U) -> Self::Restructured {
404 // SAFETY: `ManuallyDrop<U>` is `repr(transparent)` and so guaranteed to
405 // have the same representation as the `U` it contains. Therefore, the
406 // pointer metadata for `*mut ManuallyDrop<U>` is the same as the
407 // metadata for `*mut U`, and transmuting between the two types is
408 // sound.
409 let ptr = unsafe { transmute::<*mut U, *mut ManuallyDrop<U>>(ptr) };
410 // SAFETY: The caller has guaranteed that `ptr` points to a subfield of
411 // some `ManuallyDrop<T>`, so it's safe to dereference. Because the
412 // destructuring type for `&mut ManuallyDrop<T>` is `Borrow`, we may
413 // create a disjoint borrow of it for `'a`.
414 unsafe { &mut *ptr }
415 }
416}