From e64212ed9e951d1d95f753e0cc2a93cd5d2e18ee Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Fri, 7 Feb 2025 03:14:13 +0100 Subject: [PATCH 1/4] fixup list of valid `as` casts `&m1 T -> *m2 T` is not specific to `as` casts (it's a coercion!), but `*[T; N]` -> `*T` is! (previously only the reference source version was documented) --- src/expressions/operator-expr.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index 55b7bbcb4..180f3f1b4 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -463,8 +463,8 @@ reference types and `mut` or `const` in pointer types. | `*T` | `*V` where `V: Sized` \* | Pointer to pointer cast | | `*T` where `T: Sized` | Integer type | Pointer to address cast | | Integer type | `*V` where `V: Sized` | Address to pointer cast | -| `&m₁ T` | `*m₂ T` \*\* | Reference to pointer cast | | `&m₁ [T; n]` | `*m₂ T` \*\* | Array to pointer cast | +| `*m₁ [T; n]` | `*m₂ T` \*\* | Array to pointer cast | | [Function item] | [Function pointer] | Function item to function pointer cast | | [Function item] | `*V` where `V: Sized` | Function item to pointer cast | | [Function item] | Integer | Function item to address cast | From 7dc9ee318321bb8ecebe6d1008287f9bd0590771 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Fri, 7 Feb 2025 03:26:19 +0100 Subject: [PATCH 2/4] use footnotes instead of `\*` in `as` description --- src/expressions/operator-expr.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index 180f3f1b4..e509e06a0 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -460,29 +460,29 @@ reference types and `mut` or `const` in pointer types. | Enumeration | Integer type | Enum cast | | `bool` or `char` | Integer type | Primitive to integer cast | | `u8` | `char` | `u8` to `char` cast | -| `*T` | `*V` where `V: Sized` \* | Pointer to pointer cast | +| `*T` | `*V` [^1] | Pointer to pointer cast | | `*T` where `T: Sized` | Integer type | Pointer to address cast | | Integer type | `*V` where `V: Sized` | Address to pointer cast | -| `&m₁ [T; n]` | `*m₂ T` \*\* | Array to pointer cast | -| `*m₁ [T; n]` | `*m₂ T` \*\* | Array to pointer cast | +| `&m₁ [T; n]` | `*m₂ T` [^2] | Array to pointer cast | +| `*m₁ [T; n]` | `*m₂ T` [^2] | Array to pointer cast | | [Function item] | [Function pointer] | Function item to function pointer cast | | [Function item] | `*V` where `V: Sized` | Function item to pointer cast | | [Function item] | Integer | Function item to address cast | | [Function pointer] | `*V` where `V: Sized` | Function pointer to pointer cast | | [Function pointer] | Integer | Function pointer to address cast | -| Closure \*\*\* | Function pointer | Closure to function pointer cast | +| Closure [^3] | Function pointer | Closure to function pointer cast | -\* or `T` and `V` are unsized types with compatible metadata: +[^1]: where `T` and `V` have compatible metadata: + * `V: Sized`, or + * Both slice metadata (`*[u16]` -> `*[u8]`, `*str` -> `*(u8, [u32])`), or + * 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`) -* 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 +[^2]: only when `m₁` is `mut` or `m₂` is `const`. Casting `mut` reference/pointer to `const` pointer is allowed. -\*\*\* only for closures that do not capture (close over) any local variables +[^3]: only for closures that do not capture (close over) any local variables can be casted to function pointers. ### Semantics From cd3ec42076f5a9877b149b502b57e17755721015 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Fri, 7 Feb 2025 03:35:03 +0100 Subject: [PATCH 3/4] link from `as` cast table to semantic chapters --- src/expressions/operator-expr.md | 34 ++++++++++++++++---------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index e509e06a0..f7d3a97eb 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -454,23 +454,23 @@ Any cast that does not fit either a coercion rule or an entry in the table is a Here `*T` means either `*const T` or `*mut T`. `m` stands for optional `mut` in reference types and `mut` or `const` in pointer types. -| Type of `e` | `U` | Cast performed by `e as U` | -|-----------------------|-----------------------|----------------------------------| -| Integer or Float type | Integer or Float type | Numeric cast | -| Enumeration | Integer type | Enum cast | -| `bool` or `char` | Integer type | Primitive to integer cast | -| `u8` | `char` | `u8` to `char` cast | -| `*T` | `*V` [^1] | Pointer to pointer cast | -| `*T` where `T: Sized` | Integer type | Pointer to address cast | -| Integer type | `*V` where `V: Sized` | Address to pointer cast | -| `&m₁ [T; n]` | `*m₂ T` [^2] | Array to pointer cast | -| `*m₁ [T; n]` | `*m₂ T` [^2] | Array to pointer cast | -| [Function item] | [Function pointer] | Function item to function pointer cast | -| [Function item] | `*V` where `V: Sized` | Function item to pointer cast | -| [Function item] | Integer | Function item to address cast | -| [Function pointer] | `*V` where `V: Sized` | Function pointer to pointer cast | -| [Function pointer] | Integer | Function pointer to address cast | -| Closure [^3] | Function pointer | Closure to function pointer cast | +| Type of `e` | `U` | Cast performed by `e as U` | +|-----------------------|-----------------------|-------------------------------------------------------| +| Integer or Float type | Integer or Float type | [Numeric cast][expr.as.numeric] | +| Enumeration | Integer type | [Enum cast][expr.as.enum] | +| `bool` or `char` | Integer type | [Primitive to integer cast][expr.as.bool-char-as-int] | +| `u8` | `char` | [`u8` to `char` cast][expr.as.u8-as-char] | +| `*T` | `*V` [^1] | [Pointer to pointer cast][expr.as.pointer] | +| `*T` where `T: Sized` | Integer type | [Pointer to address cast][expr.as.pointer-as-int] | +| Integer type | `*V` where `V: Sized` | [Address to pointer cast][expr.as.int-as-pointer] | +| `&m₁ [T; n]` | `*m₂ T` [^2] | Array to pointer cast | +| `*m₁ [T; n]` | `*m₂ T` [^2] | Array to pointer cast | +| [Function item] | [Function pointer] | Function item to function pointer cast | +| [Function item] | `*V` where `V: Sized` | Function item to pointer cast | +| [Function item] | Integer | Function item to address cast | +| [Function pointer] | `*V` where `V: Sized` | Function pointer to pointer cast | +| [Function pointer] | Integer | Function pointer to address cast | +| Closure [^3] | Function pointer | Closure to function pointer cast | [^1]: where `T` and `V` have compatible metadata: * `V: Sized`, or From 39d94e1a24d1971d9e333815319a3c898ad4e871 Mon Sep 17 00:00:00 2001 From: Waffle Lapkin Date: Mon, 10 Feb 2025 17:31:52 +0100 Subject: [PATCH 4/4] fixup footnotes apparently mdbook requires them to have globally unique identifiers (but they are still rendered as ^1, ^2, ...) --- src/expressions/operator-expr.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index f7d3a97eb..55dcbcb6a 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -460,29 +460,29 @@ reference types and `mut` or `const` in pointer types. | Enumeration | Integer type | [Enum cast][expr.as.enum] | | `bool` or `char` | Integer type | [Primitive to integer cast][expr.as.bool-char-as-int] | | `u8` | `char` | [`u8` to `char` cast][expr.as.u8-as-char] | -| `*T` | `*V` [^1] | [Pointer to pointer cast][expr.as.pointer] | +| `*T` | `*V` [^meta-compat] | [Pointer to pointer cast][expr.as.pointer] | | `*T` where `T: Sized` | Integer type | [Pointer to address cast][expr.as.pointer-as-int] | | Integer type | `*V` where `V: Sized` | [Address to pointer cast][expr.as.int-as-pointer] | -| `&m₁ [T; n]` | `*m₂ T` [^2] | Array to pointer cast | -| `*m₁ [T; n]` | `*m₂ T` [^2] | Array to pointer cast | +| `&m₁ [T; n]` | `*m₂ T` [^lessmut] | Array to pointer cast | +| `*m₁ [T; n]` | `*m₂ T` [^lessmut] | Array to pointer cast | | [Function item] | [Function pointer] | Function item to function pointer cast | | [Function item] | `*V` where `V: Sized` | Function item to pointer cast | | [Function item] | Integer | Function item to address cast | | [Function pointer] | `*V` where `V: Sized` | Function pointer to pointer cast | | [Function pointer] | Integer | Function pointer to address cast | -| Closure [^3] | Function pointer | Closure to function pointer cast | +| Closure [^no-capture] | Function pointer | Closure to function pointer cast | -[^1]: where `T` and `V` have compatible metadata: +[^meta-compat]: where `T` and `V` have compatible metadata: * `V: Sized`, or * Both slice metadata (`*[u16]` -> `*[u8]`, `*str` -> `*(u8, [u32])`), or * 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`) -[^2]: only when `m₁` is `mut` or `m₂` is `const`. Casting `mut` reference/pointer to +[^lessmut]: only when `m₁` is `mut` or `m₂` is `const`. Casting `mut` reference/pointer to `const` pointer is allowed. -[^3]: only for closures that do not capture (close over) any local variables can be casted to function pointers. +[^no-capture]: only for closures that do not capture (close over) any local variables can be casted to function pointers. ### Semantics