diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index 530d41d10..09ff8ed49 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -385,7 +385,12 @@ reference types and `mut` or `const` in pointer types. | [Function pointer] | Integer | Function pointer to address cast | | Closure \*\*\* | Function pointer | Closure to function pointer cast | -\* or `T` and `V` are compatible unsized types, e.g., both slices, both the same trait object. +\* or `T` and `V` are unsized types with compatible metadata: +* both slice metadata (`*[u16]` -> `*[u8]`, `*str` -> `*(u8, [u32])`). +* both the same trait object metadata, modulo dropping auto traits (`*dyn Debug` -> `*(u16, dyn Debug)`, `*dyn Debug + Send` -> `*dyn Debug`). + * **Note**: *adding* auto traits is only allowed if the principal trait has the auto trait as a super trait + (given `trait T: Send {}`, `*dyn T` -> `*dyn T + Send` is valid, but `*dyn Debug` -> `*dyn Debug + Send` is not). + * **Note**: generics (including lifetimes) must match (`*dyn T<'a, A>` -> `*dyn T<'b, B>` requires `'a = 'b` and `A = B`). \*\* only when `m₁` is `mut` or `m₂` is `const`. Casting `mut` reference to `const` pointer is allowed. diff --git a/src/type-coercions.md b/src/type-coercions.md index 26e27eb1d..f02abd9e4 100644 --- a/src/type-coercions.md +++ b/src/type-coercions.md @@ -195,10 +195,14 @@ r[coerce.unsize] r[coerce.unsize.intro] The following coercions are called `unsized coercions`, since they -relate to converting sized types to unsized types, and are permitted in a few +relate to converting types to unsized types, and are permitted in a few cases where other coercions are not, as described above. They can still happen anywhere else a coercion can occur. +r[coerce.unsize.misnomer] +> Note: "unsizing" is a bit of a misnomer, +> since this covers unsized->unsized coercions too. + r[coerce.unsize.trait] Two traits, [`Unsize`] and [`CoerceUnsized`], are used to assist in this process and expose it for library use. The following @@ -211,6 +215,12 @@ r[coerce.unsize.slice] r[coerce.unsize.trait-object] * `T` to `dyn U`, when `T` implements `U + Sized`, and `U` is [dyn compatible]. +r[coerce.unsize.trait-upcast] +* `dyn T` to `dyn U`, when `U` is one of `T`'s [supertraits]. + * This allows dropping auto traits, i.e. `dyn T + Auto` to `dyn U` is allowed. + * This allows adding auto traits if the principal trait has the auto trait as a super trait, + i.e. given `trait T: U + Send {}`, `dyn T` to `dyn T + Send` or to `dyn U + Send` coercions are allowed. + r[coerce.unsized.composite] * `Foo<..., T, ...>` to `Foo<..., U, ...>`, when: * `Foo` is a struct. @@ -327,3 +337,4 @@ precisely. [`Unsize`]: std::marker::Unsize [`CoerceUnsized`]: std::ops::CoerceUnsized [method-call expressions]: expressions/method-call-expr.md +[supertraits]: items/traits.md#supertraits