Skip to content

Commit

Permalink
Merge pull request #1451 from udoprog/document-ptr-casts
Browse files Browse the repository at this point in the history
Clarify semantics of the various pointer to pointer casts
  • Loading branch information
ehuss committed Feb 21, 2024
2 parents 405242b + 97c9ad1 commit b25c20b
Showing 1 changed file with 27 additions and 8 deletions.
35 changes: 27 additions & 8 deletions src/expressions/operator-expr.md
Original file line number Diff line number Diff line change
Expand Up @@ -478,15 +478,20 @@ 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

Expand Down Expand Up @@ -687,3 +692,17 @@ See [this test] for an example of using this dependency.
[_TypeNoBounds_]: ../types.md#type-expressions
[_RangeExpression_]: ./range-expr.md
[_UnderscoreExpression_]: ./underscore-expr.md

<script>
(function() {
var fragments = {
"#slice-dst-pointer-to-pointer-cast": "operator-expr.html#pointer-to-pointer-cast",
};
var target = fragments[window.location.hash];
if (target) {
var url = window.location.toString();
var base = url.substring(0, url.lastIndexOf('/'));
window.location.replace(base + "/" + target);
}
})();
</script>

0 comments on commit b25c20b

Please sign in to comment.