Skip to content

Commit 7a7fad1

Browse files
committed
Extend author lint
1 parent 00821ca commit 7a7fad1

File tree

14 files changed

+491
-72
lines changed

14 files changed

+491
-72
lines changed

clippy_lints/src/utils/author.rs

Lines changed: 166 additions & 46 deletions
Large diffs are not rendered by default.

clippy_utils/src/higher.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//! This module contains functions that retrieves specifiec elements.
1+
//! This module contains functions that retrieves specific elements.
22
33
#![deny(clippy::missing_docs_in_private_items)]
44

tests/ui/author.stdout

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ if_chain! {
55
if let TyKind::Path(ref qp) = cast_ty.kind;
66
if match_qpath(qp, &["char"]);
77
if let ExprKind::Lit(ref lit) = expr.kind;
8-
if let LitKind::Int(69, _) = lit.node;
8+
if let LitKind::Int(69, LitIntType::Unsuffixed) = lit.node;
99
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind;
1010
if name.as_str() == "x";
1111
then {

tests/ui/author/blocks.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,24 @@
1+
// edition:2018
2+
13
#![allow(redundant_semicolons, clippy::no_effect)]
4+
#![feature(stmt_expr_attributes)]
5+
#![feature(async_closure)]
26

37
#[rustfmt::skip]
48
fn main() {
59
#[clippy::author]
610
{
711
let x = 42i32;
12+
let _t = 1f32;
13+
814
-x;
915
};
1016
#[clippy::author]
1117
{
1218
let expr = String::new();
1319
drop(expr)
1420
};
21+
22+
#[clippy::author]
23+
async move || {};
1524
}

tests/ui/author/blocks.stdout

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
if_chain! {
22
if let ExprKind::Block(ref block) = expr.kind;
3-
if block.stmts.len() == 2;
3+
if block.stmts.len() == 3;
44
if let StmtKind::Local(ref local) = block.stmts[0].kind;
55
if let Some(ref init) = local.init;
66
if let ExprKind::Lit(ref lit) = init.kind;
7-
if let LitKind::Int(42, _) = lit.node;
7+
if let LitKind::Int(42, LitIntType::Signed(IntTy::I32)) = lit.node;
88
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind;
99
if name.as_str() == "x";
10-
if let StmtKind::Semi(ref e, _) = block.stmts[1].kind
10+
if let StmtKind::Local(ref local1) = block.stmts[1].kind;
11+
if let Some(ref init1) = local1.init;
12+
if let ExprKind::Lit(ref lit1) = init1.kind;
13+
if let LitKind::Float(_, ref suffix) = lit1.node;
14+
if let LitFloatType::Suffixed(ref float_ty) = suffix
15+
if let FloatTy::F32 = float_ty
16+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local1.pat.kind;
17+
if name1.as_str() == "_t";
18+
if let StmtKind::Semi(ref e, _) = block.stmts[2].kind
1119
if let ExprKind::Unary(UnOp::Neg, ref inner) = e.kind;
1220
if let ExprKind::Path(ref path) = inner.kind;
1321
if match_qpath(path, &["x"]);
@@ -38,3 +46,17 @@ if_chain! {
3846
// report your lint here
3947
}
4048
}
49+
if_chain! {
50+
if let ExprKind::Closure(CaptureBy::Value, Async::Yes { .. }, _, _, ref fn_expr, _) = expr.kind;
51+
if let ExprKind::Call(ref func, ref args) = fn_expr.kind;
52+
if let ExprKind::Path(ref path) = func.kind;
53+
if matches!(path, QPath::LangItem(LangItem::FromGenerator, _));
54+
if args.len() == 1;
55+
if let ExprKind::Closure(CaptureBy::Value, Async::No, _, _, ref fn_expr1, _) = args[0].kind;
56+
if let ExprKind::Block(ref block) = fn_expr1.kind;
57+
if block.stmts.len() == 0;
58+
if block.expr.is_none();
59+
then {
60+
// report your lint here
61+
}
62+
}

tests/ui/author/call.stdout

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ if_chain! {
66
if match_qpath(path, &["{{root}}", "std", "cmp", "min"]);
77
if args.len() == 2;
88
if let ExprKind::Lit(ref lit) = args[0].kind;
9-
if let LitKind::Int(3, _) = lit.node;
9+
if let LitKind::Int(3, LitIntType::Unsuffixed) = lit.node;
1010
if let ExprKind::Lit(ref lit1) = args[1].kind;
11-
if let LitKind::Int(4, _) = lit1.node;
11+
if let LitKind::Int(4, LitIntType::Unsuffixed) = lit1.node;
1212
if let PatKind::Wild = local.pat.kind;
1313
then {
1414
// report your lint here

tests/ui/author/for_loop.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
#![feature(stmt_expr_attributes)]
22

3+
#[allow(clippy::never_loop)]
34
fn main() {
45
#[clippy::author]
56
for y in 0..10 {
67
let z = y;
78
}
9+
10+
#[clippy::author]
11+
for _ in 0..10 {
12+
break;
13+
}
14+
15+
#[clippy::author]
16+
'label: for _ in 0..10 {
17+
break 'label;
18+
}
819
}

tests/ui/author/for_loop.stdout

Lines changed: 149 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ if_chain! {
88
if let ExprKind::Struct(ref path1, ref fields, None) = args[0].kind;
99
if matches!(path1, QPath::LangItem(LangItem::Range, _));
1010
if fields.len() == 2;
11-
// unimplemented: field checks
11+
if fields[0].ident.name.as_str() == "start"
12+
if let ExprKind::Lit(ref lit) = fields[0].kind;
13+
if let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node;
14+
if fields[1].ident.name.as_str() == "end"
15+
if let ExprKind::Lit(ref lit1) = fields[1].kind;
16+
if let LitKind::Int(10, LitIntType::Unsuffixed) = lit1.node;
1217
if arms.len() == 1;
1318
if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.kind;
1419
if body.stmts.len() == 4;
@@ -33,31 +38,166 @@ if_chain! {
3338
if let PatKind::Struct(ref path6, ref fields1, false) = arms1[0].pat.kind;
3439
if matches!(path6, QPath::LangItem(LangItem::OptionSome, _));
3540
if fields1.len() == 1;
36-
// unimplemented: field checks
41+
if fields1[0].ident.name.as_str() == "0"
42+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = fields1[0].kind;
43+
if name1.as_str() == "val";
3744
if let ExprKind::Break(ref destination, None) = arms1[1].body.kind;
3845
if let PatKind::Struct(ref path7, ref fields2, false) = arms1[1].pat.kind;
3946
if matches!(path7, QPath::LangItem(LangItem::OptionNone, _));
4047
if fields2.len() == 0;
41-
// unimplemented: field checks
4248
if let StmtKind::Local(ref local1) = body.stmts[2].kind;
4349
if let Some(ref init) = local1.init;
4450
if let ExprKind::Path(ref path8) = init.kind;
4551
if match_qpath(path8, &["__next"]);
46-
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local1.pat.kind;
47-
if name1.as_str() == "y";
52+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local1.pat.kind;
53+
if name2.as_str() == "y";
4854
if let StmtKind::Expr(ref e1, _) = body.stmts[3].kind
4955
if let ExprKind::Block(ref block) = e1.kind;
5056
if block.stmts.len() == 1;
5157
if let StmtKind::Local(ref local2) = block.stmts[0].kind;
5258
if let Some(ref init1) = local2.init;
5359
if let ExprKind::Path(ref path9) = init1.kind;
5460
if match_qpath(path9, &["y"]);
55-
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local2.pat.kind;
56-
if name2.as_str() == "z";
61+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name3, None) = local2.pat.kind;
62+
if name3.as_str() == "z";
5763
if block.expr.is_none();
5864
if body.expr.is_none();
59-
if let PatKind::Binding(BindingAnnotation::Mutable, _, name3, None) = arms[0].pat.kind;
60-
if name3.as_str() == "iter";
65+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name4, None) = arms[0].pat.kind;
66+
if name4.as_str() == "iter";
67+
then {
68+
// report your lint here
69+
}
70+
}
71+
if_chain! {
72+
if let ExprKind::DropTemps(ref expr) = expr.kind;
73+
if let ExprKind::Match(ref expr1, ref arms, MatchSource::ForLoopDesugar) = expr.kind;
74+
if let ExprKind::Call(ref func, ref args) = expr1.kind;
75+
if let ExprKind::Path(ref path) = func.kind;
76+
if matches!(path, QPath::LangItem(LangItem::IntoIterIntoIter, _));
77+
if args.len() == 1;
78+
if let ExprKind::Struct(ref path1, ref fields, None) = args[0].kind;
79+
if matches!(path1, QPath::LangItem(LangItem::Range, _));
80+
if fields.len() == 2;
81+
if fields[0].ident.name.as_str() == "start"
82+
if let ExprKind::Lit(ref lit) = fields[0].kind;
83+
if let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node;
84+
if fields[1].ident.name.as_str() == "end"
85+
if let ExprKind::Lit(ref lit1) = fields[1].kind;
86+
if let LitKind::Int(10, LitIntType::Unsuffixed) = lit1.node;
87+
if arms.len() == 1;
88+
if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.kind;
89+
if body.stmts.len() == 4;
90+
if let StmtKind::Local(ref local) = body.stmts[0].kind;
91+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local.pat.kind;
92+
if name.as_str() == "__next";
93+
if let StmtKind::Expr(ref e, _) = body.stmts[1].kind
94+
if let ExprKind::Match(ref expr2, ref arms1, MatchSource::ForLoopDesugar) = e.kind;
95+
if let ExprKind::Call(ref func1, ref args1) = expr2.kind;
96+
if let ExprKind::Path(ref path2) = func1.kind;
97+
if matches!(path2, QPath::LangItem(LangItem::IteratorNext, _));
98+
if args1.len() == 1;
99+
if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, ref inner) = args1[0].kind;
100+
if let ExprKind::Path(ref path3) = inner.kind;
101+
if match_qpath(path3, &["iter"]);
102+
if arms1.len() == 2;
103+
if let ExprKind::Assign(ref target, ref value, ref _span) = arms1[0].body.kind;
104+
if let ExprKind::Path(ref path4) = target.kind;
105+
if match_qpath(path4, &["__next"]);
106+
if let ExprKind::Path(ref path5) = value.kind;
107+
if match_qpath(path5, &["val"]);
108+
if let PatKind::Struct(ref path6, ref fields1, false) = arms1[0].pat.kind;
109+
if matches!(path6, QPath::LangItem(LangItem::OptionSome, _));
110+
if fields1.len() == 1;
111+
if fields1[0].ident.name.as_str() == "0"
112+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = fields1[0].kind;
113+
if name1.as_str() == "val";
114+
if let ExprKind::Break(ref destination, None) = arms1[1].body.kind;
115+
if let PatKind::Struct(ref path7, ref fields2, false) = arms1[1].pat.kind;
116+
if matches!(path7, QPath::LangItem(LangItem::OptionNone, _));
117+
if fields2.len() == 0;
118+
if let StmtKind::Local(ref local1) = body.stmts[2].kind;
119+
if let Some(ref init) = local1.init;
120+
if let ExprKind::Path(ref path8) = init.kind;
121+
if match_qpath(path8, &["__next"]);
122+
if let PatKind::Wild = local1.pat.kind;
123+
if let StmtKind::Expr(ref e1, _) = body.stmts[3].kind
124+
if let ExprKind::Block(ref block) = e1.kind;
125+
if block.stmts.len() == 1;
126+
if let StmtKind::Semi(ref e2, _) = block.stmts[0].kind
127+
if let ExprKind::Break(ref destination1, None) = e2.kind;
128+
if block.expr.is_none();
129+
if body.expr.is_none();
130+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name2, None) = arms[0].pat.kind;
131+
if name2.as_str() == "iter";
132+
then {
133+
// report your lint here
134+
}
135+
}
136+
if_chain! {
137+
if let ExprKind::DropTemps(ref expr) = expr.kind;
138+
if let ExprKind::Match(ref expr1, ref arms, MatchSource::ForLoopDesugar) = expr.kind;
139+
if let ExprKind::Call(ref func, ref args) = expr1.kind;
140+
if let ExprKind::Path(ref path) = func.kind;
141+
if matches!(path, QPath::LangItem(LangItem::IntoIterIntoIter, _));
142+
if args.len() == 1;
143+
if let ExprKind::Struct(ref path1, ref fields, None) = args[0].kind;
144+
if matches!(path1, QPath::LangItem(LangItem::Range, _));
145+
if fields.len() == 2;
146+
if fields[0].ident.name.as_str() == "start"
147+
if let ExprKind::Lit(ref lit) = fields[0].kind;
148+
if let LitKind::Int(0, LitIntType::Unsuffixed) = lit.node;
149+
if fields[1].ident.name.as_str() == "end"
150+
if let ExprKind::Lit(ref lit1) = fields[1].kind;
151+
if let LitKind::Int(10, LitIntType::Unsuffixed) = lit1.node;
152+
if arms.len() == 1;
153+
if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.kind;
154+
if body.stmts.len() == 4;
155+
if let StmtKind::Local(ref local) = body.stmts[0].kind;
156+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local.pat.kind;
157+
if name.as_str() == "__next";
158+
if let StmtKind::Expr(ref e, _) = body.stmts[1].kind
159+
if let ExprKind::Match(ref expr2, ref arms1, MatchSource::ForLoopDesugar) = e.kind;
160+
if let ExprKind::Call(ref func1, ref args1) = expr2.kind;
161+
if let ExprKind::Path(ref path2) = func1.kind;
162+
if matches!(path2, QPath::LangItem(LangItem::IteratorNext, _));
163+
if args1.len() == 1;
164+
if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, ref inner) = args1[0].kind;
165+
if let ExprKind::Path(ref path3) = inner.kind;
166+
if match_qpath(path3, &["iter"]);
167+
if arms1.len() == 2;
168+
if let ExprKind::Assign(ref target, ref value, ref _span) = arms1[0].body.kind;
169+
if let ExprKind::Path(ref path4) = target.kind;
170+
if match_qpath(path4, &["__next"]);
171+
if let ExprKind::Path(ref path5) = value.kind;
172+
if match_qpath(path5, &["val"]);
173+
if let PatKind::Struct(ref path6, ref fields1, false) = arms1[0].pat.kind;
174+
if matches!(path6, QPath::LangItem(LangItem::OptionSome, _));
175+
if fields1.len() == 1;
176+
if fields1[0].ident.name.as_str() == "0"
177+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = fields1[0].kind;
178+
if name1.as_str() == "val";
179+
if let ExprKind::Break(ref destination, None) = arms1[1].body.kind;
180+
if let PatKind::Struct(ref path7, ref fields2, false) = arms1[1].pat.kind;
181+
if matches!(path7, QPath::LangItem(LangItem::OptionNone, _));
182+
if fields2.len() == 0;
183+
if let StmtKind::Local(ref local1) = body.stmts[2].kind;
184+
if let Some(ref init) = local1.init;
185+
if let ExprKind::Path(ref path8) = init.kind;
186+
if match_qpath(path8, &["__next"]);
187+
if let PatKind::Wild = local1.pat.kind;
188+
if let StmtKind::Expr(ref e1, _) = body.stmts[3].kind
189+
if let ExprKind::Block(ref block) = e1.kind;
190+
if block.stmts.len() == 1;
191+
if let StmtKind::Semi(ref e2, _) = block.stmts[0].kind
192+
if let ExprKind::Break(ref destination1, None) = e2.kind;
193+
if let Some(ref label1) = destination1.label
194+
if label_name.ident.name.as_str() == "'label";
195+
if block.expr.is_none();
196+
if body.expr.is_none();
197+
if let Some(ref label2) = label
198+
if label_name1.ident.name.as_str() == "'label";
199+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name2, None) = arms[0].pat.kind;
200+
if name2.as_str() == "iter";
61201
then {
62202
// report your lint here
63203
}

tests/ui/author/if.stdout

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ if_chain! {
88
if let ExprKind::Binary(ref op, ref left, ref right) = e.kind;
99
if BinOpKind::Eq == op.node;
1010
if let ExprKind::Lit(ref lit) = left.kind;
11-
if let LitKind::Int(2, _) = lit.node;
11+
if let LitKind::Int(2, LitIntType::Unsuffixed) = lit.node;
1212
if let ExprKind::Lit(ref lit1) = right.kind;
13-
if let LitKind::Int(2, _) = lit1.node;
13+
if let LitKind::Int(2, LitIntType::Unsuffixed) = lit1.node;
1414
if block.expr.is_none();
1515
if let ExprKind::DropTemps(ref expr) = cond.kind;
1616
if let ExprKind::Lit(ref lit2) = expr.kind;
@@ -21,9 +21,9 @@ if_chain! {
2121
if let ExprKind::Binary(ref op1, ref left1, ref right1) = e1.kind;
2222
if BinOpKind::Eq == op1.node;
2323
if let ExprKind::Lit(ref lit3) = left1.kind;
24-
if let LitKind::Int(1, _) = lit3.node;
24+
if let LitKind::Int(1, LitIntType::Unsuffixed) = lit3.node;
2525
if let ExprKind::Lit(ref lit4) = right1.kind;
26-
if let LitKind::Int(1, _) = lit4.node;
26+
if let LitKind::Int(1, LitIntType::Unsuffixed) = lit4.node;
2727
if block1.expr.is_none();
2828
if let PatKind::Wild = local.pat.kind;
2929
then {

tests/ui/author/matches.stdout

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,29 @@ if_chain! {
33
if let Some(ref init) = local.init;
44
if let ExprKind::Match(ref expr, ref arms, MatchSource::Normal) = init.kind;
55
if let ExprKind::Lit(ref lit) = expr.kind;
6-
if let LitKind::Int(42, _) = lit.node;
6+
if let LitKind::Int(42, LitIntType::Unsuffixed) = lit.node;
77
if arms.len() == 3;
88
if let ExprKind::Lit(ref lit1) = arms[0].body.kind;
9-
if let LitKind::Int(5, _) = lit1.node;
9+
if let LitKind::Int(5, LitIntType::Unsuffixed) = lit1.node;
1010
if let PatKind::Lit(ref lit_expr) = arms[0].pat.kind
1111
if let ExprKind::Lit(ref lit2) = lit_expr.kind;
12-
if let LitKind::Int(16, _) = lit2.node;
12+
if let LitKind::Int(16, LitIntType::Unsuffixed) = lit2.node;
1313
if let ExprKind::Block(ref block) = arms[1].body.kind;
1414
if block.stmts.len() == 1;
1515
if let StmtKind::Local(ref local1) = block.stmts[0].kind;
1616
if let Some(ref init1) = local1.init;
1717
if let ExprKind::Lit(ref lit3) = init1.kind;
18-
if let LitKind::Int(3, _) = lit3.node;
18+
if let LitKind::Int(3, LitIntType::Unsuffixed) = lit3.node;
1919
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local1.pat.kind;
2020
if name.as_str() == "x";
2121
if let Some(trailing_expr) = &block.expr;
2222
if let ExprKind::Path(ref path) = trailing_expr.kind;
2323
if match_qpath(path, &["x"]);
2424
if let PatKind::Lit(ref lit_expr1) = arms[1].pat.kind
2525
if let ExprKind::Lit(ref lit4) = lit_expr1.kind;
26-
if let LitKind::Int(17, _) = lit4.node;
26+
if let LitKind::Int(17, LitIntType::Unsuffixed) = lit4.node;
2727
if let ExprKind::Lit(ref lit5) = arms[2].body.kind;
28-
if let LitKind::Int(1, _) = lit5.node;
28+
if let LitKind::Int(1, LitIntType::Unsuffixed) = lit5.node;
2929
if let PatKind::Wild = arms[2].pat.kind;
3030
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local.pat.kind;
3131
if name1.as_str() == "a";

0 commit comments

Comments
 (0)