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();
}
}
}
EllipsisInclusiveRangePatterns: EllipsisInclusiveRangePatterns::default(),
NonCamelCaseTypes: NonCamelCaseTypes,
DeprecatedAttr: DeprecatedAttr::new(),
+ WhileTrue: WhileTrue,
]);
)
}
($macro:path, $args:tt) => (
$macro!($args, [
HardwiredLints: HardwiredLints,
- WhileTrue: WhileTrue,
ImproperCTypes: ImproperCTypes,
VariantSizeDifferences: VariantSizeDifferences,
BoxPointers: BoxPointers,
[(); & { 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
fn main() {
- while true {
+ while true { //~ WARN denote infinite loops with
true //~ ERROR mismatched types
//~| expected type `()`
//~| found type `bool`
+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
|
}
fn in_while(self, arg : &'a mut T) {
- while true {
+ while true { //~ WARN denote infinite loops with
(self.func)(arg) //~ ERROR cannot borrow
}
}
+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
|
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
+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
|
--> $DIR/issue-27042.rs:8:9
|
LL | / 'b:
+LL | |
LL | | while true { break }; // but here we cite the whole loop
| |____________________________^ expected i32, found ()
|
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
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 };
| ^^^^^^^^^^
error: denote infinite loops with `loop { ... }`
- --> $DIR/lint-impl-fn.rs:27:5
+ --> $DIR/lint-impl-fn.rs:18:25
|
-LL | while true {}
- | ^^^^^^^^^^ help: use `loop`
+LL | fn foo(&self) { while true {} }
+ | ^^^^^^^^^^ help: use `loop`
|
note: lint level defined here
- --> $DIR/lint-impl-fn.rs:25:8
+ --> $DIR/lint-impl-fn.rs:13:8
|
LL | #[deny(while_true)]
| ^^^^^^^^^^
error: denote infinite loops with `loop { ... }`
- --> $DIR/lint-impl-fn.rs:18:25
+ --> $DIR/lint-impl-fn.rs:27:5
|
-LL | fn foo(&self) { while true {} }
- | ^^^^^^^^^^ help: use `loop`
+LL | while true {}
+ | ^^^^^^^^^^ help: use `loop`
|
note: lint level defined here
- --> $DIR/lint-impl-fn.rs:13:8
+ --> $DIR/lint-impl-fn.rs:25:8
|
LL | #[deny(while_true)]
| ^^^^^^^^^^
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
_ => {}
}
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
+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
|
|
= 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
|
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
}
}
+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
|
};
};
- 'while_loop: while true {
+ 'while_loop: while true { //~ WARN denote infinite loops with
break;
break (); //~ ERROR `break` with value from a `while` loop
loop {
+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
|