From f21c0a274ebfb35612359e32bee965afb09640d6 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 5 Jun 2022 16:45:29 +0400 Subject: [PATCH 1/4] Suggest adding `{}` for `'label: non_block_expr` --- compiler/rustc_parse/src/parser/expr.rs | 30 ++++++++++- .../ui/parser/labeled-no-colon-expr.stderr | 5 ++ .../recover-labeled-non-block-expr.fixed | 25 +++++++++ .../parser/recover-labeled-non-block-expr.rs | 22 +++++++- .../recover-labeled-non-block-expr.stderr | 52 +++++++++++++++---- 5 files changed, 122 insertions(+), 12 deletions(-) create mode 100644 src/test/ui/parser/recover-labeled-non-block-expr.fixed diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 63c7decbb2fe..761d521a07ec 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -13,10 +13,12 @@ use rustc_ast::tokenstream::Spacing; use rustc_ast::util::classify; use rustc_ast::util::literal::LitError; use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity}; +use rustc_ast::StmtKind; use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, Lit, UnOp, DUMMY_NODE_ID}; use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind}; use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits}; use rustc_ast_pretty::pprust; +use rustc_data_structures::thin_vec::ThinVec; use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, PResult}; use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP; use rustc_session::lint::BuiltinLintDiagnostics; @@ -1548,9 +1550,33 @@ impl<'a> Parser<'a> { Ok(self.mk_expr_err(lo)) } else { let msg = "expected `while`, `for`, `loop` or `{` after a label"; - self.struct_span_err(self.token.span, msg).span_label(self.token.span, msg).emit(); + + let mut err = self.struct_span_err(self.token.span, msg); + err.span_label(self.token.span, msg); + // Continue as an expression in an effort to recover on `'label: non_block_expr`. - self.parse_expr() + let expr = self.parse_expr().map(|expr| { + let span = expr.span; + let sugg_msg = "consider enclosing expression in a block"; + let suggestions = vec![ + (span.shrink_to_lo(), "{".to_owned()), + (span.shrink_to_hi(), "}".to_owned()), + ]; + + err.multipart_suggestion_verbose( + sugg_msg, + suggestions, + Applicability::MachineApplicable, + ); + + // Replace `'label: non_block_expr` with `'label: {non_block_expr}` in order to supress future errors about `break 'label`. + let stmt = self.mk_stmt(span, StmtKind::Expr(expr)); + let blk = self.mk_block(vec![stmt], BlockCheckMode::Default, span); + self.mk_expr(span, ExprKind::Block(blk, label), ThinVec::new()) + }); + + err.emit(); + expr }?; if !ate_colon && consume_colon { diff --git a/src/test/ui/parser/labeled-no-colon-expr.stderr b/src/test/ui/parser/labeled-no-colon-expr.stderr index 26884dc5d745..4d0d9c4a00bf 100644 --- a/src/test/ui/parser/labeled-no-colon-expr.stderr +++ b/src/test/ui/parser/labeled-no-colon-expr.stderr @@ -47,6 +47,11 @@ error: expected `while`, `for`, `loop` or `{` after a label | LL | 'l4 0; | ^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider enclosing expression in a block + | +LL | 'l4 {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 new file mode 100644 index 000000000000..dbe2f2e0bdde --- /dev/null +++ b/src/test/ui/parser/recover-labeled-non-block-expr.fixed @@ -0,0 +1,25 @@ +// run-rustfix +#![feature(label_break_value)] +fn main() { + #[allow(unused_labels)] + 'label: {1 + 1}; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + + 'label: {match () { () => break 'label, }}; //~ 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 + 0 => 42, + 1 if false => break 'label 17, + 1 => { + if true { + break 'label 13 + } else { + break 'label 0; + } + } + _ => 1, + }}; + + let other = 3; + let _val = 'label: {(1, if other == 3 { break 'label (2, 3) } else { other })}; //~ 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 be92170acf02..9c22c0737129 100644 --- a/src/test/ui/parser/recover-labeled-non-block-expr.rs +++ b/src/test/ui/parser/recover-labeled-non-block-expr.rs @@ -1,5 +1,25 @@ +// run-rustfix +#![feature(label_break_value)] fn main() { + #[allow(unused_labels)] 'label: 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label - let _recovery_witness: () = 0; //~ ERROR mismatched types + 'label: match () { () => break 'label, }; //~ 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 + 0 => 42, + 1 if false => break 'label 17, + 1 => { + if true { + break 'label 13 + } else { + break 'label 0; + } + } + _ => 1, + }; + + let other = 3; + let _val = 'label: (1, if other == 3 { break 'label (2, 3) } else { other }); //~ 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 771a915288c5..2e4e45d61713 100644 --- a/src/test/ui/parser/recover-labeled-non-block-expr.stderr +++ b/src/test/ui/parser/recover-labeled-non-block-expr.stderr @@ -1,17 +1,51 @@ error: expected `while`, `for`, `loop` or `{` after a label - --> $DIR/recover-labeled-non-block-expr.rs:2:13 + --> $DIR/recover-labeled-non-block-expr.rs:5:13 | LL | 'label: 1 + 1; | ^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider enclosing expression in a block + | +LL | 'label: {1 + 1}; + | + + + +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 + | +help: consider enclosing expression in a block + | +LL | 'label: {match () { () => break 'label, }}; + | + + -error[E0308]: mismatched types - --> $DIR/recover-labeled-non-block-expr.rs:4:33 +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:10:22 + | +LL | let _i = 'label: match x { + | ^^^^^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider enclosing expression in a block + | +LL ~ let _i = 'label: {match x { +LL | 0 => 42, +LL | 1 if false => break 'label 17, +LL | 1 => { +LL | if true { +LL | break 'label 13 + ... + +error: expected `while`, `for`, `loop` or `{` after a label + --> $DIR/recover-labeled-non-block-expr.rs:24:24 + | +LL | let _val = 'label: (1, if other == 3 { break 'label (2, 3) } else { other }); + | ^ expected `while`, `for`, `loop` or `{` after a label + | +help: consider enclosing expression in a block | -LL | let _recovery_witness: () = 0; - | -- ^ expected `()`, found integer - | | - | expected due to this +LL | let _val = 'label: {(1, if other == 3 { break 'label (2, 3) } else { other })}; + | + + -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors -For more information about this error, try `rustc --explain E0308`. From c6e5bb32fbb3d0a85189e56086726c183f68ad0c Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 5 Jun 2022 23:12:51 +0400 Subject: [PATCH 2/4] Do not suggest adding labeled block if there are no labeled breaks --- compiler/rustc_parse/src/parser/expr.rs | 23 +++++++++++++++++++ .../ui/parser/labeled-no-colon-expr.stderr | 5 ---- .../recover-labeled-non-block-expr.fixed | 5 ++-- .../parser/recover-labeled-non-block-expr.rs | 5 ++-- .../recover-labeled-non-block-expr.stderr | 19 ++++----------- 5 files changed, 33 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 761d521a07ec..0d252c3d465d 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -13,6 +13,7 @@ use rustc_ast::tokenstream::Spacing; use rustc_ast::util::classify; use rustc_ast::util::literal::LitError; use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity}; +use rustc_ast::visit::Visitor; use rustc_ast::StmtKind; use rustc_ast::{self as ast, AttrStyle, AttrVec, CaptureBy, ExprField, Lit, UnOp, DUMMY_NODE_ID}; use rustc_ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind}; @@ -1556,6 +1557,28 @@ 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 found_labeled_breaks = { + struct FindLabeledBreaksVisitor(bool); + + impl<'ast> Visitor<'ast> for FindLabeledBreaksVisitor { + fn visit_expr_post(&mut self, ex: &'ast Expr) { + if let ExprKind::Break(Some(_label), _) = ex.kind { + self.0 = true; + } + } + } + + let mut vis = FindLabeledBreaksVisitor(false); + vis.visit_expr(&expr); + 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 + if !found_labeled_breaks { + return expr; + } + let span = expr.span; let sugg_msg = "consider enclosing expression in a block"; let suggestions = vec![ diff --git a/src/test/ui/parser/labeled-no-colon-expr.stderr b/src/test/ui/parser/labeled-no-colon-expr.stderr index 4d0d9c4a00bf..26884dc5d745 100644 --- a/src/test/ui/parser/labeled-no-colon-expr.stderr +++ b/src/test/ui/parser/labeled-no-colon-expr.stderr @@ -47,11 +47,6 @@ error: expected `while`, `for`, `loop` or `{` after a label | LL | 'l4 0; | ^ expected `while`, `for`, `loop` or `{` after a label - | -help: consider enclosing expression in a block - | -LL | 'l4 {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 dbe2f2e0bdde..aabda4a67a18 100644 --- a/src/test/ui/parser/recover-labeled-non-block-expr.fixed +++ b/src/test/ui/parser/recover-labeled-non-block-expr.fixed @@ -1,8 +1,9 @@ // run-rustfix #![feature(label_break_value)] fn main() { - #[allow(unused_labels)] - 'label: {1 + 1}; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + // FIXME(waffle): add this back + // #[allow(unused_labels)] + // 'label: 1 + 1; // ERROR expected `while`, `for`, `loop` or `{` after a label 'label: {match () { () => break 'label, }}; //~ 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 9c22c0737129..9244acabc264 100644 --- a/src/test/ui/parser/recover-labeled-non-block-expr.rs +++ b/src/test/ui/parser/recover-labeled-non-block-expr.rs @@ -1,8 +1,9 @@ // run-rustfix #![feature(label_break_value)] fn main() { - #[allow(unused_labels)] - 'label: 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + // FIXME(waffle): add this back + // #[allow(unused_labels)] + // 'label: 1 + 1; // ERROR expected `while`, `for`, `loop` or `{` after a label 'label: match () { () => break 'label, }; //~ 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 2e4e45d61713..37843141ef3b 100644 --- a/src/test/ui/parser/recover-labeled-non-block-expr.stderr +++ b/src/test/ui/parser/recover-labeled-non-block-expr.stderr @@ -1,16 +1,5 @@ error: expected `while`, `for`, `loop` or `{` after a label - --> $DIR/recover-labeled-non-block-expr.rs:5:13 - | -LL | 'label: 1 + 1; - | ^ expected `while`, `for`, `loop` or `{` after a label - | -help: consider enclosing expression in a block - | -LL | 'label: {1 + 1}; - | + + - -error: expected `while`, `for`, `loop` or `{` after a label - --> $DIR/recover-labeled-non-block-expr.rs:7:13 + --> $DIR/recover-labeled-non-block-expr.rs:8:13 | LL | 'label: match () { () => break 'label, }; | ^^^^^ expected `while`, `for`, `loop` or `{` after a label @@ -21,7 +10,7 @@ LL | 'label: {match () { () => break 'label, }}; | + + error: expected `while`, `for`, `loop` or `{` after a label - --> $DIR/recover-labeled-non-block-expr.rs:10:22 + --> $DIR/recover-labeled-non-block-expr.rs:11:22 | LL | let _i = 'label: match x { | ^^^^^ expected `while`, `for`, `loop` or `{` after a label @@ -37,7 +26,7 @@ LL | break 'label 13 ... error: expected `while`, `for`, `loop` or `{` after a label - --> $DIR/recover-labeled-non-block-expr.rs:24:24 + --> $DIR/recover-labeled-non-block-expr.rs:25:24 | LL | let _val = 'label: (1, if other == 3 { break 'label (2, 3) } else { other }); | ^ expected `while`, `for`, `loop` or `{` after a label @@ -47,5 +36,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 4 previous errors +error: aborting due to 3 previous errors From f06f05174581702e822f1d866a06e0a6a22d0b3d Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Sun, 5 Jun 2022 23:34:11 +0400 Subject: [PATCH 3/4] Suggest removing label in `'label: non_block_expr` --- compiler/rustc_parse/src/parser/expr.rs | 17 ++++++-- .../ui/parser/labeled-no-colon-expr.stderr | 6 +++ .../recover-labeled-non-block-expr.fixed | 7 +-- .../parser/recover-labeled-non-block-expr.rs | 7 +-- .../recover-labeled-non-block-expr.stderr | 43 +++++++++++++++++-- 5 files changed, 67 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 0d252c3d465d..0bc71de90ff1 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 26884dc5d745..5c9597c440cb 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 aabda4a67a18..3193d90d2d30 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 9244acabc264..35862e2eef97 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 37843141ef3b..e289c5db5cb9 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 From 4f85a73e516530844aecc44fb91d0db7604f7ac4 Mon Sep 17 00:00:00 2001 From: Waffle Maybe Date: Mon, 6 Jun 2022 01:35:37 +0400 Subject: [PATCH 4/4] Add spaces before and after expr in add {} suggestion Co-authored-by: Michael Goulet --- compiler/rustc_parse/src/parser/expr.rs | 4 ++-- .../ui/parser/recover-labeled-non-block-expr.fixed | 10 +++++----- .../parser/recover-labeled-non-block-expr.stderr | 14 +++++++------- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 0bc71de90ff1..b786c52e6880 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1593,8 +1593,8 @@ impl<'a> Parser<'a> { let sugg_msg = "consider enclosing expression in a block"; let suggestions = vec![ - (span.shrink_to_lo(), "{".to_owned()), - (span.shrink_to_hi(), "}".to_owned()), + (span.shrink_to_lo(), "{ ".to_owned()), + (span.shrink_to_hi(), " }".to_owned()), ]; err.multipart_suggestion_verbose( 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 3193d90d2d30..fe546a719711 100644 --- a/src/test/ui/parser/recover-labeled-non-block-expr.fixed +++ b/src/test/ui/parser/recover-labeled-non-block-expr.fixed @@ -4,12 +4,12 @@ fn main() { 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 + '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 + '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 + let _i = 'label: { match x { //~ ERROR expected `while`, `for`, `loop` or `{` after a label 0 => 42, 1 if false => break 'label 17, 1 => { @@ -20,8 +20,8 @@ fn main() { } } _ => 1, - }}; + } }; let other = 3; - let _val = 'label: {(1, if other == 3 { break 'label (2, 3) } else { other })}; //~ ERROR expected `while`, `for`, `loop` or `{` after a label + let _val = 'label: { (1, if other == 3 { break 'label (2, 3) } else { other }) }; //~ 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 e289c5db5cb9..767389c48088 100644 --- a/src/test/ui/parser/recover-labeled-non-block-expr.stderr +++ b/src/test/ui/parser/recover-labeled-non-block-expr.stderr @@ -30,8 +30,8 @@ LL | 'label: match () { () => break 'label, }; | help: consider enclosing expression in a block | -LL | 'label: {match () { () => break 'label, }}; - | + + +LL | 'label: { match () { () => break 'label, } }; + | + + error: expected `while`, `for`, `loop` or `{` after a label --> $DIR/recover-labeled-non-block-expr.rs:9:13 @@ -41,8 +41,8 @@ LL | 'label: match () { () => 'lp: loop { break 'lp 0 }, }; | help: consider enclosing expression in a block | -LL | 'label: {match () { () => 'lp: loop { break 'lp 0 }, }}; - | + + +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 @@ -52,7 +52,7 @@ LL | let _i = 'label: match x { | help: consider enclosing expression in a block | -LL ~ let _i = 'label: {match x { +LL ~ let _i = 'label: { match x { LL | 0 => 42, LL | 1 if false => break 'label 17, LL | 1 => { @@ -68,8 +68,8 @@ LL | let _val = 'label: (1, if other == 3 { break 'label (2, 3) } else { oth | help: consider enclosing expression in a block | -LL | let _val = 'label: {(1, if other == 3 { break 'label (2, 3) } else { other })}; - | + + +LL | let _val = 'label: { (1, if other == 3 { break 'label (2, 3) } else { other }) }; + | + + error: aborting due to 6 previous errors