@@ -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