Skip to content

Commit 2b87f8f

Browse files
committed
Extend author lint
1 parent 00821ca commit 2b87f8f

File tree

13 files changed

+543
-71
lines changed

13 files changed

+543
-71
lines changed

clippy_lints/src/utils/author.rs

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

tests/ui/author.stdout

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ 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, ref suffix) = lit.node;
9+
if let LitIntType::Unsuffixed = suffix
910
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind;
1011
if name.as_str() == "x";
1112
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+
move |_a:u32| {};
1524
}

tests/ui/author/blocks.stdout

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
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, ref suffix) = lit.node;
8+
if let LitIntType::Signed(ref int_ty) = suffix
9+
if let IntTy::I32 = int_ty
810
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local.pat.kind;
911
if name.as_str() == "x";
10-
if let StmtKind::Semi(ref e, _) = block.stmts[1].kind
12+
if let StmtKind::Local(ref local1) = block.stmts[1].kind;
13+
if let Some(ref init1) = local1.init;
14+
if let ExprKind::Lit(ref lit1) = init1.kind;
15+
if let LitKind::Float(_, ref suffix1) = lit1.node;
16+
if let LitFloatType::Suffixed(ref float_ty) = suffix1
17+
if let FloatTy::F32 = float_ty
18+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local1.pat.kind;
19+
if name1.as_str() == "_t";
20+
if let StmtKind::Semi(ref e, _) = block.stmts[2].kind
1121
if let ExprKind::Unary(UnOp::Neg, ref inner) = e.kind;
1222
if let ExprKind::Path(ref path) = inner.kind;
1323
if match_qpath(path, &["x"]);
@@ -38,3 +48,14 @@ if_chain! {
3848
// report your lint here
3949
}
4050
}
51+
if_chain! {
52+
if let ExprKind::Closure(ref capture_by, ref async, _, _, ref fn_expr, _) = expr.kind;
53+
if let CaptureBy::Value = capture_by
54+
if let Async::No = async
55+
if let ExprKind::Block(ref block) = fn_expr.kind;
56+
if block.stmts.len() == 0;
57+
if block.expr.is_none();
58+
then {
59+
// report your lint here
60+
}
61+
}

tests/ui/author/call.stdout

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,11 @@ 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, ref suffix) = lit.node;
10+
if let LitIntType::Unsuffixed = suffix
1011
if let ExprKind::Lit(ref lit1) = args[1].kind;
11-
if let LitKind::Int(4, _) = lit1.node;
12+
if let LitKind::Int(4, ref suffix1) = lit1.node;
13+
if let LitIntType::Unsuffixed = suffix1
1214
if let PatKind::Wild = local.pat.kind;
1315
then {
1416
// 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: 161 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,14 @@ 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, ref suffix) = lit.node;
14+
if let LitIntType::Unsuffixed = suffix
15+
if fields[1].ident.name.as_str() == "end"
16+
if let ExprKind::Lit(ref lit1) = fields[1].kind;
17+
if let LitKind::Int(10, ref suffix1) = lit1.node;
18+
if let LitIntType::Unsuffixed = suffix1
1219
if arms.len() == 1;
1320
if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.kind;
1421
if body.stmts.len() == 4;
@@ -33,31 +40,176 @@ if_chain! {
3340
if let PatKind::Struct(ref path6, ref fields1, false) = arms1[0].pat.kind;
3441
if matches!(path6, QPath::LangItem(LangItem::OptionSome, _));
3542
if fields1.len() == 1;
36-
// unimplemented: field checks
43+
if fields1[0].ident.name.as_str() == "0"
44+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = fields1[0].kind;
45+
if name1.as_str() == "val";
3746
if let ExprKind::Break(ref destination, None) = arms1[1].body.kind;
47+
if destination.label.is_none();
3848
if let PatKind::Struct(ref path7, ref fields2, false) = arms1[1].pat.kind;
3949
if matches!(path7, QPath::LangItem(LangItem::OptionNone, _));
4050
if fields2.len() == 0;
41-
// unimplemented: field checks
4251
if let StmtKind::Local(ref local1) = body.stmts[2].kind;
4352
if let Some(ref init) = local1.init;
4453
if let ExprKind::Path(ref path8) = init.kind;
4554
if match_qpath(path8, &["__next"]);
46-
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local1.pat.kind;
47-
if name1.as_str() == "y";
55+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local1.pat.kind;
56+
if name2.as_str() == "y";
4857
if let StmtKind::Expr(ref e1, _) = body.stmts[3].kind
4958
if let ExprKind::Block(ref block) = e1.kind;
5059
if block.stmts.len() == 1;
5160
if let StmtKind::Local(ref local2) = block.stmts[0].kind;
5261
if let Some(ref init1) = local2.init;
5362
if let ExprKind::Path(ref path9) = init1.kind;
5463
if match_qpath(path9, &["y"]);
55-
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name2, None) = local2.pat.kind;
56-
if name2.as_str() == "z";
64+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name3, None) = local2.pat.kind;
65+
if name3.as_str() == "z";
5766
if block.expr.is_none();
5867
if body.expr.is_none();
59-
if let PatKind::Binding(BindingAnnotation::Mutable, _, name3, None) = arms[0].pat.kind;
60-
if name3.as_str() == "iter";
68+
if label.is_none();
69+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name4, None) = arms[0].pat.kind;
70+
if name4.as_str() == "iter";
71+
then {
72+
// report your lint here
73+
}
74+
}
75+
if_chain! {
76+
if let ExprKind::DropTemps(ref expr) = expr.kind;
77+
if let ExprKind::Match(ref expr1, ref arms, MatchSource::ForLoopDesugar) = expr.kind;
78+
if let ExprKind::Call(ref func, ref args) = expr1.kind;
79+
if let ExprKind::Path(ref path) = func.kind;
80+
if matches!(path, QPath::LangItem(LangItem::IntoIterIntoIter, _));
81+
if args.len() == 1;
82+
if let ExprKind::Struct(ref path1, ref fields, None) = args[0].kind;
83+
if matches!(path1, QPath::LangItem(LangItem::Range, _));
84+
if fields.len() == 2;
85+
if fields[0].ident.name.as_str() == "start"
86+
if let ExprKind::Lit(ref lit) = fields[0].kind;
87+
if let LitKind::Int(0, ref suffix) = lit.node;
88+
if let LitIntType::Unsuffixed = suffix
89+
if fields[1].ident.name.as_str() == "end"
90+
if let ExprKind::Lit(ref lit1) = fields[1].kind;
91+
if let LitKind::Int(10, ref suffix1) = lit1.node;
92+
if let LitIntType::Unsuffixed = suffix1
93+
if arms.len() == 1;
94+
if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.kind;
95+
if body.stmts.len() == 4;
96+
if let StmtKind::Local(ref local) = body.stmts[0].kind;
97+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local.pat.kind;
98+
if name.as_str() == "__next";
99+
if let StmtKind::Expr(ref e, _) = body.stmts[1].kind
100+
if let ExprKind::Match(ref expr2, ref arms1, MatchSource::ForLoopDesugar) = e.kind;
101+
if let ExprKind::Call(ref func1, ref args1) = expr2.kind;
102+
if let ExprKind::Path(ref path2) = func1.kind;
103+
if matches!(path2, QPath::LangItem(LangItem::IteratorNext, _));
104+
if args1.len() == 1;
105+
if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, ref inner) = args1[0].kind;
106+
if let ExprKind::Path(ref path3) = inner.kind;
107+
if match_qpath(path3, &["iter"]);
108+
if arms1.len() == 2;
109+
if let ExprKind::Assign(ref target, ref value, ref _span) = arms1[0].body.kind;
110+
if let ExprKind::Path(ref path4) = target.kind;
111+
if match_qpath(path4, &["__next"]);
112+
if let ExprKind::Path(ref path5) = value.kind;
113+
if match_qpath(path5, &["val"]);
114+
if let PatKind::Struct(ref path6, ref fields1, false) = arms1[0].pat.kind;
115+
if matches!(path6, QPath::LangItem(LangItem::OptionSome, _));
116+
if fields1.len() == 1;
117+
if fields1[0].ident.name.as_str() == "0"
118+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = fields1[0].kind;
119+
if name1.as_str() == "val";
120+
if let ExprKind::Break(ref destination, None) = arms1[1].body.kind;
121+
if destination.label.is_none();
122+
if let PatKind::Struct(ref path7, ref fields2, false) = arms1[1].pat.kind;
123+
if matches!(path7, QPath::LangItem(LangItem::OptionNone, _));
124+
if fields2.len() == 0;
125+
if let StmtKind::Local(ref local1) = body.stmts[2].kind;
126+
if let Some(ref init) = local1.init;
127+
if let ExprKind::Path(ref path8) = init.kind;
128+
if match_qpath(path8, &["__next"]);
129+
if let PatKind::Wild = local1.pat.kind;
130+
if let StmtKind::Expr(ref e1, _) = body.stmts[3].kind
131+
if let ExprKind::Block(ref block) = e1.kind;
132+
if block.stmts.len() == 1;
133+
if let StmtKind::Semi(ref e2, _) = block.stmts[0].kind
134+
if let ExprKind::Break(ref destination1, None) = e2.kind;
135+
if destination1.label.is_none();
136+
if block.expr.is_none();
137+
if body.expr.is_none();
138+
if label.is_none();
139+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name2, None) = arms[0].pat.kind;
140+
if name2.as_str() == "iter";
141+
then {
142+
// report your lint here
143+
}
144+
}
145+
if_chain! {
146+
if let ExprKind::DropTemps(ref expr) = expr.kind;
147+
if let ExprKind::Match(ref expr1, ref arms, MatchSource::ForLoopDesugar) = expr.kind;
148+
if let ExprKind::Call(ref func, ref args) = expr1.kind;
149+
if let ExprKind::Path(ref path) = func.kind;
150+
if matches!(path, QPath::LangItem(LangItem::IntoIterIntoIter, _));
151+
if args.len() == 1;
152+
if let ExprKind::Struct(ref path1, ref fields, None) = args[0].kind;
153+
if matches!(path1, QPath::LangItem(LangItem::Range, _));
154+
if fields.len() == 2;
155+
if fields[0].ident.name.as_str() == "start"
156+
if let ExprKind::Lit(ref lit) = fields[0].kind;
157+
if let LitKind::Int(0, ref suffix) = lit.node;
158+
if let LitIntType::Unsuffixed = suffix
159+
if fields[1].ident.name.as_str() == "end"
160+
if let ExprKind::Lit(ref lit1) = fields[1].kind;
161+
if let LitKind::Int(10, ref suffix1) = lit1.node;
162+
if let LitIntType::Unsuffixed = suffix1
163+
if arms.len() == 1;
164+
if let ExprKind::Loop(ref body, ref label, LoopSource::ForLoop) = arms[0].body.kind;
165+
if body.stmts.len() == 4;
166+
if let StmtKind::Local(ref local) = body.stmts[0].kind;
167+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name, None) = local.pat.kind;
168+
if name.as_str() == "__next";
169+
if let StmtKind::Expr(ref e, _) = body.stmts[1].kind
170+
if let ExprKind::Match(ref expr2, ref arms1, MatchSource::ForLoopDesugar) = e.kind;
171+
if let ExprKind::Call(ref func1, ref args1) = expr2.kind;
172+
if let ExprKind::Path(ref path2) = func1.kind;
173+
if matches!(path2, QPath::LangItem(LangItem::IteratorNext, _));
174+
if args1.len() == 1;
175+
if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, ref inner) = args1[0].kind;
176+
if let ExprKind::Path(ref path3) = inner.kind;
177+
if match_qpath(path3, &["iter"]);
178+
if arms1.len() == 2;
179+
if let ExprKind::Assign(ref target, ref value, ref _span) = arms1[0].body.kind;
180+
if let ExprKind::Path(ref path4) = target.kind;
181+
if match_qpath(path4, &["__next"]);
182+
if let ExprKind::Path(ref path5) = value.kind;
183+
if match_qpath(path5, &["val"]);
184+
if let PatKind::Struct(ref path6, ref fields1, false) = arms1[0].pat.kind;
185+
if matches!(path6, QPath::LangItem(LangItem::OptionSome, _));
186+
if fields1.len() == 1;
187+
if fields1[0].ident.name.as_str() == "0"
188+
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = fields1[0].kind;
189+
if name1.as_str() == "val";
190+
if let ExprKind::Break(ref destination, None) = arms1[1].body.kind;
191+
if destination.label.is_none();
192+
if let PatKind::Struct(ref path7, ref fields2, false) = arms1[1].pat.kind;
193+
if matches!(path7, QPath::LangItem(LangItem::OptionNone, _));
194+
if fields2.len() == 0;
195+
if let StmtKind::Local(ref local1) = body.stmts[2].kind;
196+
if let Some(ref init) = local1.init;
197+
if let ExprKind::Path(ref path8) = init.kind;
198+
if match_qpath(path8, &["__next"]);
199+
if let PatKind::Wild = local1.pat.kind;
200+
if let StmtKind::Expr(ref e1, _) = body.stmts[3].kind
201+
if let ExprKind::Block(ref block) = e1.kind;
202+
if block.stmts.len() == 1;
203+
if let StmtKind::Semi(ref e2, _) = block.stmts[0].kind
204+
if let ExprKind::Break(ref destination1, None) = e2.kind;
205+
if let Some(ref label1) = destination1.label
206+
if label_name.ident.name.as_str() == "'label";
207+
if block.expr.is_none();
208+
if body.expr.is_none();
209+
if let Some(ref label2) = label
210+
if label_name1.ident.name.as_str() == "'label";
211+
if let PatKind::Binding(BindingAnnotation::Mutable, _, name2, None) = arms[0].pat.kind;
212+
if name2.as_str() == "iter";
61213
then {
62214
// report your lint here
63215
}

tests/ui/author/if.stdout

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,11 @@ 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, ref suffix) = lit.node;
12+
if let LitIntType::Unsuffixed = suffix
1213
if let ExprKind::Lit(ref lit1) = right.kind;
13-
if let LitKind::Int(2, _) = lit1.node;
14+
if let LitKind::Int(2, ref suffix1) = lit1.node;
15+
if let LitIntType::Unsuffixed = suffix1
1416
if block.expr.is_none();
1517
if let ExprKind::DropTemps(ref expr) = cond.kind;
1618
if let ExprKind::Lit(ref lit2) = expr.kind;
@@ -21,9 +23,11 @@ if_chain! {
2123
if let ExprKind::Binary(ref op1, ref left1, ref right1) = e1.kind;
2224
if BinOpKind::Eq == op1.node;
2325
if let ExprKind::Lit(ref lit3) = left1.kind;
24-
if let LitKind::Int(1, _) = lit3.node;
26+
if let LitKind::Int(1, ref suffix2) = lit3.node;
27+
if let LitIntType::Unsuffixed = suffix2
2528
if let ExprKind::Lit(ref lit4) = right1.kind;
26-
if let LitKind::Int(1, _) = lit4.node;
29+
if let LitKind::Int(1, ref suffix3) = lit4.node;
30+
if let LitIntType::Unsuffixed = suffix3
2731
if block1.expr.is_none();
2832
if let PatKind::Wild = local.pat.kind;
2933
then {

tests/ui/author/matches.stdout

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,35 @@ 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, ref suffix) = lit.node;
7+
if let LitIntType::Unsuffixed = suffix
78
if arms.len() == 3;
89
if let ExprKind::Lit(ref lit1) = arms[0].body.kind;
9-
if let LitKind::Int(5, _) = lit1.node;
10+
if let LitKind::Int(5, ref suffix1) = lit1.node;
11+
if let LitIntType::Unsuffixed = suffix1
1012
if let PatKind::Lit(ref lit_expr) = arms[0].pat.kind
1113
if let ExprKind::Lit(ref lit2) = lit_expr.kind;
12-
if let LitKind::Int(16, _) = lit2.node;
14+
if let LitKind::Int(16, ref suffix2) = lit2.node;
15+
if let LitIntType::Unsuffixed = suffix2
1316
if let ExprKind::Block(ref block) = arms[1].body.kind;
1417
if block.stmts.len() == 1;
1518
if let StmtKind::Local(ref local1) = block.stmts[0].kind;
1619
if let Some(ref init1) = local1.init;
1720
if let ExprKind::Lit(ref lit3) = init1.kind;
18-
if let LitKind::Int(3, _) = lit3.node;
21+
if let LitKind::Int(3, ref suffix3) = lit3.node;
22+
if let LitIntType::Unsuffixed = suffix3
1923
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name, None) = local1.pat.kind;
2024
if name.as_str() == "x";
2125
if let Some(trailing_expr) = &block.expr;
2226
if let ExprKind::Path(ref path) = trailing_expr.kind;
2327
if match_qpath(path, &["x"]);
2428
if let PatKind::Lit(ref lit_expr1) = arms[1].pat.kind
2529
if let ExprKind::Lit(ref lit4) = lit_expr1.kind;
26-
if let LitKind::Int(17, _) = lit4.node;
30+
if let LitKind::Int(17, ref suffix4) = lit4.node;
31+
if let LitIntType::Unsuffixed = suffix4
2732
if let ExprKind::Lit(ref lit5) = arms[2].body.kind;
28-
if let LitKind::Int(1, _) = lit5.node;
33+
if let LitKind::Int(1, ref suffix5) = lit5.node;
34+
if let LitIntType::Unsuffixed = suffix5
2935
if let PatKind::Wild = arms[2].pat.kind;
3036
if let PatKind::Binding(BindingAnnotation::Unannotated, _, name1, None) = local.pat.kind;
3137
if name1.as_str() == "a";

tests/ui/author/repeat.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#[allow(clippy::no_effect)]
2+
fn main() {
3+
#[clippy::author]
4+
[1_u8; 5];
5+
}

0 commit comments

Comments
 (0)