Skip to content

Small inconsistency with self: keyword but sometimes ident #27899

Closed
@jansegre

Description

@jansegre

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.

Activity

petrochenkov

petrochenkov commented on Apr 16, 2016

@petrochenkov
Contributor

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

nrc commented on Apr 18, 2016

@nrc
Member

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    T-langRelevant to the language team

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @steveklabnik@jansegre@nrc@petrochenkov

        Issue actions

          Small inconsistency with `self`: keyword but sometimes ident · Issue #27899 · rust-lang/rust