Repository navigation
Closed
rust-lang/reference
#1567Labels
B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.Blocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCF-raw_ref_op`#![feature(raw_ref_op)]``#![feature(raw_ref_op)]`S-tracking-needs-summaryStatus: It's hard to tell what's been done and what hasn't! Someone should do some investigation.Status: It's hard to tell what's been done and what hasn't! Someone should do some investigation.T-langRelevant to the language teamRelevant to the language teamrequires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Description
This is a tracking issue for the RFC "an operator to take a raw reference" (rust-lang/rfcs#2582), feature(raw_ref_op).
Steps:
- Implement the RFC (see this comment for a detailed checklist)
- Adjust documentation (see instructions on rustc-guide): operator expressions: add &raw reference#1567
- Stabilization PR (see instructions on rustc-guide): Stabilize
raw_ref_op(RFC 2582) #127679
Unresolved questions:
(None left here, since the lint was moved to #127724)
Implementation history:
- Initial implementation: Add a raw "address of" operator #64588
Reacted by Stanislav Tkach, oilaba, Nano, Cherry and Mo Bitar
Metadata
Metadata
Assignees
Labels
B-RFC-approvedBlocker: Approved by a merged RFC but not yet implemented.Blocker: Approved by a merged RFC but not yet implemented.C-tracking-issueCategory: An issue tracking the progress of sth. like the implementation of an RFCCategory: An issue tracking the progress of sth. like the implementation of an RFCF-raw_ref_op`#![feature(raw_ref_op)]``#![feature(raw_ref_op)]`S-tracking-needs-summaryStatus: It's hard to tell what's been done and what hasn't! Someone should do some investigation.Status: It's hard to tell what's been done and what hasn't! Someone should do some investigation.T-langRelevant to the language teamRelevant to the language teamrequires-nightlyThis issue requires a nightly compiler in some way. When possible, use a F-* label instead.This issue requires a nightly compiler in some way. When possible, use a F-* label instead.
Activity
matthewjasper commentedon Sep 15, 2019
I'll try to get a PR open for this soon.
Centril commentedon Sep 15, 2019
I would suggest splitting the implementation work up into phases to make each part thoroughly reviewed and tested. However, think of this list as a bunch of tasks that need to be done at some point.
&raw [mut | const] $exprin the parser and AST.unused_parenslint works alright.safe_packed_borrowsa hard error when the feature gate is active, and make this the case as well forunsafeequivalents....but it seems @matthewjasper already has a PR heh.
Aaron1011 commentedon Sep 15, 2019
I'm not sure that this is a good idea. This would make it impossible to gradually migrate a codebase over to using raw references - once the feature gate is enabled, all references to packed structs must be fixed at once in order to get the crate building again.
moshg commentedon Sep 15, 2019
I wonder why not
&raw $exprbut&raw const $expr. Is there a discussion about this?mjbshaw commentedon Sep 15, 2019
@moshg Yes, this was discussed. See here (and the following comments) for an initial discussion. And here (and the following comments) for a signoff from grammar-wg. And here for an example that
&raw (expr)can be ambiguous.I think it might be worth amending the RFC to state why
&raw const $exprwas chosen over&raw $expr.Ixrec commentedon Sep 15, 2019
The RFC thread noted a couple times (including in the FCP comment) that
&raw exprwithout theconstconflicts with existing syntax and would break real code. rust-lang/rfcs#2582 (comment) goes into some detail. My understanding is that it is still possible to migrate to&raw exprwith breaking changes in an edition, and I didn't see much explicit discussion of that, but I think everyone agrees that there's enough urgency here that we definitely prefer making&raw const expra thing over blocking any solution on waiting for another edition.moshg commentedon Sep 16, 2019
@mjbshaw @lxrec
Thank you for your explanations! I've understood why
&raw $expris breaking change.RalfJung commentedon Sep 16, 2019
rust-lang/rfcs#2764
red75prime commentedon Oct 9, 2019
@RalfJung I'm addressing the points you've made in rust-lang/rfcs#2582 (comment)
While it would be helpful to have at least a warning for a promotion in
&mut <rvalue>case, disabling it is a backward incompatible change to the language. In&raw mut <rvalue>case it can be done from the beginning.I would expect
&raw mut <rvalue>to result in compilation error, as&<rvalue>does in C.I have an impression that silently allowing such promotions is more error prone, as it violates the principle of least surprise.
oli-obk commentedon Oct 9, 2019
yes, promotion has nothing to do with it as far as I can tell.
I agree. We should error on any
&raw placewhereplaceDerefprojections (*) orIndex([i]) projectionssince we still want to permit
&raw *foo()I would assume. Or more concretely&raw foo().barwhenfoo()returns a reference.If "erroring if not" has too many negations (i confused myself in the process of writing this), here's a version of what I think we should permit (and only that):
We should permit
&raw placeonly ifplaceDerefprojections orIndexprojections83 remaining items
CAD97 commentedon Jun 23, 2022
It's also my recollection that there were no blocking concerns on the grammar or parsing side.
There were three questions I recall without a definitive answer:
&raw $placeversus&raw const $place, and whether the syntax should be evoking*const Tor&T.&raw (expr)still requires makingrawa contextual keyword here. But the question is whetherconstis just a concession to parsing that we'd prefer to remove, or if it's desirable as evocative of*const T.&raw const $placegiving a read-only pointer even when used on a writable place is contentious.&raw const (*ptr).fieldrequires fromptr— is itgepiorgep, and the related generality/optimization toggles.Additionally, there is one big "shiny future" possibility:
&raw const T(or just&raw T, or&'unsafe T, or any other number of possibilities) for a "better raw pointer" type. The problems and footguns with working with the existing*[const|mut] Tandptr::NonNull<T>are well documented and I won't rehash them here. If in a shiny future we get a built-in nicer raw pointer type,&raw [const|mut] Tis currently the most promising syntax for creating a raw pointer (and that's why it's used here), and it'd be a shame to have worse syntax for the better thing, and better syntax for the worse thing.(But seriously, go read every single thing @Gankra has written about pointers.)
To be clear: I'm not arguing we shouldn't improve what we have because we might be able to do it better in the future. Rather, there are existing proposals that show we really should consider
If we had a time machine, what would we want Rust pointers to look like?
and how close can we realistically get to that ideal?
I think we can get close enough that Rust is a contender for the best language to write C in. This isn't the case currently because of how easy it is to incidentally introduce reference semantics into pointer code (along with other papercuts), but I have faith that we can make it there.
So I guess the conclusion of this is:
&rawhasn't stabilized yet because while it is agreeably the best implementation of this solution to this problem, we're still not necessarily in agreement that this is the correct problem to be solving.Given a magical grant of bandwidth, this is what I personally think should be the path forward:
&raw $placesyntax 🎉&raw T:&raw $placemakes them and not* [const|mut] Tptr::NonNull<T>)& {?} $placesyntax space&raw $placesyntax to make today's Rust significantly better 🎉(And to try to predict the future: I predict that a far-future pointer-perfect Rust has refinement typing for pointers and that
ptr::NonNullandptr::WellFormedare aliases for the namable refined pointer types that can cross function boundaries. Prefix deref is deprecated in favor of.read()/.write()/.as_ref()/.as_mut()and.for safe field offsetting,~for unsafe GEPi field offsetting.container_of!is still, as usual, a controversial nightmare.)Update Rust crate syn to v2 (#396)
fix(deps): update rust crate syn to v2 (#2512)
RalfJung commentedon Mar 16, 2024
Seems like we are still at this stage. So if someone wants to push this forward, working on such a document would be the best way to help. :)
RalfJung commentedon Mar 17, 2024
On the other hand, if we are getting a better raw pointer type in the future, we always have the option of using an edition transition to change the meaning of
&raw. So maybe we should just stabilize what we got so that we can finally stop using a macro for this?RalfJung commentedon Aug 15, 2024
Stabilization of this feature is in FCP over at #127679. :)
Auto merge of rust-lang#127679 - RalfJung:raw_ref_op, r=<try>
Auto merge of rust-lang#127679 - RalfJung:raw_ref_op, r=<try>
Rollup merge of rust-lang#127679 - RalfJung:raw_ref_op, r=traviscross…
Rollup merge of rust-lang#127679 - RalfJung:raw_ref_op, r=jieyouxu
Unrolled build for rust-lang#127679
Rollup merge of #127679 - RalfJung:raw_ref_op, r=jieyouxu
Rollup merge of #127679 - RalfJung:raw_ref_op, r=jieyouxu
Rollup merge of #127679 - RalfJung:raw_ref_op, r=jieyouxu