Skip to content

unreachable_pub lint ignores nested re-exports #47816

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
CAD97 opened this issue Jan 28, 2018 · 2 comments · Fixed by #57922
Closed

unreachable_pub lint ignores nested re-exports #47816

CAD97 opened this issue Jan 28, 2018 · 2 comments · Fixed by #57922
Labels
A-edition-2018 Area: The 2018 edition A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-bug Category: This is a bug.

Comments

@CAD97
Copy link
Contributor

CAD97 commented Jan 28, 2018

Playground: https://play.rust-lang.org/?gist=d9e9fe07b83f07a3f9b908c0c7405a99&version=nightly

#![deny(unreachable_pub)]

mod one {
    mod two {
        pub struct S;
    }
    pub use self::two::S;
}
pub use self::one::S;
error: unreachable `pub` item
 --> src/lib.rs:7:5
  |
7 |     pub use self::two::S;
  |     ---^^^^^^^^^^^^^^^^^^
  |     |
  |     help: consider restricting its visibility: `pub(crate)`
  |
note: lint level defined here
 --> src/lib.rs:1:32
  |
1 | #![crate_type = "lib"] #![deny(unreachable_pub)]
  |                                ^^^^^^^^^^^^^^^
  = help: or consider exporting it for use by other crates

#![deny(unreachable_pub)]

mod one {
    mod two {
        pub struct S;
    }
    pub(crate) use self::two::S;
}
pub use self::one::S;
error[E0364]: `S` is private, and cannot be reexported
 --> src/lib.rs:9:9
  |
9 | pub use self::one::S;
  |         ^^^^^^^^^^^^
  |
note: consider marking `S` as `pub` in the imported module
 --> src/lib.rs:9:9
  |
9 | pub use self::one::S;
  |         ^^^^^^^^^^^^

A single level of re-export works:

#![deny(unreachable_pub)]

mod one {
    pub struct S;
}
pub use self::one::S;
 Finished dev [unoptimized + debuginfo] target(s) in 0.27 secs
@TimNN TimNN added A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-bug Category: This is a bug. labels Jan 30, 2018
@zackmdavis
Copy link
Member

zackmdavis commented Jul 29, 2018

After inserting some logging statments, it looks like what's going on here is that use items within modules just don't get inserted into the AccessLevels map that the lint uses to determine reachability (but crate-level pub uses do) (because they inherit non-reachability from the private module that they're in).

 INFO 2018-07-29T19:12:20Z: rustc_lint::builtin: ZMD checking item Use(path(self::two::S), Single) with id NodeId(9)
 INFO 2018-07-29T19:12:20Z: rustc_lint::builtin: ZMD debug access levels map is {NodeId(0): Public, NodeId(8): Exported, NodeId(13): Public, NodeId(12): Public, NodeId(6): Exported}

It seems like this behavior is intended?—librustc_privacy's EmbargoVisitor::visit_item comments that reëxports are visit_mod's responsibility, but visit_mod looks at hir::def::Exports, which only stores information about the target, not the pub use item.

@zackmdavis
Copy link
Member

↑ Unless someone understands how the reachability analysis needs to change, and given the increased prominence of this lint owing to the 2018 edition, we might want to quickly PR a change that declines to lint use statements (with a FIXME comment pointing to this issue), on the grounds that false-negatives (whose consequence is, at worst, slightly less idiomatic code) are less bad than false-positives (whose consequence is, at worst, undermining users' trust in the correctness of the compiler, causing them to abandon Rust, causing thousands or millions of lost QALYs as our civilization continues to depend on memory-unsafe software).

Centril added a commit to Centril/rust that referenced this issue Jan 28, 2019
Update visibility of intermediate use items.

Fixes rust-lang#57410 and fixes rust-lang#53925 and fixes rust-lang#47816.

Currently, the target of a use statement will be updated with
the visibility of the use statement itself (if the use statement was
visible).

This PR ensures that if the path to the target item is via another
use statement then that intermediate use statement will also have the
visibility updated like the target. This silences incorrect
`unreachable_pub` lints with inactionable suggestions.
bors added a commit that referenced this issue Feb 3, 2019
Update visibility of intermediate use items.

Fixes #57410 and fixes #53925 and fixes #47816.

Currently, the target of a use statement will be updated with
the visibility of the use statement itself (if the use statement was
visible).

This PR ensures that if the path to the target item is via another
use statement then that intermediate use statement will also have the
visibility updated like the target. This silences incorrect
`unreachable_pub` lints with inactionable suggestions.
@fmease fmease added A-edition-2018 Area: The 2018 edition and removed A-edition-2018-lints labels Dec 21, 2024
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
A-edition-2018 Area: The 2018 edition A-lints Area: Lints (warnings about flaws in source code) such as unused_mut. C-bug Category: This is a bug.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants