From 4605af9386fe9901a338e3c38cf47702bf35e48a Mon Sep 17 00:00:00 2001
From: Charles Lew <crlf0710@gmail.com>
Date: Sat, 3 Sep 2022 01:16:09 +0800
Subject: [PATCH 1/4] Add trait_upcasting related languages changes

---
 src/type-coercions.md | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/type-coercions.md b/src/type-coercions.md
index d87ee7eb8..4a4059a77 100644
--- a/src/type-coercions.md
+++ b/src/type-coercions.md
@@ -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.
 
@@ -207,6 +207,9 @@ 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 `T` has `U` as one of its ancestor trait.
+
 r[coerce.unsized.composite]
 * `Foo<..., T, ...>` to `Foo<..., U, ...>`, when:
     * `Foo` is a struct.

From 341f188646a28e69b8393aeee63a94c53f27d4c7 Mon Sep 17 00:00:00 2001
From: Waffle Lapkin <waffle.lapkin@gmail.com>
Date: Fri, 20 Sep 2024 10:33:24 +0200
Subject: [PATCH 2/4] 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 | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md
index 5910e9074..ad4861afa 100644
--- a/src/expressions/operator-expr.md
+++ b/src/expressions/operator-expr.md
@@ -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 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 97b48104228fcf384422c266b21e0126180bd5a1 Mon Sep 17 00:00:00 2001
From: Waffle Lapkin <waffle.lapkin@gmail.com>
Date: Fri, 20 Sep 2024 10:35:17 +0200
Subject: [PATCH 3/4] Apply review comments to trait upcasting description

Co-authored-by: Michael Goulet <michael@errs.io>
Co-authored-by: Charles Lew <crlf0710@gmail.com>
---
 src/type-coercions.md | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/type-coercions.md b/src/type-coercions.md
index 4a4059a77..5a8d86438 100644
--- a/src/type-coercions.md
+++ b/src/type-coercions.md
@@ -208,7 +208,8 @@ 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 `T` has `U` as one of its ancestor trait.
+* `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.
 
 r[coerce.unsized.composite]
 * `Foo<..., T, ...>` to `Foo<..., U, ...>`, when:
@@ -325,3 +326,4 @@ precisely.
 [`Unsize`]: std::marker::Unsize
 [`CoerceUnsized`]: std::ops::CoerceUnsized
 [method-call expressions]: expressions/method-call-expr.md
+[supertraits]: items/traits.md#supertraits

From 2837b28af009a3ddeae0c4a7dd419c2bf0ca024c Mon Sep 17 00:00:00 2001
From: Waffle Lapkin <waffle.lapkin@gmail.com>
Date: Sat, 21 Sep 2024 11:22:32 +0200
Subject: [PATCH 4/4] 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 | 2 +-
 src/type-coercions.md            | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md
index ad4861afa..55b7bbcb4 100644
--- a/src/expressions/operator-expr.md
+++ b/src/expressions/operator-expr.md
@@ -476,7 +476,7 @@ reference types and `mut` or `const` in pointer types.
 
 * 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 5a8d86438..1f0166a6d 100644
--- a/src/type-coercions.md
+++ b/src/type-coercions.md
@@ -210,6 +210,7 @@ r[coerce.unsize.trait-object]
 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: