Skip to content

Incorrect hint to import private member #50923

@DomWilliams0

Description

@DomWilliams0

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

Activity

petrochenkov

petrochenkov commented on May 20, 2018

@petrochenkov
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

DomWilliams0 commented on May 20, 2018

@DomWilliams0
Author

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

added
A-diagnosticsArea: Messages for errors, warnings, and lints
E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.
on May 20, 2018
ExpHP

ExpHP commented on May 21, 2018

@ExpHP
Contributor

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

zackmdavis commented on May 21, 2018

@zackmdavis
Member

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

zackmdavis commented on May 22, 2018

@zackmdavis
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

pandark commented on May 28, 2018

@pandark

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

estk

estk commented on Jul 1, 2018

@estk
Contributor

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`
  |
added
C-enhancementCategory: An issue proposing an enhancement or a PR with one.
T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
on Oct 2, 2018
Dushistov

Dushistov commented on Jan 6, 2019

@Dushistov
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

carols10cents commented on Jan 9, 2019

@carols10cents
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

nicholastmosher commented on Feb 3, 2019

@nicholastmosher

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.

18 remaining items

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-suggestion-diagnosticsArea: Suggestions generated by the compiler applied by `cargo fix`C-enhancementCategory: An issue proposing an enhancement or a PR with one.D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.E-easyCall for participation: Easy difficulty. Experience needed to fix: Not much. Good first issue.T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

      Development

      No branches or pull requests

        Participants

        @Dushistov@carols10cents@pandark@oli-obk@estk

        Issue actions

          Incorrect hint to import private member · Issue #50923 · rust-lang/rust