diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ac7297f8f1..931517e72f6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5105,6 +5105,7 @@ Released 2018-09-13 [`else_if_without_else`]: https://rust-lang.github.io/rust-clippy/master/index.html#else_if_without_else [`empty_drop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_drop [`empty_enum`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enum +[`empty_enum_variants_with_brackets`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_enum_variants_with_brackets [`empty_line_after_doc_comments`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_doc_comments [`empty_line_after_outer_attr`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_line_after_outer_attr [`empty_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#empty_loop diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs index 9dd22135d95..b606bb4aa33 100644 --- a/clippy_lints/src/declared_lints.rs +++ b/clippy_lints/src/declared_lints.rs @@ -150,7 +150,8 @@ crate::else_if_without_else::ELSE_IF_WITHOUT_ELSE_INFO, crate::empty_drop::EMPTY_DROP_INFO, crate::empty_enum::EMPTY_ENUM_INFO, - crate::empty_structs_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS_INFO, + crate::empty_with_brackets::EMPTY_ENUM_VARIANTS_WITH_BRACKETS_INFO, + crate::empty_with_brackets::EMPTY_STRUCTS_WITH_BRACKETS_INFO, crate::endian_bytes::BIG_ENDIAN_BYTES_INFO, crate::endian_bytes::HOST_ENDIAN_BYTES_INFO, crate::endian_bytes::LITTLE_ENDIAN_BYTES_INFO, diff --git a/clippy_lints/src/empty_structs_with_brackets.rs b/clippy_lints/src/empty_with_brackets.rs similarity index 62% rename from clippy_lints/src/empty_structs_with_brackets.rs rename to clippy_lints/src/empty_with_brackets.rs index 3cf67b3ecbf..52a88324fc3 100644 --- a/clippy_lints/src/empty_structs_with_brackets.rs +++ b/clippy_lints/src/empty_with_brackets.rs @@ -1,6 +1,6 @@ use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::source::snippet_opt; -use rustc_ast::ast::{Item, ItemKind, VariantData}; +use rustc_ast::ast::{Item, ItemKind, Variant, VariantData}; use rustc_errors::Applicability; use rustc_lexer::TokenKind; use rustc_lint::{EarlyContext, EarlyLintPass}; @@ -27,9 +27,38 @@ restriction, "finds struct declarations with empty brackets" } -declare_lint_pass!(EmptyStructsWithBrackets => [EMPTY_STRUCTS_WITH_BRACKETS]); -impl EarlyLintPass for EmptyStructsWithBrackets { +declare_clippy_lint! { + /// ### What it does + /// Finds enum variants without fields that are declared with empty brackets. + /// + /// ### Why is this bad? + /// Empty brackets while defining enum variants are redundant and can be omitted. + /// + /// ### Example + /// ```no_run + /// enum MyEnum { + /// HasData(u8), + /// HasNoData(), // redundant parentheses + /// } + /// ``` + /// + /// Use instead: + /// ```no_run + /// enum MyEnum { + /// HasData(u8), + /// HasNoData, + /// } + /// ``` + #[clippy::version = "1.77.0"] + pub EMPTY_ENUM_VARIANTS_WITH_BRACKETS, + restriction, + "finds enum variants with empty brackets" +} + +declare_lint_pass!(EmptyWithBrackets => [EMPTY_STRUCTS_WITH_BRACKETS, EMPTY_ENUM_VARIANTS_WITH_BRACKETS]); + +impl EarlyLintPass for EmptyWithBrackets { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { let span_after_ident = item.span.with_lo(item.ident.span.hi()); @@ -53,6 +82,27 @@ fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { ); } } + + fn check_variant(&mut self, cx: &EarlyContext<'_>, variant: &Variant) { + let span_after_ident = variant.span.with_lo(variant.ident.span.hi()); + + if has_brackets(&variant.data) && has_no_fields(cx, &variant.data, span_after_ident) { + span_lint_and_then( + cx, + EMPTY_ENUM_VARIANTS_WITH_BRACKETS, + span_after_ident, + "enum variant has empty brackets", + |diagnostic| { + diagnostic.span_suggestion_hidden( + span_after_ident, + "remove the brackets", + "", + Applicability::MachineApplicable, + ); + }, + ); + } + } } fn has_no_ident_token(braces_span_str: &str) -> bool { diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index 712fe73f6a1..dc24243b574 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -115,7 +115,7 @@ mod else_if_without_else; mod empty_drop; mod empty_enum; -mod empty_structs_with_brackets; +mod empty_with_brackets; mod endian_bytes; mod entry; mod enum_clike; @@ -949,7 +949,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) { }) }); store.register_early_pass(|| Box::new(crate_in_macro_def::CrateInMacroDef)); - store.register_early_pass(|| Box::new(empty_structs_with_brackets::EmptyStructsWithBrackets)); + store.register_early_pass(|| Box::new(empty_with_brackets::EmptyWithBrackets)); store.register_late_pass(|_| Box::new(unnecessary_owned_empty_strings::UnnecessaryOwnedEmptyStrings)); store.register_early_pass(|| Box::new(pub_use::PubUse)); store.register_late_pass(|_| Box::new(format_push_string::FormatPushString)); diff --git a/tests/ui/empty_enum_variants_with_brackets.fixed b/tests/ui/empty_enum_variants_with_brackets.fixed new file mode 100644 index 00000000000..1a5e78dd47f --- /dev/null +++ b/tests/ui/empty_enum_variants_with_brackets.fixed @@ -0,0 +1,27 @@ +#![warn(clippy::empty_enum_variants_with_brackets)] +#![allow(dead_code)] + +pub enum PublicTestEnum { + NonEmptyBraces { x: i32, y: i32 }, // No error + NonEmptyParentheses(i32, i32), // No error + EmptyBraces, //~ ERROR: enum variant has empty brackets + EmptyParentheses, //~ ERROR: enum variant has empty brackets +} + +enum TestEnum { + NonEmptyBraces { x: i32, y: i32 }, // No error + NonEmptyParentheses(i32, i32), // No error + EmptyBraces, //~ ERROR: enum variant has empty brackets + EmptyParentheses, //~ ERROR: enum variant has empty brackets + AnotherEnum, // No error +} + +enum TestEnumWithFeatures { + NonEmptyBraces { + #[cfg(feature = "thisisneverenabled")] + x: i32, + }, // No error + NonEmptyParentheses(#[cfg(feature = "thisisneverenabled")] i32), // No error +} + +fn main() {} diff --git a/tests/ui/empty_enum_variants_with_brackets.rs b/tests/ui/empty_enum_variants_with_brackets.rs new file mode 100644 index 00000000000..ca20b969a24 --- /dev/null +++ b/tests/ui/empty_enum_variants_with_brackets.rs @@ -0,0 +1,27 @@ +#![warn(clippy::empty_enum_variants_with_brackets)] +#![allow(dead_code)] + +pub enum PublicTestEnum { + NonEmptyBraces { x: i32, y: i32 }, // No error + NonEmptyParentheses(i32, i32), // No error + EmptyBraces {}, //~ ERROR: enum variant has empty brackets + EmptyParentheses(), //~ ERROR: enum variant has empty brackets +} + +enum TestEnum { + NonEmptyBraces { x: i32, y: i32 }, // No error + NonEmptyParentheses(i32, i32), // No error + EmptyBraces {}, //~ ERROR: enum variant has empty brackets + EmptyParentheses(), //~ ERROR: enum variant has empty brackets + AnotherEnum, // No error +} + +enum TestEnumWithFeatures { + NonEmptyBraces { + #[cfg(feature = "thisisneverenabled")] + x: i32, + }, // No error + NonEmptyParentheses(#[cfg(feature = "thisisneverenabled")] i32), // No error +} + +fn main() {} diff --git a/tests/ui/empty_enum_variants_with_brackets.stderr b/tests/ui/empty_enum_variants_with_brackets.stderr new file mode 100644 index 00000000000..6b2f286147f --- /dev/null +++ b/tests/ui/empty_enum_variants_with_brackets.stderr @@ -0,0 +1,36 @@ +error: enum variant has empty brackets + --> $DIR/empty_enum_variants_with_brackets.rs:7:16 + | +LL | EmptyBraces {}, + | ^^^ + | + = note: `-D clippy::empty-enum-variants-with-brackets` implied by `-D warnings` + = help: to override `-D warnings` add `#[allow(clippy::empty_enum_variants_with_brackets)]` + = help: remove the brackets + +error: enum variant has empty brackets + --> $DIR/empty_enum_variants_with_brackets.rs:8:21 + | +LL | EmptyParentheses(), + | ^^ + | + = help: remove the brackets + +error: enum variant has empty brackets + --> $DIR/empty_enum_variants_with_brackets.rs:14:16 + | +LL | EmptyBraces {}, + | ^^^ + | + = help: remove the brackets + +error: enum variant has empty brackets + --> $DIR/empty_enum_variants_with_brackets.rs:15:21 + | +LL | EmptyParentheses(), + | ^^ + | + = help: remove the brackets + +error: aborting due to 4 previous errors +