self and super behave inconsistently in use statements and as module names
Handling of self and super in use and mod statements is inconsistent. Playpen:
use self; // error: `self` imports are only allowed within a { } list [E0429] (expected)
// error: unresolved import `self`. There is no `self` in the crate root [E0432]
mod super { // error: expected identifier, found keyword `super`
type Test = u32;
mod submodule {
use super; // error: a module named `super` has already been imported in this module [E0252]
use super::{self, Test}; // (^^^ apparently "already" means "on the next line"?)
}
use super; // (no error for this one?)
}
There are probably several (related) issues here.
- Inconsistent handling of keyword status for
selfandsuperas module names: if we add amod self { }to the above, we get the two "expected identifier, found keyword" errors we'd expect -- and no other output. It appears thatmod self { }causes an immediate "aborting due to previous error", whilemod super { }does not. use super::{self, ...};doesn't special-case theselfkeyword as a keyword likeuse foo::bar::{self, ...};does.use super;doesn't special-case thesuperkeyword as a keyword.use self;does do some special-casing so it can produce "error:selfimports are only allowed within a { } list [E0429]", but it then continues by attempting to resolveselfas an ident.
I'd be happy to take a shot at fixing these issues, but I'd like some feedback on my summary of what's going on before I do.
Collin J. Sutton at 2016-08-12 00:01:39
use super::{self, ...};doesn't special-case the self keyword as a keyword likeuse foo::bar::{self, ...};does.Why do you say this? Judging by the errors,
use super::{self};is equivalent touse super;.Eduard-Mihai Burtescu at 2016-08-12 03:18:52
This is similar to https://github.com/rust-lang/rust/issues/29036
Vadim Petrochenkov at 2016-08-12 08:15:56
Inconsistent handling of keyword status for
selfandsuperas module namesThis is not true, try to experiment more. Keywords in identifier positions do the next things: 1) report a non-fatal error, 2) define an identifier with keyword name - this is a part of error recovery in parser.
So,
mod superactually defines a module namedsuper. This is ok because the code is already erroneous and we can do anything more or less reasonable, perfect error recovery is not guaranteed.mod super { // reports an error and defines a module mod m { pub struct S; } // no error, module super is imported, this is bug #29036, // naked self and super are not treated correctly in imports use super as ident; // no error, everything is correctly routed to "super"::m::S type Z = ident::m::S; }Vadim Petrochenkov at 2016-08-12 08:32:59
I'm not sure what action should be taken here. @petrochenkov do we need to change any behaviour or should we just improve diagnostics?
Oli Scherer at 2020-01-25 17:23:20
In general, the behavior needs to be changed. Imports of
selfandsuperneed to be accepted if they are renamed into something that is not a keyword, similarly tocrate.use crate as name; // OK use crate; // ERROR, needs the "as name" partFor the examples in the issue it will only result in diagnostic changes though, because they are all erroneous.
Vadim Petrochenkov at 2020-01-25 17:28:45