about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2021-01-19 15:51:51 -0800
committerEsteban Küber <esteban@kuber.com.ar>2021-01-21 21:41:46 -0800
commit707ce2b798ad7bb6c1e0fce0da542d9caef07b56 (patch)
treea4676eaeb8c54e1f7297cf542757b08159cdf596
parentdc1eee2f256efbd1d3b50b6b090232f81cac6d72 (diff)
downloadrust-707ce2b798ad7bb6c1e0fce0da542d9caef07b56.tar.gz
rust-707ce2b798ad7bb6c1e0fce0da542d9caef07b56.zip
Account for labels when suggesting `loop` instead of `while true`
-rw-r--r--compiler/rustc_lint/src/builtin.rs12
-rw-r--r--src/test/ui/issues/issue-1962.fixed4
-rw-r--r--src/test/ui/issues/issue-1962.rs4
-rw-r--r--src/test/ui/issues/issue-1962.stderr4
-rw-r--r--src/test/ui/issues/issue-27042.stderr2
-rw-r--r--src/test/ui/label/label_misspelled.rs22
-rw-r--r--src/test/ui/label/label_misspelled.stderr80
7 files changed, 116 insertions, 12 deletions
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 8cdb33ea317..b37660e4a90 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -96,18 +96,24 @@ fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr {
 
 impl EarlyLintPass for WhileTrue {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
-        if let ast::ExprKind::While(cond, ..) = &e.kind {
+        if let ast::ExprKind::While(cond, _, label) = &e.kind {
             if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind {
                 if let ast::LitKind::Bool(true) = lit.kind {
                     if !lit.span.from_expansion() {
                         let msg = "denote infinite loops with `loop { ... }`";
-                        let condition_span = cx.sess.source_map().guess_head_span(e.span);
+                        let condition_span = e.span.with_hi(cond.span.hi());
                         cx.struct_span_lint(WHILE_TRUE, condition_span, |lint| {
                             lint.build(msg)
                                 .span_suggestion_short(
                                     condition_span,
                                     "use `loop`",
-                                    "loop".to_owned(),
+                                    format!(
+                                        "{}loop",
+                                        label.map_or_else(String::new, |label| format!(
+                                            "{}: ",
+                                            label.ident,
+                                        ))
+                                    ),
                                     Applicability::MachineApplicable,
                                 )
                                 .emit();
diff --git a/src/test/ui/issues/issue-1962.fixed b/src/test/ui/issues/issue-1962.fixed
index b810a90ef37..897fd172b29 100644
--- a/src/test/ui/issues/issue-1962.fixed
+++ b/src/test/ui/issues/issue-1962.fixed
@@ -3,8 +3,8 @@
 
 fn main() {
     let mut i = 0;
-    loop { //~ ERROR denote infinite loops with `loop
+    'a: loop { //~ ERROR denote infinite loops with `loop
         i += 1;
-        if i == 5 { break; }
+        if i == 5 { break 'a; }
     }
 }
diff --git a/src/test/ui/issues/issue-1962.rs b/src/test/ui/issues/issue-1962.rs
index 00d2bbd2850..71e87410087 100644
--- a/src/test/ui/issues/issue-1962.rs
+++ b/src/test/ui/issues/issue-1962.rs
@@ -3,8 +3,8 @@
 
 fn main() {
     let mut i = 0;
-    while true { //~ ERROR denote infinite loops with `loop
+    'a: while true { //~ ERROR denote infinite loops with `loop
         i += 1;
-        if i == 5 { break; }
+        if i == 5 { break 'a; }
     }
 }
diff --git a/src/test/ui/issues/issue-1962.stderr b/src/test/ui/issues/issue-1962.stderr
index 17142912696..4c32a4cf3dd 100644
--- a/src/test/ui/issues/issue-1962.stderr
+++ b/src/test/ui/issues/issue-1962.stderr
@@ -1,8 +1,8 @@
 error: denote infinite loops with `loop { ... }`
   --> $DIR/issue-1962.rs:6:5
    |
-LL |     while true {
-   |     ^^^^^^^^^^ help: use `loop`
+LL |     'a: while true {
+   |     ^^^^^^^^^^^^^^ help: use `loop`
    |
    = note: requested on the command line with `-D while-true`
 
diff --git a/src/test/ui/issues/issue-27042.stderr b/src/test/ui/issues/issue-27042.stderr
index 7dee1a6a5f0..59ef28481d0 100644
--- a/src/test/ui/issues/issue-27042.stderr
+++ b/src/test/ui/issues/issue-27042.stderr
@@ -4,7 +4,7 @@ warning: denote infinite loops with `loop { ... }`
 LL | /         'b:
 LL | |
 LL | |         while true { break }; // but here we cite the whole loop
-   | |____________________________^ help: use `loop`
+   | |__________________^ help: use `loop`
    |
    = note: `#[warn(while_true)]` on by default
 
diff --git a/src/test/ui/label/label_misspelled.rs b/src/test/ui/label/label_misspelled.rs
index ebfd5642c9f..7a8ff0360f6 100644
--- a/src/test/ui/label/label_misspelled.rs
+++ b/src/test/ui/label/label_misspelled.rs
@@ -16,3 +16,25 @@ fn main() {
         //~^ ERROR cannot find value `for_loop` in this scope
     };
 }
+
+fn foo() {
+    'LOOP: loop {
+        break LOOP;
+        //~^ ERROR cannot find value `LOOP` in this scope
+    };
+    'while_loop: while true { //~ WARN denote infinite loops with
+        break while_loop;
+        //~^ ERROR cannot find value `while_loop` in this scope
+        //~| ERROR `break` with value from a `while` loop
+    };
+    'while_let: while let Some(_) = Some(()) {
+        break while_let;
+        //~^ ERROR cannot find value `while_let` in this scope
+        //~| ERROR `break` with value from a `while` loop
+    }
+    'for_loop: for _ in 0..3 {
+        break for_loop;
+        //~^ ERROR cannot find value `for_loop` in this scope
+        //~| ERROR `break` with value from a `for` loop
+    };
+}
diff --git a/src/test/ui/label/label_misspelled.stderr b/src/test/ui/label/label_misspelled.stderr
index 1368ca4126c..8282d3ada32 100644
--- a/src/test/ui/label/label_misspelled.stderr
+++ b/src/test/ui/label/label_misspelled.stderr
@@ -34,6 +34,42 @@ LL |         for_loop;
    |         not found in this scope
    |         help: a label with a similar name exists: `'for_loop`
 
+error[E0425]: cannot find value `LOOP` in this scope
+  --> $DIR/label_misspelled.rs:22:15
+   |
+LL |         break LOOP;
+   |               ^^^^
+   |               |
+   |               not found in this scope
+   |               help: a label with a similar name exists: `'LOOP`
+
+error[E0425]: cannot find value `while_loop` in this scope
+  --> $DIR/label_misspelled.rs:26:15
+   |
+LL |         break while_loop;
+   |               ^^^^^^^^^^
+   |               |
+   |               not found in this scope
+   |               help: a label with a similar name exists: `'while_loop`
+
+error[E0425]: cannot find value `while_let` in this scope
+  --> $DIR/label_misspelled.rs:31:15
+   |
+LL |         break while_let;
+   |               ^^^^^^^^^
+   |               |
+   |               not found in this scope
+   |               help: a label with a similar name exists: `'while_let`
+
+error[E0425]: cannot find value `for_loop` in this scope
+  --> $DIR/label_misspelled.rs:36:15
+   |
+LL |         break for_loop;
+   |               ^^^^^^^^
+   |               |
+   |               not found in this scope
+   |               help: a label with a similar name exists: `'for_loop`
+
 warning: denote infinite loops with `loop { ... }`
   --> $DIR/label_misspelled.rs:6:5
    |
@@ -42,6 +78,46 @@ LL |     'while_loop: while true {
    |
    = note: `#[warn(while_true)]` on by default
 
-error: aborting due to 4 previous errors; 1 warning emitted
+warning: denote infinite loops with `loop { ... }`
+  --> $DIR/label_misspelled.rs:25:5
+   |
+LL |     'while_loop: while true {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop`
+
+error[E0571]: `break` with value from a `while` loop
+  --> $DIR/label_misspelled.rs:26:9
+   |
+LL |         break while_loop;
+   |         ^^^^^^^^^^^^^^^^ can only break with a value inside `loop` or breakable block
+   |
+help: instead, use `break` on its own without a value inside this `while` loop
+   |
+LL |         break;
+   |         ^^^^^
+
+error[E0571]: `break` with value from a `while` loop
+  --> $DIR/label_misspelled.rs:31:9
+   |
+LL |         break while_let;
+   |         ^^^^^^^^^^^^^^^ can only break with a value inside `loop` or breakable block
+   |
+help: instead, use `break` on its own without a value inside this `while` loop
+   |
+LL |         break;
+   |         ^^^^^
+
+error[E0571]: `break` with value from a `for` loop
+  --> $DIR/label_misspelled.rs:36:9
+   |
+LL |         break for_loop;
+   |         ^^^^^^^^^^^^^^ can only break with a value inside `loop` or breakable block
+   |
+help: instead, use `break` on its own without a value inside this `for` loop
+   |
+LL |         break;
+   |         ^^^^^
+
+error: aborting due to 11 previous errors; 2 warnings emitted
 
-For more information about this error, try `rustc --explain E0425`.
+Some errors have detailed explanations: E0425, E0571.
+For more information about an error, try `rustc --explain E0425`.