diff options
| author | est31 <MTest31@outlook.com> | 2018-04-16 05:44:39 +0200 |
|---|---|---|
| committer | est31 <MTest31@outlook.com> | 2018-05-16 13:56:24 +0200 |
| commit | 11f5893610b8511eefde072b580e7f7a286aa422 (patch) | |
| tree | ee558eb05bf3e70808d773cd7acb699682bdfdf7 /src/libsyntax | |
| parent | 448cc578a903730d422f6e638641787d0dbd7bc7 (diff) | |
| download | rust-11f5893610b8511eefde072b580e7f7a286aa422.tar.gz rust-11f5893610b8511eefde072b580e7f7a286aa422.zip | |
label-break-value: Parsing and AST/HIR changes
Diffstat (limited to 'src/libsyntax')
| -rw-r--r-- | src/libsyntax/ast.rs | 6 | ||||
| -rw-r--r-- | src/libsyntax/ext/build.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/fold.rs | 5 | ||||
| -rw-r--r-- | src/libsyntax/parse/classify.rs | 2 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 22 | ||||
| -rw-r--r-- | src/libsyntax/print/pprust.rs | 15 | ||||
| -rw-r--r-- | src/libsyntax/visit.rs | 5 |
7 files changed, 40 insertions, 17 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index f8cd6103bdf..2b6635ec783 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -934,7 +934,7 @@ impl Expr { /// Whether this expression would be valid somewhere that expects a value, for example, an `if` /// condition. pub fn returns(&self) -> bool { - if let ExprKind::Block(ref block) = self.node { + if let ExprKind::Block(ref block, _) = self.node { match block.stmts.last().map(|last_stmt| &last_stmt.node) { // implicit return Some(&StmtKind::Expr(_)) => true, @@ -1121,8 +1121,8 @@ pub enum ExprKind { /// /// The final span is the span of the argument block `|...|` Closure(CaptureBy, Movability, P<FnDecl>, P<Expr>, Span), - /// A block (`{ ... }`) - Block(P<Block>), + /// A block (`'label: { ... }`) + Block(P<Block>, Option<Label>), /// A catch block (`catch { ... }`) Catch(P<Block>), diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 0b64189b2bc..a4f9ebcf418 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -668,7 +668,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.expr(span, ast::ExprKind::MethodCall(segment, args)) } fn expr_block(&self, b: P<ast::Block>) -> P<ast::Expr> { - self.expr(b.span, ast::ExprKind::Block(b)) + self.expr(b.span, ast::ExprKind::Block(b, None)) } fn field_imm(&self, span: Span, ident: Ident, e: P<ast::Expr>) -> ast::Field { ast::Field { diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index d67995761f6..29cc208c06b 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -1256,7 +1256,10 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span, attrs}: Expr, folder: &mu folder.fold_expr(body), folder.new_span(span)) } - ExprKind::Block(blk) => ExprKind::Block(folder.fold_block(blk)), + ExprKind::Block(blk, opt_label) => { + ExprKind::Block(folder.fold_block(blk), + opt_label.map(|label| folder.fold_label(label))) + } ExprKind::Assign(el, er) => { ExprKind::Assign(folder.fold_expr(el), folder.fold_expr(er)) } diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index b8e02556625..531483e7de1 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -26,7 +26,7 @@ pub fn expr_requires_semi_to_be_stmt(e: &ast::Expr) -> bool { ast::ExprKind::If(..) | ast::ExprKind::IfLet(..) | ast::ExprKind::Match(..) | - ast::ExprKind::Block(_) | + ast::ExprKind::Block(..) | ast::ExprKind::While(..) | ast::ExprKind::WhileLet(..) | ast::ExprKind::Loop(..) | diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 3f0df6d055b..7b91c491700 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -128,7 +128,7 @@ macro_rules! maybe_whole_expr { token::NtBlock(ref block) => { $p.bump(); let span = $p.span; - let kind = ExprKind::Block((*block).clone()); + let kind = ExprKind::Block((*block).clone(), None); return Ok($p.mk_expr(span, kind, ThinVec::new())); } _ => {}, @@ -2244,7 +2244,7 @@ impl<'a> Parser<'a> { }; } token::OpenDelim(token::Brace) => { - return self.parse_block_expr(lo, BlockCheckMode::Default, attrs); + return self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs); } token::BinOp(token::Or) | token::OrOr => { return self.parse_lambda_expr(attrs); @@ -2318,7 +2318,13 @@ impl<'a> Parser<'a> { if self.eat_keyword(keywords::Loop) { return self.parse_loop_expr(Some(label), lo, attrs) } - let msg = "expected `while`, `for`, or `loop` after a label"; + if self.token == token::OpenDelim(token::Brace) { + return self.parse_block_expr(Some(label), + lo, + BlockCheckMode::Default, + attrs); + } + let msg = "expected `while`, `for`, `loop` or `{` after a label"; let mut err = self.fatal(msg); err.span_label(self.span, msg); return Err(err); @@ -2338,6 +2344,7 @@ impl<'a> Parser<'a> { } if self.eat_keyword(keywords::Unsafe) { return self.parse_block_expr( + None, lo, BlockCheckMode::Unsafe(ast::UserProvided), attrs); @@ -2502,7 +2509,8 @@ impl<'a> Parser<'a> { } /// Parse a block or unsafe block - pub fn parse_block_expr(&mut self, lo: Span, blk_mode: BlockCheckMode, + pub fn parse_block_expr(&mut self, opt_label: Option<Label>, + lo: Span, blk_mode: BlockCheckMode, outer_attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> { self.expect(&token::OpenDelim(token::Brace))?; @@ -2511,7 +2519,7 @@ impl<'a> Parser<'a> { attrs.extend(self.parse_inner_attributes()?); let blk = self.parse_block_tail(lo, blk_mode)?; - return Ok(self.mk_expr(blk.span, ExprKind::Block(blk), attrs)); + return Ok(self.mk_expr(blk.span, ExprKind::Block(blk, opt_label), attrs)); } /// parse a.b or a(13) or a[4] or just a @@ -3261,7 +3269,7 @@ impl<'a> Parser<'a> { // If an explicit return type is given, require a // block to appear (RFC 968). let body_lo = self.span; - self.parse_block_expr(body_lo, BlockCheckMode::Default, ThinVec::new())? + self.parse_block_expr(None, body_lo, BlockCheckMode::Default, ThinVec::new())? } }; @@ -3277,7 +3285,7 @@ impl<'a> Parser<'a> { return self.parse_if_expr(ThinVec::new()); } else { let blk = self.parse_block()?; - return Ok(self.mk_expr(blk.span, ExprKind::Block(blk), ThinVec::new())); + return Ok(self.mk_expr(blk.span, ExprKind::Block(blk, None), ThinVec::new())); } } diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 99a6fcf170d..0fe48f791dc 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1791,7 +1791,7 @@ impl<'a> State<'a> { self.print_else(e.as_ref().map(|e| &**e)) } // "final else" - ast::ExprKind::Block(ref b) => { + ast::ExprKind::Block(ref b, _) => { self.cbox(INDENT_UNIT - 1)?; self.ibox(0)?; self.s.word(" else ")?; @@ -2181,7 +2181,11 @@ impl<'a> State<'a> { // empty box to satisfy the close. self.ibox(0)?; } - ast::ExprKind::Block(ref blk) => { + ast::ExprKind::Block(ref blk, opt_label) => { + if let Some(label) = opt_label { + self.print_ident(label.ident)?; + self.word_space(":")?; + } // containing cbox, will be closed by print-block at } self.cbox(INDENT_UNIT)?; // head-box, will be closed by print-block after { @@ -2694,7 +2698,12 @@ impl<'a> State<'a> { self.word_space("=>")?; match arm.body.node { - ast::ExprKind::Block(ref blk) => { + ast::ExprKind::Block(ref blk, opt_label) => { + if let Some(label) = opt_label { + self.print_ident(label.ident)?; + self.word_space(":")?; + } + // the block will close the pattern's ibox self.print_block_unclosed_indent(blk, INDENT_UNIT)?; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 40d59d3ff8b..2013e838c05 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -736,7 +736,10 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) { expression.span, expression.id) } - ExprKind::Block(ref block) => visitor.visit_block(block), + ExprKind::Block(ref block, ref opt_label) => { + walk_list!(visitor, visit_label, opt_label); + visitor.visit_block(block); + } ExprKind::Assign(ref left_hand_expression, ref right_hand_expression) => { visitor.visit_expr(left_hand_expression); visitor.visit_expr(right_hand_expression); |
