Skip to content

Commit 5477354

Browse files
committed
Make WhileTrue into an EarlyLintPass lint.
1 parent f01562a commit 5477354

17 files changed

+116
-55
lines changed

src/librustc_lint/builtin.rs

Lines changed: 18 additions & 26 deletions
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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ macro_rules! early_lint_passes {
9696
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
9797
NonCamelCaseTypes: NonCamelCaseTypes,
9898
DeprecatedAttr: DeprecatedAttr::new(),
99+
WhileTrue: WhileTrue,
99100
]);
100101
)
101102
}
@@ -140,7 +141,6 @@ macro_rules! late_lint_mod_passes {
140141
($macro:path, $args:tt) => (
141142
$macro!($args, [
142143
HardwiredLints: HardwiredLints,
143-
WhileTrue: WhileTrue,
144144
ImproperCTypes: ImproperCTypes,
145145
VariantSizeDifferences: VariantSizeDifferences,
146146
BoxPointers: BoxPointers,

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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 8 additions & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 8 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 13 additions & 2 deletions
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

Lines changed: 8 additions & 8 deletions
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
| ^^^^^^^^^^

0 commit comments

Comments
 (0)