Add trait_upcasting related languages changes by WaffleLapkin · Pull Request #1622 · rust-lang/reference (original) (raw)
@compiler-errors doc.rust-lang.org/reference/behavior-considered-undefined.html already mentions invalid metadata in any kind of pointer makes an invalid value, so I don't think we need to add anything on top of that?
- Invalid metadata in a wide reference,
Box<T>
, or raw pointer. The requirement for the metadata is determined by the type of the unsized tail:
dyn Trait
metadata is invalid if it is not a pointer to a vtable forTrait
.Slice
([T]
) metadata is invalid if the length is not a validusize
(i.e., it must not be read from uninitialized memory). Furthermore, for wide references andBox<T>
, slice metadata is invalid if it makes the total size of the pointed-to value bigger thanisize::MAX
.
@WaffleLapkin I think this isn't quite right. How I read the Behaviors Considered Undefined section, it says...
Producing an invalid value. “Producing” a value happens any time a value is assigned to or read from a place, passed to a function/primitive operation or returned from a function/primitive operation.
where "producing an invalid value is hence immediate UB". But the consensus from rust-lang/rust#101336 was that having an invalid vtable is not a failure of the validity invariant. Rather, the UB occurs when a dyn
pointer (raw, reference, whatever) with a malformed vtable is upcast or has a method invoked on it. Because safe code can perform those operations (including on raw pointers, in the case of upcast and potentially method calls in the future), this implies that the safety invariant (the conditions required to release such a value to safe code) requires a valid vtable. But if you can keep the *const dyn Foo
confined to unsafe code and be absolutely sure nobody upcasts it, it doesn't require a valid vtable. Quoting rust-lang/rust#101336:
The proposal is as follows:
- Vtable-adjusting upcasts are safe operations. The upcast is UB if performed on a value without a valid vtable
- As such, the "safety invariant" requires a fully valid vtable.
- The "validity invariant" requires
*dyn
metadata to be word-aligned and non-null.Vtable-adjusting upcasts are defined as:
- Trait upcasts that alter the set of methods that can be invoked on the resulting value at runtime (e.g.,
dyn Bar
todyn Foo
from the introduction). In particular, upcasts that simply add or remove auto-traits are not vtable-adjusting (e.g.,dyn Debug + Send
todyn Debug
).