|
| 1 | +- Feature Name: `aligned` |
| 2 | +- Start Date: 2022-09-24 |
| 3 | +- RFC PR: [rust-lang/rfcs#3319](https://github.com/rust-lang/rfcs/pull/3319) |
| 4 | +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) |
| 5 | + |
| 6 | +# Summary |
| 7 | + |
| 8 | +Add an `Aligned` marker trait to `core::marker`, as a supertrait of the `Sized` trait. `Aligned` is implemented for all types with an alignment determined at compile time. This includes all `Sized` types, as well as slices and records containing them. Relax `core::mem::align_of<T>()`'s trait bound from `T: Sized` to `T: ?Sized + Aligned`. |
| 9 | + |
| 10 | +# Motivation |
| 11 | + |
| 12 | +Data structures and containers that wish to store unsized types are easier to implement if they can produce a dangling, well-aligned pointer to the unsized type. Being able to determine a type's alignment without a value of the type allows doing this. |
| 13 | + |
| 14 | +In addition, this RFC allows implementing certain object-safe traits for slices, where this was not possible before. |
| 15 | + |
| 16 | +# Guide-level explanation |
| 17 | + |
| 18 | +`Aligned` is a marker trait defined in `core::marker`. It's automatically implemented for all types with an alignment determined at compile time. This includes all `Sized` types (`Aligned` is a supertrait of `Sized`), as well as slices and records containing them. Trait objects are not `Aligned`. |
| 19 | + |
| 20 | +You can't implement `Aligned` yourself. |
| 21 | + |
| 22 | +To get the alignment of a type that implements `Aligned`, call `core::mem::align_of<T>()`. |
| 23 | + |
| 24 | +Implied `Sized` bounds also imply `Aligned`, because `Aligned` is a supertrait of `Sized`. To bound a type parameter by `Aligned` only, write `?Sized + Aligned`. |
| 25 | + |
| 26 | +# Reference-level explanation |
| 27 | + |
| 28 | +`Aligned` is not object-safe. Trait methods bounded by `Self: Aligned` can't be called from a vtable, but don't affect the object safety of the trait as a whole, just like `Self: Sized` currently. |
| 29 | +Relaxing `Self: Sized` bounds to `Self: Aligned` allows implementing certain object-safe traits for slices, where this was not previously possible. |
| 30 | + |
| 31 | +# Drawbacks |
| 32 | + |
| 33 | +- Slightly compicates situation around implied `Sized` bounds. |
| 34 | +- May make certain object safety diagnostics more confusing, as they will now refer to the new, lesser-known `Aligned` trait instead of `Sized`. |
| 35 | + |
| 36 | +# Rationale and alternatives |
| 37 | + |
| 38 | +`core::mem::align_of<T>()` for slices could be implemented with a library. However, a library would be unable to support records that contain a slice as the last field. Also, relaxing the trait dyn safety requirements can only be done with a language feature. |
| 39 | + |
| 40 | +# Prior art |
| 41 | + |
| 42 | +None that I am aware of. |
| 43 | + |
| 44 | +# Unresolved questions |
| 45 | + |
| 46 | +- Should `Aligned` be `#[fundamental]`? `Sized` is. |
| 47 | + |
| 48 | +# Future possibilities |
| 49 | + |
| 50 | +- Relaxing `NonNull::<T>::dangling()`'s trait bound from `T: Sized` to `T: ?Sized + Aligned + Pointee<Metadata: ~const Default>` may be desirable once the necessary library and language features are stabilized. |
| 51 | +- `extern type`s may want to be able to implement `Aligned`. |
| 52 | +- `Aligned` may warrant an addition the next edition's prelude. |
0 commit comments