Add PME backstop to detect padding in `IntoBytes` types
- Dominant language
- Rust
- Stars
- 2.6k
- Forks
- 179
- Avg merge
- 1d 19h
- Merged PRs (30d)
- 29
Description
As demonstrated in #1764, #1763, #1758, and #1757, reasoning about the presence or absence of padding is subtle.
When a type is `Sized` and concrete, we can easily emit a padding check using `size_of` to confirm that the size of the type is equal to the sum of the sizes of its fields (although note that this is still unsound in the presence of niche-filling). However, on unsized or generic types, our job is much harder, and `#[derive(IntoBytes)]` employs subtle logic to determine whether Rust could in principle emit padding bytes in a particular type.
When the type is generic, the only reason that we can't emit a padding check is that it requires the unstable `generic_const_exprs` feature. However, we could still use a post-monomorphization error (PME). In particular, I propose the following:
- Add a `#[doc(hidden)]` associated const to `IntoBytes` which evaluates to `()` if a type has no padding or panics during evaluation if it does have padding
- Evaluate this const in all `IntoBytes` methods, and maybe in other places that consume `T: IntoBytes`
Note that this is a backstop, but it must *not* be taken as a complete proof that a type is padding-free. In particular, user code is permitted to use `T: IntoBytes` as a precondition to justify the soundness of `unsafe` code - we cannot guarantee that such user code will call our methods. Thus, we cannot guarantee that such user code would trigger a PME.
Contributor guide
Assessment
This issue has not been assessed yet.