Skip to content

Add trait_upcasting related languages changes #1622

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 8, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/expressions/operator-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,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.
Expand Down
8 changes: 7 additions & 1 deletion src/type-coercions.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ 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.

Expand All @@ -207,6 +207,11 @@ 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.
Expand Down Expand Up @@ -322,3 +327,4 @@ precisely.
[`Unsize`]: std::marker::Unsize
[`CoerceUnsized`]: std::ops::CoerceUnsized
[method-call expressions]: expressions/method-call-expr.md
[supertraits]: items/traits.md#supertraits