When a private member is accessed from another module an error is raised as expected, but it is wrongly hinted that you can import it into scope, as seen in this example:
mod other_module {
struct PrivateMember;
}
fn main() {
PrivateMember;
}
error[E0425]: cannot find value `PrivateMember` in this scope
--> src/main.rs:6:5
|
6 | PrivateMember;
| ^^^^^^^^^^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
|
1 | use other_module::PrivateMember;
|
md5-ea3bdbcef8932db899765a65bdcb5611
error[E0603]: struct `PrivateMember` is private
--> src/main.rs:5:5
|
5 | use other_module::PrivateMember;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
md5-feebe56d34f043717366e615dd16d8db
$ rustc --version --verbose
rustc 1.26.0 (a77568041 2018-05-07)
binary: rustc
commit-hash: a7756804103447ea4e68a71ccf071e7ad8f7a03e
commit-date: 2018-05-07
host: x86_64-unknown-linux-gnu
release: 1.26.0
LLVM version: 6.0
This was actually intentional (see the PR introducing this diagnostic https://github.com/rust-lang/rust/pull/31674).
Items from the current crate are always suggested in case you forgot pub, because if you want to use some item outside of its module it's more often happens because the items is intended to be used, it just has pub missing.
Private items from other crates are indeed filtered away.
Ah, makes sense.
Perhaps a second hint could be added to suggest you had forgotten to make it pub?
I don't feel a second hint is necessary? Code bases of sufficient size may have many types with the same name, and sometimes it really is the case that you forgot to define it (or got the name wrong).
mod a {
struct Input;
fn foo(x: Input) { }
}
mod b {
struct Input(i32);
fn foo(x: Input) { }
}
mod c {
struct Input {
boo: ()
}
fn foo(x: Input) { }
}
mod d {
fn foo(x: Input) { }
}
Compiling playground v0.0.1 (file:///playground)
error[E0412]: cannot find type `Input` in this scope
--> src/main.rs:21:15
|
21 | fn foo(x: Input) { }
| ^^^^^ not found in this scope
help: possible candidates are found in other modules, you can import them into scope
|
21 | use a::Input;
|
21 | use b::Input;
|
21 | use c::Input;
|
I think the current error says quite enough.
may have many types with the same name [...] the current error says quite enough
If the concern is about wasting vertical terminal real estate, we can take that into account. (Only output _n_ lines worth of suggestions, even if more than _n_ lines worth of candidates are found, with already-public candidates prioritized before those with the additional "add pub" suggestion.)
(It's plausible that I'll find time to work on this this week.)
(It's plausible that I'll find time to work on this this week.)
Never mind; I'm _not_ going to work on this. (I don't see any _insurmountable_ difficulties, but my enthusiasm has waned remembering the time I introduced a similar suggestion in resolve and it ended up invoking some gross snippet-munging that depended on knowing the type of item.)
Hi,
I'm at Impl Days and I'm looking into this.
I've run into this personally. I would be interested in modifying the error message so that when a possible type is suggested it will include information about whether the type is pub or not. Additionally we could order the suggestions such that public members are first. I'm particularly interested in what people think about the messaging.
Example:
error[E0425]: cannot find value `Member` in this scope
--> src/main.rs:6:5
|
6 | Member;
| ^^^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
|
1 | use other_module_with_pub::Member;
1 | use other_module_with_private::Member; // Could be made `pub`
|
As example there is https://github.com/dtolnay/quote crate, by @dtolnay .
rustc always suggests use wrong trait: use quote::to_tokens::ToTokens; instead of
use quote::ToTokens;, usage of this suggestion lead to compile error.
I think what @Dushistov is getting at is that public re-exports aren't being suggested and private paths are; here's a minimal case (stable 1.31.0, edition 2018):
// Leave the following `use` lines commented out to see the suggestion
// The suggestion given, but doesn't work because inner is private
// use crate::outer::inner::Thing;
// This works because of the re-export, but isn't suggested at all
// use crate::outer::Thing;
fn main() {
let x = Thing {};
}
pub mod outer {
pub use self::inner::Thing;
mod inner {
pub struct Thing {}
}
}
That is, the suggestion I get is:
help: possible candidate is found in another module, you can import it into scope
|
9 | use crate::outer::inner::Thing;
|
But the suggestion I expect to get with the re-export is use crate::outer::Thing;.
So if I'm understanding this correctly, there are a few factors that should be considered when deciding what help message to print:
It seems like the order of operations should look something like this:
1) If there's a matching re-export available, the standard candidate suggestion should be printed, using the re-exported path.
2) Otherwise, if the candidate belongs to the current crate but is private, give a "make pub" suggestion.
3) Otherwise (if the candidate belongs to an external crate), I'm not sure whether it'd be best to suggest the private (inaccessible) candidate anyway, or to leave it at a "not found in this scope" error.
I'd be willing to take a stab at this with a little guidance (if nobody's started it). I want to get some more opinions on the exact approach to take before I start, though.
@nicholastmosher any progress?, this is really starting to become annoying :/
This appears to have been partially resolved. What remains now is that rustc recommends private members when it doesn't find any public alternatives, and it doesn't point out that they're private (the initial issue).
My suggestion is that we just change the message in that particular case from consider importing this struct to something like possible candidates were found in other modules, but they're private.
I have no experience with the codebase but will set aside some time to study it for Hacktoberfest, and would be willing to give this a go. I'll just wait for some confirmation on how to tackle this.
Most helpful comment
Ah, makes sense.
Perhaps a second hint could be added to suggest you had forgotten to make it
pub?