forked from rust-lang/rust
-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of rust-lang#8594 - FoseFx:unit_like_struct_brackets, r=gi…
…raffate add `empty_structs_with_brackets` <!-- Thank you for making Clippy better! We're collecting our changelog from pull request descriptions. If your PR only includes internal changes, you can just write `changelog: none`. Otherwise, please write a short comment explaining your change. Also, it's helpful for us that the lint name is put into brackets `[]` and backticks `` ` ` ``, e.g. ``[`lint_name`]``. If your PR fixes an issue, you can add "fixes #issue_number" into this PR description. This way the issue will be automatically closed when your PR is merged. If you added a new lint, here's a checklist for things that will be checked during review or continuous integration. - \[ ] Followed [lint naming conventions][lint_naming] - \[ ] Added passing UI tests (including committed `.stderr` file) - \[ ] `cargo test` passes locally - \[ ] Executed `cargo dev update_lints` - \[ ] Added lint documentation - \[ ] Run `cargo dev fmt` [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints Note that you can skip the above if you are just opening a WIP PR in order to get feedback. Delete this line and everything above before opening your PR. -- *Please write a short comment explaining your change (or "none" for internal only changes)* --> Closes rust-lang#8591 I'm already sorry for the massive diff 😅 changelog: New lint [`empty_structs_with_brackets`]
- Loading branch information
Showing
58 changed files
with
274 additions
and
101 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
use clippy_utils::{diagnostics::span_lint_and_then, source::snippet_opt}; | ||
use rustc_ast::ast::{Item, ItemKind, VariantData}; | ||
use rustc_errors::Applicability; | ||
use rustc_lexer::TokenKind; | ||
use rustc_lint::{EarlyContext, EarlyLintPass}; | ||
use rustc_session::{declare_lint_pass, declare_tool_lint}; | ||
use rustc_span::Span; | ||
|
||
declare_clippy_lint! { | ||
/// ### What it does | ||
/// Finds structs without fields (a so-called "empty struct") that are declared with brackets. | ||
/// | ||
/// ### Why is this bad? | ||
/// Empty brackets after a struct declaration can be omitted. | ||
/// | ||
/// ### Example | ||
/// ```rust | ||
/// struct Cookie {} | ||
/// ``` | ||
/// Use instead: | ||
/// ```rust | ||
/// struct Cookie; | ||
/// ``` | ||
#[clippy::version = "1.62.0"] | ||
pub EMPTY_STRUCTS_WITH_BRACKETS, | ||
restriction, | ||
"finds struct declarations with empty brackets" | ||
} | ||
declare_lint_pass!(EmptyStructsWithBrackets => [EMPTY_STRUCTS_WITH_BRACKETS]); | ||
|
||
impl EarlyLintPass for EmptyStructsWithBrackets { | ||
fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { | ||
let span_after_ident = item.span.with_lo(item.ident.span.hi()); | ||
|
||
if let ItemKind::Struct(var_data, _) = &item.kind | ||
&& has_brackets(var_data) | ||
&& has_no_fields(cx, var_data, span_after_ident) { | ||
span_lint_and_then( | ||
cx, | ||
EMPTY_STRUCTS_WITH_BRACKETS, | ||
span_after_ident, | ||
"found empty brackets on struct declaration", | ||
|diagnostic| { | ||
diagnostic.span_suggestion_hidden( | ||
span_after_ident, | ||
"remove the brackets", | ||
";".to_string(), | ||
Applicability::MachineApplicable); | ||
}, | ||
); | ||
} | ||
} | ||
} | ||
|
||
fn has_no_ident_token(braces_span_str: &str) -> bool { | ||
!rustc_lexer::tokenize(braces_span_str).any(|t| t.kind == TokenKind::Ident) | ||
} | ||
|
||
fn has_brackets(var_data: &VariantData) -> bool { | ||
!matches!(var_data, VariantData::Unit(_)) | ||
} | ||
|
||
fn has_no_fields(cx: &EarlyContext<'_>, var_data: &VariantData, braces_span: Span) -> bool { | ||
if !var_data.fields().is_empty() { | ||
return false; | ||
} | ||
|
||
// there might still be field declarations hidden from the AST | ||
// (conditionaly compiled code using #[cfg(..)]) | ||
|
||
let Some(braces_span_str) = snippet_opt(cx, braces_span) else { | ||
return false; | ||
}; | ||
|
||
has_no_ident_token(braces_span_str.as_ref()) | ||
} | ||
|
||
#[cfg(test)] | ||
mod unit_test { | ||
use super::*; | ||
|
||
#[test] | ||
fn test_has_no_ident_token() { | ||
let input = "{ field: u8 }"; | ||
assert!(!has_no_ident_token(input)); | ||
|
||
let input = "(u8, String);"; | ||
assert!(!has_no_ident_token(input)); | ||
|
||
let input = " { | ||
// test = 5 | ||
} | ||
"; | ||
assert!(has_no_ident_token(input)); | ||
|
||
let input = " ();"; | ||
assert!(has_no_ident_token(input)); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,6 @@ struct S { | |
a: bool, | ||
} | ||
|
||
struct Foo {} | ||
struct Foo; | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
|
||
trait Foo {} | ||
|
||
struct Bar {} | ||
struct Bar; | ||
|
||
struct Baz<'a> { | ||
bar: &'a Bar, | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// run-rustfix | ||
#![warn(clippy::empty_structs_with_brackets)] | ||
#![allow(dead_code)] | ||
|
||
pub struct MyEmptyStruct; // should trigger lint | ||
struct MyEmptyTupleStruct; // should trigger lint | ||
|
||
// should not trigger lint | ||
struct MyCfgStruct { | ||
#[cfg(feature = "thisisneverenabled")] | ||
field: u8, | ||
} | ||
|
||
// should not trigger lint | ||
struct MyCfgTupleStruct(#[cfg(feature = "thisisneverenabled")] u8); | ||
|
||
// should not trigger lint | ||
struct MyStruct { | ||
field: u8, | ||
} | ||
struct MyTupleStruct(usize, String); // should not trigger lint | ||
struct MySingleTupleStruct(usize); // should not trigger lint | ||
struct MyUnitLikeStruct; // should not trigger lint | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// run-rustfix | ||
#![warn(clippy::empty_structs_with_brackets)] | ||
#![allow(dead_code)] | ||
|
||
pub struct MyEmptyStruct {} // should trigger lint | ||
struct MyEmptyTupleStruct(); // should trigger lint | ||
|
||
// should not trigger lint | ||
struct MyCfgStruct { | ||
#[cfg(feature = "thisisneverenabled")] | ||
field: u8, | ||
} | ||
|
||
// should not trigger lint | ||
struct MyCfgTupleStruct(#[cfg(feature = "thisisneverenabled")] u8); | ||
|
||
// should not trigger lint | ||
struct MyStruct { | ||
field: u8, | ||
} | ||
struct MyTupleStruct(usize, String); // should not trigger lint | ||
struct MySingleTupleStruct(usize); // should not trigger lint | ||
struct MyUnitLikeStruct; // should not trigger lint | ||
|
||
fn main() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
error: found empty brackets on struct declaration | ||
--> $DIR/empty_structs_with_brackets.rs:5:25 | ||
| | ||
LL | pub struct MyEmptyStruct {} // should trigger lint | ||
| ^^^ | ||
| | ||
= note: `-D clippy::empty-structs-with-brackets` implied by `-D warnings` | ||
= help: remove the brackets | ||
|
||
error: found empty brackets on struct declaration | ||
--> $DIR/empty_structs_with_brackets.rs:6:26 | ||
| | ||
LL | struct MyEmptyTupleStruct(); // should trigger lint | ||
| ^^^ | ||
| | ||
= help: remove the brackets | ||
|
||
error: aborting due to 2 previous errors | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -88,7 +88,7 @@ mod no_lint_if_stmt_borrows { | |
ret | ||
} | ||
|
||
struct Bar {} | ||
struct Bar; | ||
|
||
impl Bar { | ||
fn new() -> Self { | ||
|
Oops, something went wrong.