@@ -2,13 +2,13 @@ use clippy_utils::attrs::span_contains_cfg;
22use clippy_utils:: diagnostics:: { span_lint_and_then, span_lint_hir_and_then} ;
33use rustc_data_structures:: fx:: FxIndexMap ;
44use rustc_errors:: Applicability ;
5- use rustc_hir:: def:: CtorOf ;
65use rustc_hir:: def:: DefKind :: Ctor ;
76use rustc_hir:: def:: Res :: Def ;
7+ use rustc_hir:: def:: { CtorOf , DefKind } ;
88use rustc_hir:: def_id:: LocalDefId ;
9- use rustc_hir:: { Expr , ExprKind , Item , ItemKind , Node , Path , QPath , Variant , VariantData } ;
9+ use rustc_hir:: { Expr , ExprKind , Item , ItemKind , Node , Pat , PatKind , Path , QPath , Variant , VariantData } ;
1010use rustc_lint:: { LateContext , LateLintPass } ;
11- use rustc_middle:: ty:: TyCtxt ;
11+ use rustc_middle:: ty:: { self , TyCtxt } ;
1212use rustc_session:: impl_lint_pass;
1313use rustc_span:: Span ;
1414
@@ -177,35 +177,24 @@ impl LateLintPass<'_> for EmptyWithBrackets {
177177 if expr. span . from_expansion ( ) {
178178 return ;
179179 }
180- match self . empty_tuple_enum_variants . get_mut ( & def_id) {
181- Some (
182- & mut ( Usage :: Unused {
183- ref mut redundant_use_sites,
184- }
185- | Usage :: NoDefinition {
186- ref mut redundant_use_sites,
187- } ) ,
188- ) => {
189- redundant_use_sites. push ( parentheses_span) ;
190- } ,
191- None => {
192- // The variant isn't in the IndexMap which means its definition wasn't encountered yet.
193- self . empty_tuple_enum_variants . insert (
194- def_id,
195- Usage :: NoDefinition {
196- redundant_use_sites : vec ! [ parentheses_span] ,
197- } ,
198- ) ;
199- } ,
200- _ => { } ,
201- }
180+ self . update_enum_variant_usage ( def_id, parentheses_span) ;
202181 } else {
203182 // The parentheses are not redundant.
204183 self . empty_tuple_enum_variants . insert ( def_id, Usage :: Used ) ;
205184 }
206185 }
207186 }
208187
188+ fn check_pat ( & mut self , cx : & LateContext < ' _ > , pat : & Pat < ' _ > ) {
189+ if let Some ( ( def_id, parentheses_span) ) = check_pat_for_enum_as_function ( cx, pat) {
190+ if pat. span . from_expansion ( ) {
191+ return ;
192+ }
193+
194+ self . update_enum_variant_usage ( def_id, parentheses_span) ;
195+ }
196+ }
197+
209198 fn check_crate_post ( & mut self , cx : & LateContext < ' _ > ) {
210199 for ( local_def_id, usage) in & self . empty_tuple_enum_variants {
211200 // Ignore all variants with Usage::Used or Usage::NoDefinition
@@ -252,6 +241,33 @@ impl LateLintPass<'_> for EmptyWithBrackets {
252241 }
253242}
254243
244+ impl EmptyWithBrackets {
245+ fn update_enum_variant_usage ( & mut self , def_id : LocalDefId , parentheses_span : Span ) {
246+ match self . empty_tuple_enum_variants . get_mut ( & def_id) {
247+ Some (
248+ & mut ( Usage :: Unused {
249+ ref mut redundant_use_sites,
250+ }
251+ | Usage :: NoDefinition {
252+ ref mut redundant_use_sites,
253+ } ) ,
254+ ) => {
255+ redundant_use_sites. push ( parentheses_span) ;
256+ } ,
257+ None => {
258+ // The variant isn't in the IndexMap which means its definition wasn't encountered yet.
259+ self . empty_tuple_enum_variants . insert (
260+ def_id,
261+ Usage :: NoDefinition {
262+ redundant_use_sites : vec ! [ parentheses_span] ,
263+ } ,
264+ ) ;
265+ } ,
266+ _ => { } ,
267+ }
268+ }
269+ }
270+
255271fn has_brackets ( var_data : & VariantData < ' _ > ) -> bool {
256272 !matches ! ( var_data, VariantData :: Unit ( ..) )
257273}
@@ -291,3 +307,21 @@ fn check_expr_for_enum_as_function(expr: &Expr<'_>) -> Option<LocalDefId> {
291307 None
292308 }
293309}
310+
311+ fn check_pat_for_enum_as_function ( cx : & LateContext < ' _ > , pat : & Pat < ' _ > ) -> Option < ( LocalDefId , Span ) > {
312+ match pat. kind {
313+ PatKind :: TupleStruct ( qpath, ..)
314+ if let Def ( Ctor ( CtorOf :: Variant , _) , def_id) = cx. typeck_results ( ) . qpath_res ( & qpath, pat. hir_id ) =>
315+ {
316+ def_id. as_local ( ) . map ( |id| ( id, qpath. span ( ) . with_lo ( pat. span . hi ( ) ) ) )
317+ } ,
318+ PatKind :: Struct ( qpath, ..)
319+ if let Def ( DefKind :: Variant , def_id) = cx. typeck_results ( ) . qpath_res ( & qpath, pat. hir_id )
320+ && let ty = cx. tcx . type_of ( def_id) . instantiate_identity ( )
321+ && let ty:: FnDef ( def_id, _) = ty. kind ( ) =>
322+ {
323+ def_id. as_local ( ) . map ( |id| ( id, qpath. span ( ) . with_lo ( pat. span . hi ( ) ) ) )
324+ } ,
325+ _ => None ,
326+ }
327+ }
0 commit comments