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]);
|
||||
|
||||
fn as_while_cond(expr: &hir::Expr) -> Option<&hir::Expr> {
|
||||
if let hir::ExprKind::Loop(blk, ..) = &expr.node {
|
||||
if let Some(match_expr) = &blk.expr {
|
||||
if let hir::ExprKind::Match(cond, .., hir::MatchSource::WhileDesugar)
|
||||
= &match_expr.node
|
||||
{
|
||||
if let hir::ExprKind::DropTemps(cond) = &cond.node {
|
||||
return Some(cond);
|
||||
}
|
||||
}
|
||||
/// Traverse through any amount of parenthesis and return the first non-parens expression.
|
||||
fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr {
|
||||
while let ast::ExprKind::Paren(sub) = &expr.node {
|
||||
expr = sub;
|
||||
}
|
||||
expr
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LateLintPass<'a, 'tcx> for WhileTrue {
|
||||
fn check_expr(&mut self, cx: &LateContext<'_, '_>, e: &hir::Expr) {
|
||||
if let Some(ref cond) = as_while_cond(e) {
|
||||
if let hir::ExprKind::Lit(ref lit) = cond.node {
|
||||
impl EarlyLintPass for WhileTrue {
|
||||
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
|
||||
if let ast::ExprKind::While(cond, ..) = &e.node {
|
||||
if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).node {
|
||||
if let ast::LitKind::Bool(true) = lit.node {
|
||||
if lit.span.ctxt() == SyntaxContext::empty() {
|
||||
let msg = "denote infinite loops with `loop { ... }`";
|
||||
let condition_span = cx.tcx.sess.source_map().def_span(e.span);
|
||||
let mut err = cx.struct_span_lint(WHILE_TRUE, condition_span, msg);
|
||||
err.span_suggestion_short(
|
||||
let condition_span = cx.sess.source_map().def_span(e.span);
|
||||
cx.struct_span_lint(WHILE_TRUE, condition_span, msg)
|
||||
.span_suggestion_short(
|
||||
condition_span,
|
||||
"use `loop`",
|
||||
"loop".to_owned(),
|
||||
Applicability::MachineApplicable
|
||||
);
|
||||
err.emit();
|
||||
)
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -96,6 +96,7 @@ macro_rules! early_lint_passes {
|
|||
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
|
||||
NonCamelCaseTypes: NonCamelCaseTypes,
|
||||
DeprecatedAttr: DeprecatedAttr::new(),
|
||||
WhileTrue: WhileTrue,
|
||||
]);
|
||||
)
|
||||
}
|
||||
|
@ -140,7 +141,6 @@ macro_rules! late_lint_mod_passes {
|
|||
($macro:path, $args:tt) => (
|
||||
$macro!($args, [
|
||||
HardwiredLints: HardwiredLints,
|
||||
WhileTrue: WhileTrue,
|
||||
ImproperCTypes: ImproperCTypes,
|
||||
VariantSizeDifferences: VariantSizeDifferences,
|
||||
BoxPointers: BoxPointers,
|
||||
|
|
|
@ -2,6 +2,7 @@ fn main() {
|
|||
[(); & { loop { continue } } ]; //~ ERROR mismatched types
|
||||
[(); loop { break }]; //~ ERROR mismatched types
|
||||
[(); {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
|
||||
//~^ ERROR constant contains unimplemented expression type
|
||||
//~| ERROR constant contains unimplemented expression type
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
fn main() {
|
||||
while true {
|
||||
while true { //~ WARN denote infinite loops with
|
||||
true //~ ERROR mismatched types
|
||||
//~| expected type `()`
|
||||
//~| 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
|
||||
--> $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) {
|
||||
while true {
|
||||
while true { //~ WARN denote infinite loops with
|
||||
(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
|
||||
--> $DIR/mut-borrow-in-loop.rs:10:25
|
||||
|
|
||||
|
|
|
@ -6,6 +6,7 @@ fn main() {
|
|||
loop { break }; //~ ERROR mismatched types
|
||||
let _: i32 =
|
||||
'b: //~ ERROR mismatched types
|
||||
//~^ WARN denote infinite loops with
|
||||
while true { break }; // but here we cite the whole loop
|
||||
let _: i32 =
|
||||
'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
|
||||
--> $DIR/issue-27042.rs:6:16
|
||||
|
|
||||
|
@ -11,6 +21,7 @@ error[E0308]: mismatched types
|
|||
--> $DIR/issue-27042.rs:8:9
|
||||
|
|
||||
LL | / 'b:
|
||||
LL | |
|
||||
LL | | while true { break }; // but here we cite the whole loop
|
||||
| |____________________________^ expected i32, found ()
|
||||
|
|
||||
|
@ -18,7 +29,7 @@ LL | | while true { break }; // but here we cite the whole loop
|
|||
found type `()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-27042.rs:11:9
|
||||
--> $DIR/issue-27042.rs:12:9
|
||||
|
|
||||
LL | / 'c:
|
||||
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 `()`
|
||||
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-27042.rs:14:9
|
||||
--> $DIR/issue-27042.rs:15:9
|
||||
|
|
||||
LL | / 'd:
|
||||
LL | | while let Some(_) = None { break };
|
||||
|
|
|
@ -10,18 +10,6 @@ note: lint level defined here
|
|||
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 { ... }`
|
||||
--> $DIR/lint-impl-fn.rs:18:25
|
||||
|
|
||||
|
@ -34,5 +22,17 @@ note: lint level defined here
|
|||
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
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ fn main() {
|
|||
|
||||
if (true) {} //~ ERROR unnecessary parentheses around `if` condition
|
||||
while (true) {} //~ ERROR unnecessary parentheses around `while` condition
|
||||
//~^ WARN denote infinite loops with
|
||||
match (true) { //~ ERROR unnecessary parentheses around `match` head expression
|
||||
_ => {}
|
||||
}
|
||||
|
|
|
@ -34,44 +34,52 @@ error: unnecessary parentheses around `while` condition
|
|||
LL | while (true) {}
|
||||
| ^^^^^^ 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
|
||||
--> $DIR/lint-unnecessary-parens.rs:22:11
|
||||
--> $DIR/lint-unnecessary-parens.rs:23:11
|
||||
|
|
||||
LL | match (true) {
|
||||
| ^^^^^^ help: remove these parentheses
|
||||
|
||||
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) {}
|
||||
| ^^^ help: remove these parentheses
|
||||
|
||||
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) {}
|
||||
| ^^^ help: remove these parentheses
|
||||
|
||||
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));
|
||||
| ^^^^^^ help: remove these parentheses
|
||||
|
||||
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);
|
||||
| ^^^ help: remove these parentheses
|
||||
|
||||
error: unnecessary parentheses around assigned value
|
||||
--> $DIR/lint-unnecessary-parens.rs:43:10
|
||||
--> $DIR/lint-unnecessary-parens.rs:44:10
|
||||
|
|
||||
LL | _a = (0);
|
||||
| ^^^ help: remove these parentheses
|
||||
|
||||
error: unnecessary parentheses around assigned value
|
||||
--> $DIR/lint-unnecessary-parens.rs:44:11
|
||||
--> $DIR/lint-unnecessary-parens.rs:45:11
|
||||
|
|
||||
LL | _a += (1);
|
||||
| ^^^ 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
|
||||
--> $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
|
||||
|
||||
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
|
||||
--> $DIR/suggestions.rs:61:23
|
||||
|
|
||||
|
|
|
@ -6,5 +6,8 @@ fn main() {
|
|||
loop {
|
||||
println!("{}", y); //~ ERROR borrow of moved value: `y`
|
||||
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`
|
||||
--> $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 (); //~ ERROR `break` with value from a `while` 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
|
||||
--> $DIR/loop-break-value.rs:28:9
|
||||
|
|
||||
|
|
Loading…
Reference in New Issue