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 | |
| parent | 448cc578a903730d422f6e638641787d0dbd7bc7 (diff) | |
| download | rust-11f5893610b8511eefde072b580e7f7a286aa422.tar.gz rust-11f5893610b8511eefde072b580e7f7a286aa422.zip | |
label-break-value: Parsing and AST/HIR changes
| -rw-r--r-- | src/librustc/cfg/construct.rs | 2 | ||||
| -rw-r--r-- | src/librustc/hir/intravisit.rs | 5 | ||||
| -rw-r--r-- | src/librustc/hir/lowering.rs | 8 | ||||
| -rw-r--r-- | src/librustc/hir/mod.rs | 4 | ||||
| -rw-r--r-- | src/librustc/hir/print.rs | 16 | ||||
| -rw-r--r-- | src/librustc/ich/impls_hir.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/expr_use_visitor.rs | 2 | ||||
| -rw-r--r-- | src/librustc/middle/liveness.rs | 4 | ||||
| -rw-r--r-- | src/librustc/middle/region.rs | 2 | ||||
| -rw-r--r-- | src/librustc_lint/builtin.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/hair/cx/expr.rs | 2 | ||||
| -rw-r--r-- | src/librustc_mir/transform/add_validation.rs | 2 | ||||
| -rw-r--r-- | src/librustc_passes/rvalue_promotion.rs | 4 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 4 | ||||
| -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 |
21 files changed, 77 insertions, 39 deletions
diff --git a/src/librustc/cfg/construct.rs b/src/librustc/cfg/construct.rs index d8cf147e3ee..7e03288f572 100644 --- a/src/librustc/cfg/construct.rs +++ b/src/librustc/cfg/construct.rs @@ -179,7 +179,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> { fn expr(&mut self, expr: &hir::Expr, pred: CFGIndex) -> CFGIndex { match expr.node { - hir::ExprBlock(ref blk) => { + hir::ExprBlock(ref blk, _) => { let blk_exit = self.block(&blk, pred); self.add_ast_node(expr.hir_id.local_id, &[blk_exit]) } diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 1fb496cca62..59b058e9861 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -1015,7 +1015,10 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) { expression.span, expression.id) } - ExprBlock(ref block) => visitor.visit_block(block), + ExprBlock(ref block, ref opt_label) => { + walk_list!(visitor, visit_label, opt_label); + visitor.visit_block(block); + } ExprAssign(ref left_hand_expression, ref right_hand_expression) => { visitor.visit_expr(right_hand_expression); visitor.visit_expr(left_hand_expression) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7a360f7ee43..09fff64094f 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -3048,7 +3048,7 @@ impl<'a> LoweringContext<'a> { ); block.expr = Some(this.wrap_in_try_constructor( "from_ok", tail, unstable_span)); - hir::ExprBlock(P(block)) + hir::ExprBlock(P(block), None) }) } ExprKind::Match(ref expr, ref arms) => hir::ExprMatch( @@ -3100,7 +3100,9 @@ impl<'a> LoweringContext<'a> { }) }) } - ExprKind::Block(ref blk) => hir::ExprBlock(self.lower_block(blk, false)), + ExprKind::Block(ref blk, opt_label) => { + hir::ExprBlock(self.lower_block(blk, false), self.lower_label(opt_label)) + } ExprKind::Assign(ref el, ref er) => { hir::ExprAssign(P(self.lower_expr(el)), P(self.lower_expr(er))) } @@ -3843,7 +3845,7 @@ impl<'a> LoweringContext<'a> { } fn expr_block(&mut self, b: P<hir::Block>, attrs: ThinVec<Attribute>) -> hir::Expr { - self.expr(b.span, hir::ExprBlock(b), attrs) + self.expr(b.span, hir::ExprBlock(b, None), attrs) } fn expr_tuple(&mut self, sp: Span, exprs: hir::HirVec<hir::Expr>) -> P<hir::Expr> { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 3f49e0bfd19..722a920d91c 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1381,8 +1381,8 @@ pub enum Expr_ { /// This may also be a generator literal, indicated by the final boolean, /// in that case there is an GeneratorClause. ExprClosure(CaptureClause, P<FnDecl>, BodyId, Span, Option<GeneratorMovability>), - /// A block (`{ ... }`) - ExprBlock(P<Block>), + /// A block (`'label: { ... }`) + ExprBlock(P<Block>, Option<Label>), /// An assignment (`a = foo()`) ExprAssign(P<Expr>, P<Expr>), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 3943c30127d..9cd9e0dce54 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1047,7 +1047,7 @@ impl<'a> State<'a> { self.print_else(e.as_ref().map(|e| &**e)) } // "final else" - hir::ExprBlock(ref b) => { + hir::ExprBlock(ref b, _) => { self.cbox(indent_unit - 1)?; self.ibox(0)?; self.s.word(" else ")?; @@ -1377,7 +1377,11 @@ impl<'a> State<'a> { // empty box to satisfy the close. self.ibox(0)?; } - hir::ExprBlock(ref blk) => { + hir::ExprBlock(ref blk, opt_label) => { + if let Some(label) = opt_label { + self.print_name(label.name)?; + 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 { @@ -1893,7 +1897,11 @@ impl<'a> State<'a> { self.word_space("=>")?; match arm.body.node { - hir::ExprBlock(ref blk) => { + hir::ExprBlock(ref blk, opt_label) => { + if let Some(label) = opt_label { + self.print_name(label.name)?; + self.word_space(":")?; + } // the block will close the pattern's ibox self.print_block_unclosed_indent(&blk, indent_unit)?; @@ -2299,7 +2307,7 @@ fn expr_requires_semi_to_be_stmt(e: &hir::Expr) -> bool { match e.node { hir::ExprIf(..) | hir::ExprMatch(..) | - hir::ExprBlock(_) | + hir::ExprBlock(..) | hir::ExprWhile(..) | hir::ExprLoop(..) => false, _ => true, diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 6edf1b35bdd..ed01704e6a4 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -589,7 +589,7 @@ impl_stable_hash_for!(enum hir::Expr_ { ExprLoop(body, label, loop_src), ExprMatch(matchee, arms, match_src), ExprClosure(capture_clause, decl, body_id, span, gen), - ExprBlock(blk), + ExprBlock(blk, label), ExprAssign(lhs, rhs), ExprAssignOp(op, lhs, rhs), ExprField(owner, field_name), diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 614ae17fa46..3ba230fe55a 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -499,7 +499,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { self.consume_expr(&rhs); } - hir::ExprBlock(ref blk) => { + hir::ExprBlock(ref blk, _) => { self.walk_block(&blk); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 2b1663bed2f..b39311a7471 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -1187,7 +1187,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> { succ } - hir::ExprBlock(ref blk) => { + // Note that labels have been resolved, so we don't need to look + // at the label ident + hir::ExprBlock(ref blk, _) => { self.propagate_through_block(&blk, succ) } } diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index bfc9ff6660d..52217600759 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -1247,7 +1247,7 @@ fn resolve_local<'a, 'tcx>(visitor: &mut RegionResolutionVisitor<'a, 'tcx>, hir::ExprCast(ref subexpr, _) => { record_rvalue_scope_if_borrow_expr(visitor, &subexpr, blk_id) } - hir::ExprBlock(ref block) => { + hir::ExprBlock(ref block, _) => { if let Some(ref subexpr) = block.expr { record_rvalue_scope_if_borrow_expr( visitor, &subexpr, blk_id); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 0b1e9081a72..19280372d55 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -228,7 +228,7 @@ impl UnsafeCode { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for UnsafeCode { fn check_expr(&mut self, cx: &LateContext, e: &hir::Expr) { - if let hir::ExprBlock(ref blk) = e.node { + if let hir::ExprBlock(ref blk, _) = e.node { // Don't warn about generated blocks, that'll just pollute the output. if blk.rules == hir::UnsafeBlock(hir::UserProvided) { self.report_unsafe(cx, blk.span, "usage of an `unsafe` block"); diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 3e432d84c69..97a4e0f3724 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -292,7 +292,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } - hir::ExprBlock(ref blk) => ExprKind::Block { body: &blk }, + hir::ExprBlock(ref blk, _) => ExprKind::Block { body: &blk }, hir::ExprAssign(ref lhs, ref rhs) => { ExprKind::Assign { diff --git a/src/librustc_mir/transform/add_validation.rs b/src/librustc_mir/transform/add_validation.rs index 584887d0373..85af00956c9 100644 --- a/src/librustc_mir/transform/add_validation.rs +++ b/src/librustc_mir/transform/add_validation.rs @@ -141,7 +141,7 @@ fn fn_contains_unsafe<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource) -> } // Check if this is an unsafe block, or an item match node { - Node::NodeExpr(&hir::Expr { node: hir::ExprBlock(ref block), ..}) => { + Node::NodeExpr(&hir::Expr { node: hir::ExprBlock(ref block, _), ..}) => { if block_is_unsafe(&*block) { // Found an unsafe block, we can bail out here. return true; diff --git a/src/librustc_passes/rvalue_promotion.rs b/src/librustc_passes/rvalue_promotion.rs index 3a577341f7e..e488bb47e34 100644 --- a/src/librustc_passes/rvalue_promotion.rs +++ b/src/librustc_passes/rvalue_promotion.rs @@ -342,7 +342,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node let mut callee = &**callee; loop { callee = match callee.node { - hir::ExprBlock(ref block) => match block.expr { + hir::ExprBlock(ref block, _) => match block.expr { Some(ref tail) => &tail, None => break }, @@ -404,7 +404,7 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node } } - hir::ExprBlock(_) | + hir::ExprBlock(..) | hir::ExprIndex(..) | hir::ExprField(..) | hir::ExprArray(_) | diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f98a8ba1e4d..86c8ab66f77 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3536,7 +3536,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Warn for non-block expressions with diverging children. match expr.node { - hir::ExprBlock(_) | + hir::ExprBlock(..) | hir::ExprLoop(..) | hir::ExprWhile(..) | hir::ExprIf(..) | hir::ExprMatch(..) => {} @@ -3912,7 +3912,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::ExprClosure(capture, ref decl, body_id, _, gen) => { self.check_expr_closure(expr, capture, &decl, body_id, gen, expected) } - hir::ExprBlock(ref body) => { + hir::ExprBlock(ref body, _) => { self.check_block_with_expected(&body, expected) } hir::ExprCall(ref callee, ref args) => { 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); |
