Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 59 additions & 25 deletions clippy_lints/src/empty_with_brackets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use clippy_utils::attrs::span_contains_cfg;
use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::Applicability;
use rustc_hir::def::CtorOf;
use rustc_hir::def::DefKind::Ctor;
use rustc_hir::def::Res::Def;
use rustc_hir::def::{CtorOf, DefKind};
use rustc_hir::def_id::LocalDefId;
use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node, Path, QPath, Variant, VariantData};
use rustc_hir::{Expr, ExprKind, Item, ItemKind, Node, Pat, PatKind, Path, QPath, Variant, VariantData};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyCtxt;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::impl_lint_pass;
use rustc_span::Span;

Expand Down Expand Up @@ -177,35 +177,24 @@ impl LateLintPass<'_> for EmptyWithBrackets {
if expr.span.from_expansion() {
return;
}
match self.empty_tuple_enum_variants.get_mut(&def_id) {
Some(
&mut (Usage::Unused {
ref mut redundant_use_sites,
}
| Usage::NoDefinition {
ref mut redundant_use_sites,
}),
) => {
redundant_use_sites.push(parentheses_span);
},
None => {
// The variant isn't in the IndexMap which means its definition wasn't encountered yet.
self.empty_tuple_enum_variants.insert(
def_id,
Usage::NoDefinition {
redundant_use_sites: vec![parentheses_span],
},
);
},
_ => {},
}
self.update_enum_variant_usage(def_id, parentheses_span);
} else {
// The parentheses are not redundant.
self.empty_tuple_enum_variants.insert(def_id, Usage::Used);
}
}
}

fn check_pat(&mut self, cx: &LateContext<'_>, pat: &Pat<'_>) {
if let Some((def_id, parentheses_span)) = check_pat_for_enum_as_function(cx, pat) {
if pat.span.from_expansion() {
return;
}

self.update_enum_variant_usage(def_id, parentheses_span);
}
}

fn check_crate_post(&mut self, cx: &LateContext<'_>) {
for (local_def_id, usage) in &self.empty_tuple_enum_variants {
// Ignore all variants with Usage::Used or Usage::NoDefinition
Expand Down Expand Up @@ -252,6 +241,33 @@ impl LateLintPass<'_> for EmptyWithBrackets {
}
}

impl EmptyWithBrackets {
fn update_enum_variant_usage(&mut self, def_id: LocalDefId, parentheses_span: Span) {
match self.empty_tuple_enum_variants.get_mut(&def_id) {
Some(
&mut (Usage::Unused {
ref mut redundant_use_sites,
}
| Usage::NoDefinition {
ref mut redundant_use_sites,
}),
) => {
redundant_use_sites.push(parentheses_span);
},
None => {
// The variant isn't in the IndexMap which means its definition wasn't encountered yet.
self.empty_tuple_enum_variants.insert(
def_id,
Usage::NoDefinition {
redundant_use_sites: vec![parentheses_span],
},
);
},
_ => {},
}
}
}

fn has_brackets(var_data: &VariantData<'_>) -> bool {
!matches!(var_data, VariantData::Unit(..))
}
Expand Down Expand Up @@ -291,3 +307,21 @@ fn check_expr_for_enum_as_function(expr: &Expr<'_>) -> Option<LocalDefId> {
None
}
}

fn check_pat_for_enum_as_function(cx: &LateContext<'_>, pat: &Pat<'_>) -> Option<(LocalDefId, Span)> {
match pat.kind {
PatKind::TupleStruct(qpath, ..)
if let Def(Ctor(CtorOf::Variant, _), def_id) = cx.typeck_results().qpath_res(&qpath, pat.hir_id) =>
{
def_id.as_local().map(|id| (id, qpath.span().with_lo(pat.span.hi())))
},
PatKind::Struct(qpath, ..)
if let Def(DefKind::Variant, def_id) = cx.typeck_results().qpath_res(&qpath, pat.hir_id)
&& let ty = cx.tcx.type_of(def_id).instantiate_identity()
&& let ty::FnDef(def_id, _) = ty.kind() =>
{
def_id.as_local().map(|id| (id, qpath.span().with_lo(pat.span.hi())))
},
_ => None,
}
}
13 changes: 13 additions & 0 deletions tests/ui/empty_enum_variants_with_brackets.fixed
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![warn(clippy::empty_enum_variants_with_brackets)]
#![allow(dead_code)]
#![feature(more_qualified_paths)]

pub enum PublicTestEnum {
NonEmptyBraces { x: i32, y: i32 }, // No error
Expand Down Expand Up @@ -102,4 +103,16 @@ pub enum PubFoo {
Variant3(),
}

fn issue16157() {
enum E {
V,
//~^ empty_enum_variants_with_brackets
}

let E::V = E::V;

<E>::V = E::V;
<E>::V = E::V;
}

fn main() {}
13 changes: 13 additions & 0 deletions tests/ui/empty_enum_variants_with_brackets.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#![warn(clippy::empty_enum_variants_with_brackets)]
#![allow(dead_code)]
#![feature(more_qualified_paths)]

pub enum PublicTestEnum {
NonEmptyBraces { x: i32, y: i32 }, // No error
Expand Down Expand Up @@ -102,4 +103,16 @@ pub enum PubFoo {
Variant3(),
}

fn issue16157() {
enum E {
V(),
//~^ empty_enum_variants_with_brackets
}

let E::V() = E::V();

<E>::V() = E::V();
<E>::V {} = E::V();
}

fn main() {}
36 changes: 27 additions & 9 deletions tests/ui/empty_enum_variants_with_brackets.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: enum variant has empty brackets
--> tests/ui/empty_enum_variants_with_brackets.rs:7:16
--> tests/ui/empty_enum_variants_with_brackets.rs:8:16
|
LL | EmptyBraces {},
| ^^^
Expand All @@ -9,39 +9,39 @@ LL | EmptyBraces {},
= help: remove the brackets

error: enum variant has empty brackets
--> tests/ui/empty_enum_variants_with_brackets.rs:15:16
--> tests/ui/empty_enum_variants_with_brackets.rs:16:16
|
LL | EmptyBraces {},
| ^^^
|
= help: remove the brackets

error: enum variant has empty brackets
--> tests/ui/empty_enum_variants_with_brackets.rs:17:21
--> tests/ui/empty_enum_variants_with_brackets.rs:18:21
|
LL | EmptyParentheses(),
| ^^
|
= help: remove the brackets

error: enum variant has empty brackets
--> tests/ui/empty_enum_variants_with_brackets.rs:28:16
--> tests/ui/empty_enum_variants_with_brackets.rs:29:16
|
LL | Unknown(),
| ^^
|
= help: remove the brackets

error: enum variant has empty brackets
--> tests/ui/empty_enum_variants_with_brackets.rs:47:16
--> tests/ui/empty_enum_variants_with_brackets.rs:48:16
|
LL | Unknown(),
| ^^
|
= help: remove the brackets

error: enum variant has empty brackets
--> tests/ui/empty_enum_variants_with_brackets.rs:53:20
--> tests/ui/empty_enum_variants_with_brackets.rs:54:20
|
LL | Parentheses(),
| ^^
Expand All @@ -56,7 +56,7 @@ LL ~ RedundantParenthesesFunctionCall::Parentheses;
|

error: enum variant has empty brackets
--> tests/ui/empty_enum_variants_with_brackets.rs:76:20
--> tests/ui/empty_enum_variants_with_brackets.rs:77:20
|
LL | Parentheses(),
| ^^
Expand All @@ -71,12 +71,30 @@ LL ~ Parentheses,
|

error: enum variant has empty brackets
--> tests/ui/empty_enum_variants_with_brackets.rs:95:13
--> tests/ui/empty_enum_variants_with_brackets.rs:96:13
|
LL | Variant3(),
| ^^
|
= help: remove the brackets

error: aborting due to 8 previous errors
error: enum variant has empty brackets
--> tests/ui/empty_enum_variants_with_brackets.rs:108:10
|
LL | V(),
| ^^
|
help: remove the brackets
|
LL ~ V,
LL |
LL | }
LL |
LL ~ let E::V = E::V;
LL |
LL ~ <E>::V = E::V;
LL ~ <E>::V = E::V;
|

error: aborting due to 9 previous errors

Loading