Skip to content

Tracking issue for release notes of #127679: Stabilize raw_ref_op (RFC 2582) #129576

Closed
@rustbot

Description

@rustbot

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    I-release-nominatedNominated for the release team.T-langRelevant to the language team, which will review and decide on the PR/issue.relnotesMarks issues that should be documented in the release notes of the next release.relnotes-tracking-issueMarks issues tracking what text to put in release notes.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions