diff --git a/src/expressions/operator-expr.md b/src/expressions/operator-expr.md index 785665da5..4d8e61b29 100644 --- a/src/expressions/operator-expr.md +++ b/src/expressions/operator-expr.md @@ -478,48 +478,17 @@ unsafe { assert_eq!(values[1], 3); ``` -#### Sized to sized pointer casts +#### Pointer-to-pointer cast -A sized pointer to pointer cast `*const T as *const U` or `*mut T as *mut U` -where `T: Sized` and `U: Sized` produces a value identical to the original -pointer. +`*const T` / `*mut T` can be cast to `*const U` / `*mut U` under the following +conditions: -#### Unsized to unsized pointer casts - -Any unsized to unsized pointer cast `*const T as *const U` or `*mut T as *mut U` -produces a value identical to the original pointer if `T` and `U` are compatible -unsized types. - -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)`. - -#### Unsized to sized pointer casts - -Any wide to narrow pointer cast discards all metadata that completes the wide -pointer and produces a thin base pointer. - -The following casts are well-defined: - -* `*const [T] to *const U` or `*mut [T] to *mut U` discards the length of the - slice and produces a pointer to the first element. The produced pointer is - casted to `U` in the same manner as a sized pointer to pointer cast. -* `*const dyn T to *const U` or `*mut dyn T to *mut U` discards all metadata - associated with the [trait object] and produces a pointer to the instance from - which the trait object was constructed. The produced pointer is casted to `U` - in the same manner as a sized pointer to pointer cast. - -For example: - -* `*const [u32] as *const u8` would produce a pointer to the first element - constituting the slice, casted to a `*const u8` pointer. -* `*const str` and `*mut str` have the same semantics as `*const [u8]` and `*mut - [u8]` since they have [identical layouts][_str_layout_]. +- If both `T` and `U` are sized, the cast produces a value identical to the + original pointer. +- If both `T` and `U` are unsized, the cast produces a value identical to the + original pointer if `T` and `U` are compatible unsized types. +- If `T` is unsized and `U` is sized, the cast discards all metadata that + completes the wide pointer `T` and produces a thin base pointer `U`. ## Assignment expressions @@ -704,8 +673,6 @@ See [this test] for an example of using this dependency. [undefined behavior]: ../behavior-considered-undefined.md [addr_of]: ../../std/ptr/macro.addr_of.html [addr_of_mut]: ../../std/ptr/macro.addr_of_mut.html -[slice]: ../types/slice.md -[trait object]: ../types/trait-object.md [_BorrowExpression_]: #borrow-operators [_DereferenceExpression_]: #the-dereference-operator @@ -722,4 +689,3 @@ See [this test] for an example of using this dependency. [_TypeNoBounds_]: ../types.md#type-expressions [_RangeExpression_]: ./range-expr.md [_UnderscoreExpression_]: ./underscore-expr.md -[_str_layout_]: ../type-layout.md#str-layout