-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
syntax: Make _
a reserved identifier
#48842
Conversation
r? @aturon (rust_highfive has picked a reviewer for you, use r? to override) |
cc @rust-lang/lang |
(0, Invalid, "") | ||
(1, CrateRoot, "{{root}}") | ||
(2, DollarCrate, "$crate") | ||
(3, Underscore, "_") |
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 can move it into the keyword list below, the only difference would be whether error messages say "keyword _
" or "reserved identifier _
".
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 "reserved identifier" is better than "keyword" as it doesn't really look/feel like a keyword.
|
I agree with @rkruppe. I don't want |
I also think this also conflicts with one of the alternatives to |
@Centril
|
_
an identifier_
a reserved identifier
👍 to that plan, this is what I was going to suggest. |
Updated with |
Ok, I guess I'll have to tweak the |
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, the code seems fine modulo one nit -- but remind me, what is the motivation for this change again? =)
src/libsyntax/ext/tt/macro_parser.rs
Outdated
@@ -725,7 +725,7 @@ fn may_begin_with(name: &str, token: &Token) -> bool { | |||
match name { | |||
"expr" => token.can_begin_expr(), | |||
"ty" => token.can_begin_type(), | |||
"ident" => token.is_ident(), | |||
"ident" => token.is_ident() && !token.is_keyword(keywords::Underscore), |
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.
can we add some sort of helper for this check, like is_macro_ident
?
src/libsyntax/ext/tt/macro_parser.rs
Outdated
"ident" => match p.token { | ||
token::Ident(sn) => { | ||
token::Ident(sn) if sn.name != keywords::Underscore.name() => { |
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.
we could then use the helper here too, rather than open-coding this
Wait: one other question .. is |
Re-read motivation from the intro. r=me with nit addressed -- presuming |
@nikomatsakis We can prohibit this for consistency (both |
One more important thing that I didn't mention - |
@petrochenkov @jseyfried IMO we should just switch to relying on |
This reminded me of something - (This is totally orthogonal to this PR though, it would still be more convenient for |
Question: given that #48942 is already in flight, should |
I believe that indeed |
Well, I'm mildly reconsidering that -- see this comment |
@bors r=nikomatsakis |
📌 Commit ed5ea5c has been approved by |
syntax: Make `_` a reserved identifier Why: - Lexically `_` is an identifier. - Internally it makes implementation of `use Trait as _;` (#48216) and some other things cleaner. - We prevent the externally observable effect of `_` being accepted by macros expecting `ident` by treating `_` specially in the `ident` matcher: ```rust macro_rules! m { ($i: ident) => { let $i = 10; } } m!(_); // Still an error ```
☀️ Test successful - status-appveyor, status-travis |
AST: Give spans to all identifiers Change representation of `ast::Ident` from `{ name: Symbol, ctxt: SyntaxContext }` to `{ name: Symbol, span: Span }`. Syntax contexts still can be extracted from spans (`span.ctxt()`). Why this should not require more memory: - `Span` is `u32` just like `SyntaxContext`. - Despite keeping more spans in AST we don't actually *create* more spans, so the number of "outlined" spans kept in span interner shouldn't become larger. Why this may be slightly slower: - When we need to extract ctxt from an identifier instead of just field read we need to do bit field extraction possibly followed by and access by index into span interner's vector. Both operations should be fast (unless the span interner is under some synchronization) and we already do ctxt extraction from spans all the time during macro expansion, so the difference should be lost in noise. cc rust-lang#48842 (comment)
AST: Give spans to all identifiers Change representation of `ast::Ident` from `{ name: Symbol, ctxt: SyntaxContext }` to `{ name: Symbol, span: Span }`. Syntax contexts still can be extracted from spans (`span.ctxt()`). Why this should not require more memory: - `Span` is `u32` just like `SyntaxContext`. - Despite keeping more spans in AST we don't actually *create* more spans, so the number of "outlined" spans kept in span interner shouldn't become larger. Why this may be slightly slower: - When we need to extract ctxt from an identifier instead of just field read we need to do bit field extraction possibly followed by and access by index into span interner's vector. Both operations should be fast (unless the span interner is under some synchronization) and we already do ctxt extraction from spans all the time during macro expansion, so the difference should be lost in noise. cc #48842 (comment)
8122: Make bare underscore token an Ident rather than Punct in proc-macro r=edwin0cheng a=kevinmehall In rustc and proc-macro2, a bare `_` token is parsed for procedural macro purposes as `Ident` rather than `Punct` (see rust-lang/rust#48842). This changes rust-analyzer to match rustc's behavior and implementation by handling `_` as an Ident in token trees, but explicitly preventing `$x:ident` from matching it in MBE. proc macro crate: ```rust #[proc_macro] pub fn input(input: proc_macro::TokenStream) -> proc_macro::TokenStream { dbg!(input) } ``` test crate: ```rust test_proc_macro::input!(_); ``` output (rustc): ```rust [test-proc-macro/src/lib.rs:10] input = TokenStream [ Ident { ident: "_", span: #0 bytes(173..174), }, ] ``` output (rust-analyzer before this change): ```rust [test-proc-macro/src/lib.rs:10] input = TokenStream [ Punct { ch: '_', spacing: Joint, span: 4294967295, }, ] ``` output (rust-analyzer after this change): ```rust [test-proc-macro/src/lib.rs:10] input = TokenStream [ Ident { ident: "_", span: 4294967295, }, ] ``` Co-authored-by: Kevin Mehall <km@kevinmehall.net>
Why:
_
is an identifier.use Trait as _;
(Tracking issue for RFC #2166: impl-only-use #48216) and some other things cleaner._
being accepted by macros expectingident
by treating_
specially in theident
matcher: