Skip to content

Added long diagnostics for E0254. #26992

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

Closed
wants to merge 7 commits into from
Closed
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 35 additions & 1 deletion src/librustc_resolve/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,41 @@ mod bar {
```
"##,

E0254: r##"
This error indicates that an imported symbol resolved to an already imported
symbol.

An example of this error:

```
// crate foo
pub use foo::bar;
pub mod foo; // note that there's a `pub` here
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the pub is only relevant due to the use of a glob import ... my opinion is that this detail distracts from the real issue that we want to describe for this error code: Namely the conflict between one extern crate and some other import into the type+module namespace. (See my suggested alternative examples given in my other feedback.)

```

```
// other program
extern crate foo;

use foo::*; // error, `foo::*` tries to bind `foo::foo` to `foo`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would discourage reusing the same name foo for such totally different roles, unless it is strictly necessary for replicating this particular error diagnostic. Its okay for the example program to be a little bit longer, if it makes the example clearer. (Also, if I read this correctly, you are using the mod foo; form, but have not included the text of the associated foo.rs file that would hold the body of that module? That also seems overly difficult for the reader to understand; why not just put the definition of mod foo inline?)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(i'm investigating this now; I can see that the most trivial examples of duplicate imported symbols flag other error codes, so let me see if I can tease out exactly what it is about your example that matters)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay so here is what I think is a more direct example:

This works for any external crate, but I'll include a trivial one that provides zero exports. (But if you want to add a one line definition to it, that's fine, as long as its not named foo too.)

external crate foo.rs:

#![crate_type="lib"]

client code bar.rs:

extern crate foo; // this puts `foo` into the root type+module namespace

use inner_mod::foo; // this also tries to put `foo` in the same namespace

mod inner_mod {
    pub mod foo { }
}

And then one might note that this variant of bar.rs also has the same problem:

extern crate foo; // this puts `foo` into the root type+module namespace

use inner_mod::foo; // this also tries to put `foo` in the same namespace

mod inner_mod {
    pub type foo = i32;
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(we could remove the foo.rs entirely by referring to a crate that is always available. For example by using core everywhere that foo occurs in my example. But its probably better to explicitly include the foo crate itself, even if it is a trivial crate with no exports.)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that it's more direct but it doesn't make clear that an import from an external crate can cause this problem too (and I say this because, reading your code, I wouldn't be able to figure out that the code I was writing were correct and the external lib I was using that exported something weird.)
Still, I will do some rewriting, thanks.

```

Or yet:

```
// crate foo
pub use foo::bar;
mod foo; // note that there's no `pub` here
```

```
// other program
extern crate foo;

use foo::{self,bar}; // error, `use`ing `self` tries to bind `foo::foo` to `foo`
```
"##,

E0255: r##"
You can't import a value whose name is the same as another value defined in the
module.
Expand Down Expand Up @@ -205,7 +240,6 @@ register_diagnostics! {
E0157,
E0153,
E0253, // not directly importable
E0254, // import conflicts with imported crate in this module
E0257,
E0258,
E0364, // item is private
Expand Down