Skip to content

Commit 7a900bc

Browse files
committed
Document layout equivalences for pointer types
We guarantee various things about the layout of pointers and references, but we'd made no guarantees of equivalence between two pointers to distinct unsized types that differ in the unsized tail. Let's make some useful guarantees about this.
1 parent 52d554e commit 7a900bc

1 file changed

Lines changed: 38 additions & 0 deletions

File tree

src/type-layout.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,40 @@ Pointers to unsized types are sized. The size and alignment of a pointer to an u
6969
> [!NOTE]
7070
> Though you should not rely on this, all pointers to <abbr title="Dynamically Sized Types">DSTs</abbr> are currently twice the size of the size of `usize` and have the same alignment.
7171
72+
r[layout.pointer.parametric]
73+
The raw pointer types `*const T` and `*const U` have the same layout, as do `*mut T` and `*mut U`, the shared references `&T` and `&U`, and the mutable references `&mut T` and `&mut U`, in each of the following cases:
74+
75+
- `T` and `U` are both sized types.
76+
- `T` and `U` both have a [slice] or [`str`] as their [unsized tail].
77+
- `T` and `U` both have a [trait object] as their unsized tail.
78+
79+
```rust
80+
# use core::alloc::Layout;
81+
macro_rules! assert_layout_eq {
82+
($a:ty, $b:ty) => {
83+
assert_eq!(Layout::new::<$a>(), Layout::new::<$b>())
84+
};
85+
}
86+
trait Tr1 {}
87+
trait Tr2 {}
88+
struct W<T: ?Sized> {
89+
head: u8,
90+
tail: T,
91+
}
92+
// Pointers to two types share a layout when the types are both sized,
93+
// both have a slice or `str` tail, or both have a trait object tail.
94+
assert_layout_eq!(*const u8, *const u64);
95+
assert_layout_eq!(*const [u8], *const [u64]);
96+
assert_layout_eq!(*const str, *const [u8]);
97+
assert_layout_eq!(*const dyn Tr1, *const dyn Tr2);
98+
assert_layout_eq!(*const W<[u8]>, *const W<[u64]>);
99+
// References share a layout on the same terms.
100+
assert_layout_eq!(&u8, &u64);
101+
# assert_layout_eq!(&str, &[u8]);
102+
# assert_layout_eq!(&dyn Tr1, &dyn Tr2);
103+
# assert_layout_eq!(&W<[u8]>, &W<[u64]>);
104+
```
105+
72106
r[layout.array]
73107
## Array layout
74108

@@ -571,3 +605,7 @@ Because this representation delegates type layout to another type, it cannot be
571605
[structs]: items/structs.md
572606
[`transparent`]: #the-transparent-representation
573607
[`Layout`]: std::alloc::Layout
608+
[slice]: types/slice.md
609+
[`str`]: types/str.md
610+
[trait object]: types/trait-object.md
611+
[unsized tail]: dynamic-sized.tail

0 commit comments

Comments
 (0)