-
Notifications
You must be signed in to change notification settings - Fork 1.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
Add the experimental_keywords
ability
#2919
Conversation
Thank you for writing this up, @Lokathor! |
[rationale-and-alternatives]: #rationale-and-alternatives | ||
|
||
* Alternative: We could select _some other_ sequence of invalid tokens to use as a prefix for experimental keywords. | ||
* `r#$` is used because it is close enough to the "raw literal" and "raw string" syntaxes that people are very likely to understand what's going on even if they're not familiar with a specific experimental keyword when they first see it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this needs a justification for $
in particular. Why is r#$
better than r#@
, say? (Not that I think that one's necessarily superior, just that it's not clearly worse either.)
Historically macros have zealously guarded the use of $
for themselves, and it's not impossible to imagine someone trying to do ($mystring:literal) => { r#$mystring }
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Speaking as the RFC author: the current text simply reflects the "first thing that came to mind" during the discussion that lead to this proposal, with not much bike-shedding during that discussion.
Speaking as a user: either way is fine and I have no opinion.
So I'll happily put in whatever people want to decide on for this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
r#$mystring
doesn't work today, and I don't think it will ever work in the future. You can't just stick a r#
next to a lexed token to turn it into a raw string. Macro's use of $
shouldn't really matter here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@kennytm Sure, but macro authors use $
so commonly that it can cause confusion (they might think that r#$foo
can work). So why not reduce that confusion by choosing a different character?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well for sure there are plenty of alternatives we could choose.
spellings which currently are tokenization error:
r##keyword
r#[keyword]
r#@keyword
/r#!keyword
/ etcr#805209
br#haha_lang_design_go
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, br#keyword
was also mentioned in #2151.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only question I have while reading this thread is "why?".
Why come up with these contrived monstrosities messing with lexer if pretty much any combination of two existing keywords would work (do catch
style)?
If you want a generic tool for this (which is, again, excessive in my opinion), make __experimental
a keyword and use __experimental other_keyword
as the combination.
Isn't that just the same idea as That's pretty different from stabilizing an experimental form of a feature, which is what you're proposing here. Really, this RFC seems like it's asking for a much broader shift in direction than a mere change in keyword policy. Has it ever actually happened that we're ready to commit to the exact final design of a feature, but need to wait for the next edition to give it its final name? None of the features you mentioned satisfy that condition:
So I guess what you're really asking for is openness to stabilizing experimental designs for features, to be maintained indefinitely in parallel with the final design, which might be slightly different. Which sounds great to me. I think Rust has worked itself into a corner with the experiments-only-on-nightly policy. (But then I'm not the one who'd be maintaining old features in the compiler.) Still, if we're going to move in that direction, the RFC should be more clear about what it's proposing. For example: would stabilizing experimental keywords be appropriate: I think the answer should be yes to both, since such features are not less deserving of experimentation than ones with keyword availability issues. But I'm not sure what the RFC intends. |
To be absolutely clear, and perhaps this needs big bold text in the RFC, actually ever stabilizing an experimental keyword is on a feature by feature basis only. I'm writing this as part of a proposal from earlier today, so others can have their own opinions on this, but to me the primary benefit is to put off syntax bikeshed until after the feature is in nightly and able to be used, instead of having to settle it before the rfc for the feature can even be accepted to even start the work. |
I don't think there is any doubt that there should be a way to turn places into raw pointers without going through a reference. There is doubt whether |
Honestly, I'm extremely confused as to what's even being proposed here.
Isn't this exactly what already happens for... well, every feature with syntax? Because that's just what "nightly" is? This is exactly what |
Another example mentioned in the RFC is rust-lang/rust#64490. |
This is just a difference in terminology. You're describing the experimental-keyword iteration and the future final iteration as different "operations"; I'd call them two versions of the same feature, or in the terminology of the RFC, two "forms" of an "ability". Regardless, my point is that we would be stabilizing one thing with the intent to quickly deprecate it in favor of another thing, which wouldn't just have different syntax but also possibly different semantics. If it did have different semantics, the compiler would have to support two sets of semantics forever. In the case of But for other features it might be harder to justify. Again, I'm not against this RFC! I'm just saying it's more than an issue of syntax. Talking about keywords makes it sound like the long-term implementation burden is just having the lexer support two names for the same keyword. The reality is a risk of something more than that. |
Raw pointers are not going to go away no matter what other pointer types we add, so having If we end up also getting another pointer type, then the address-of operator for that, while solving similar problems to |
Co-authored-by: Jake Goulding <shepmaster@mac.com>
So This resolves the primary concern I had when looking at this RFC for the first time. Note that it turns I still don't see much motivation for this though. |
@petrochenkov No macro_rules! check {
($($x:tt)*) => {}
}
check!(r # $ abc);
check!(r#$abc); // this line errors (expected) |
huh, i honestly thought that it was a sequence of tokens too, just an invalid one. that's why i spaced it out in one spot. So that's worth writing down either way once we agree on what's what. |
If a sequence is acceptable we would have used |
Introduction of new token kinds will require extending proc macro APIs as well, which makes it even more of an overkill for something that I'm not sure is a problem at all. |
Wait, so assume we hypothetically stabilized Are you envisioning that we would then move to give the old-raw-pointer operator its own permanent name? In which case, the purpose of stabilizing it as Or are you envisioning that the old-raw-pointer operator would stay as |
I am not sure, honestly. I feel it could go either way, depending on other aspects of the new raw/unsafe pointer type. If it is truly a replacement for raw pointers and we'd basically deprecated |
It would also be possible to do this with an attribute: make the new keywords contextual keywords based on the presence of that attribute. eg. #[keyword(feature_name = foo)]
mod a {
// foo is a keyword
}
mod b {
// foo is not a keyword
} Then if the keyword changes, the attribute can be updated to remap the keyword appropriately so the code continues to work. |
@Diggsey This proposal is supposed to be usable on Stable (no |
@kennytm the keyword name would be whatever was specified in the attribute. You could think of it as being a procedural macro that just substitutes all instances of "foo" (because we used The only thing that would be stabilised is the name of the feature itself, although there's nothing stopping us from adding additional names for it. |
I see. But let's say we stabilized Can we nest macro_rules! foo1 {
() => { fn bar() {} }
}
#[keyword(feature_name = bar)]
mod a {
foo1!(); // ?
pub macro_rules! foo2() {
() => { /* code which involve the keyword */ bar; }
}
}
a::foo2!(); // ? |
@kennytm there are certainly several questions to answer, but of the ones you posed it doesn't seem to really matter what answers we choose as long as it's consistent. I don't see any back-compat problems because if a new keyword is indeed stabilised it will necessitate a new edition anyway: we already have the problem of macros being used across editions so we can go ahead and used the exact same rules here in terms of macro hygiene. |
Experience with vendor prefixes shows that this doesn't work, because:
|
Closing this since it's gone stagnant. If people want to continue the idea later they should open an issue for a major change proposal. |
rendered
I rushed a little bit, so we probably need extra words towards the end for the drawbacks / alternatives / etc., but it should overall be ready for serious feedback.