CoerceUnsizedCoerceUnsized is primarily concerned with data containers. When a struct (typically, a smart pointer) implements CoerceUnsized, that means that the data it points to is being unsized.
Some implementors of CoerceUnsized include:
&TArc<T>Box<T>This trait is (eventually) intended to be implemented by user-written smart pointers, and there are rules about when a type is allowed to implement CoerceUnsized that are explained in the trait's documentation.
UnsizeTo contrast, the Unsize trait is concerned the actual types that are allowed to be unsized.
This is not intended to be implemented by users ever, since Unsize does not instruct the compiler (namely codegen) how to unsize a type, just whether it is allowed to be unsized. This is paired somewhat intimately with codegen which must understand how types are represented and unsized.
Built-in implementations are provided for:
T -> dyn Trait + 'a when T: Trait (and T: Sized + 'a, and Trait is dyn-compatible[^2]).[T; N] -> [T]There are two implementations of Unsize which can be thought of as structural:
(A1, A2, .., An): Unsize<(A1, A2, .., U)> given An: Unsize<U>, which allows the tail field of a tuple to be unsized. This is gated behind the unsized_tuple_coercion feature.Struct<.., Pi, .., Pj, ..>: Unsize<Struct<.., Ui, .., Uj, ..>> given TailField<Pi, .., Pj>: Unsize<Ui, .. Uj>, which allows the tail field of a struct to be unsized if it is the only field that mentions generic parameters Pi, .., Pj (which don't need to be contiguous).The rules for the latter implementation are slightly complicated, since they may allow more than one parameter to be changed (not necessarily unsized) and are best stated in terms of the tail field of the struct.
Two things are called “upcasting” internally:
dyn SubTrait -> dyn SuperTrait (this also allows dropping auto traits and adjusting lifetimes, as below).dyn Trait + AutoTraits... + 'a -> dyn Trait + NewAutoTraits... + 'b when AutoTraits ⊇ NewAutoTraits, and 'a: 'b.These may seem like different operations, since (1.) includes adjusting the vtable of a dyn trait, while (2.) is a no-op. However, to the type system, these are handled with much the same code.
This built-in implementation of Unsize is the most involved, particularly after it was reworked to support the complexities of associated types.
Specifically, the upcasting algorithm involves: For each supertrait of the source dyn trait's principal (including itself)...
trait Sub: Sup<.., A = i32> + Sup<.., A = u32>).Specifically, (3.) prevents a choice of projection bound to guide inference unnecessarily, though it may guide inference when it is unambiguous.
[^1]: The principal is the one non-auto trait of a dyn Trait. [^2]: Formerly known as “object safe”.