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

Confusing error & warning message when importing a function and using it as if it were a module #81232

Closed
joshuawarner32 opened this issue Jan 21, 2021 · 2 comments · Fixed by #117964
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@joshuawarner32
Copy link

When importing a function and using it (accidentally!) as if it were a module, rustc says the name doesn't exist. This lead me to quite a bit of head-scratching. I would humbly suggest either clarifying the error message in such a case, or adding a 'note:' with such a clarification.

I tried this code (playground link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=e9602022b26521481d93c47608503185):

// Context: This is an attempt to distill down the essence of a confusing set of
// error messages I saw while using rust at my day job. Apologies if this is a little wordy,
// but I feel it's important to set context to understand my mindset when I hit this issue.
//
// My task of the day involved setting up some communication between threads.
// I decided to use crossbeam for this. I glanced at the docs briefly, as well
// as some existing uses laying around in our codebase.
//
// Somehow, not having looked in detail, I built up the faulty assumption
// that the relevant pieces of crossbeam_channel would be organized something like this:
//
// ```
// // crossbeam_channel/lib.rs
// pub mod bounded {
//     pub struct Sender { /*...*/ }
//     pub struct Receiver { /*...*/ }
//     pub fn channel() -> (Sender, Receiver) { /*...*/}
// }
// pub mod unbounded {
//     pub struct Sender { /*...*/ }
//     pub struct Receiver { /*...*/ }
//     pub fn channel() -> (Sender, Receiver) { /*...*/}
// }
// pub mod oneshot { // I know now this is not a thing in crossbeam ;)
//     pub struct Sender { /*...*/ }
//     pub struct Receiver { /*...*/ }
//     pub fn channel() -> (Sender, Receiver) { /*...*/}
// }
// ```
//
// This is of course _wrong_, and the real code is more like:
//
// ```
// // crossbeam_channel/lib.rs
// pub struct Sender { /*...*/ }
// pub struct Receiver { /*...*/ }
// pub fn bounded(bound: usize) -> (Sender, Receiver) { /*...*/}
// pub fn unbounded() -> (Sender, Receiver) { /*...*/}
// ```
//
// but setting that aside for the moment, I decided to import what I _thought_
// was a module (crossbeam_channel::unbounded), and start using types/functions from it.
//
// I thought I had an existing import of 'unbounded' elsewhere in the file, so I decided to
// rename the crossbeam import with `as`, like so:

use crossbeam_channel::unbounded as crossbeam_unbounded; // 0.8.0
// ^^^ warning: unused import: `crossbeam_channel::unbounded as crossbeam_unbounded`
//
// The fact that I see _both_ this warning and the undeclared error below made this more confusing.
// Note, in the real compiler output, both errors appear _before_ the warning. 

struct MyStruct {
    receiver: crossbeam_unbounded::Receiver<()>,
    // ^^^ 'error[E0433]: failed to resolve: use of undeclared crate or module `crossbeam_unbounded`'
    //
    // Suggestion: it'd be really helpful to either modify the error message itself
    // or else add a 'note:', to make it clear that crossbeam_unbounded _is_ in scope,
    // it's just a function rather than a module.
    //
    // e.g. 'note: there is a `crossbeam_unbounded` is in scope, but it's a function not a module'
}

fn my_fn(unimportant_param: usize) -> MyStruct {
    let (sender, receiver) = crossbeam_unbounded::channel();
    // ^^^ 'error[E0433]: failed to resolve: use of undeclared crate or module `crossbeam_unbounded`'
    // (same suggestion here as above)

    // do something with sender... or whatever
    MyStruct {
        receiver,
    }
}

// At this point, I was a bit flabargasted - the compiler clearly sees the import!
//
// I double-checked that I used the same name, copy-pasting one on top of the other.
//
// Then I thought, "oh maybe there's some intervening mod declaration so these aren't in the same scope"
// (the real file is much, _much_ longer)
//
// But nope, they're definitely in the same scope.
//
// I moved the first use of `crossbeam_unbounded` to directly after the import,
// and of course received the same error.

I expected to see this happen:

  • The compiler should let me know, somewhere in it's output, that the name is actually in scope, but it's not the right 'kind' of name (e.g. a function instead of a module).
  • This would be a great use-case for a 'note:' or a 'help:' output

Instead, this happened:

  • I scratched my head for ~30 minutes, thinking I was running into some sort of bizarre compiler bug where the compiler somehow wasn't tracking the imports correctly
  • I then figured out that the error was actually mine.

Meta

rustc --version --verbose:

rustc 1.49.0 (e1884a8e3 2020-12-29)
binary: rustc
commit-hash: e1884a8e3c3e813aada8254edfa120e85bf5ffca
commit-date: 2020-12-29
host: x86_64-apple-darwin
release: 1.49.0

(this also repros on the latest nightly in the playground, as of writing)

Not sure how difficult it would be to implement this, but if it's a reasonable 'beginner' issue, I'd be down to try to implement this.

@joshuawarner32 joshuawarner32 added the C-bug Category: This is a bug. label Jan 21, 2021
@estebank estebank added A-diagnostics Area: Messages for errors, warnings, and lints D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 21, 2021
@estebank
Copy link
Contributor

Minimized repro case:

pub mod foo {
    pub fn bar() {}
    pub fn qux() {}
}

use foo::bar;
fn main() {
    bar::qux();
}

@estebank
Copy link
Contributor

Current output, no change:

error[E0433]: failed to resolve: use of undeclared crate or module `bar`
 --> src/main.rs:8:5
  |
8 |     bar::qux();
  |     ^^^ use of undeclared crate or module `bar`
  |
help: there is a crate or module with a similar name
  |
8 |     tar::qux();
  |     ~~~

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 17, 2023
When using existing fn as module, don't claim it doesn't exist

Tweak wording of module not found in resolve, when the name exists but belongs to a non-`mod` item.

Fix rust-lang#81232.
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Nov 17, 2023
When using existing fn as module, don't claim it doesn't exist

Tweak wording of module not found in resolve, when the name exists but belongs to a non-`mod` item.

Fix rust-lang#81232.
@bors bors closed this as completed in 890ce26 Nov 18, 2023
rust-timer added a commit to rust-lang-ci/rust that referenced this issue Nov 18, 2023
Rollup merge of rust-lang#117964 - estebank:issue-81232, r=petrochenkov

When using existing fn as module, don't claim it doesn't exist

Tweak wording of module not found in resolve, when the name exists but belongs to a non-`mod` item.

Fix rust-lang#81232.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-bug Category: This is a bug. D-confusing Diagnostics: Confusing error or lint that should be reworked. D-newcomer-roadblock Diagnostics: Confusing error or lint; hard to understand for new users. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants