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
docs: add comprehensive documentation for borrowing from repr(packed) arrays
- Add detailed explanation of alignment requirements when borrowing from packed structs
- Document that array/slice ABI alignment equals element type alignment
- Provide concrete examples showing allowed and forbidden borrowing patterns
- Clarify that E0793 error prevents creation of misaligned references
- Explain the conservative nature of alignment checks in generic contexts
This documentation helps developers understand the safety constraints
when working with packed structs containing arrays of different types.
Copy file name to clipboardExpand all lines: src/type-layout.md
+34Lines changed: 34 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -595,6 +595,40 @@ own, `packed` does not provide any guarantee about field ordering). An
595
595
important consequence of these rules is that a type with `#[repr(packed(1))]`
596
596
(or `#[repr(packed)]`) will have no inter-field padding.
597
597
598
+
[r[layout.repr.packed.borrowing]]
599
+
When borrowing a field of a `repr(packed(...))` struct, Rust must not create a **misaligned reference** (which would be undefined behavior). Therefore:
600
+
601
+
- It is a **hard error** (E0793) to create a reference whose **ABI alignment requirement** is **greater** than the struct’s packed alignment.
602
+
- Borrowing is **allowed** if the target’s ABI alignment is **less than or equal to** the struct’s packed alignment.
603
+
604
+
For array and slice fields `[T; N]` and `[T]`, the ABI alignment equals that of the element type `T` and **does not depend on the length `N`**. (Sketch: from `&[T]` one can obtain `&T`, hence `align([T]) ≥ align(T)`; from `&T` one can obtain `&[T; 1]` via `std::array::from_ref`, hence `align(T) ≥ align([T])`. Therefore `align([T]) == align(T)`.)
605
+
606
+
**Examples**
607
+
608
+
```rust
609
+
// Allowed: `u8` has ABI alignment 1, which is ≤ the packed alignment (typically 1).
610
+
#[repr(C, packed)]
611
+
structS<constN:usize> { buf: [u8; N] }
612
+
613
+
fnok<constN:usize>(s:&S<N>) ->&[u8] {
614
+
&s.buf[..]
615
+
}
616
+
617
+
// Error (E0793): `u16` has ABI alignment 2, which is > the packed alignment.
618
+
#[repr(C, packed)]
619
+
structT<constN:usize> { buf: [u16; N] }
620
+
621
+
fnerr<constN:usize>(t:&T<N>) ->&[u16] {
622
+
&t.buf[..] // creates a reference requiring alignment 2 from a packed(1) field
623
+
}
624
+
```
625
+
626
+
Note: This is a hard error, not a lint. Implementations may determine the
627
+
target’s ABI alignment either directly from the borrowed type, or—when the full
628
+
layout of an array is unavailable in generic contexts—by using the element type’s
629
+
alignment (align([T]) == align(T)). The check must remain conservative and never
630
+
permit creating misaligned references.
631
+
598
632
r[layout.repr.alignment.constraint-exclusive]
599
633
The `align` and `packed` modifiers cannot be applied on the same type and a
600
634
`packed` type cannot transitively contain another `align`ed type. `align` and
0 commit comments