Skip to content

unreachable_pub false negative when type is referenced in a public field, even if it is not reachable #135134

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

Closed
djmitche opened this issue Jan 5, 2025 · 6 comments
Labels
A-diagnostics Area: Messages for errors, warnings, and lints C-discussion Category: Discussion or questions that doesn't represent real issues. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@djmitche
Copy link

djmitche commented Jan 5, 2025

Code

#![deny(unreachable_pub)]
mod config {
    pub struct AccessMode;
}

pub enum StorageConfig {
    OnDisk(config::AccessMode),
}

Current output

Compiling playground v0.0.1 (/playground)
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.50s

Desired output

error: unreachable `pub` item
 --> src/lib.rs:4:5
  |
4 |     pub struct AccessMode;
  |     ---^^^^^^^^^^^^^^^^^^
  |     |
  |     help: consider restricting its visibility: `pub(crate)`
  |
  = help: or consider exporting it for use by other crates

Rationale and extra context

Changing StorageConfig to

pub struct StorageConfig(config::AccessMode);

produces the desired output, so this is a difference between a reference to a type from an enum variant and a reference to a type from a struct.

Other cases

The same occurs if the enum variant and struct are defined with a named field (`access_mode: config::AccessMode`)

Rust Version

rustc 1.83.0 (90b35a623 2024-11-26)
binary: rustc
commit-hash: 90b35a6239c3d8bdabc530a6a0816f7ff89a0aaf
commit-date: 2024-11-26
host: x86_64-unknown-linux-gnu
release: 1.83.0
LLVM version: 19.1.1

Anything else?

No response

@djmitche djmitche added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Jan 5, 2025
@djmitche
Copy link
Author

djmitche commented Jan 5, 2025

In fact,

pub struct StorageConfig(pub config::AccessMode);

shows the incorrect output. Enum variants have an implicit pub, so the issue is not the enum variant.

The issue is that a type that is referenced publicly but not reachable publicly is not detected. So, this may be a duplicate of #116604.

@djmitche djmitche changed the title unreachable_pub false negative when unreachable type is used in an enum variant unreachable_pub false negative when type is referenced in a public field, even if it is not reachable Jan 5, 2025
@cyrgani
Copy link
Contributor

cyrgani commented Jan 5, 2025

Why do you think this is a false positive? In your first example, AccessMode types can be extracted from the StorageConfig:

fn f(config: StorageConfig) {
    match config {
        StorageConfig::OnDisk(mode) => todo!(),
    }
}

In fact, removing the pub on AccessMode or reducing it to pub(crate) would be incorrect and cause compiler errors with my example usage:

warning: type `AccessMode` is more private than the item `StorageConfig::OnDisk::0`
 --> src/lib.rs:7:12
  |
7 |     OnDisk(config::AccessMode),
  |            ^^^^^^^^^^^^^^^^^^ field `StorageConfig::OnDisk::0` is reachable at visibility `pub`
  |
note: but type `AccessMode` is only usable at visibility `pub(crate)`
 --> src/lib.rs:3:5
  |
3 |     pub(crate) struct AccessMode;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  = note: `#[warn(private_interfaces)]` on by default

error: type `abcd::config::AccessMode` is private
 --> src/main.rs:9:31
  |
9 |         StorageConfig::OnDisk(mode) => todo!(),
  |                               ^^^^ private type

@Urgau
Copy link
Member

Urgau commented Jan 5, 2025

What you want is done by the unnameable_types lint which:

detects types for which you can get objects of that type, but cannot name the type itself.

which is the case here as one can get AccessMode from the enum but cannot name it.

error: struct `AccessMode` is reachable but cannot be named
 --> src/lib.rs:3:5
  |
3 |     pub struct AccessMode;
  |     ^^^^^^^^^^^^^^^^^^^^^ reachable at visibility `pub`, but can only be named at visibility `pub(crate)`
  |
note: the lint level is defined here
 --> src/lib.rs:1:9
  |
1 | #![deny(unnameable_types)]
  |         ^^^^^^^^^^^^^^^^

While the unreachable_pub description state that it does not lint on "leaked types":

The unreachable_pub lint triggers for pub items not reachable from other crates - that means neither directly accessible, nor reexported, nor leaked through things like return types.

@rustbot label +C-discussion

@rustbot rustbot added the C-discussion Category: Discussion or questions that doesn't represent real issues. label Jan 5, 2025
@djmitche
Copy link
Author

djmitche commented Jan 5, 2025

Ah, thank you! That's an important misunderstanding of the term "reachable" on my part.

@Urgau
Copy link
Member

Urgau commented Jan 6, 2025

@djmitche We added a reference to the unnameable_types lint in the unreachable_pub lint documentation in #135145. Do you think that addresses your issue here?

@djmitche
Copy link
Author

djmitche commented Jan 7, 2025

Thanks -- that's great! ❤

@djmitche djmitche closed this as completed Jan 7, 2025
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 C-discussion Category: Discussion or questions that doesn't represent real issues. 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

4 participants