@@ -478,15 +478,48 @@ unsafe {
478478assert_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