Skip to content
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

Small inconsistency with self: keyword but sometimes ident #27899

Closed
jansegre opened this issue Aug 19, 2015 · 2 comments
Closed

Small inconsistency with self: keyword but sometimes ident #27899

jansegre opened this issue Aug 19, 2015 · 2 comments
Labels
T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@jansegre
Copy link

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() {}

on playpen

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() {}

on playpen

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.

@petrochenkov
Copy link
Contributor

petrochenkov commented 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 why let self = 10; or struct self { field: u8 } are prohibited.
Referencing existing entities with keywords is possible in some cases - keywords super, self and Self can be used as segments in paths (including paths with one segment).

ident nonterminal accepting self is strange, because self can't be used everywhere where identifiers can be used.
However, ident seems to accept not only valid identifiers, but everything fitting into token::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 keywords super, self and Self (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
Copy link
Member

nrc commented 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

4 participants