about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/empty_enum.rs45
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,