Rust: trying to import a `use` statement should not talk of privacy

Created on 26 Jun 2017  路  10Comments  路  Source: rust-lang/rust

fn main() {
    use foo::mem;
}

pub mod foo {
    use std::mem;
}

gives the error:

error: module `mem` is private
 --> <anon>:2:9
  |
2 |     use foo::mem;
  |         ^^^^^^^^

error: aborting due to previous error

However, really, we don't consider use std::mem to be introducing a module, so it's confusing when we say that it's private. This gives off the impression that we typed the correct path, but the library author neglected to make it public.

We should instead give an error that the module/type/etc does not exist, but perhaps note that there is a use statement that could be made pub use if the error is from the same crate.

A-diagnostics C-enhancement E-needs-mentor T-compiler WG-compiler-errors

All 10 comments

I somewhat disagree. I think we shouldn't say that module "mem" is private, instead something more along the lines of imported module... would be better, I think. I don't think the "is private" itself is wrong -- it seems fairly clear that mem is inside foo, it's just not public.

From the point of view of another crate what imports you have should not really be a visible detail.

The problem is that the way imports are generally taught; use is thought of as bringing in a name locally, not bringing in a name that can be imported from other modules (even though you can do it from e.g. a submodule)

However, if you're accidently importing a private name (say, a struct found in the source code of the crate), then the current error message is helpful. I encountered this a couple of times.

Changing this to not mentioning the privacy at all would make me wonder whether I mistyped some part of the path instead of wondering about the privacy.

Yes, I am talking about importing a use statement only.

The point is to distinguish between the case where you typed the correct path but it is private, and you typed the wrong path but does exist as a private use statement. Currently the two give the same error, even though they are generally fixed in very different ways.

I find this confusing as well. (JFYI I am planning on suggesting this issue for the upcoming "Boston rust hackathon" meetup.)

Proposed output:

error[E0603]: module `mem` is private
 --> src/main.rs:2:9
  |
2 |     use foo::mem;
  |         ^^^^^^^^
...
6 |     use std::mem;
  |     ^^^^^^^^^^^^^ private module
  |     |
  |     help: consider making it public: `pub use std::mem;`

This would be shown only when a span is available, which is the only time when you can actually do something about it. When there's no span available, produce the output for nonexistent modules:

error[E0432]: unresolved import `foo::mem`
 --> src/main.rs:2:9
  |
2 |     use foo::mem;
  |         ^^^^^^^^ no `mem` in the root

When there's no span available, produce the output for nonexistent modules:

or we could emit a suggestion to use std::mem directly here, which often is what we wanted in the first place.

@oli-obk that would only apply to use statements, but I agree.

I think making a pub use is almost never what the person actually wants. I would prefer that we start with the assumption that they just forgot to import something and it happens to match an import used in another module -- at least, this is always what happens to me.

I've ran into a variant of this error by getting module name slightly wrong (playground):

pub mod definer {
    pub struct PubStruct;
}

mod user {
    use crate::definer::PubStruct;
}

mod fail {
    use crate::user::PubStruct;
    // error[E0603]: struct `PubStruct` is private
}

The problem was I've used crate::user::PubStruct instead of crate::definer::PubStruct. It's the same struct, just a layer of indirection too much.

I find this message misleading, because:

  • The message says struct PubStruct is private, but that's not really true: the struct PubStruct is public. It's probably referring to the use PubStruct statement being private, but that detail isn't clear from the message, and it's not a useful information, because I wanted the struct, not the use.

  • Existence of a private use "leaks" outside of the module. If mod user didn't have the use statement, the message would be correct "error[E0432]: unresolved import crate::user::PubStruct"

Was this page helpful?
0 / 5 - 0 ratings