Skip to content

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

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
1 of 4 tasks
rustbot opened this issue Aug 25, 2024 · 3 comments
Closed
1 of 4 tasks
Labels
I-release-nominated Nominated for the release team. relnotes Marks issues that should be documented in the release notes of the next release. relnotes-tracking-issue Marks issues tracking what text to put in release notes. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Milestone

Comments

@rustbot
Copy link
Collaborator

rustbot commented Aug 25, 2024

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.
@rustbot rustbot added I-release-nominated Nominated for the release team. relnotes Marks issues that should be documented in the release notes of the next release. needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. labels Aug 25, 2024
@Mark-Simulacrum Mark-Simulacrum added I-lang-nominated Nominated for discussion during a lang team meeting. and removed needs-triage This issue may need triage. Remove it if it has been sufficiently triaged. I-release-nominated Nominated for the release team. labels Aug 25, 2024
@Mark-Simulacrum Mark-Simulacrum added this to the 1.82.0 milestone Aug 25, 2024
@traviscross
Copy link
Contributor

@RalfJung: What do you think?

cc @rust-lang/lang

@RalfJung
Copy link
Member

RalfJung commented Aug 28, 2024

Here's a first version. Maybe this should be a joint blog section with #129578.

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:

#[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. It also avoids the term "address-of" when referring to the action of creating a pointer. A pointer is more than just an address, so Rust is moving away from terms like "address-of" that reaffirm a false equivalence of pointers and addresses.

@traviscross
Copy link
Contributor

Sounds good. Where you mention a place expression, let's link to your blog post:

https://www.ralfj.de/blog/2024/08/14/places.html

@Mark-Simulacrum Mark-Simulacrum added the relnotes-tracking-issue Marks issues tracking what text to put in release notes. label Sep 6, 2024
@traviscross traviscross added T-lang Relevant to the language team, which will review and decide on the PR/issue. relnotes Marks issues that should be documented in the release notes of the next release. I-release-nominated Nominated for the release team. relnotes-tracking-issue Marks issues tracking what text to put in release notes. and removed relnotes Marks issues that should be documented in the release notes of the next release. I-lang-nominated Nominated for discussion during a lang team meeting. relnotes-tracking-issue Marks issues tracking what text to put in release notes. labels Sep 24, 2024
@cuviper cuviper closed this as completed Oct 19, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
I-release-nominated Nominated for the release team. relnotes Marks issues that should be documented in the release notes of the next release. relnotes-tracking-issue Marks issues tracking what text to put in release notes. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants