about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-06-22 01:30:24 +0200
committerMazdak Farrokhzad <twingoow@gmail.com>2019-07-06 06:43:58 +0200
commit547735457ff698dd44ba818a65d1f10853fbeb8e (patch)
treed7197c5d275179b06bbd41cbaa9ffa4e3fdc14b9
parentf01562af33272fd5960fd2b6d1880abfcb790116 (diff)
downloadrust-547735457ff698dd44ba818a65d1f10853fbeb8e.tar.gz
rust-547735457ff698dd44ba818a65d1f10853fbeb8e.zip
Make WhileTrue into an EarlyLintPass lint.
-rw-r--r--src/librustc_lint/builtin.rs44
-rw-r--r--src/librustc_lint/lib.rs2
-rw-r--r--src/test/compile-fail/issue-52443.rs1
-rw-r--r--src/test/ui/block-result/block-must-not-have-result-while.rs2
-rw-r--r--src/test/ui/block-result/block-must-not-have-result-while.stderr8
-rw-r--r--src/test/ui/borrowck/mut-borrow-in-loop.rs2
-rw-r--r--src/test/ui/borrowck/mut-borrow-in-loop.stderr8
-rw-r--r--src/test/ui/issues/issue-27042.rs1
-rw-r--r--src/test/ui/issues/issue-27042.stderr15
-rw-r--r--src/test/ui/lint/lint-impl-fn.stderr16
-rw-r--r--src/test/ui/lint/lint-unnecessary-parens.rs1
-rw-r--r--src/test/ui/lint/lint-unnecessary-parens.stderr22
-rw-r--r--src/test/ui/lint/suggestions.stderr16
-rw-r--r--src/test/ui/liveness/liveness-move-in-while.rs3
-rw-r--r--src/test/ui/liveness/liveness-move-in-while.stderr20
-rw-r--r--src/test/ui/loops/loop-break-value.rs2
-rw-r--r--src/test/ui/loops/loop-break-value.stderr8
17 files changed, 116 insertions, 55 deletions
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index d98dfb5478a..c9605445c24 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -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();
                     }
                 }
             }
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index fb02782e6d3..2519981fa21 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -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,
diff --git a/src/test/compile-fail/issue-52443.rs b/src/test/compile-fail/issue-52443.rs
index 0d6906086e9..a993d811d32 100644
--- a/src/test/compile-fail/issue-52443.rs
+++ b/src/test/compile-fail/issue-52443.rs
@@ -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
diff --git a/src/test/ui/block-result/block-must-not-have-result-while.rs b/src/test/ui/block-result/block-must-not-have-result-while.rs
index 96597631396..108b9bc9e9b 100644
--- a/src/test/ui/block-result/block-must-not-have-result-while.rs
+++ b/src/test/ui/block-result/block-must-not-have-result-while.rs
@@ -1,5 +1,5 @@
 fn main() {
-    while true {
+    while true { //~ WARN denote infinite loops with
         true //~  ERROR mismatched types
              //~| expected type `()`
              //~| found type `bool`
diff --git a/src/test/ui/block-result/block-must-not-have-result-while.stderr b/src/test/ui/block-result/block-must-not-have-result-while.stderr
index 302d2972f7d..c41afcc9121 100644
--- a/src/test/ui/block-result/block-must-not-have-result-while.stderr
+++ b/src/test/ui/block-result/block-must-not-have-result-while.stderr
@@ -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
    |
diff --git a/src/test/ui/borrowck/mut-borrow-in-loop.rs b/src/test/ui/borrowck/mut-borrow-in-loop.rs
index 09f3e4f9b76..22667906e12 100644
--- a/src/test/ui/borrowck/mut-borrow-in-loop.rs
+++ b/src/test/ui/borrowck/mut-borrow-in-loop.rs
@@ -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
         }
     }
diff --git a/src/test/ui/borrowck/mut-borrow-in-loop.stderr b/src/test/ui/borrowck/mut-borrow-in-loop.stderr
index eda2f518f92..59cf4d533de 100644
--- a/src/test/ui/borrowck/mut-borrow-in-loop.stderr
+++ b/src/test/ui/borrowck/mut-borrow-in-loop.stderr
@@ -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
    |
diff --git a/src/test/ui/issues/issue-27042.rs b/src/test/ui/issues/issue-27042.rs
index 8c7758597f0..517c1f2e6c7 100644
--- a/src/test/ui/issues/issue-27042.rs
+++ b/src/test/ui/issues/issue-27042.rs
@@ -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
diff --git a/src/test/ui/issues/issue-27042.stderr b/src/test/ui/issues/issue-27042.stderr
index cce7d24a5f6..c67b8ad7381 100644
--- a/src/test/ui/issues/issue-27042.stderr
+++ b/src/test/ui/issues/issue-27042.stderr
@@ -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 };
diff --git a/src/test/ui/lint/lint-impl-fn.stderr b/src/test/ui/lint/lint-impl-fn.stderr
index 56f85111d42..2c9a264287c 100644
--- a/src/test/ui/lint/lint-impl-fn.stderr
+++ b/src/test/ui/lint/lint-impl-fn.stderr
@@ -11,25 +11,25 @@ LL |     #[deny(while_true)]
    |            ^^^^^^^^^^
 
 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)]
    |        ^^^^^^^^^^
diff --git a/src/test/ui/lint/lint-unnecessary-parens.rs b/src/test/ui/lint/lint-unnecessary-parens.rs
index c36101043a7..811bc87eb0e 100644
--- a/src/test/ui/lint/lint-unnecessary-parens.rs
+++ b/src/test/ui/lint/lint-unnecessary-parens.rs
@@ -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
         _ => {}
     }
diff --git a/src/test/ui/lint/lint-unnecessary-parens.stderr b/src/test/ui/lint/lint-unnecessary-parens.stderr
index dfbefd7b03e..05ecbfdf4fa 100644
--- a/src/test/ui/lint/lint-unnecessary-parens.stderr
+++ b/src/test/ui/lint/lint-unnecessary-parens.stderr
@@ -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
diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr
index 5aaa9947f99..de7c1fb8986 100644
--- a/src/test/ui/lint/suggestions.stderr
+++ b/src/test/ui/lint/suggestions.stderr
@@ -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
    |
diff --git a/src/test/ui/liveness/liveness-move-in-while.rs b/src/test/ui/liveness/liveness-move-in-while.rs
index 420d1311f8b..9f3ebf1362b 100644
--- a/src/test/ui/liveness/liveness-move-in-while.rs
+++ b/src/test/ui/liveness/liveness-move-in-while.rs
@@ -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
     }
 }
diff --git a/src/test/ui/liveness/liveness-move-in-while.stderr b/src/test/ui/liveness/liveness-move-in-while.stderr
index e1eed1b59f4..bbf5e50f1e0 100644
--- a/src/test/ui/liveness/liveness-move-in-while.stderr
+++ b/src/test/ui/liveness/liveness-move-in-while.stderr
@@ -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
    |
diff --git a/src/test/ui/loops/loop-break-value.rs b/src/test/ui/loops/loop-break-value.rs
index b80c847deb9..7c2f63ec51a 100644
--- a/src/test/ui/loops/loop-break-value.rs
+++ b/src/test/ui/loops/loop-break-value.rs
@@ -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 {
diff --git a/src/test/ui/loops/loop-break-value.stderr b/src/test/ui/loops/loop-break-value.stderr
index 13fe5085540..f458c88ea48 100644
--- a/src/test/ui/loops/loop-break-value.stderr
+++ b/src/test/ui/loops/loop-break-value.stderr
@@ -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
    |