Closed
Description
In the following example self
is accepted as an ident
in a macro, that is an identifier:
#![allow(dead_code)]
macro_rules! foo {
($this:ident) => ($this)
}
struct Bar;
impl Bar {
fn bar(self) -> Self { foo!(self) }
}
fn main() {}
But the following doesn't work:
#![allow(dead_code)]
macro_rules! foo {
($self:ident) => ($self)
}
struct Bar;
impl Bar {
fn bar(self) -> Self { foo!(self) }
}
fn main() {}
Note: the same occurs on all current 3 channels (1.2.0, 1.3.0beta, 1.4.0nightly)
With the following error: expected identifier, found keyword self
It's a small inconsistency, but it's there nonetheless, self
is accepted as an identifier for using a macro but not for declaring a macro.
Naturally it can't be rejected as a macro argument expecting ident
for compatibility, and it would be weird to accept it as an identifier outside of macro arguments. But I thought this should be brought up.
Metadata
Metadata
Assignees
Type
Projects
Milestone
Relationships
Development
No branches or pull requests
Activity
pub(restricted)
privacy (RFC 1422) #32875petrochenkov commentedon Apr 16, 2016
The fact that you can't declare new items with keywords is certainly intended.
$self: ident
is prohibited for the same reason whylet self = 10;
orstruct self { field: u8 }
are prohibited.Referencing existing entities with keywords is possible in some cases - keywords
super
,self
andSelf
can be used as segments in paths (including paths with one segment).ident
nonterminal acceptingself
is strange, becauseself
can't be used everywhere where identifiers can be used.However,
ident
seems to accept not only valid identifiers, but everything fitting intotoken::Ident
- identifiers, keywords, reserved keywords - and errors (like the one from your example) are caught during macro expansion and not at macro use.This seems to be a pretty reasonable approach, albeit surprising, and is probably intended.
I suppose,
ident
can be backward compatibly restricted to reject keywords and reserved identifiers with exception of path segment keywordssuper
,self
andSelf
(because you may want to write things like$seg: ident => $seg::foo::bar
), but I don't see much benefit from such restriction.Basically, I'd close this as Not-a-Bug, but need a confirmation from someone, cc @nrc
nrc commentedon Apr 18, 2016
Agree with @petrochenkov. For all the macro token classifiers, I would treat
foo
as meaning 'vaguely foo like', otherwise we would end up with hundreds of classifiers and it would be awkward to write macros. This has some downsides in terms of catching errors a bit later than is optimal, but I think the trade-off is OK here.macro_rules!
thinksuse
is anident
. It isn't. #40569ident
should not match keywords rust-lang/rfcs#772const
considered as a potential identifier in macro_rules pattern #117099