Skip to content

manual_non_exhaustive is overzealous for items not visible outside the crate #10301

Closed
@jakubzytka

Description

@jakubzytka

Summary

manual_non_exhaustive lint and a suggestion to use #[non_exhaustive] is emitted for items that are not visible outside the crate, whereas the non_exhaustive attribute controls cross-crate behaviour.

Lint Name

manual_non_exhaustive

Reproducer

I tried this code:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=dc927a61851e2fd8e25e4d3570a4eb57

mod inner {
    pub(super) struct Inner {
        pub foo: u32,
        _private: (),
    }
    
    impl Inner {
        pub fn new() -> Inner {
            Inner { foo: 123, _private: () }
        }
    }
    
    #[non_exhaustive]
    pub(super) struct NonExhaustive {
        pub foo: u32
    }
    
    impl NonExhaustive {
        pub fn new() -> NonExhaustive {
            NonExhaustive { foo: 123 }
        }
    }
    
}

pub fn main() {
    println!("{}", inner::Inner::new().foo);
    println!("{}", inner::NonExhaustive::new().foo);
    println!("{}", inner::NonExhaustive { foo: 32 }.foo);
}

I saw this happen:

    Checking playground v0.0.1 (/playground)
warning: this seems like a manual implementation of the non-exhaustive pattern
 --> src/main.rs:2:5
  |
2 |       pub(super) struct Inner {
  |       ^----------------------
  |       |
  |  _____help: add the attribute: `#[non_exhaustive] pub(super) struct Inner`
  | |
3 | |         pub foo: u32,
4 | |         _private: (),
5 | |     }
  | |_____^
  |
help: remove this field
 --> src/main.rs:4:9
  |
4 |         _private: (),
  |         ^^^^^^^^^^^^
  = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_non_exhaustive
  = note: `#[warn(clippy::manual_non_exhaustive)]` on by default

warning: `playground` (bin "playground") generated 1 warning
    Finished dev [unoptimized + debuginfo] target(s) in 0.37s

I expected to see this happen:

  • no warning from clippy for pub(crate), pub(super) etc. items

The example also contains code showing that clippy's suggestion is not equivalent - adding non_exhaustive attribute does not prevent the construction of the NonExhausive struct

Version

rustc 1.67.0 (fc594f156 2023-01-24)
binary: rustc
commit-hash: fc594f15669680fa70d255faec3ca3fb507c3405
commit-date: 2023-01-24
host: x86_64-unknown-linux-gnu
release: 1.67.0
LLVM version: 15.0.6

tested also in Playground
Clippy
0.1.69 (2023-02-05 75a0be9)

Additional Labels

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: Clippy is not doing the correct thingI-false-positiveIssue: The lint was triggered on code it shouldn't have

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions