Document semantics of various pointer casts

Co-authored-by: Ralf Jung <post@ralfj.de>
This commit is contained in:
John-John Tedro 2024-01-22 06:32:05 +01:00
parent 9104f17835
commit 8c7cdd39ef
1 changed files with 16 additions and 8 deletions

View File

@ -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