]> git.lizzy.rs Git - rust.git/blob - clippy_lints/src/exhaustive_items.rs
ExhaustiveEnums -> ExhaustiveItems
[rust.git] / clippy_lints / src / exhaustive_items.rs
1 use crate::utils::{snippet_opt, span_lint_and_help, span_lint_and_sugg};
2 use if_chain::if_chain;
3 use rustc_hir::{Item, ItemKind};
4 use rustc_errors::Applicability;
5 use rustc_lint::{LateContext, LateLintPass};
6 use rustc_session::{declare_lint_pass, declare_tool_lint};
7 use rustc_span::sym;
8
9 declare_clippy_lint! {
10     /// **What it does:** Warns on any exported `enum`s that are not tagged `#[non_exhaustive]`
11     ///
12     /// **Why is this bad?** Exhaustive enums are typically fine, but a project which does
13     /// not wish to make a stability commitment around enums may wish to disable them by default.
14     ///
15     /// **Known problems:** None.
16     ///
17     /// **Example:**
18     ///
19     /// ```rust
20     /// enum Foo {
21     ///     Bar,
22     ///     Baz
23     /// }
24     /// ```
25     /// Use instead:
26     /// ```rust
27     /// #[non_exhaustive]
28     /// enum Foo {
29     ///     Bar,
30     ///     Baz
31     /// }    /// ```
32     pub EXHAUSTIVE_ENUMS,
33     restriction,
34     "default lint description"
35 }
36
37 declare_lint_pass!(ExhaustiveItems => [EXHAUSTIVE_ENUMS]);
38
39 impl LateLintPass<'_> for ExhaustiveItems {
40     fn check_item(&mut self, cx: &LateContext<'_>, item: &Item<'_>) {
41         if_chain! {
42             if let ItemKind::Enum(..) = item.kind;
43             if cx.access_levels.is_exported(item.hir_id);
44             if !item.attrs.iter().any(|a| a.has_name(sym::non_exhaustive));
45             then {
46                 if let Some(snippet) = snippet_opt(cx, item.span) {
47                     span_lint_and_sugg(
48                         cx,
49                         EXHAUSTIVE_ENUMS,
50                         item.span,
51                         "enums should not be exhaustive",
52                         "try adding #[non_exhaustive]",
53                         format!("#[non_exhaustive]\n{}", snippet),
54                         Applicability::MaybeIncorrect,
55                     );
56                 } else {
57                     span_lint_and_help(
58                         cx,
59                         EXHAUSTIVE_ENUMS,
60                         item.span,
61                         "enums should not be exhaustive",
62                         None,
63                         "try adding #[non_exhaustive]",
64                     );
65                 }
66             }
67         }
68     }
69 }