Closed
Description
This issue tracks the release notes text for #127679.
- Issue is nominated for the responsible team (and T-release nomination is removed).
- Proposed text is drafted by team responsible for underlying change.
- Issue is nominated for release team review of clarity for wider audience.
- Release team includes text in release notes/blog posts.
Release notes text:
The section title will be de-duplicated by the release team with other release notes issues.
Prefer to use the standard titles from previous releases.
More than one section can be included if needed.
# Language
- [Stabilize `&raw const` and `&raw mut` operators (RFC 2582)](https://github.com/rust-lang/rust/pull/127679)
Release blog section (if any, leave blank if no section is expected):
### Native syntax for creating a raw pointer
Unsafe code sometimes has to deal with pointers that may dangle, may be misaligned, or may not point to valid data. A common case where this comes up are packed structs. In such a case, it is important to avoid creating a reference, as that would cause undefined behavior. This means the usual `&` and `&mut` operators cannot be used, as those create a reference -- even if the reference is immediately cast to a raw pointer, it's too late to avoid the undefined behavior.
For several years, the macros `std::ptr::addr_of!` and `std::ptr::addr_of_mut!` have served this purpose. Now the time has come to provide a proper native syntax for this operation: `addr_of!(expr)` becomes `&raw const expr`, and `addr_of_mut!(expr)` becomes `&raw mut expr`. For example:
```rust
#[repr(packed)]
struct Packed {
not_aligned_field: i32,
}
fn main() {
let p = Packed { not_aligned_field: 1_82 };
// This would be undefined behavior!
// It is rejected by the compiler.
//let ptr = &p.not_aligned_field as *const i32;
// This is the old way of creating a pointer.
let ptr = std::ptr::addr_of!(p.not_aligned_field);
// This is the new way.
let ptr = &raw const p.not_aligned_field;
// Accessing the pointer has not changed.
// Note that `val = *ptr` would be undefined behavior because
// the pointer is not aligned!
let val = unsafe { ptr.read_unaligned() };
}
```
The native syntax makes it more clear that the operand expression of these operators is interpreted as a [place expression](https://www.ralfj.de/blog/2024/08/14/places.html). It also avoids the term "address-of" when referring to the action of creating a pointer. A pointer is [more than just an address](https://rust-lang.github.io/rfcs/3559-rust-has-provenance.html), so Rust is moving away from terms like "address-of" that reaffirm a false equivalence of pointers and addresses.