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

Incorrect hint to import private member #50923

Closed
DomWilliams0 opened this issue May 20, 2018 · 23 comments
Closed

Incorrect hint to import private member #50923

DomWilliams0 opened this issue May 20, 2018 · 23 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@DomWilliams0
Copy link

DomWilliams0 commented May 20, 2018

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;
  |

Following the hint is clearly wrong:

error[E0603]: struct `PrivateMember` is private
 --> src/main.rs:5:5
  |
5 | use other_module::PrivateMember;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^

Meta

$ 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
@petrochenkov
Copy link
Contributor

This was actually intentional (see the PR introducing this diagnostic #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.

@DomWilliams0
Copy link
Author

Ah, makes sense.
Perhaps a second hint could be added to suggest you had forgotten to make it pub?

@oli-obk oli-obk added A-diagnostics Area: Messages for errors, warnings, and lints E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. labels May 20, 2018
@ExpHP
Copy link
Contributor

ExpHP commented May 21, 2018

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.

@zackmdavis
Copy link
Member

zackmdavis commented May 21, 2018

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.)

@zackmdavis
Copy link
Member

(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.)

@pandark
Copy link

pandark commented May 28, 2018

Hi,
I'm at Impl Days and I'm looking into this.

@estk
Copy link
Contributor

estk commented Jul 1, 2018

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`
  |

@XAMPPRocky XAMPPRocky added C-enhancement Category: An issue proposing an enhancement or a PR with one. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Oct 2, 2018
@Dushistov
Copy link
Contributor

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.

@carols10cents
Copy link
Member

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;.

@nicholastmosher
Copy link

So if I'm understanding this correctly, there are a few factors that should be considered when deciding what help message to print:

  • Does the private candidate suggestion have a re-export that's accessible?
  • Does the private candidate suggestion belong to the current crate?

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.

@estebank estebank added A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. labels Oct 18, 2019
@jannickj
Copy link

@nicholastmosher any progress?, this is really starting to become annoying :/

@cauebs
Copy link
Contributor

cauebs commented Oct 2, 2020

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.

@FlakM
Copy link

FlakM commented Mar 8, 2021

Hi @cauebs are you still working on this? If not I would like to fix this ;)

@cauebs
Copy link
Contributor

cauebs commented Mar 8, 2021

@FlakM I'm not. You can go ahead.

@spaarmann
Copy link

@FlakM, am I correct in guessing that you're not still working on this? If so, I'd like to have a go at it :)

@FlakM
Copy link

FlakM commented Sep 3, 2021 via email

@spaarmann
Copy link

Thanks!

@rustbot claim

@spaarmann
Copy link

After not finding nearly as much time to look at this as I'd hoped, I looked at it again, and it seems to have been fixed in the meantime 🎉

The test from the original comment now outputs: Playground link

error[E0425]: cannot find value `PrivateMember` in this scope
 --> src/main.rs:6:5
  |
6 |     PrivateMember;
  |     ^^^^^^^^^^^^^ not found in this scope
  |
note: unit struct `crate::other_module::PrivateMember` exists but is inaccessible
--> src/main.rs:2:5
  |
2 |     struct PrivateMember;
  |     ^^^^^^^^^^^^^^^^^^^^^ not accessible

I think this is from #88838. (cc @FabianWolff ). I think with that this issue can be closed now?

@jannickj
Copy link

jannickj commented Feb 6, 2022

@spaarmann the bug is that it suggest private members instead of the public ones, not that private access is incorrectly reported.

@spaarmann
Copy link

@jannickj Can you provide an example? The original issue in the first comment is certainly not that.
The example that carols10cents posted in this thread regarding public re-exports has been fixed for a while (playground), as mentioned by cauebs:

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).

@jannickj
Copy link

jannickj commented Feb 6, 2022

ahh mb, I missed that it had been fixed 😅

@TornaxO7
Copy link

TornaxO7 commented May 2, 2023

One year later

May I ask if this issue can be closed then or am missunderstanding something here?

@estebank
Copy link
Contributor

I believe all of the cases mentioned on this thread have been addressed. If there are more specific cases, feel free to create a new ticket (referencing this one, if needed).

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 A-suggestion-diagnostics Area: Suggestions generated by the compiler applied by `cargo fix` C-enhancement Category: An issue proposing an enhancement or a PR with one. D-invalid-suggestion Diagnostics: A structured suggestion resulting in incorrect code. E-easy Call for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests