From fd60187b802d8f600c7c9ff0fafd4218eff4b079 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Sat, 3 Sep 2022 01:16:09 +0800 Subject: [PATCH 1/6] Add trait_upcasting related languages changes --- src/behavior-considered-undefined.md | 1 + src/type-coercions.md | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 63fa28f63..23c8052c6 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -49,6 +49,7 @@ undefined behavior, it is *unsound*. * Invoking undefined behavior via compiler intrinsics. * Executing code compiled with platform features that the current platform does not support (see [`target_feature`]), *except* if the platform explicitly documents this to be safe. +* Performing non-nop coercion on a dangling or unaligned raw pointer. * Calling a function with the wrong call ABI or unwinding from a function with the wrong unwind ABI. * Producing an [invalid value][invalid-values]. "Producing" a value happens any time a value is assigned to or read from a place, passed to diff --git a/src/type-coercions.md b/src/type-coercions.md index 7d254f4e7..65d06b8b0 100644 --- a/src/type-coercions.md +++ b/src/type-coercions.md @@ -159,7 +159,7 @@ Coercion is allowed between the following types: ### Unsized Coercions 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. @@ -172,6 +172,8 @@ an implementation of `Unsize` for `T` will be provided: * `T` to `dyn U`, when `T` implements `U + Sized`, and `U` is [object safe]. +* `dyn T` to `dyn U`, when `T` has `U` as one of its ancestor trait. + * `Foo<..., T, ...>` to `Foo<..., U, ...>`, when: * `Foo` is a struct. * `T` implements `Unsize`. From b936305e96cf8afc7f6526aec1ae6321fd732356 Mon Sep 17 00:00:00 2001 From: Charles Lew Date: Wed, 22 Nov 2023 13:07:36 +0800 Subject: [PATCH 2/6] Address review comments. Co-authored-by: Michael Goulet --- src/type-coercions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/type-coercions.md b/src/type-coercions.md index 65d06b8b0..f843a747f 100644 --- a/src/type-coercions.md +++ b/src/type-coercions.md @@ -172,7 +172,7 @@ an implementation of `Unsize` for `T` will be provided: * `T` to `dyn U`, when `T` implements `U + Sized`, and `U` is [object safe]. -* `dyn T` to `dyn U`, when `T` has `U` as one of its ancestor trait. +* `dyn T` to `dyn U`, when `U` is one of `T`'s supertraits. * `Foo<..., T, ...>` to `Foo<..., U, ...>`, when: * `Foo` is a struct. From e7c2fa0c3086ad3b2e36e15a09ef0146662a7da1 Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Fri, 20 Sep 2024 10:32:40 +0200 Subject: [PATCH 3/6] Remove useless UB point As suggested by the review, this is already covered by "metadata must be valid" point. --- src/behavior-considered-undefined.md | 1 - 1 file changed, 1 deletion(-) diff --git a/src/behavior-considered-undefined.md b/src/behavior-considered-undefined.md index 23c8052c6..63fa28f63 100644 --- a/src/behavior-considered-undefined.md +++ b/src/behavior-considered-undefined.md @@ -49,7 +49,6 @@ undefined behavior, it is *unsound*. * Invoking undefined behavior via compiler intrinsics. * Executing code compiled with platform features that the current platform does not support (see [`target_feature`]), *except* if the platform explicitly documents this to be safe. -* Performing non-nop coercion on a dangling or unaligned raw pointer. * Calling a function with the wrong call ABI or unwinding from a function with the wrong unwind ABI. * Producing an [invalid value][invalid-values]. "Producing" a value happens any time a value is assigned to or read from a place, passed to From d07f7f02b0739b338d2e2dbb7c363189a8da988a Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Fri, 20 Sep 2024 10:33:24 +0200 Subject: [PATCH 4/6] Add information about casting pointers to unsized types This aligns the reference with the results of r-l/r/120248. --- src/expressions/operator-expr.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index a9e91f0a6..3d7319d7e 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -385,7 +385,11 @@ 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 not allowed (`*dyn Debug` -> `*dyn Debug + Send` is invalid). + * **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. From f021dfe36b9be021674e5d932bd2a4d752e9115e Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Fri, 20 Sep 2024 10:35:17 +0200 Subject: [PATCH 5/6] Apply review comments to trait upcasting description --- src/type-coercions.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/type-coercions.md b/src/type-coercions.md index f843a747f..002f78934 100644 --- a/src/type-coercions.md +++ b/src/type-coercions.md @@ -163,6 +163,9 @@ 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. +> Note: "unsizing" is a bit of a misnomer, +> since this covers unsized->unsized coercions too. + Two traits, [`Unsize`] and [`CoerceUnsized`], are used to assist in this process and expose it for library use. The following coercions are built-ins and, if `T` can be coerced to `U` with one of them, then @@ -172,7 +175,8 @@ an implementation of `Unsize` for `T` will be provided: * `T` to `dyn U`, when `T` implements `U + Sized`, and `U` is [object safe]. -* `dyn T` to `dyn U`, when `U` is one of `T`'s supertraits. +* `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. * `Foo<..., T, ...>` to `Foo<..., U, ...>`, when: * `Foo` is a struct. @@ -276,3 +280,4 @@ precisely. [`Unsize`]: std::marker::Unsize [`CoerceUnsized`]: std::ops::CoerceUnsized [method-call expressions]: expressions/method-call-expr.md +[supertraits]: items/traits.md#supertraits From 607255c877924286b903ba1409ce4371bc293942 Mon Sep 17 00:00:00 2001 From: Maybe Lapkin Date: Sat, 21 Sep 2024 11:22:32 +0200 Subject: [PATCH 6/6] Mention that you can add auto traits if principal has them as supers i.e. document the behavior after r-l/r/119338 --- src/expressions/operator-expr.md | 3 ++- src/type-coercions.md | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index 3d7319d7e..ef9bc0eb5 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -388,7 +388,8 @@ reference types and `mut` or `const` in pointer types. \* 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 not allowed (`*dyn Debug` -> `*dyn Debug + Send` is invalid). + * **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 diff --git a/src/type-coercions.md b/src/type-coercions.md index 002f78934..b84fc9321 100644 --- a/src/type-coercions.md +++ b/src/type-coercions.md @@ -177,6 +177,8 @@ an implementation of `Unsize` for `T` will be provided: * `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. * `Foo<..., T, ...>` to `Foo<..., U, ...>`, when: * `Foo` is a struct.