@@ -5,7 +5,7 @@ use clippy_utils::macros::span_is_local;
5
5
use clippy_utils:: source:: is_present_in_source;
6
6
use clippy_utils:: str_utils:: { camel_case_split, count_match_end, count_match_start, to_camel_case, to_snake_case} ;
7
7
use rustc_data_structures:: fx:: FxHashSet ;
8
- use rustc_hir:: { EnumDef , FieldDef , Item , ItemKind , OwnerId , Variant , VariantData } ;
8
+ use rustc_hir:: { EnumDef , FieldDef , Item , ItemKind , OwnerId , QPath , TyKind , Variant , VariantData } ;
9
9
use rustc_lint:: { LateContext , LateLintPass } ;
10
10
use rustc_session:: impl_lint_pass;
11
11
use rustc_span:: symbol:: Symbol ;
@@ -202,22 +202,55 @@ impl ItemNameRepetitions {
202
202
return ;
203
203
}
204
204
205
- if ( def. variants . len ( ) as u64 ) < self . enum_threshold {
205
+ let variants = Self :: filter_matching_enum_data ( def) ;
206
+ if ( variants. len ( ) as u64 ) < self . enum_threshold {
206
207
return ;
207
208
}
208
209
209
210
let Some ( ident) = item. kind . ident ( ) else {
210
211
return ;
211
212
} ;
212
213
let item_name = ident. name . as_str ( ) ;
213
- for var in def . variants {
214
+ for var in variants {
214
215
check_enum_start ( cx, item_name, var) ;
215
216
check_enum_end ( cx, item_name, var) ;
216
217
}
217
218
218
219
Self :: check_enum_common_affix ( cx, item, def) ;
219
220
}
220
221
222
+ // Exclude enum variants that contain a single item where any component
223
+ // of the contained item's path is identical to the variant's name.
224
+ fn filter_matching_enum_data < ' a > ( def : & ' a EnumDef < ' a > ) -> Vec < & ' a Variant < ' a > > {
225
+ def. variants
226
+ . iter ( )
227
+ . filter ( |var| {
228
+ let variant_name = var. ident . name . as_str ( ) ;
229
+ if let VariantData :: Tuple ( fields, ..) = var. data
230
+ && fields. len ( ) == 1
231
+ {
232
+ let field_ty = & fields[ 0 ] . ty ;
233
+ if let TyKind :: Path ( qpath) = field_ty. kind {
234
+ let path = match qpath {
235
+ QPath :: Resolved ( _, path) => path,
236
+ QPath :: TypeRelative ( _, segment) => {
237
+ return segment. ident . name . as_str ( ) != variant_name;
238
+ } ,
239
+ QPath :: LangItem ( ..) => return true ,
240
+ } ;
241
+ // Check if any path segment matches the variant name
242
+ for segment in path. segments {
243
+ if segment. ident . name . as_str ( ) == variant_name {
244
+ return false ;
245
+ }
246
+ }
247
+ }
248
+ }
249
+ true
250
+ } )
251
+ . collect ( )
252
+ }
253
+
221
254
/// Lint the names of struct fields against the name of the struct.
222
255
fn check_fields ( & self , cx : & LateContext < ' _ > , item : & Item < ' _ > , fields : & [ FieldDef < ' _ > ] ) {
223
256
if ( fields. len ( ) as u64 ) < self . struct_threshold {
0 commit comments