-
Notifications
You must be signed in to change notification settings - Fork 12.6k
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
Stabilize raw_ref_op
(RFC 2582)
#127679
Conversation
This comment was marked as resolved.
This comment was marked as resolved.
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 |
@rust-lang/lang nominating for discussion. See the PR description for a summary of all relevant details. :) Cc @rust-lang/opsem |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
a16b5eb
to
069b996
Compare
I'm having mixed feelings, but it's really just... vibes I guess. Overall I've found using `addr_of!` to be "kind of ok". Obviously `&raw const a.b` is more built-in, but I'm not 100% convinced it carries its weight, and it looks "kind of funny". Though I do want to make authoring unsafe code more ergonomic in general; I don't subscribe to the philosophy that we ought to add syntactic salt just because it's unsafe, in fact I think that's quite counterproductive.
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. |
@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. |
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 |
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. |
... does those test need blessing, or is this comment outdated I wonder |
Probably just needs blessing. @bors r- |
@bors r=jieyouxu |
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
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
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
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.
Since the stabilization in rust-lang#127679 has reached stage0, 1.82-beta, we can start using `&raw` freely, and even the soft-deprecated `ptr::addr_of!` and `ptr::addr_of_mut!` can stop allowing the unstable feature. I intentionally did not change any documentation or tests, but the rest of those macro uses are all now using `&raw const` or `&raw mut` in the standard library.
…ss35 Use `&raw` in the standard library Since the stabilization in rust-lang#127679 has reached stage0, 1.82-beta, we can start using `&raw` freely, and even the soft-deprecated `ptr::addr_of!` and `ptr::addr_of_mut!` can stop allowing the unstable feature. I intentionally did not change any documentation or tests, but the rest of those macro uses are all now using `&raw const` or `&raw mut` in the standard library.
Use `&raw` in the standard library Since the stabilization in rust-lang#127679 has reached stage0, 1.82-beta, we can start using `&raw` freely, and even the soft-deprecated `ptr::addr_of!` and `ptr::addr_of_mut!` can stop allowing the unstable feature. I intentionally did not change any documentation or tests, but the rest of those macro uses are all now using `&raw const` or `&raw mut` in the standard library.
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 theaddr_of
andaddr_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: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.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 termaddr
in two different ways is quite unfortunate. That's why this PR soft-deprecatesaddr_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:
&raw const *mut_ref
give a read-only pointer?*const T
and*mut T
. Initially*const T
pointers are forever read-only? unsafe-code-guidelines#257&raw const (*ptr).field
require? Answered in the reference: the arithmetic to compute the field offset follows the rules ofptr::offset
, making it UB if it goes out-of-bounds. Making this a safe operation (usingwrapping_offset
rules) is considered too much of a loss for alias analysis.&raw $place
instead of&raw const $place
, which (IIUC) could be achieved by makingraw
a contextual keyword in a new edition. The type is named*const T
, so the explicitconst
is consistent in that regard.&raw expr
lacks the explicit indication of immutability. However,&raw const expr
is quite a but longer thanaddr_of!(expr)
.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.)&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 forstatic mut
a lint suggesting raw pointers is being rolled out.offsetof
woes: we now have nativeoffset_of
so this is not relevant any more.To be done before landing:
unused_parens
lint around&raw {const|mut}
expressionsraw_ref_op
(RFC 2582) #127679 (comment) for rationaleFixes #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