Skip to content

Commit 4bdfd96

Browse files
committed
Make WhileTrue into an EarlyLintPass lint.
1 parent 68eba9a commit 4bdfd96

17 files changed

+116
-55
lines changed

src/librustc_lint/builtin.rs

+18-26
Original file line numberDiff line numberDiff line change
@@ -64,38 +64,30 @@ declare_lint! {
6464

6565
declare_lint_pass!(WhileTrue => [WHILE_TRUE]);
6666

67-
fn as_while_cond(expr: &hir::Expr) -> Option<&hir::Expr> {
68-
if let hir::ExprKind::Loop(blk, ..) = &expr.node {
69-
if let Some(match_expr) = &blk.expr {
70-
if let hir::ExprKind::Match(cond, .., hir::MatchSource::WhileDesugar)
71-
= &match_expr.node
72-
{
73-
if let hir::ExprKind::DropTemps(cond) = &cond.node {
74-
return Some(cond);
75-
}
76-
}
77-
}
67+
/// Traverse through any amount of parenthesis and return the first non-parens expression.
68+
fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr {
69+
while let ast::ExprKind::Paren(sub) = &expr.node {
70+
expr = sub;
7871
}
79-
80-
None
72+
expr
8173
}
8274

83-
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue {
84-
fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {
85-
if let Some(ref cond) = as_while_cond(e) {
86-
if let hir::ExprKind::Lit(ref lit) = cond.node {
75+
impl EarlyLintPass for WhileTrue {
76+
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
77+
if let ast::ExprKind::While(cond, ..) = &e.node {
78+
if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).node {
8779
if let ast::LitKind::Bool(true) = lit.node {
8880
if lit.span.ctxt() == SyntaxContext::empty() {
8981
let msg = "denote infinite loops with `loop { ... }`";
90-
let condition_span = cx.tcx.sess.source_map().def_span(e.span);
91-
let mut err = cx.struct_span_lint(WHILE_TRUE, condition_span, msg);
92-
err.span_suggestion_short(
93-
condition_span,
94-
"use `loop`",
95-
"loop".to_owned(),
96-
Applicability::MachineApplicable
97-
);
98-
err.emit();
82+
let condition_span = cx.sess.source_map().def_span(e.span);
83+
cx.struct_span_lint(WHILE_TRUE, condition_span, msg)
84+
.span_suggestion_short(
85+
condition_span,
86+
"use `loop`",
87+
"loop".to_owned(),
88+
Applicability::MachineApplicable
89+
)
90+
.emit();
9991
}
10092
}
10193
}

src/librustc_lint/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ macro_rules! early_lint_passes {
9898
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
9999
NonCamelCaseTypes: NonCamelCaseTypes,
100100
DeprecatedAttr: DeprecatedAttr::new(),
101+
WhileTrue: WhileTrue,
101102
]);
102103
)
103104
}
@@ -142,7 +143,6 @@ macro_rules! late_lint_mod_passes {
142143
($macro:path, $args:tt) => (
143144
$macro!($args, [
144145
HardwiredLints: HardwiredLints,
145-
WhileTrue: WhileTrue,
146146
ImproperCTypes: ImproperCTypes,
147147
VariantSizeDifferences: VariantSizeDifferences,
148148
BoxPointers: BoxPointers,

src/test/compile-fail/issue-52443.rs

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ fn main() {
22
[(); & { loop { continue } } ]; //~ ERROR mismatched types
33
[(); loop { break }]; //~ ERROR mismatched types
44
[(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type
5+
//~^ WARN denote infinite loops with
56
[(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
67
//~^ ERROR constant contains unimplemented expression type
78
//~| ERROR constant contains unimplemented expression type

src/test/ui/block-result/block-must-not-have-result-while.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
fn main() {
2-
while true {
2+
while true { //~ WARN denote infinite loops with
33
true //~ ERROR mismatched types
44
//~| expected type `()`
55
//~| found type `bool`

src/test/ui/block-result/block-must-not-have-result-while.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
warning: denote infinite loops with `loop { ... }`
2+
--> $DIR/block-must-not-have-result-while.rs:2:5
3+
|
4+
LL | while true {
5+
| ^^^^^^^^^^ help: use `loop`
6+
|
7+
= note: #[warn(while_true)] on by default
8+
19
error[E0308]: mismatched types
210
--> $DIR/block-must-not-have-result-while.rs:3:9
311
|

src/test/ui/borrowck/mut-borrow-in-loop.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ impl<'a, T : 'a> FuncWrapper<'a, T> {
1212
}
1313

1414
fn in_while(self, arg : &'a mut T) {
15-
while true {
15+
while true { //~ WARN denote infinite loops with
1616
(self.func)(arg) //~ ERROR cannot borrow
1717
}
1818
}

src/test/ui/borrowck/mut-borrow-in-loop.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
warning: denote infinite loops with `loop { ... }`
2+
--> $DIR/mut-borrow-in-loop.rs:15:9
3+
|
4+
LL | while true {
5+
| ^^^^^^^^^^ help: use `loop`
6+
|
7+
= note: #[warn(while_true)] on by default
8+
19
error[E0499]: cannot borrow `*arg` as mutable more than once at a time
210
--> $DIR/mut-borrow-in-loop.rs:10:25
311
|

src/test/ui/issues/issue-27042.rs

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ fn main() {
66
loop { break }; //~ ERROR mismatched types
77
let _: i32 =
88
'b: //~ ERROR mismatched types
9+
//~^ WARN denote infinite loops with
910
while true { break }; // but here we cite the whole loop
1011
let _: i32 =
1112
'c: //~ ERROR mismatched types

src/test/ui/issues/issue-27042.stderr

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
warning: denote infinite loops with `loop { ... }`
2+
--> $DIR/issue-27042.rs:8:9
3+
|
4+
LL | / 'b:
5+
LL | |
6+
LL | | while true { break }; // but here we cite the whole loop
7+
| |____________________________^ help: use `loop`
8+
|
9+
= note: #[warn(while_true)] on by default
10+
111
error[E0308]: mismatched types
212
--> $DIR/issue-27042.rs:6:16
313
|
@@ -11,14 +21,15 @@ error[E0308]: mismatched types
1121
--> $DIR/issue-27042.rs:8:9
1222
|
1323
LL | / 'b:
24+
LL | |
1425
LL | | while true { break }; // but here we cite the whole loop
1526
| |____________________________^ expected i32, found ()
1627
|
1728
= note: expected type `i32`
1829
found type `()`
1930

2031
error[E0308]: mismatched types
21-
--> $DIR/issue-27042.rs:11:9
32+
--> $DIR/issue-27042.rs:12:9
2233
|
2334
LL | / 'c:
2435
LL | | for _ in None { break }; // but here we cite the whole loop
@@ -28,7 +39,7 @@ LL | | for _ in None { break }; // but here we cite the whole loop
2839
found type `()`
2940

3041
error[E0308]: mismatched types
31-
--> $DIR/issue-27042.rs:14:9
42+
--> $DIR/issue-27042.rs:15:9
3243
|
3344
LL | / 'd:
3445
LL | | while let Some(_) = None { break };

src/test/ui/lint/lint-impl-fn.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,25 @@ LL | #[deny(while_true)]
1111
| ^^^^^^^^^^
1212

1313
error: denote infinite loops with `loop { ... }`
14-
--> $DIR/lint-impl-fn.rs:27:5
14+
--> $DIR/lint-impl-fn.rs:18:25
1515
|
16-
LL | while true {}
17-
| ^^^^^^^^^^ help: use `loop`
16+
LL | fn foo(&self) { while true {} }
17+
| ^^^^^^^^^^ help: use `loop`
1818
|
1919
note: lint level defined here
20-
--> $DIR/lint-impl-fn.rs:25:8
20+
--> $DIR/lint-impl-fn.rs:13:8
2121
|
2222
LL | #[deny(while_true)]
2323
| ^^^^^^^^^^
2424

2525
error: denote infinite loops with `loop { ... }`
26-
--> $DIR/lint-impl-fn.rs:18:25
26+
--> $DIR/lint-impl-fn.rs:27:5
2727
|
28-
LL | fn foo(&self) { while true {} }
29-
| ^^^^^^^^^^ help: use `loop`
28+
LL | while true {}
29+
| ^^^^^^^^^^ help: use `loop`
3030
|
3131
note: lint level defined here
32-
--> $DIR/lint-impl-fn.rs:13:8
32+
--> $DIR/lint-impl-fn.rs:25:8
3333
|
3434
LL | #[deny(while_true)]
3535
| ^^^^^^^^^^

src/test/ui/lint/lint-unnecessary-parens.rs

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ fn main() {
1919

2020
if (true) {} //~ ERROR unnecessary parentheses around `if` condition
2121
while (true) {} //~ ERROR unnecessary parentheses around `while` condition
22+
//~^ WARN denote infinite loops with
2223
match (true) { //~ ERROR unnecessary parentheses around `match` head expression
2324
_ => {}
2425
}

src/test/ui/lint/lint-unnecessary-parens.stderr

+15-7
Original file line numberDiff line numberDiff line change
@@ -34,44 +34,52 @@ error: unnecessary parentheses around `while` condition
3434
LL | while (true) {}
3535
| ^^^^^^ help: remove these parentheses
3636

37+
warning: denote infinite loops with `loop { ... }`
38+
--> $DIR/lint-unnecessary-parens.rs:21:5
39+
|
40+
LL | while (true) {}
41+
| ^^^^^^^^^^^^ help: use `loop`
42+
|
43+
= note: #[warn(while_true)] on by default
44+
3745
error: unnecessary parentheses around `match` head expression
38-
--> $DIR/lint-unnecessary-parens.rs:22:11
46+
--> $DIR/lint-unnecessary-parens.rs:23:11
3947
|
4048
LL | match (true) {
4149
| ^^^^^^ help: remove these parentheses
4250

4351
error: unnecessary parentheses around `let` head expression
44-
--> $DIR/lint-unnecessary-parens.rs:25:16
52+
--> $DIR/lint-unnecessary-parens.rs:26:16
4553
|
4654
LL | if let 1 = (1) {}
4755
| ^^^ help: remove these parentheses
4856

4957
error: unnecessary parentheses around `let` head expression
50-
--> $DIR/lint-unnecessary-parens.rs:26:19
58+
--> $DIR/lint-unnecessary-parens.rs:27:19
5159
|
5260
LL | while let 1 = (2) {}
5361
| ^^^ help: remove these parentheses
5462

5563
error: unnecessary parentheses around method argument
56-
--> $DIR/lint-unnecessary-parens.rs:40:24
64+
--> $DIR/lint-unnecessary-parens.rs:41:24
5765
|
5866
LL | X { y: false }.foo((true));
5967
| ^^^^^^ help: remove these parentheses
6068

6169
error: unnecessary parentheses around assigned value
62-
--> $DIR/lint-unnecessary-parens.rs:42:18
70+
--> $DIR/lint-unnecessary-parens.rs:43:18
6371
|
6472
LL | let mut _a = (0);
6573
| ^^^ help: remove these parentheses
6674

6775
error: unnecessary parentheses around assigned value
68-
--> $DIR/lint-unnecessary-parens.rs:43:10
76+
--> $DIR/lint-unnecessary-parens.rs:44:10
6977
|
7078
LL | _a = (0);
7179
| ^^^ help: remove these parentheses
7280

7381
error: unnecessary parentheses around assigned value
74-
--> $DIR/lint-unnecessary-parens.rs:44:11
82+
--> $DIR/lint-unnecessary-parens.rs:45:11
7583
|
7684
LL | _a += (1);
7785
| ^^^ help: remove these parentheses

src/test/ui/lint/suggestions.stderr

+8-8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
warning: denote infinite loops with `loop { ... }`
2+
--> $DIR/suggestions.rs:46:5
3+
|
4+
LL | while true {
5+
| ^^^^^^^^^^ help: use `loop`
6+
|
7+
= note: #[warn(while_true)] on by default
8+
19
warning: unnecessary parentheses around assigned value
210
--> $DIR/suggestions.rs:49:31
311
|
@@ -65,14 +73,6 @@ LL | pub fn defiant<T>(_t: T) {}
6573
|
6674
= note: #[warn(no_mangle_generic_items)] on by default
6775

68-
warning: denote infinite loops with `loop { ... }`
69-
--> $DIR/suggestions.rs:46:5
70-
|
71-
LL | while true {
72-
| ^^^^^^^^^^ help: use `loop`
73-
|
74-
= note: #[warn(while_true)] on by default
75-
7676
warning: the `warp_factor:` in this pattern is redundant
7777
--> $DIR/suggestions.rs:61:23
7878
|

src/test/ui/liveness/liveness-move-in-while.rs

+3
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,8 @@ fn main() {
66
loop {
77
println!("{}", y); //~ ERROR borrow of moved value: `y`
88
while true { while true { while true { x = y; x.clone(); } } }
9+
//~^ WARN denote infinite loops with
10+
//~| WARN denote infinite loops with
11+
//~| WARN denote infinite loops with
912
}
1013
}

src/test/ui/liveness/liveness-move-in-while.stderr

+20
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,23 @@
1+
warning: denote infinite loops with `loop { ... }`
2+
--> $DIR/liveness-move-in-while.rs:8:9
3+
|
4+
LL | while true { while true { while true { x = y; x.clone(); } } }
5+
| ^^^^^^^^^^ help: use `loop`
6+
|
7+
= note: #[warn(while_true)] on by default
8+
9+
warning: denote infinite loops with `loop { ... }`
10+
--> $DIR/liveness-move-in-while.rs:8:22
11+
|
12+
LL | while true { while true { while true { x = y; x.clone(); } } }
13+
| ^^^^^^^^^^ help: use `loop`
14+
15+
warning: denote infinite loops with `loop { ... }`
16+
--> $DIR/liveness-move-in-while.rs:8:35
17+
|
18+
LL | while true { while true { while true { x = y; x.clone(); } } }
19+
| ^^^^^^^^^^ help: use `loop`
20+
121
error[E0382]: borrow of moved value: `y`
222
--> $DIR/liveness-move-in-while.rs:7:24
323
|

src/test/ui/loops/loop-break-value.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn main() {
2323
};
2424
};
2525

26-
'while_loop: while true {
26+
'while_loop: while true { //~ WARN denote infinite loops with
2727
break;
2828
break (); //~ ERROR `break` with value from a `while` loop
2929
loop {

src/test/ui/loops/loop-break-value.stderr

+8
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
warning: denote infinite loops with `loop { ... }`
2+
--> $DIR/loop-break-value.rs:26:5
3+
|
4+
LL | 'while_loop: while true {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop`
6+
|
7+
= note: #[warn(while_true)] on by default
8+
19
error[E0571]: `break` with value from a `while` loop
210
--> $DIR/loop-break-value.rs:28:9
311
|

0 commit comments

Comments
 (0)