Suggest adding {}
for 'label: non_block_expr
This commit is contained in:
parent
a2da4af33c
commit
f21c0a274e
@ -13,10 +13,12 @@ use rustc_ast::tokenstream::Spacing;
|
|||||||
use rustc_ast::util::classify;
|
use rustc_ast::util::classify;
|
||||||
use rustc_ast::util::literal::LitError;
|
use rustc_ast::util::literal::LitError;
|
||||||
use rustc_ast::util::parser::{prec_let_scrutinee_needs_par, AssocOp, Fixity};
|
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::{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::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, MacCall, Param, Ty, TyKind};
|
||||||
use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
|
use rustc_ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
|
||||||
use rustc_ast_pretty::pprust;
|
use rustc_ast_pretty::pprust;
|
||||||
|
use rustc_data_structures::thin_vec::ThinVec;
|
||||||
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, PResult};
|
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, PResult};
|
||||||
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
|
use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
|
||||||
use rustc_session::lint::BuiltinLintDiagnostics;
|
use rustc_session::lint::BuiltinLintDiagnostics;
|
||||||
@ -1548,9 +1550,33 @@ impl<'a> Parser<'a> {
|
|||||||
Ok(self.mk_expr_err(lo))
|
Ok(self.mk_expr_err(lo))
|
||||||
} else {
|
} else {
|
||||||
let msg = "expected `while`, `for`, `loop` or `{` after a label";
|
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`.
|
// 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 {
|
if !ate_colon && consume_colon {
|
||||||
|
@ -47,6 +47,11 @@ error: expected `while`, `for`, `loop` or `{` after a label
|
|||||||
|
|
|
|
||||||
LL | 'l4 0;
|
LL | 'l4 0;
|
||||||
| ^ expected `while`, `for`, `loop` or `{` after a label
|
| ^ 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 `:`
|
error: labeled expression must be followed by `:`
|
||||||
--> $DIR/labeled-no-colon-expr.rs:8:9
|
--> $DIR/labeled-no-colon-expr.rs:8:9
|
||||||
|
25
src/test/ui/parser/recover-labeled-non-block-expr.fixed
Normal file
25
src/test/ui/parser/recover-labeled-non-block-expr.fixed
Normal file
@ -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
|
||||||
|
}
|
@ -1,5 +1,25 @@
|
|||||||
|
// run-rustfix
|
||||||
|
#![feature(label_break_value)]
|
||||||
fn main() {
|
fn main() {
|
||||||
|
#[allow(unused_labels)]
|
||||||
'label: 1 + 1; //~ ERROR expected `while`, `for`, `loop` or `{` after a label
|
'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
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,51 @@
|
|||||||
error: expected `while`, `for`, `loop` or `{` after a label
|
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;
|
LL | 'label: 1 + 1;
|
||||||
| ^ expected `while`, `for`, `loop` or `{` after a label
|
| ^ expected `while`, `for`, `loop` or `{` after a label
|
||||||
|
|
||||||
error[E0308]: mismatched types
|
|
||||||
--> $DIR/recover-labeled-non-block-expr.rs:4:33
|
|
||||||
|
|
|
|
||||||
LL | let _recovery_witness: () = 0;
|
help: consider enclosing expression in a block
|
||||||
| -- ^ expected `()`, found integer
|
|
|
||||||
| |
|
LL | 'label: {1 + 1};
|
||||||
| expected due to this
|
| + +
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
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: 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 _val = 'label: {(1, if other == 3 { break 'label (2, 3) } else { other })};
|
||||||
|
| + +
|
||||||
|
|
||||||
|
error: aborting due to 4 previous errors
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0308`.
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user