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}