diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 0d252c3d465..0bc71de90ff 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1557,6 +1557,8 @@ impl<'a> Parser<'a> { // Continue as an expression in an effort to recover on `'label: non_block_expr`. let expr = self.parse_expr().map(|expr| { + let span = expr.span; + let found_labeled_breaks = { struct FindLabeledBreaksVisitor(bool); @@ -1573,13 +1575,22 @@ impl<'a> Parser<'a> { vis.0 }; - // Suggestion involves adding a (as of time of writing this, unstable) labeled block - // so if the label is not used, just return the unmodified expression + // Suggestion involves adding a (as of time of writing this, unstable) labeled block. + // + // If there are no breaks that may use this label, suggest removing the label and + // recover to the unmodified expression. if !found_labeled_breaks { + let msg = "consider removing the label"; + err.span_suggestion_verbose( + lo.until(span), + msg, + "", + Applicability::MachineApplicable, + ); + return expr; } - let span = expr.span; let sugg_msg = "consider enclosing expression in a block"; let suggestions = vec![ (span.shrink_to_lo(), "{".to_owned()), diff --git a/src/test/ui/parser/labeled-no-colon-expr.stderr b/src/test/ui/parser/labeled-no-colon-expr.stderr index 26884dc5d74..5c9597c440c 100644 --- a/src/test/ui/parser/labeled-no-colon-expr.stderr +++ b/src/test/ui/parser/labeled-no-colon-expr.stderr @@ -47,6 +47,12 @@ error: expected `while`, `for`, `loop` or `{` after a label | LL | 'l4 0; | ^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider removing the label + | +LL - 'l4 0; +LL + 0; + | error: labeled expression must be followed by `:` --> $DIR/labeled-no-colon-expr.rs:8:9 diff --git a/src/test/ui/parser/recover-labeled-non-block-expr.fixed b/src/test/ui/parser/recover-labeled-non-block-expr.fixed index aabda4a67a1..3193d90d2d3 100644 --- a/src/test/ui/parser/recover-labeled-non-block-expr.fixed +++ b/src/test/ui/parser/recover-labeled-non-block-expr.fixed @@ -1,11 +1,12 @@ // run-rustfix #![feature(label_break_value)] fn main() { - // FIXME(waffle): add this back - // #[allow(unused_labels)] - // 'label: 1 + 1; // ERROR expected `while`, `for`, `loop` or `{` after a label + let _ = 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + match () { () => {}, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label 'label: {match () { () => break 'label, }}; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + #[allow(unused_labels)] + 'label: {match () { () => 'lp: loop { break 'lp 0 }, }}; //~ ERROR expected `while`, `for`, `loop` or `{` after a label let x = 1; let _i = 'label: {match x { //~ ERROR expected `while`, `for`, `loop` or `{` after a label diff --git a/src/test/ui/parser/recover-labeled-non-block-expr.rs b/src/test/ui/parser/recover-labeled-non-block-expr.rs index 9244acabc26..35862e2eef9 100644 --- a/src/test/ui/parser/recover-labeled-non-block-expr.rs +++ b/src/test/ui/parser/recover-labeled-non-block-expr.rs @@ -1,11 +1,12 @@ // run-rustfix #![feature(label_break_value)] fn main() { - // FIXME(waffle): add this back - // #[allow(unused_labels)] - // 'label: 1 + 1; // ERROR expected `while`, `for`, `loop` or `{` after a label + let _ = 'label: 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + 'label: match () { () => {}, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label 'label: match () { () => break 'label, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + #[allow(unused_labels)] + 'label: match () { () => 'lp: loop { break 'lp 0 }, }; //~ ERROR expected `while`, `for`, `loop` or `{` after a label let x = 1; let _i = 'label: match x { //~ ERROR expected `while`, `for`, `loop` or `{` after a label diff --git a/src/test/ui/parser/recover-labeled-non-block-expr.stderr b/src/test/ui/parser/recover-labeled-non-block-expr.stderr index 37843141ef3..e289c5db5cb 100644 --- a/src/test/ui/parser/recover-labeled-non-block-expr.stderr +++ b/src/test/ui/parser/recover-labeled-non-block-expr.stderr @@ -1,5 +1,29 @@ error: expected `while`, `for`, `loop` or `{` after a label - --> $DIR/recover-labeled-non-block-expr.rs:8:13 + --> $DIR/recover-labeled-non-block-expr.rs:4:21 + | +LL | let _ = 'label: 1 + 1; + | ^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider removing the label + | +LL - let _ = 'label: 1 + 1; +LL + let _ = 1 + 1; + | + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:6:13 + | +LL | 'label: match () { () => {}, }; + | ^^^^^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider removing the label + | +LL - 'label: match () { () => {}, }; +LL + match () { () => {}, }; + | + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:7:13 | LL | 'label: match () { () => break 'label, }; | ^^^^^ expected `while`, `for`, `loop` or `{` after a label @@ -10,7 +34,18 @@ LL | 'label: {match () { () => break 'label, }}; | + + error: expected `while`, `for`, `loop` or `{` after a label - --> $DIR/recover-labeled-non-block-expr.rs:11:22 + --> $DIR/recover-labeled-non-block-expr.rs:9:13 + | +LL | 'label: match () { () => 'lp: loop { break 'lp 0 }, }; + | ^^^^^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider enclosing expression in a block + | +LL | 'label: {match () { () => 'lp: loop { break 'lp 0 }, }}; + | + + + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:12:22 | LL | let _i = 'label: match x { | ^^^^^ expected `while`, `for`, `loop` or `{` after a label @@ -26,7 +61,7 @@ LL | break 'label 13 ... error: expected `while`, `for`, `loop` or `{` after a label - --> $DIR/recover-labeled-non-block-expr.rs:25:24 + --> $DIR/recover-labeled-non-block-expr.rs:26:24 | LL | let _val = 'label: (1, if other == 3 { break 'label (2, 3) } else { other }); | ^ expected `while`, `for`, `loop` or `{` after a label @@ -36,5 +71,5 @@ help: consider enclosing expression in a block LL | let _val = 'label: {(1, if other == 3 { break 'label (2, 3) } else { other })}; | + + -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors