1 use clippy_utils
::{diagnostics::span_lint_and_then, source::snippet_opt}
;
2 use rustc_ast
::ast
::{Item, ItemKind, VariantData}
;
3 use rustc_errors
::Applicability
;
4 use rustc_lexer
::TokenKind
;
5 use rustc_lint
::{EarlyContext, EarlyLintPass}
;
6 use rustc_session
::{declare_lint_pass, declare_tool_lint}
;
11 /// Finds structs without fields (a so-called "empty struct") that are declared with brackets.
13 /// ### Why is this bad?
14 /// Empty brackets after a struct declaration can be omitted.
24 #[clippy::version = "1.62.0"]
25 pub EMPTY_STRUCTS_WITH_BRACKETS
,
27 "finds struct declarations with empty brackets"
29 declare_lint_pass
!(EmptyStructsWithBrackets
=> [EMPTY_STRUCTS_WITH_BRACKETS
]);
31 impl EarlyLintPass
for EmptyStructsWithBrackets
{
32 fn check_item(&mut self, cx
: &EarlyContext
<'_
>, item
: &Item
) {
33 let span_after_ident
= item
.span
.with_lo(item
.ident
.span
.hi());
35 if let ItemKind
::Struct(var_data
, _
) = &item
.kind
36 && has_brackets(var_data
)
37 && has_no_fields(cx
, var_data
, span_after_ident
) {
40 EMPTY_STRUCTS_WITH_BRACKETS
,
42 "found empty brackets on struct declaration",
44 diagnostic
.span_suggestion_hidden(
46 "remove the brackets",
48 Applicability
::Unspecified
);
55 fn has_no_ident_token(braces_span_str
: &str) -> bool
{
56 !rustc_lexer
::tokenize(braces_span_str
).any(|t
| t
.kind
== TokenKind
::Ident
)
59 fn has_brackets(var_data
: &VariantData
) -> bool
{
60 !matches
!(var_data
, VariantData
::Unit(_
))
63 fn has_no_fields(cx
: &EarlyContext
<'_
>, var_data
: &VariantData
, braces_span
: Span
) -> bool
{
64 if !var_data
.fields().is_empty() {
68 // there might still be field declarations hidden from the AST
69 // (conditionally compiled code using #[cfg(..)])
71 let Some(braces_span_str
) = snippet_opt(cx
, braces_span
) else {
75 has_no_ident_token(braces_span_str
.as_ref())
83 fn test_has_no_ident_token() {
84 let input
= "{ field: u8 }";
85 assert
!(!has_no_ident_token(input
));
87 let input
= "(u8, String);";
88 assert
!(!has_no_ident_token(input
));
94 assert
!(has_no_ident_token(input
));
97 assert
!(has_no_ident_token(input
));