Skip to content

Commit 982b830

Browse files
committed
---
yaml --- r: 4370 b: refs/heads/master c: 843767a h: refs/heads/master v: v3
1 parent 6a2a9f7 commit 982b830

File tree

4 files changed

+80
-3
lines changed

4 files changed

+80
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: ea81c03960264bf590cd99ed2b662243e3db7a7c
2+
refs/heads/master: 843767a841d49ce3c5005b9fd2705217af22d5d5

trunk/src/comp/syntax/print/pprust.rs

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,9 +595,16 @@ fn print_possibly_embedded_block(s: &ps, blk: &ast::blk, embedded: bool,
595595
let ann_node = node_block(s, blk);
596596
s.ann.pre(ann_node);
597597
if embedded { word(s.s, "#{"); end(s); } else { bopen(s); }
598-
for st: @ast::stmt in blk.node.stmts { print_stmt(s, *st) }
598+
599+
let last_stmt = option::none;
600+
for st: @ast::stmt in blk.node.stmts {
601+
maybe_protect_unop(s, last_stmt, stmt_(st));
602+
print_stmt(s, *st);
603+
last_stmt = option::some(st);
604+
}
599605
alt blk.node.expr {
600606
some(expr) {
607+
maybe_protect_unop(s, last_stmt, expr_(expr));
601608
space_if_not_bol(s);
602609
print_expr(s, expr);
603610
maybe_print_trailing_comment(s, expr.span, some(blk.span.hi));
@@ -606,6 +613,42 @@ fn print_possibly_embedded_block(s: &ps, blk: &ast::blk, embedded: bool,
606613
}
607614
bclose_(s, blk.span, indented);
608615
s.ann.post(ann_node);
616+
617+
tag expr_or_stmt { stmt_(@ast::stmt); expr_(@ast::expr); }
618+
619+
// The Rust syntax has an ambiguity when an if, alt, or block statement is
620+
// followed by a unary op statement. In those cases we have to add an
621+
// extra semi to make sure the unop is not parsed as a binop with the
622+
// if/alt/block expression.
623+
fn maybe_protect_unop(s: &ps, last: &option::t[@ast::stmt],
624+
next: &expr_or_stmt) {
625+
let last_expr_is_block = alt last {
626+
option::some(@{node: ast::stmt_expr(e, _), _}) {
627+
alt e.node {
628+
ast::expr_if(_ ,_ ,_)
629+
| ast::expr_alt(_, _)
630+
| ast::expr_block(_) { true }
631+
_ { false }
632+
}
633+
true
634+
}
635+
_ { false }
636+
};
637+
let next_expr_is_unnop = alt next {
638+
expr_(@{node: ast::expr_unary(_, _), _}) { true }
639+
stmt_(@{node: ast::stmt_expr(e, _), _}) {
640+
alt e.node {
641+
ast::expr_unary(_, _) { true }
642+
_ { false }
643+
}
644+
}
645+
_ { false }
646+
};
647+
648+
if last_expr_is_block && next_expr_is_unnop {
649+
word(s.s, ";");
650+
}
651+
}
609652
}
610653

611654
fn print_if(s: &ps, test: &@ast::expr, blk: &ast::blk,
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Preserve semicolons that disambiguate unops
2+
3+
fn f() { }
4+
5+
fn block_semi() -> int {
6+
{ f() };
7+
-1
8+
}
9+
10+
fn block_nosemi() -> int {
11+
{ 0 } - 1
12+
}
13+
14+
fn if_semi() -> int {
15+
if true { f() } else { f() };
16+
-1
17+
}
18+
19+
fn if_nosemi() -> int {
20+
if true { 0 } else { 0 } - 1
21+
}
22+
23+
fn alt_semi() -> int {
24+
alt true { true { f() } };
25+
-1
26+
}
27+
28+
fn alt_no_semi() -> int {
29+
alt true { true { 0 } } - 1
30+
}
31+
32+
fn stmt() {
33+
{ f() };
34+
-1;
35+
}

trunk/src/test/run-pass/block-expr-precedence.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// xfail-pretty
21
// no-reformat
32

43
/*

0 commit comments

Comments
 (0)