Skip to content

Commit

Permalink
Auto merge of rust-lang#12047 - ARandomDev99:12007-empty-enum-variant…
Browse files Browse the repository at this point in the history
…s-with-brackets, r=Jarcho

New Lint: empty_enum_variants_with_brackets

This PR:
- adds a new early pass lint that checks for enum variants with no fields that were defined using brackets. **Category: Restriction**
- adds relevant UI tests for the new lint.

Closes rust-lang#12007

```
changelog: New lint: [`empty_enum_variants_with_brackets`]
```
  • Loading branch information
bors committed Dec 30, 2023
2 parents 0cc53f4 + 5f17188 commit 7f185bd
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion clippy_lints/src/declared_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
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,
Expand Down
Original file line number Diff line number Diff line change
@@ -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};
Expand All @@ -27,9 +27,38 @@ declare_clippy_lint! {
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());

Expand All @@ -53,6 +82,27 @@ impl EarlyLintPass for EmptyStructsWithBrackets {
);
}
}

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::MaybeIncorrect,
);
},
);
}
}
}

fn has_no_ident_token(braces_span_str: &str) -> bool {
Expand Down
4 changes: 2 additions & 2 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ mod duplicate_mod;
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;
Expand Down Expand Up @@ -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));
Expand Down
27 changes: 27 additions & 0 deletions tests/ui/empty_enum_variants_with_brackets.fixed
Original file line number Diff line number Diff line change
@@ -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() {}
27 changes: 27 additions & 0 deletions tests/ui/empty_enum_variants_with_brackets.rs
Original file line number Diff line number Diff line change
@@ -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() {}
36 changes: 36 additions & 0 deletions tests/ui/empty_enum_variants_with_brackets.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 7f185bd

Please sign in to comment.