From 8c7cdd39effa8c463080c7e509c6ea0fa1291d9c Mon Sep 17 00:00:00 2001 From: John-John Tedro Date: Mon, 22 Jan 2024 06:32:05 +0100 Subject: [PATCH 1/3] Document semantics of various pointer casts Co-authored-by: Ralf Jung --- src/expressions/operator-expr.md | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index bd4998a..8f35dd6 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -478,15 +478,23 @@ unsafe { assert_eq!(values[1], 3); ``` -#### Slice DST pointer to pointer cast +#### Pointer-to-pointer cast -For slice types like `[T]` and `[U]`, the raw pointer types `*const [T]`, `*mut [T]`, -`*const [U]`, and `*mut [U]` encode the number of elements in this slice. Casts between -these raw pointer types preserve the number of elements. Note that, as a consequence, -such casts do *not* necessarily preserve the size of the pointer's referent (e.g., -casting `*const [u16]` to `*const [u8]` will result in a raw pointer which refers to an -object of half the size of the original). The same holds for `str` and any compound type -whose unsized tail is a slice type, such as struct `Foo(i32, [u8])` or `(u64, Foo)`. +`*const T` / `*mut T` can be cast to `*const U` / `*mut U` with the following behavior: + +- If `T` and `U` are both sized, the pointer is returned unchanged. +- If `T` and `U` are both unsized, the pointer is also returned unchanged. In particular, + the metadata is preserved exactly. + + For instance, a cast from `*const [T]` to `*const [U]` preserves the number of elements. + Note that, as a consequence, such casts do not necessarily preserve the size of the + pointer's referent (e.g., casting `*const [u16]` to `*const [u8]` will result in a raw + pointer which refers to an object of half the size of the original). The same + holds for `str` and any compound type whose unsized tail is a slice type, such + as `struct Foo(i32, [u8])` or `(u64, Foo)`. +- If `T` is unsized and `U` is sized, the cast discards all metadata that + completes the wide pointer `T` and produces a thin pointer `U` consisting + of the data part of the unsized pointer. ## Assignment expressions From 72fb6265962347679f8db5ced4504756592705d9 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 21 Feb 2024 13:17:59 -0800 Subject: [PATCH 2/3] Add redirect for slice-dst-pointer-to-pointer-cast --- src/expressions/operator-expr.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index 8f35dd6..d5af503 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -695,3 +695,17 @@ See [this test] for an example of using this dependency. [_TypeNoBounds_]: ../types.md#type-expressions [_RangeExpression_]: ./range-expr.md [_UnderscoreExpression_]: ./underscore-expr.md + + From 97c9ad16e565f2d47593a1ac56c806b2892e4223 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 21 Feb 2024 13:20:15 -0800 Subject: [PATCH 3/3] Semantic line wrapping. --- src/expressions/operator-expr.md | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index d5af503..d3fa33b 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -483,18 +483,15 @@ assert_eq!(values[1], 3); `*const T` / `*mut T` can be cast to `*const U` / `*mut U` with the following behavior: - If `T` and `U` are both sized, the pointer is returned unchanged. -- If `T` and `U` are both unsized, the pointer is also returned unchanged. In particular, - the metadata is preserved exactly. +- If `T` and `U` are both unsized, the pointer is also returned unchanged. + In particular, the metadata is preserved exactly. - For instance, a cast from `*const [T]` to `*const [U]` preserves the number of elements. - Note that, as a consequence, such casts do not necessarily preserve the size of the - pointer's referent (e.g., casting `*const [u16]` to `*const [u8]` will result in a raw - pointer which refers to an object of half the size of the original). The same - holds for `str` and any compound type whose unsized tail is a slice type, such - as `struct Foo(i32, [u8])` or `(u64, Foo)`. -- If `T` is unsized and `U` is sized, the cast discards all metadata that - completes the wide pointer `T` and produces a thin pointer `U` consisting - of the data part of the unsized pointer. + For instance, a cast from `*const [T]` to `*const [U]` preserves the number of elements. + Note that, as a consequence, such casts do not necessarily preserve the size of the pointer's referent + (e.g., casting `*const [u16]` to `*const [u8]` will result in a raw pointer which refers to an object of half the size of the original). + The same holds for `str` and any compound type whose unsized tail is a slice type, + such as `struct Foo(i32, [u8])` or `(u64, Foo)`. +- If `T` is unsized and `U` is sized, the cast discards all metadata that completes the wide pointer `T` and produces a thin pointer `U` consisting of the data part of the unsized pointer. ## Assignment expressions