You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We hadn't documented when it's sound to transmute a `Box<T>` to a
`Box<U>`. Now that we've documented when `*mut T` and `*mut U` can be
assumed to have the same layout, let's use that to document when this
transmute is sound.
Copy file name to clipboardExpand all lines: src/special-types-and-traits.md
+30Lines changed: 30 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -21,6 +21,33 @@ r[lang-types.box.fundamental]
21
21
22
22
<!-- Editor Note: This is nowhere close to an exhaustive list -->
23
23
24
+
r[lang-types.box.transmute]
25
+
For types `T` and `U` such that `*mut T` and `*mut U` have the same layout (per [layout.pointer.parametric]) and a [pointer-to-pointer cast] from `*mut T` to `*mut U` is permitted, transmuting a `Box<T>` to a `Box<U>`, where both boxes use the global allocator, is sound when both of the following hold:
26
+
27
+
- The pointee has the same [size] and [alignment] whether viewed as `T` or as `U`.
28
+
- The pointee is a valid value of `U`.
29
+
30
+
```rust
31
+
# usecore::mem::transmute;
32
+
letboxed:Box<i8> =Box::new(1);
33
+
letaddr= (&rawconst*boxed).addr();
34
+
// SAFETY: `i8` and `u8` have the same size and the same alignment, so
35
+
// `boxed`'s allocation is valid for `u8`.
36
+
letreboxed:Box<u8> =unsafe { transmute(boxed) };
37
+
// The transmute reuses the same allocation.
38
+
assert_eq!((&rawconst*reboxed).addr(), addr);
39
+
assert_eq!(*reboxed, 1);
40
+
41
+
// The pointee may also be unsized.
42
+
assert_eq!(size_of::<u32>(), size_of::<f32>());
43
+
assert_eq!(align_of::<u32>(), align_of::<f32>());
44
+
letslice:Box<[u32]> =Box::new([1, 2, 3]);
45
+
// SAFETY: Every bit pattern is a valid `f32`, and transmuting the box
0 commit comments