Skip to content

Commit 6ea5a05

Browse files
committed
Clearly document semantics of various pointer casts
1 parent 8c77e8b commit 6ea5a05

File tree

1 file changed

+44
-8
lines changed

1 file changed

+44
-8
lines changed

src/expressions/operator-expr.md

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -478,15 +478,48 @@ unsafe {
478478
assert_eq!(values[1], 3);
479479
```
480480

481-
#### Slice DST pointer to pointer cast
481+
#### Sized to sized pointer casts
482482

483-
For slice types like `[T]` and `[U]`, the raw pointer types `*const [T]`, `*mut [T]`,
484-
`*const [U]`, and `*mut [U]` encode the number of elements in this slice. Casts between
485-
these raw pointer types preserve the number of elements. Note that, as a consequence,
486-
such casts do *not* necessarily preserve the size of the pointer's referent (e.g.,
487-
casting `*const [u16]` to `*const [u8]` will result in a raw pointer which refers to an
488-
object of half the size of the original). The same holds for `str` and any compound type
489-
whose unsized tail is a slice type, such as struct `Foo(i32, [u8])` or `(u64, Foo)`.
483+
A sized pointer to pointer cast `*const T as *const U` or `*mut T as *mut U`
484+
where `T: Sized` and `U: Sized` produces a value identical to the original
485+
pointer.
486+
487+
#### Unsized to unsized pointer casts
488+
489+
Any unsized to unsized pointer cast `*const T as *const U` or `*mut T as *mut U`
490+
produces a value identical to the original pointer if `T` and `U` are compatible
491+
unsized types.
492+
493+
For slice types like `[T]` and `[U]`, the raw pointer types `*const [T]`, `*mut
494+
[T]`, `*const [U]`, and `*mut [U]` encode the number of elements in this slice.
495+
Casts between these raw pointer types preserve the number of elements. Note
496+
that, as a consequence, such casts do *not* necessarily preserve the size of the
497+
pointer's referent (e.g., casting `*const [u16]` to `*const [u8]` will result in
498+
a raw pointer which refers to an object of half the size of the original). The
499+
same holds for `str` and any compound type whose unsized tail is a slice type,
500+
such as struct `Foo(i32, [u8])` or `(u64, Foo)`.
501+
502+
#### Unsized to sized pointer casts
503+
504+
Any wide to narrow pointer cast discards all metadata that completes the wide
505+
pointer and produces a thin base pointer.
506+
507+
The following casts are well-defined:
508+
509+
* `*const [T] to *const U` or `*mut [T] to *mut U` discards the length of the
510+
slice and produces a pointer to the first element. The produced pointer is
511+
casted to `U` in the same manner as a sized pointer to pointer cast.
512+
* `*const dyn T to *const U` or `*mut dyn T to *mut U` discards all metadata
513+
associated with the [trait object] and produces a pointer to the instance from
514+
which the trait object was constructed. The produced pointer is casted to `U`
515+
in the same manner as a sized pointer to pointer cast.
516+
517+
For example:
518+
519+
* `*const [u32] as *const u8` would produce a pointer to the first element
520+
constituting the slice, casted to a `*const u8` pointer.
521+
* `*const str` and `*mut str` have the same semantics as `*const [u8]` and `*mut
522+
[u8]` since they have [identical layouts][_str_layout_].
490523

491524
## Assignment expressions
492525

@@ -671,6 +704,8 @@ See [this test] for an example of using this dependency.
671704
[undefined behavior]: ../behavior-considered-undefined.md
672705
[addr_of]: ../../std/ptr/macro.addr_of.html
673706
[addr_of_mut]: ../../std/ptr/macro.addr_of_mut.html
707+
[slice]: ../types/slice.md
708+
[trait object]: ../types/trait-object.md
674709

675710
[_BorrowExpression_]: #borrow-operators
676711
[_DereferenceExpression_]: #the-dereference-operator
@@ -687,3 +722,4 @@ See [this test] for an example of using this dependency.
687722
[_TypeNoBounds_]: ../types.md#type-expressions
688723
[_RangeExpression_]: ./range-expr.md
689724
[_UnderscoreExpression_]: ./underscore-expr.md
725+
[_str_layout_]: ../type-layout.md#str-layout

0 commit comments

Comments
 (0)