diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 6ce299a941708..68f59baffce17 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -542,6 +542,26 @@ impl<'a: 'ast, 'ast> LateResolutionVisitor<'a, '_, 'ast> { err.span_label(base_span, fallback_label); } } + if let Some(err_code) = &err.code { + if err_code == &rustc_errors::error_code!(E0425) { + for label_rib in &self.label_ribs { + for (label_ident, _) in &label_rib.bindings { + if format!("'{}", ident) == label_ident.to_string() { + let msg = "a label with a similar name exists"; + // FIXME: consider only emitting this suggestion if a label would be valid here + // which is pretty much only the case for `break` expressions. + err.span_suggestion( + span, + &msg, + label_ident.name.to_string(), + Applicability::MaybeIncorrect, + ); + } + } + } + } + } + (err, candidates) } diff --git a/src/test/ui/label/label_misspelled.rs b/src/test/ui/label/label_misspelled.rs new file mode 100644 index 0000000000000..ebfd5642c9fa8 --- /dev/null +++ b/src/test/ui/label/label_misspelled.rs @@ -0,0 +1,18 @@ +fn main() { + 'LOOP: loop { + LOOP; + //~^ ERROR cannot find value `LOOP` in this scope + }; + 'while_loop: while true { //~ WARN denote infinite loops with + while_loop; + //~^ ERROR cannot find value `while_loop` in this scope + }; + 'while_let: while let Some(_) = Some(()) { + while_let; + //~^ ERROR cannot find value `while_let` in this scope + } + 'for_loop: for _ in 0..3 { + for_loop; + //~^ ERROR cannot find value `for_loop` in this scope + }; +} diff --git a/src/test/ui/label/label_misspelled.stderr b/src/test/ui/label/label_misspelled.stderr new file mode 100644 index 0000000000000..1368ca4126cdd --- /dev/null +++ b/src/test/ui/label/label_misspelled.stderr @@ -0,0 +1,47 @@ +error[E0425]: cannot find value `LOOP` in this scope + --> $DIR/label_misspelled.rs:3:9 + | +LL | 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:7:9 + | +LL | 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:11:9 + | +LL | 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:15:9 + | +LL | 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 + | +LL | 'while_loop: while true { + | ^^^^^^^^^^^^^^^^^^^^^^^ help: use `loop` + | + = note: `#[warn(while_true)]` on by default + +error: aborting due to 4 previous errors; 1 warning emitted + +For more information about this error, try `rustc --explain E0425`. diff --git a/src/test/ui/loops/loop-break-value.rs b/src/test/ui/loops/loop-break-value.rs index 6c4160c36aa39..8a080cfdf494a 100644 --- a/src/test/ui/loops/loop-break-value.rs +++ b/src/test/ui/loops/loop-break-value.rs @@ -90,4 +90,10 @@ fn main() { break; //~ ERROR mismatched types break 4; }; + + 'LOOP: for _ in 0 .. 9 { + break LOOP; + //~^ ERROR cannot find value `LOOP` in this scope + //~| ERROR `break` with value from a `for` loop + } } diff --git a/src/test/ui/loops/loop-break-value.stderr b/src/test/ui/loops/loop-break-value.stderr index 0503d3d4c7817..0237435c8b46a 100644 --- a/src/test/ui/loops/loop-break-value.stderr +++ b/src/test/ui/loops/loop-break-value.stderr @@ -1,3 +1,12 @@ +error[E0425]: cannot find value `LOOP` in this scope + --> $DIR/loop-break-value.rs:95:15 + | +LL | break LOOP; + | ^^^^ + | | + | not found in this scope + | help: a label with a similar name exists: `'LOOP` + warning: denote infinite loops with `loop { ... }` --> $DIR/loop-break-value.rs:26:5 | @@ -94,6 +103,17 @@ help: instead, use `break` on its own without a value inside this `for` loop LL | break; | ^^^^^ +error[E0571]: `break` with value from a `for` loop + --> $DIR/loop-break-value.rs:95:9 + | +LL | break 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[E0308]: mismatched types --> $DIR/loop-break-value.rs:4:31 | @@ -151,7 +171,7 @@ LL | break; | expected integer, found `()` | help: give it a value of the expected type: `break value` -error: aborting due to 16 previous errors; 1 warning emitted +error: aborting due to 18 previous errors; 1 warning emitted -Some errors have detailed explanations: E0308, E0571. +Some errors have detailed explanations: E0308, E0425, E0571. For more information about an error, try `rustc --explain E0308`.