diff options
| author | bors <bors@rust-lang.org> | 2024-05-23 16:19:15 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-05-23 16:19:15 +0000 |
| commit | 76856ffb576fb2dff472481a6389d42ca836db6f (patch) | |
| tree | dfe9e1d8f6d0a2e1f6090bf231d593155f6e28c7 | |
| parent | 05c40536285245d31f2bd6ed43c5bc43cc768752 (diff) | |
| parent | cfa150b0ddc28ea3723a3b4d0916e729dcea3246 (diff) | |
| download | rust-76856ffb576fb2dff472481a6389d42ca836db6f.tar.gz rust-76856ffb576fb2dff472481a6389d42ca836db6f.zip | |
Auto merge of #12833 - kpreid:empty-enum-doc, r=Manishearth
Rephrase and expand `empty_enum` documentation. * Remove incorrect claim that “wrappers around it are the conventional way to define an uninhabited type”. * Discuss why one would use `!`, a newtype struct, or keep the enum. * Add links to relevant documentation. Before writing this change, I asked the community via [IRLO](https://internals.rust-lang.org/t/idiomatic-definition-of-uninhabited-never-newtypes/20877) and [Zulip](https://rust-lang.zulipchat.com/#narrow/stream/213817-t-lang/topic/Never.20type.20wrappers.20.2F.20defining.20uninhabited.20newtypes) for feedback. The broad consensus seemed to me to be that in a world where both `never_type` and `min_exhaustive_patterns` are stable and therefore available for general use, we _might_ want to `!` or newtypes of it — but it's certainly not “conventional” _yet._ Therefore, I've removed “conventional” and added a discussion of the pros and cons of different choices. changelog: [`empty_enum`]: expanded documentation
| -rw-r--r-- | clippy_lints/src/empty_enum.rs | 45 |
1 files changed, 33 insertions, 12 deletions
diff --git a/clippy_lints/src/empty_enum.rs b/clippy_lints/src/empty_enum.rs index 420888b6ccb..d16714695cb 100644 --- a/clippy_lints/src/empty_enum.rs +++ b/clippy_lints/src/empty_enum.rs @@ -7,32 +7,53 @@ use rustc_session::declare_lint_pass; declare_clippy_lint! { /// ### What it does - /// Checks for `enum`s with no variants. + /// Checks for `enum`s with no variants, which therefore are uninhabited types + /// (cannot be instantiated). /// - /// As of this writing, the `never_type` is still a - /// nightly-only experimental API. Therefore, this lint is only triggered - /// if the `never_type` is enabled. + /// As of this writing, the `never_type` is still a nightly-only experimental API. + /// Therefore, this lint is only triggered if `#![feature(never_type)]` is enabled. /// /// ### Why is this bad? - /// If you want to introduce a type which - /// can't be instantiated, you should use `!` (the primitive type "never"), - /// or a wrapper around it, because `!` has more extensive - /// compiler support (type inference, etc...) and wrappers - /// around it are the conventional way to define an uninhabited type. - /// For further information visit [never type documentation](https://doc.rust-lang.org/std/primitive.never.html) + /// * If you only want a type which can’t be instantiated, you should use [`!`] + /// (the primitive type "never"), because [`!`] has more extensive compiler support + /// (type inference, etc.) and implementations of common traits. /// + /// * If you need to introduce a distinct type, consider using a [newtype] `struct` + /// containing [`!`] instead (`struct MyType(pub !)`), because it is more idiomatic + /// to use a `struct` rather than an `enum` when an `enum` is unnecessary. + /// + /// If you do this, note that the [visibility] of the [`!`] field determines whether + /// the uninhabitedness is visible in documentation, and whether it can be pattern + /// matched to mark code unreachable. If the field is not visible, then the struct + /// acts like any other struct with private fields. + /// + /// * If the enum has no variants only because all variants happen to be + /// [disabled by conditional compilation][cfg], then it would be appropriate + /// to allow the lint, with `#[allow(empty_enum)]`. + /// + /// For further information, visit + /// [the never type’s documentation][`!`]. /// /// ### Example /// ```no_run - /// enum Test {} + /// enum CannotExist {} /// ``` /// /// Use instead: /// ```no_run /// #![feature(never_type)] /// - /// struct Test(!); + /// /// Use the `!` type directly... + /// type CannotExist = !; + /// + /// /// ...or define a newtype which is distinct. + /// struct CannotExist2(pub !); /// ``` + /// + /// [`!`]: https://doc.rust-lang.org/std/primitive.never.html + /// [cfg]: https://doc.rust-lang.org/reference/conditional-compilation.html + /// [newtype]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction + /// [visibility]: https://doc.rust-lang.org/reference/visibility-and-privacy.html #[clippy::version = "pre 1.29.0"] pub EMPTY_ENUM, pedantic, |
