item_name_repetitions: exclude enum variants with identical path components (#14619)
fix rust-lang/rust-clippy#13637 As suggested in the PR above, we should not lint enum variants containing matching path names. changelog: [`item_name_repetitions`]: exclude enum variants with identical path components
This commit is contained in:
commit
fc811f7e2e
2 changed files with 41 additions and 2 deletions
|
|
@ -5,7 +5,7 @@ use clippy_utils::macros::span_is_local;
|
|||
use clippy_utils::source::is_present_in_source;
|
||||
use clippy_utils::str_utils::{camel_case_split, count_match_end, count_match_start, to_camel_case, to_snake_case};
|
||||
use rustc_data_structures::fx::FxHashSet;
|
||||
use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, Variant, VariantData};
|
||||
use rustc_hir::{EnumDef, FieldDef, Item, ItemKind, OwnerId, QPath, TyKind, Variant, VariantData};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_session::impl_lint_pass;
|
||||
use rustc_span::symbol::Symbol;
|
||||
|
|
@ -405,6 +405,7 @@ fn check_enum_start(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>
|
|||
if count_match_start(item_name, name).char_count == item_name_chars
|
||||
&& name.chars().nth(item_name_chars).is_some_and(|c| !c.is_lowercase())
|
||||
&& name.chars().nth(item_name_chars + 1).is_some_and(|c| !c.is_numeric())
|
||||
&& !check_enum_tuple_path_match(name, variant.data)
|
||||
{
|
||||
span_lint_hir(
|
||||
cx,
|
||||
|
|
@ -420,7 +421,9 @@ fn check_enum_end(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>)
|
|||
let name = variant.ident.name.as_str();
|
||||
let item_name_chars = item_name.chars().count();
|
||||
|
||||
if count_match_end(item_name, name).char_count == item_name_chars {
|
||||
if count_match_end(item_name, name).char_count == item_name_chars
|
||||
&& !check_enum_tuple_path_match(name, variant.data)
|
||||
{
|
||||
span_lint_hir(
|
||||
cx,
|
||||
ENUM_VARIANT_NAMES,
|
||||
|
|
@ -431,6 +434,27 @@ fn check_enum_end(cx: &LateContext<'_>, item_name: &str, variant: &Variant<'_>)
|
|||
}
|
||||
}
|
||||
|
||||
/// Checks if an enum tuple variant contains a single field
|
||||
/// whose qualified path contains the variant's name.
|
||||
fn check_enum_tuple_path_match(variant_name: &str, variant_data: VariantData<'_>) -> bool {
|
||||
// Only check single-field tuple variants
|
||||
let VariantData::Tuple(fields, ..) = variant_data else {
|
||||
return false;
|
||||
};
|
||||
if fields.len() != 1 {
|
||||
return false;
|
||||
}
|
||||
// Check if field type is a path and contains the variant name
|
||||
match fields[0].ty.kind {
|
||||
TyKind::Path(QPath::Resolved(_, path)) => path
|
||||
.segments
|
||||
.iter()
|
||||
.any(|segment| segment.ident.name.as_str() == variant_name),
|
||||
TyKind::Path(QPath::TypeRelative(_, segment)) => segment.ident.name.as_str() == variant_name,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
impl LateLintPass<'_> for ItemNameRepetitions {
|
||||
fn check_item_post(&mut self, _cx: &LateContext<'_>, item: &Item<'_>) {
|
||||
let Some(_ident) = item.kind.ident() else { return };
|
||||
|
|
|
|||
|
|
@ -220,4 +220,19 @@ mod issue11494 {
|
|||
}
|
||||
}
|
||||
|
||||
mod encapsulated {
|
||||
mod types {
|
||||
pub struct FooError;
|
||||
pub struct BarError;
|
||||
pub struct BazError;
|
||||
}
|
||||
|
||||
enum Error {
|
||||
FooError(types::FooError),
|
||||
BarError(types::BarError),
|
||||
BazError(types::BazError),
|
||||
Other,
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue