Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Stabilize raw_ref_op (RFC 2582) #127679

Merged
merged 3 commits into from
Aug 19, 2024
Merged

Stabilize raw_ref_op (RFC 2582) #127679

merged 3 commits into from
Aug 19, 2024

Conversation

RalfJung
Copy link
Member

@RalfJung RalfJung commented Jul 13, 2024

This stabilizes the syntax &raw const $expr and &raw mut $expr. It has existed unstably for ~4 years now, and has been exposed on stable via the addr_of and addr_of_mut macros since Rust 1.51 (released more than 3 years ago). I think it has become clear that these operations are here to stay. So it is about time we give them proper primitive syntax. This has two advantages over the macro:

  • Being macros, addr_of/addr_of_mut could in theory do arbitrary magic with the expression on which they work. The only "magic" they actually do is using the argument as a place expression rather than as a value expression. Place expressions are already a subtle topic and poorly understood by many programmers; having this hidden behind a macro using unstable language features makes this even worse. Conversely, people do have an idea of what happens below &/&mut, so we can make the subtle topic a lot more approachable by connecting to existing intuition.
  • The name addr_of is quite unfortunate from today's perspective, given that we have accepted provenance as a reality, which means that a pointer is not just an address. Strict provenance has a method, addr, which extracts the address of a pointer; using the term addr in two different ways is quite unfortunate. That's why this PR soft-deprecates addr_of -- we will wait a long time before actually showing any warning here, but we should start telling people that the "addr" part of this name is somewhat misleading, and &raw avoids that potential confusion.

In summary, this syntax improves developers' ability to conceptualize the operational semantics of Rust, while making a fundamental operation frequently used in unsafe code feel properly built in.

Possible questions to consider, based on the RFC and this great summary by @CAD97:

  • Some questions are entirely about the semantics. The semantics are the same as with the macros so I don't think this should have any impact on this syntax PR. Still, for completeness' sake:
  • Choose a different syntax? I don't want to re-litigate the RFC. The only credible alternative that has been proposed is &raw $place instead of &raw const $place, which (IIUC) could be achieved by making raw a contextual keyword in a new edition. The type is named *const T, so the explicit const is consistent in that regard. &raw expr lacks the explicit indication of immutability. However, &raw const expr is quite a but longer than addr_of!(expr).
  • Shouldn't we have a completely new, better raw pointer type instead? Yes we all want to see that happen -- but I don't think we should block stabilization on that, given that such a nicer type is not on the horizon currently and given the issues with addr_of! mentioned above. (If we keep the &raw $place syntax free for this, we could use it in the future for that new type.)
  • What about the lint the RFC talked about? It hasn't been implemented yet. Given that the problematic code is UB with or without this stabilization, I don't think the lack of the lint should block stabilization.
  • Other points from the "future possibilites of the RFC
    • "Syntactic sugar" extension: this has not been implemented. I'd argue this is too confusing, we should stick to what the RFC suggested and if we want to do anything about such expressions, add the lint.
    • Encouraging / requiring &raw in situations where references are often/definitely incorrect: this has been / is being implemented. On packed fields this already is a hard error, and for static mut a lint suggesting raw pointers is being rolled out.
    • Lowering of casts: this has been implemented. (It's also an invisible implementation detail.)
    • offsetof woes: we now have native offset_of so this is not relevant any more.

To be done before landing:

Fixes #64490

cc @rust-lang/lang @rust-lang/opsem

try-job: x86_64-msvc
try-job: test-various
try-job: dist-various-1
try-job: armhf-gnu
try-job: aarch64-apple

@rustbot
Copy link
Collaborator

rustbot commented Jul 13, 2024

r? @TaKO8Ki

rustbot has assigned @TaKO8Ki.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rustbot

This comment was marked as resolved.

@rustbot rustbot added PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jul 13, 2024
@rustbot
Copy link
Collaborator

rustbot commented Jul 13, 2024

Some changes occurred in compiler/rustc_codegen_cranelift

cc @bjorn3

Some changes occurred in src/tools/cargo

cc @ehuss

Some changes occurred in tests/ui/sanitizer

cc @rust-lang/project-exploit-mitigations, @rcvalle

The Miri subtree was changed

cc @rust-lang/miri

Some changes occurred in compiler/rustc_codegen_gcc

cc @antoyo, @GuillaumeGomez

@RalfJung RalfJung added T-lang Relevant to the language team, which will review and decide on the PR/issue. I-lang-nominated Nominated for discussion during a lang team meeting. and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. PG-exploit-mitigations Project group: Exploit mitigations labels Jul 13, 2024
@RalfJung
Copy link
Member Author

@rust-lang/lang nominating for discussion. See the PR description for a summary of all relevant details. :)

Cc @rust-lang/opsem

@RalfJung RalfJung added the relnotes Marks issues that should be documented in the release notes of the next release. label Jul 13, 2024
@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added the PG-exploit-mitigations Project group: Exploit mitigations label Jul 13, 2024
@rust-log-analyzer

This comment has been minimized.

@RalfJung RalfJung force-pushed the raw_ref_op branch 2 times, most recently from a16b5eb to 069b996 Compare July 14, 2024 06:13
@traviscross traviscross changed the title stabilize raw_ref_op Stabilize raw_ref_op Jul 15, 2024
@traviscross traviscross changed the title Stabilize raw_ref_op Stabilize raw_ref_op (RFC 2582) Jul 15, 2024
@nikomatsakis
Copy link
Contributor

nikomatsakis commented Jul 15, 2024 via email

@saethlin
Copy link
Member

saethlin commented Jul 15, 2024

I think for me the bigger challenge is that I'm still not 100% clear on the "mental model" for validity requirements of references vs raw pointers.

How is that related to this stabilization? I follow the rest of your comment, but not this last bit.

@RalfJung
Copy link
Member Author

@nikomatsakis what about the two first points in the PR, the arguments in favor of stabilizing this?

I am happy to elaborate on the raw pointer op.sem and what is and is not UB, if you have any specific questions.

@joshtriplett
Copy link
Member

I'm going to go ahead and propose FCP, to asynchronously see how close we are to consensus. (This does not preclude the filing of concerns.)

@rfcbot merge

@rfcbot
Copy link

rfcbot commented Jul 22, 2024

Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:

Concerns:

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

cc @rust-lang/lang-advisors: FCP proposed for lang, please feel free to register concerns.
See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Proposed to merge/close by relevant subteam, see T-<team> label. Will enter FCP once signed off. disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. labels Jul 22, 2024
@bors
Copy link
Contributor

bors commented Aug 18, 2024

📌 Commit d139705 has been approved by jieyouxu

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 18, 2024
@rust-log-analyzer

This comment has been minimized.

@jieyouxu
Copy link
Member

... does those test need blessing, or is this comment outdated I wonder

@RalfJung
Copy link
Member Author

Probably just needs blessing.

@bors r-

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Aug 18, 2024
@RalfJung
Copy link
Member Author

@bors r=jieyouxu

@bors
Copy link
Contributor

bors commented Aug 18, 2024

📌 Commit 35709be has been approved by jieyouxu

It is now in the queue for this repository.

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Aug 18, 2024
bors added a commit to rust-lang-ci/rust that referenced this pull request Aug 19, 2024
Rollup of 7 pull requests

Successful merges:

 - rust-lang#127679 (Stabilize `raw_ref_op` (RFC 2582))
 - rust-lang#128084 (Suggest adding Result return type for associated method in E0277.)
 - rust-lang#128628 (When deduplicating unreachable blocks, erase the source information.)
 - rust-lang#128902 (doc: std::env::var: Returns None for names with '=' or NUL byte)
 - rust-lang#129048 (Update `crosstool-ng` for loongarch64)
 - rust-lang#129116 (Include a copy of `compiler-rt` source in the `download-ci-llvm` tarball)
 - rust-lang#129208 (Fix order of normalization and recursion in const folding.)

r? `@ghost`
`@rustbot` modify labels: rollup
@bors bors merged commit f27a9b1 into rust-lang:master Aug 19, 2024
6 checks passed
@rustbot rustbot added this to the 1.82.0 milestone Aug 19, 2024
rust-timer added a commit to rust-lang-ci/rust that referenced this pull request Aug 19, 2024
Rollup merge of rust-lang#127679 - RalfJung:raw_ref_op, r=jieyouxu

Stabilize `raw_ref_op` (RFC 2582)

This stabilizes the syntax `&raw const $expr` and `&raw mut $expr`. It has existed unstably for ~4 years now, and has been exposed on stable via the `addr_of` and `addr_of_mut` macros since Rust 1.51 (released more than 3 years ago). I think it has become clear that these operations are here to stay. So it is about time we give them proper primitive syntax. This has two advantages over the macro:

- Being macros, `addr_of`/`addr_of_mut` could in theory do arbitrary magic with the expression on which they work. The only "magic" they actually do is using the argument as a place expression rather than as a value expression. Place expressions are already a subtle topic and poorly understood by many programmers; having this hidden behind a macro using unstable language features makes this even worse. Conversely, people do have an idea of what happens below `&`/`&mut`, so we can make the subtle topic a lot more approachable by connecting to existing intuition.
- The name `addr_of` is quite unfortunate from today's perspective, given that we have accepted provenance as a reality, which means that a pointer is *not* just an address. Strict provenance has a method, `addr`, which extracts the address of a pointer; using the term `addr` in two different ways is quite unfortunate. That's why this PR soft-deprecates `addr_of` -- we will wait a long time before actually showing any warning here, but we should start telling people that the "addr" part of this name is somewhat misleading, and `&raw` avoids that potential confusion.

In summary, this syntax improves developers' ability to conceptualize the operational semantics of Rust, while making a fundamental operation frequently used in unsafe code feel properly built in.

Possible questions to consider, based on the RFC and [this](rust-lang#64490 (comment)) great summary by `@CAD97:`

- Some questions are entirely about the semantics. The semantics are the same as with the macros so I don't think this should have any impact on this syntax PR. Still, for completeness' sake:
  - Should `&raw const *mut_ref` give a read-only pointer?
    - Tracked at: rust-lang/unsafe-code-guidelines#257
    - I think ideally the answer is "no". Stacked Borrows says that pointer is read-only, but Tree Borrows says it is mutable.
  - What exactly does `&raw const (*ptr).field` require? Answered in [the reference](https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html): the arithmetic to compute the field offset follows the rules of `ptr::offset`, making it UB if it goes out-of-bounds. Making this a safe operation (using `wrapping_offset` rules) is considered too much of a loss for alias analysis.
- Choose a different syntax? I don't want to re-litigate the RFC. The only credible alternative that has been proposed is `&raw $place` instead of `&raw const $place`, which (IIUC) could be achieved by making `raw` a contextual keyword in a new edition. The type is named `*const T`, so the explicit `const` is consistent in that regard. `&raw expr` lacks the explicit indication of immutability. However, `&raw const expr` is quite a but longer than `addr_of!(expr)`.
- Shouldn't we have a completely new, better raw pointer type instead? Yes we all want to see that happen -- but I don't think we should block stabilization on that, given that such a nicer type is not on the horizon currently and given the issues with `addr_of!` mentioned above. (If we keep the `&raw $place` syntax free for this, we could use it in the future for that new type.)
- What about the lint the RFC talked about? It hasn't been implemented yet.  Given that the problematic code is UB with or without this stabilization, I don't think the lack of the lint should block stabilization.
  - I created an issue to track adding it: rust-lang#127724
- Other points from the "future possibilites of the RFC
  - "Syntactic sugar" extension: this has not been implemented. I'd argue this is too confusing, we should stick to what the RFC suggested and if we want to do anything about such expressions, add the lint.
  - Encouraging / requiring `&raw` in situations where references are often/definitely incorrect: this has been / is being implemented. On packed fields this already is a hard error, and for `static mut` a lint suggesting raw pointers is being rolled out.
  - Lowering of casts: this has been implemented. (It's also an invisible implementation detail.)
  - `offsetof` woes: we now have native `offset_of` so this is not relevant any more.

To be done before landing:

- [x] Suppress `unused_parens` lint around `&raw {const|mut}` expressions
  - See bottom of rust-lang#127679 (comment) for rationale
  - Implementation: rust-lang#128782
- [ ] Update the Reference.
  - rust-lang/reference#1567

Fixes rust-lang#64490

cc `@rust-lang/lang` `@rust-lang/opsem`

try-job: x86_64-msvc
try-job: test-various
try-job: dist-various-1
try-job: armhf-gnu
try-job: aarch64-apple
@RalfJung RalfJung deleted the raw_ref_op branch August 19, 2024 11:33
github-actions bot pushed a commit to rust-lang/miri that referenced this pull request Aug 20, 2024
Stabilize `raw_ref_op` (RFC 2582)

This stabilizes the syntax `&raw const $expr` and `&raw mut $expr`. It has existed unstably for ~4 years now, and has been exposed on stable via the `addr_of` and `addr_of_mut` macros since Rust 1.51 (released more than 3 years ago). I think it has become clear that these operations are here to stay. So it is about time we give them proper primitive syntax. This has two advantages over the macro:

- Being macros, `addr_of`/`addr_of_mut` could in theory do arbitrary magic with the expression on which they work. The only "magic" they actually do is using the argument as a place expression rather than as a value expression. Place expressions are already a subtle topic and poorly understood by many programmers; having this hidden behind a macro using unstable language features makes this even worse. Conversely, people do have an idea of what happens below `&`/`&mut`, so we can make the subtle topic a lot more approachable by connecting to existing intuition.
- The name `addr_of` is quite unfortunate from today's perspective, given that we have accepted provenance as a reality, which means that a pointer is *not* just an address. Strict provenance has a method, `addr`, which extracts the address of a pointer; using the term `addr` in two different ways is quite unfortunate. That's why this PR soft-deprecates `addr_of` -- we will wait a long time before actually showing any warning here, but we should start telling people that the "addr" part of this name is somewhat misleading, and `&raw` avoids that potential confusion.

In summary, this syntax improves developers' ability to conceptualize the operational semantics of Rust, while making a fundamental operation frequently used in unsafe code feel properly built in.

Possible questions to consider, based on the RFC and [this](rust-lang/rust#64490 (comment)) great summary by `@CAD97:`

- Some questions are entirely about the semantics. The semantics are the same as with the macros so I don't think this should have any impact on this syntax PR. Still, for completeness' sake:
  - Should `&raw const *mut_ref` give a read-only pointer?
    - Tracked at: rust-lang/unsafe-code-guidelines#257
    - I think ideally the answer is "no". Stacked Borrows says that pointer is read-only, but Tree Borrows says it is mutable.
  - What exactly does `&raw const (*ptr).field` require? Answered in [the reference](https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html): the arithmetic to compute the field offset follows the rules of `ptr::offset`, making it UB if it goes out-of-bounds. Making this a safe operation (using `wrapping_offset` rules) is considered too much of a loss for alias analysis.
- Choose a different syntax? I don't want to re-litigate the RFC. The only credible alternative that has been proposed is `&raw $place` instead of `&raw const $place`, which (IIUC) could be achieved by making `raw` a contextual keyword in a new edition. The type is named `*const T`, so the explicit `const` is consistent in that regard. `&raw expr` lacks the explicit indication of immutability. However, `&raw const expr` is quite a but longer than `addr_of!(expr)`.
- Shouldn't we have a completely new, better raw pointer type instead? Yes we all want to see that happen -- but I don't think we should block stabilization on that, given that such a nicer type is not on the horizon currently and given the issues with `addr_of!` mentioned above. (If we keep the `&raw $place` syntax free for this, we could use it in the future for that new type.)
- What about the lint the RFC talked about? It hasn't been implemented yet.  Given that the problematic code is UB with or without this stabilization, I don't think the lack of the lint should block stabilization.
  - I created an issue to track adding it: rust-lang/rust#127724
- Other points from the "future possibilites of the RFC
  - "Syntactic sugar" extension: this has not been implemented. I'd argue this is too confusing, we should stick to what the RFC suggested and if we want to do anything about such expressions, add the lint.
  - Encouraging / requiring `&raw` in situations where references are often/definitely incorrect: this has been / is being implemented. On packed fields this already is a hard error, and for `static mut` a lint suggesting raw pointers is being rolled out.
  - Lowering of casts: this has been implemented. (It's also an invisible implementation detail.)
  - `offsetof` woes: we now have native `offset_of` so this is not relevant any more.

To be done before landing:

- [x] Suppress `unused_parens` lint around `&raw {const|mut}` expressions
  - See bottom of rust-lang/rust#127679 (comment) for rationale
  - Implementation: rust-lang/rust#128782
- [ ] Update the Reference.
  - rust-lang/reference#1567

Fixes rust-lang/rust#64490

cc `@rust-lang/lang` `@rust-lang/opsem`

try-job: x86_64-msvc
try-job: test-various
try-job: dist-various-1
try-job: armhf-gnu
try-job: aarch64-apple
@apiraino apiraino removed the to-announce Announce this issue on triage meeting label Aug 22, 2024
@Mark-Simulacrum Mark-Simulacrum added relnotes Marks issues that should be documented in the release notes of the next release. and removed relnotes Marks issues that should be documented in the release notes of the next release. labels Aug 25, 2024
github-merge-queue bot pushed a commit to model-checking/kani that referenced this pull request Aug 28, 2024
Upgrades toolchain to 08/28

Culprit upstream changes:
1. rust-lang/rust#128812
2. rust-lang/rust#128703
3. rust-lang/rust#127679
4. rust-lang/rust-clippy#12993
5. rust-lang/cargo#14370
6. rust-lang/rust#128806

Resolves #3429
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This issue / PR is in PFCP or FCP with a disposition to merge it. F-raw_ref_op `#![feature(raw_ref_op)]` finished-final-comment-period The final comment period is finished for this PR / Issue. PG-exploit-mitigations Project group: Exploit mitigations relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. T-opsem Relevant to the opsem team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Tracking issue for RFC 2582, &raw [mut | const] $place (raw_ref_op)