Make WhileTrue into an EarlyLintPass lint.
This commit is contained in:
parent
f01562af33
commit
547735457f
|
@ -64,38 +64,30 @@ declare_lint! {
|
||||||
|
|
||||||
declare_lint_pass!(WhileTrue => [WHILE_TRUE]);
|
declare_lint_pass!(WhileTrue => [WHILE_TRUE]);
|
||||||
|
|
||||||
fn as_while_cond(expr: &hir::Expr) -> Option<&hir::Expr> {
|
/// Traverse through any amount of parenthesis and return the first non-parens expression.
|
||||||
if let hir::ExprKind::Loop(blk, ..) = &expr.node {
|
fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr {
|
||||||
if let Some(match_expr) = &blk.expr {
|
while let ast::ExprKind::Paren(sub) = &expr.node {
|
||||||
if let hir::ExprKind::Match(cond, .., hir::MatchSource::WhileDesugar)
|
expr = sub;
|
||||||
= &match_expr.node
|
|
||||||
{
|
|
||||||
if let hir::ExprKind::DropTemps(cond) = &cond.node {
|
|
||||||
return Some(cond);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
expr
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue {
|
impl EarlyLintPass for WhileTrue {
|
||||||
fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {
|
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||||
if let Some(ref cond) = as_while_cond(e) {
|
if let ast::ExprKind::While(cond, ..) = &e.node {
|
||||||
if let hir::ExprKind::Lit(ref lit) = cond.node {
|
if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).node {
|
||||||
if let ast::LitKind::Bool(true) = lit.node {
|
if let ast::LitKind::Bool(true) = lit.node {
|
||||||
if lit.span.ctxt() == SyntaxContext::empty() {
|
if lit.span.ctxt() == SyntaxContext::empty() {
|
||||||
let msg = "denote infinite loops with `loop { ... }`";
|
let msg = "denote infinite loops with `loop { ... }`";
|
||||||
let condition_span = cx.tcx.sess.source_map().def_span(e.span);
|
let condition_span = cx.sess.source_map().def_span(e.span);
|
||||||
let mut err = cx.struct_span_lint(WHILE_TRUE, condition_span, msg);
|
cx.struct_span_lint(WHILE_TRUE, condition_span, msg)
|
||||||
err.span_suggestion_short(
|
.span_suggestion_short(
|
||||||
condition_span,
|
condition_span,
|
||||||
"use `loop`",
|
"use `loop`",
|
||||||
"loop".to_owned(),
|
"loop".to_owned(),
|
||||||
Applicability::MachineApplicable
|
Applicability::MachineApplicable
|
||||||
);
|
)
|
||||||
err.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -96,6 +96,7 @@ macro_rules! early_lint_passes {
|
||||||
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
|
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
|
||||||
NonCamelCaseTypes: NonCamelCaseTypes,
|
NonCamelCaseTypes: NonCamelCaseTypes,
|
||||||
DeprecatedAttr: DeprecatedAttr::new(),
|
DeprecatedAttr: DeprecatedAttr::new(),
|
||||||
|
WhileTrue: WhileTrue,
|
||||||
]);
|
]);
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -140,7 +141,6 @@ macro_rules! late_lint_mod_passes {
|
||||||
($macro:path, $args:tt) => (
|
($macro:path, $args:tt) => (
|
||||||
$macro!($args, [
|
$macro!($args, [
|
||||||
HardwiredLints: HardwiredLints,
|
HardwiredLints: HardwiredLints,
|
||||||
WhileTrue: WhileTrue,
|
|
||||||
ImproperCTypes: ImproperCTypes,
|
ImproperCTypes: ImproperCTypes,
|
||||||
VariantSizeDifferences: VariantSizeDifferences,
|
VariantSizeDifferences: VariantSizeDifferences,
|
||||||
BoxPointers: BoxPointers,
|
BoxPointers: BoxPointers,
|
||||||
|
|
|
@ -2,6 +2,7 @@ fn main() {
|
||||||
[(); & { loop { continue } } ]; //~ ERROR mismatched types
|
[(); & { loop { continue } } ]; //~ ERROR mismatched types
|
||||||
[(); loop { break }]; //~ ERROR mismatched types
|
[(); loop { break }]; //~ ERROR mismatched types
|
||||||
[(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type
|
[(); {while true {break}; 0}]; //~ ERROR constant contains unimplemented expression type
|
||||||
|
//~^ WARN denote infinite loops with
|
||||||
[(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
|
[(); { for _ in 0usize.. {}; 0}]; //~ ERROR calls in constants are limited to constant functions
|
||||||
//~^ ERROR constant contains unimplemented expression type
|
//~^ ERROR constant contains unimplemented expression type
|
||||||
//~| ERROR constant contains unimplemented expression type
|
//~| ERROR constant contains unimplemented expression type
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
fn main() {
|
fn main() {
|
||||||
while true {
|
while true { //~ WARN denote infinite loops with
|
||||||
true //~ ERROR mismatched types
|
true //~ ERROR mismatched types
|
||||||
//~| expected type `()`
|
//~| expected type `()`
|
||||||
//~| found type `bool`
|
//~| found type `bool`
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
warning: denote infinite loops with `loop { ... }`
|
||||||
|
--> $DIR/block-must-not-have-result-while.rs:2:5
|
||||||
|
|
|
||||||
|
LL | while true {
|
||||||
|
| ^^^^^^^^^^ help: use `loop`
|
||||||
|
|
|
||||||
|
= note: #[warn(while_true)] on by default
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/block-must-not-have-result-while.rs:3:9
|
--> $DIR/block-must-not-have-result-while.rs:3:9
|
||||||
|
|
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ impl<'a, T : 'a> FuncWrapper<'a, T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn in_while(self, arg : &'a mut T) {
|
fn in_while(self, arg : &'a mut T) {
|
||||||
while true {
|
while true { //~ WARN denote infinite loops with
|
||||||
(self.func)(arg) //~ ERROR cannot borrow
|
(self.func)(arg) //~ ERROR cannot borrow
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
warning: denote infinite loops with `loop { ... }`
|
||||||
|
--> $DIR/mut-borrow-in-loop.rs:15:9
|
||||||
|
|
|
||||||
|
LL | while true {
|
||||||
|
| ^^^^^^^^^^ help: use `loop`
|
||||||
|
|
|
||||||
|
= note: #[warn(while_true)] on by default
|
||||||
|
|
||||||
error[E0499]: cannot borrow `*arg` as mutable more than once at a time
|
error[E0499]: cannot borrow `*arg` as mutable more than once at a time
|
||||||
--> $DIR/mut-borrow-in-loop.rs:10:25
|
--> $DIR/mut-borrow-in-loop.rs:10:25
|
||||||
|
|
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ fn main() {
|
||||||
loop { break }; //~ ERROR mismatched types
|
loop { break }; //~ ERROR mismatched types
|
||||||
let _: i32 =
|
let _: i32 =
|
||||||
'b: //~ ERROR mismatched types
|
'b: //~ ERROR mismatched types
|
||||||
|
//~^ WARN denote infinite loops with
|
||||||
while true { break }; // but here we cite the whole loop
|
while true { break }; // but here we cite the whole loop
|
||||||
let _: i32 =
|
let _: i32 =
|
||||||
'c: //~ ERROR mismatched types
|
'c: //~ ERROR mismatched types
|
||||||
|
|
|
@ -1,3 +1,13 @@
|
||||||
|
warning: denote infinite loops with `loop { ... }`
|
||||||
|
--> $DIR/issue-27042.rs:8:9
|
||||||
|
|
|
||||||
|
LL | / 'b:
|
||||||
|
LL | |
|
||||||
|
LL | | while true { break }; // but here we cite the whole loop
|
||||||
|
| |____________________________^ help: use `loop`
|
||||||
|
|
|
||||||
|
= note: #[warn(while_true)] on by default
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-27042.rs:6:16
|
--> $DIR/issue-27042.rs:6:16
|
||||||
|
|
|
|
||||||
|
@ -11,6 +21,7 @@ error[E0308]: mismatched types
|
||||||
--> $DIR/issue-27042.rs:8:9
|
--> $DIR/issue-27042.rs:8:9
|
||||||
|
|
|
|
||||||
LL | / 'b:
|
LL | / 'b:
|
||||||
|
LL | |
|
||||||
LL | | while true { break }; // but here we cite the whole loop
|
LL | | while true { break }; // but here we cite the whole loop
|
||||||
| |____________________________^ expected i32, found ()
|
| |____________________________^ expected i32, found ()
|
||||||
|
|
|
|
||||||
|
@ -18,7 +29,7 @@ LL | | while true { break }; // but here we cite the whole loop
|
||||||
found type `()`
|
found type `()`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-27042.rs:11:9
|
--> $DIR/issue-27042.rs:12:9
|
||||||
|
|
|
|
||||||
LL | / 'c:
|
LL | / 'c:
|
||||||
LL | | for _ in None { break }; // but here we cite the whole loop
|
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
|
||||||
found type `()`
|
found type `()`
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
error[E0308]: mismatched types
|
||||||
--> $DIR/issue-27042.rs:14:9
|
--> $DIR/issue-27042.rs:15:9
|
||||||
|
|
|
|
||||||
LL | / 'd:
|
LL | / 'd:
|
||||||
LL | | while let Some(_) = None { break };
|
LL | | while let Some(_) = None { break };
|
||||||
|
|
|
@ -10,18 +10,6 @@ note: lint level defined here
|
||||||
LL | #[deny(while_true)]
|
LL | #[deny(while_true)]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: denote infinite loops with `loop { ... }`
|
|
||||||
--> $DIR/lint-impl-fn.rs:27:5
|
|
||||||
|
|
|
||||||
LL | while true {}
|
|
||||||
| ^^^^^^^^^^ help: use `loop`
|
|
||||||
|
|
|
||||||
note: lint level defined here
|
|
||||||
--> $DIR/lint-impl-fn.rs:25:8
|
|
||||||
|
|
|
||||||
LL | #[deny(while_true)]
|
|
||||||
| ^^^^^^^^^^
|
|
||||||
|
|
||||||
error: denote infinite loops with `loop { ... }`
|
error: denote infinite loops with `loop { ... }`
|
||||||
--> $DIR/lint-impl-fn.rs:18:25
|
--> $DIR/lint-impl-fn.rs:18:25
|
||||||
|
|
|
|
||||||
|
@ -34,5 +22,17 @@ note: lint level defined here
|
||||||
LL | #[deny(while_true)]
|
LL | #[deny(while_true)]
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
|
error: denote infinite loops with `loop { ... }`
|
||||||
|
--> $DIR/lint-impl-fn.rs:27:5
|
||||||
|
|
|
||||||
|
LL | while true {}
|
||||||
|
| ^^^^^^^^^^ help: use `loop`
|
||||||
|
|
|
||||||
|
note: lint level defined here
|
||||||
|
--> $DIR/lint-impl-fn.rs:25:8
|
||||||
|
|
|
||||||
|
LL | #[deny(while_true)]
|
||||||
|
| ^^^^^^^^^^
|
||||||
|
|
||||||
error: aborting due to 3 previous errors
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ fn main() {
|
||||||
|
|
||||||
if (true) {} //~ ERROR unnecessary parentheses around `if` condition
|
if (true) {} //~ ERROR unnecessary parentheses around `if` condition
|
||||||
while (true) {} //~ ERROR unnecessary parentheses around `while` condition
|
while (true) {} //~ ERROR unnecessary parentheses around `while` condition
|
||||||
|
//~^ WARN denote infinite loops with
|
||||||
match (true) { //~ ERROR unnecessary parentheses around `match` head expression
|
match (true) { //~ ERROR unnecessary parentheses around `match` head expression
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,44 +34,52 @@ error: unnecessary parentheses around `while` condition
|
||||||
LL | while (true) {}
|
LL | while (true) {}
|
||||||
| ^^^^^^ help: remove these parentheses
|
| ^^^^^^ help: remove these parentheses
|
||||||
|
|
||||||
|
warning: denote infinite loops with `loop { ... }`
|
||||||
|
--> $DIR/lint-unnecessary-parens.rs:21:5
|
||||||
|
|
|
||||||
|
LL | while (true) {}
|
||||||
|
| ^^^^^^^^^^^^ help: use `loop`
|
||||||
|
|
|
||||||
|
= note: #[warn(while_true)] on by default
|
||||||
|
|
||||||
error: unnecessary parentheses around `match` head expression
|
error: unnecessary parentheses around `match` head expression
|
||||||
--> $DIR/lint-unnecessary-parens.rs:22:11
|
--> $DIR/lint-unnecessary-parens.rs:23:11
|
||||||
|
|
|
|
||||||
LL | match (true) {
|
LL | match (true) {
|
||||||
| ^^^^^^ help: remove these parentheses
|
| ^^^^^^ help: remove these parentheses
|
||||||
|
|
||||||
error: unnecessary parentheses around `let` head expression
|
error: unnecessary parentheses around `let` head expression
|
||||||
--> $DIR/lint-unnecessary-parens.rs:25:16
|
--> $DIR/lint-unnecessary-parens.rs:26:16
|
||||||
|
|
|
|
||||||
LL | if let 1 = (1) {}
|
LL | if let 1 = (1) {}
|
||||||
| ^^^ help: remove these parentheses
|
| ^^^ help: remove these parentheses
|
||||||
|
|
||||||
error: unnecessary parentheses around `let` head expression
|
error: unnecessary parentheses around `let` head expression
|
||||||
--> $DIR/lint-unnecessary-parens.rs:26:19
|
--> $DIR/lint-unnecessary-parens.rs:27:19
|
||||||
|
|
|
|
||||||
LL | while let 1 = (2) {}
|
LL | while let 1 = (2) {}
|
||||||
| ^^^ help: remove these parentheses
|
| ^^^ help: remove these parentheses
|
||||||
|
|
||||||
error: unnecessary parentheses around method argument
|
error: unnecessary parentheses around method argument
|
||||||
--> $DIR/lint-unnecessary-parens.rs:40:24
|
--> $DIR/lint-unnecessary-parens.rs:41:24
|
||||||
|
|
|
|
||||||
LL | X { y: false }.foo((true));
|
LL | X { y: false }.foo((true));
|
||||||
| ^^^^^^ help: remove these parentheses
|
| ^^^^^^ help: remove these parentheses
|
||||||
|
|
||||||
error: unnecessary parentheses around assigned value
|
error: unnecessary parentheses around assigned value
|
||||||
--> $DIR/lint-unnecessary-parens.rs:42:18
|
--> $DIR/lint-unnecessary-parens.rs:43:18
|
||||||
|
|
|
|
||||||
LL | let mut _a = (0);
|
LL | let mut _a = (0);
|
||||||
| ^^^ help: remove these parentheses
|
| ^^^ help: remove these parentheses
|
||||||
|
|
||||||
error: unnecessary parentheses around assigned value
|
error: unnecessary parentheses around assigned value
|
||||||
--> $DIR/lint-unnecessary-parens.rs:43:10
|
--> $DIR/lint-unnecessary-parens.rs:44:10
|
||||||
|
|
|
|
||||||
LL | _a = (0);
|
LL | _a = (0);
|
||||||
| ^^^ help: remove these parentheses
|
| ^^^ help: remove these parentheses
|
||||||
|
|
||||||
error: unnecessary parentheses around assigned value
|
error: unnecessary parentheses around assigned value
|
||||||
--> $DIR/lint-unnecessary-parens.rs:44:11
|
--> $DIR/lint-unnecessary-parens.rs:45:11
|
||||||
|
|
|
|
||||||
LL | _a += (1);
|
LL | _a += (1);
|
||||||
| ^^^ help: remove these parentheses
|
| ^^^ help: remove these parentheses
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
warning: denote infinite loops with `loop { ... }`
|
||||||
|
--> $DIR/suggestions.rs:46:5
|
||||||
|
|
|
||||||
|
LL | while true {
|
||||||
|
| ^^^^^^^^^^ help: use `loop`
|
||||||
|
|
|
||||||
|
= note: #[warn(while_true)] on by default
|
||||||
|
|
||||||
warning: unnecessary parentheses around assigned value
|
warning: unnecessary parentheses around assigned value
|
||||||
--> $DIR/suggestions.rs:49:31
|
--> $DIR/suggestions.rs:49:31
|
||||||
|
|
|
|
||||||
|
@ -65,14 +73,6 @@ LL | pub fn defiant<T>(_t: T) {}
|
||||||
|
|
|
|
||||||
= note: #[warn(no_mangle_generic_items)] on by default
|
= note: #[warn(no_mangle_generic_items)] on by default
|
||||||
|
|
||||||
warning: denote infinite loops with `loop { ... }`
|
|
||||||
--> $DIR/suggestions.rs:46:5
|
|
||||||
|
|
|
||||||
LL | while true {
|
|
||||||
| ^^^^^^^^^^ help: use `loop`
|
|
||||||
|
|
|
||||||
= note: #[warn(while_true)] on by default
|
|
||||||
|
|
||||||
warning: the `warp_factor:` in this pattern is redundant
|
warning: the `warp_factor:` in this pattern is redundant
|
||||||
--> $DIR/suggestions.rs:61:23
|
--> $DIR/suggestions.rs:61:23
|
||||||
|
|
|
|
||||||
|
|
|
@ -6,5 +6,8 @@ fn main() {
|
||||||
loop {
|
loop {
|
||||||
println!("{}", y); //~ ERROR borrow of moved value: `y`
|
println!("{}", y); //~ ERROR borrow of moved value: `y`
|
||||||
while true { while true { while true { x = y; x.clone(); } } }
|
while true { while true { while true { x = y; x.clone(); } } }
|
||||||
|
//~^ WARN denote infinite loops with
|
||||||
|
//~| WARN denote infinite loops with
|
||||||
|
//~| WARN denote infinite loops with
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,23 @@
|
||||||
|
warning: denote infinite loops with `loop { ... }`
|
||||||
|
--> $DIR/liveness-move-in-while.rs:8:9
|
||||||
|
|
|
||||||
|
LL | while true { while true { while true { x = y; x.clone(); } } }
|
||||||
|
| ^^^^^^^^^^ help: use `loop`
|
||||||
|
|
|
||||||
|
= note: #[warn(while_true)] on by default
|
||||||
|
|
||||||
|
warning: denote infinite loops with `loop { ... }`
|
||||||
|
--> $DIR/liveness-move-in-while.rs:8:22
|
||||||
|
|
|
||||||
|
LL | while true { while true { while true { x = y; x.clone(); } } }
|
||||||
|
| ^^^^^^^^^^ help: use `loop`
|
||||||
|
|
||||||
|
warning: denote infinite loops with `loop { ... }`
|
||||||
|
--> $DIR/liveness-move-in-while.rs:8:35
|
||||||
|
|
|
||||||
|
LL | while true { while true { while true { x = y; x.clone(); } } }
|
||||||
|
| ^^^^^^^^^^ help: use `loop`
|
||||||
|
|
||||||
error[E0382]: borrow of moved value: `y`
|
error[E0382]: borrow of moved value: `y`
|
||||||
--> $DIR/liveness-move-in-while.rs:7:24
|
--> $DIR/liveness-move-in-while.rs:7:24
|
||||||
|
|
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ fn main() {
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
'while_loop: while true {
|
'while_loop: while true { //~ WARN denote infinite loops with
|
||||||
break;
|
break;
|
||||||
break (); //~ ERROR `break` with value from a `while` loop
|
break (); //~ ERROR `break` with value from a `while` loop
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
warning: denote infinite loops with `loop { ... }`
|
||||||
|
--> $DIR/loop-break-value.rs:26:5
|
||||||
|
|
|
||||||
|
LL | 'while_loop: while true {
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop`
|
||||||
|
|
|
||||||
|
= note: #[warn(while_true)] on by default
|
||||||
|
|
||||||
error[E0571]: `break` with value from a `while` loop
|
error[E0571]: `break` with value from a `while` loop
|
||||||
--> $DIR/loop-break-value.rs:28:9
|
--> $DIR/loop-break-value.rs:28:9
|
||||||
|
|
|
|
||||||
|
|
Loading…
Reference in New Issue