Skip to content

Commit

Permalink
label-break-value: Parsing and AST/HIR changes
Browse files Browse the repository at this point in the history
  • Loading branch information
est31 committed May 16, 2018
1 parent 448cc57 commit 11f5893
Show file tree
Hide file tree
Showing 21 changed files with 77 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/librustc/cfg/construct.rs
Expand Up @@ -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])
}
Expand Down
5 changes: 4 additions & 1 deletion src/librustc/hir/intravisit.rs
Expand Up @@ -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)
Expand Down
8 changes: 5 additions & 3 deletions src/librustc/hir/lowering.rs
Expand Up @@ -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(
Expand Down Expand Up @@ -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)))
}
Expand Down Expand Up @@ -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> {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/hir/mod.rs
Expand Up @@ -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>),
Expand Down
16 changes: 12 additions & 4 deletions src/librustc/hir/print.rs
Expand Up @@ -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 ")?;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)?;

Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ich/impls_hir.rs
Expand Up @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/expr_use_visitor.rs
Expand Up @@ -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);
}

Expand Down
4 changes: 3 additions & 1 deletion src/librustc/middle/liveness.rs
Expand Up @@ -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)
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/region.rs
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_lint/builtin.rs
Expand Up @@ -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");
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/hair/cx/expr.rs
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/transform/add_validation.rs
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_passes/rvalue_promotion.rs
Expand Up @@ -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
},
Expand Down Expand Up @@ -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(_) |
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_typeck/check/mod.rs
Expand Up @@ -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(..) => {}

Expand Down Expand Up @@ -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) => {
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/ast.rs
Expand Up @@ -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,
Expand Down Expand Up @@ -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>),

Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/build.rs
Expand Up @@ -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 {
Expand Down
5 changes: 4 additions & 1 deletion src/libsyntax/fold.rs
Expand Up @@ -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))
}
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/classify.rs
Expand Up @@ -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(..) |
Expand Down
22 changes: 15 additions & 7 deletions src/libsyntax/parse/parser.rs
Expand Up @@ -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()));
}
_ => {},
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down Expand Up @@ -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))?;
Expand All @@ -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
Expand Down Expand Up @@ -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())?
}
};

Expand All @@ -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()));
}
}

Expand Down
15 changes: 12 additions & 3 deletions src/libsyntax/print/pprust.rs
Expand Up @@ -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 ")?;
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -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)?;

Expand Down
5 changes: 4 additions & 1 deletion src/libsyntax/visit.rs
Expand Up @@ -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);
Expand Down

0 comments on commit 11f5893

Please sign in to comment.