Skip to content

Commit bd0a5e4

Browse files
committed
fix: empty_enum_variants_with_brackets misses removing brackets in patterns
1 parent 45168a7 commit bd0a5e4

File tree

4 files changed

+112
-34
lines changed

4 files changed

+112
-34
lines changed

clippy_lints/src/empty_with_brackets.rs

Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ use clippy_utils::attrs::span_contains_cfg;
22
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
33
use rustc_data_structures::fx::FxIndexMap;
44
use rustc_errors::Applicability;
5-
use rustc_hir::def::CtorOf;
65
use rustc_hir::def::DefKind::Ctor;
76
use rustc_hir::def::Res::Def;
7+
use rustc_hir::def::{CtorOf, DefKind};
88
use 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};
1010
use rustc_lint::{LateContext, LateLintPass};
11-
use rustc_middle::ty::TyCtxt;
11+
use rustc_middle::ty::{self, TyCtxt};
1212
use rustc_session::impl_lint_pass;
1313
use 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+
255271
fn 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+
}

tests/ui/empty_enum_variants_with_brackets.fixed

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![warn(clippy::empty_enum_variants_with_brackets)]
22
#![allow(dead_code)]
3+
#![feature(more_qualified_paths)]
34

45
pub enum PublicTestEnum {
56
NonEmptyBraces { x: i32, y: i32 }, // No error
@@ -102,4 +103,16 @@ pub enum PubFoo {
102103
Variant3(),
103104
}
104105

106+
fn issue16157() {
107+
enum E {
108+
V,
109+
//~^ empty_enum_variants_with_brackets
110+
}
111+
112+
let E::V = E::V;
113+
114+
<E>::V = E::V;
115+
<E>::V = E::V;
116+
}
117+
105118
fn main() {}

tests/ui/empty_enum_variants_with_brackets.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#![warn(clippy::empty_enum_variants_with_brackets)]
22
#![allow(dead_code)]
3+
#![feature(more_qualified_paths)]
34

45
pub enum PublicTestEnum {
56
NonEmptyBraces { x: i32, y: i32 }, // No error
@@ -102,4 +103,16 @@ pub enum PubFoo {
102103
Variant3(),
103104
}
104105

106+
fn issue16157() {
107+
enum E {
108+
V(),
109+
//~^ empty_enum_variants_with_brackets
110+
}
111+
112+
let E::V() = E::V();
113+
114+
<E>::V() = E::V();
115+
<E>::V {} = E::V();
116+
}
117+
105118
fn main() {}

tests/ui/empty_enum_variants_with_brackets.stderr

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: enum variant has empty brackets
2-
--> tests/ui/empty_enum_variants_with_brackets.rs:7:16
2+
--> tests/ui/empty_enum_variants_with_brackets.rs:8:16
33
|
44
LL | EmptyBraces {},
55
| ^^^
@@ -9,39 +9,39 @@ LL | EmptyBraces {},
99
= help: remove the brackets
1010

1111
error: enum variant has empty brackets
12-
--> tests/ui/empty_enum_variants_with_brackets.rs:15:16
12+
--> tests/ui/empty_enum_variants_with_brackets.rs:16:16
1313
|
1414
LL | EmptyBraces {},
1515
| ^^^
1616
|
1717
= help: remove the brackets
1818

1919
error: enum variant has empty brackets
20-
--> tests/ui/empty_enum_variants_with_brackets.rs:17:21
20+
--> tests/ui/empty_enum_variants_with_brackets.rs:18:21
2121
|
2222
LL | EmptyParentheses(),
2323
| ^^
2424
|
2525
= help: remove the brackets
2626

2727
error: enum variant has empty brackets
28-
--> tests/ui/empty_enum_variants_with_brackets.rs:28:16
28+
--> tests/ui/empty_enum_variants_with_brackets.rs:29:16
2929
|
3030
LL | Unknown(),
3131
| ^^
3232
|
3333
= help: remove the brackets
3434

3535
error: enum variant has empty brackets
36-
--> tests/ui/empty_enum_variants_with_brackets.rs:47:16
36+
--> tests/ui/empty_enum_variants_with_brackets.rs:48:16
3737
|
3838
LL | Unknown(),
3939
| ^^
4040
|
4141
= help: remove the brackets
4242

4343
error: enum variant has empty brackets
44-
--> tests/ui/empty_enum_variants_with_brackets.rs:53:20
44+
--> tests/ui/empty_enum_variants_with_brackets.rs:54:20
4545
|
4646
LL | Parentheses(),
4747
| ^^
@@ -56,7 +56,7 @@ LL ~ RedundantParenthesesFunctionCall::Parentheses;
5656
|
5757

5858
error: enum variant has empty brackets
59-
--> tests/ui/empty_enum_variants_with_brackets.rs:76:20
59+
--> tests/ui/empty_enum_variants_with_brackets.rs:77:20
6060
|
6161
LL | Parentheses(),
6262
| ^^
@@ -71,12 +71,30 @@ LL ~ Parentheses,
7171
|
7272

7373
error: enum variant has empty brackets
74-
--> tests/ui/empty_enum_variants_with_brackets.rs:95:13
74+
--> tests/ui/empty_enum_variants_with_brackets.rs:96:13
7575
|
7676
LL | Variant3(),
7777
| ^^
7878
|
7979
= help: remove the brackets
8080

81-
error: aborting due to 8 previous errors
81+
error: enum variant has empty brackets
82+
--> tests/ui/empty_enum_variants_with_brackets.rs:108:10
83+
|
84+
LL | V(),
85+
| ^^
86+
|
87+
help: remove the brackets
88+
|
89+
LL ~ V,
90+
LL |
91+
LL | }
92+
LL |
93+
LL ~ let E::V = E::V;
94+
LL |
95+
LL ~ <E>::V = E::V;
96+
LL ~ <E>::V = E::V;
97+
|
98+
99+
error: aborting due to 9 previous errors
82100

0 commit comments

Comments
 (0)