Make WhileTrue into an EarlyLintPass lint.

This commit is contained in:
Mazdak Farrokhzad 2019-06-22 01:30:24 +02:00
parent f01562af33
commit 547735457f
17 changed files with 120 additions and 59 deletions

View File

@ -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;
}
None
expr
}
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(
condition_span,
"use `loop`",
"loop".to_owned(),
Applicability::MachineApplicable
);
err.emit();
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
)
.emit();
}
}
}

View File

@ -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,

View File

@ -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

View File

@ -1,5 +1,5 @@
fn main() {
while true {
while true { //~ WARN denote infinite loops with
true //~ ERROR mismatched types
//~| expected type `()`
//~| found type `bool`

View File

@ -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
|

View File

@ -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
}
}

View File

@ -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
|

View File

@ -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

View File

@ -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 };

View File

@ -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

View File

@ -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
_ => {}
}

View File

@ -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

View File

@ -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
|

View File

@ -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
}
}

View File

@ -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
|

View File

@ -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 {

View File

@ -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
|