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

(Mostly) diagnostics involving super are weird #39330

Closed
nagisa opened this issue Jan 27, 2017 · 5 comments
Closed

(Mostly) diagnostics involving super are weird #39330

nagisa opened this issue Jan 27, 2017 · 5 comments
Labels
A-resolve Area: Name/path resolution done by `rustc_resolve` specifically E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.

Comments

@nagisa
Copy link
Member

nagisa commented Jan 27, 2017

pub mod a {
    use super as root;
}
// error[E0432]: unresolved import `super`
//  --> <anon>:3:9
//   |
// 3 |     use super as root;
//   |         ^^^^^^^^^^^^^ no `super` in the root

super is a keyword. There can’t ever be anything named super in the root.

fn main() {
    let super = 2;
}
// error[E0531]: unresolved unit struct/variant or constant `super`
//  --> <anon>:2:9
//   |
// 2 |     let super = 2;
//   |         ^^^^^

Similarly, rustc should be reporting that super is a keyword and cannot be used as an identifier. I suspect the error arises from the fact that super is parsed to be the whole pattern here. Example below results in the same diagnostic, but may be easier to understand why the error is what it is:

fn main() {
    match 2 {
        super => {}
    }
}
// same error

Notably you cannot have something like this either:

mod a {}
struct a; // a is already defined

fn main() {
    let ::a = 2;
}

So in general this error message could be improved to say that super is a module (?) and cannot be used in a pattern this way.


We over at the #rust-lang have ideas how a use super as root could be used to make life easier (@solson said they’ll write an RFC). In other cases resolve should probably just stop accepting super by itself and/or just resolve it to a module.

@jseyfried
Copy link
Contributor

cc @petrochenkov

@jseyfried jseyfried self-assigned this Jan 27, 2017
@jseyfried jseyfried added A-resolve Area: Name/path resolution done by `rustc_resolve` specifically E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion. labels Jan 27, 2017
@jseyfried
Copy link
Contributor

@nagisa @solson

We over at the #rust-lang have ideas how a use super as root; could be used to make life easier

An equivalent alternative to use super as root; that works today is mod root { pub use super::*; }.

As discussed on IRC, the downside of accepting use super as root; is asymmetry with use super;, which we would continue to forbid (or only forbid if super is the crate root, which has other downsides).

Overall, I don't have strong opinion on whether having use super as root; is worth the downside.

In other cases resolve should probably just stop accepting super by itself and/or just resolve it to a module.

Agreed. To be clear, super by itself is never accepted today, but only because no item may be named super.

@solson
Copy link
Member

solson commented Jan 27, 2017

@jseyfried Good points. Along the lines of what you said, we can implement the std-in-prelude RFC (which I haven't written yet) with pub mod std { pub use ::*; } in the prelude module.

I otherwise agree with cleaning up the diagnostics around super that @nagisa brought up.

@petrochenkov
Copy link
Contributor

petrochenkov commented Jan 28, 2017

How I see this:

pub mod a {
    use super as root;
}

This should work. Root module is a usual module (mostly) and can be imported.
Using the filesystem analogy, you can create symlinks to /.

pub mod a {
    pub mod b {
        use super as a2;
    }
}

This should work too.
(You can create symlinks to ...)

pub mod a {
    use super;
}

This should work and import an unusable name (currently {{root}}).
This import will be automatically reported as unused by unused_imports.

rustc should be reporting that super is a keyword and cannot be used as an identifier

super is indeed a keyword and can't be used in all identifier contexts.
At the same time super is a valid path and can be used in all path contexts, including patterns (let PATH_PATTERN = expr;).

fn main() {
    let super = 2;
}

The error is now different:

error[E0433]: failed to resolve. There are too many initial `super`s.
 --> <anon>:2:9
  |
2 |     let super = 2;
  |         ^^^^^ There are too many initial `super`s.

error: aborting due to previous error

The wording looks ok, but may be tweaked to mention root or something.

mod m {
    fn f() {
        let super = 2;
    }
}

In other cases resolve should probably just stop accepting super by itself and/or just resolve it to a module.

This is already done. The error message is

error[E0532]: expected unit struct/variant or constant, found module `super`
 --> <anon>:3:13
  |
3 |         let super = 2;
  |             ^^^^^ not a unit struct/variant or constant

So, the action items here:

  • Make use super [as name]; work (duplicate of Can't import super #29036).
  • Possibly tweak the "too many supers" message to mention root module.

@jseyfried jseyfried removed their assignment Jan 30, 2017
@jseyfried
Copy link
Contributor

Closing in favor of #29036 and #39401.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-resolve Area: Name/path resolution done by `rustc_resolve` specifically E-mentor Call for participation: This issue has a mentor. Use #t-compiler/help on Zulip for discussion.
Projects
None yet
Development

No branches or pull requests

4 participants