Revert "Remove rule requiring non-nil block-style statements to be semi-terminated"

This reverts commit 0f5eaef5fb.
This commit is contained in:
Brian Anderson 2012-07-03 17:30:25 -07:00
parent e000d1db0a
commit ae6ea068a1
21 changed files with 35 additions and 32 deletions

View file

@ -243,7 +243,12 @@ type stmt = spanned<stmt_>;
#[auto_serialize] #[auto_serialize]
enum stmt_ { enum stmt_ {
stmt_decl(@decl, node_id), stmt_decl(@decl, node_id),
// expr without trailing semi-colon (must have unit type):
stmt_expr(@expr, node_id), stmt_expr(@expr, node_id),
// expr with trailing semi-colon (may have any type):
stmt_semi(@expr, node_id),
} }
#[auto_serialize] #[auto_serialize]

View file

@ -38,6 +38,7 @@ pure fn stmt_id(s: stmt) -> node_id {
alt s.node { alt s.node {
stmt_decl(_, id) { id } stmt_decl(_, id) { id }
stmt_expr(_, id) { id } stmt_expr(_, id) { id }
stmt_semi(_, id) { id }
} }
} }

View file

@ -206,7 +206,7 @@ impl helpers for ext_ctxt {
} }
fn stmt(expr: @ast::expr) -> @ast::stmt { fn stmt(expr: @ast::expr) -> @ast::stmt {
@{node: ast::stmt_expr(expr, self.next_id()), @{node: ast::stmt_semi(expr, self.next_id()),
span: expr.span} span: expr.span}
} }

View file

@ -315,6 +315,7 @@ fn noop_fold_stmt(s: stmt_, fld: ast_fold) -> stmt_ {
ret alt s { ret alt s {
stmt_decl(d, nid) { stmt_decl(fld.fold_decl(d), fld.new_id(nid)) } stmt_decl(d, nid) { stmt_decl(fld.fold_decl(d), fld.new_id(nid)) }
stmt_expr(e, nid) { stmt_expr(fld.fold_expr(e), fld.new_id(nid)) } stmt_expr(e, nid) { stmt_expr(fld.fold_expr(e), fld.new_id(nid)) }
stmt_semi(e, nid) { stmt_semi(fld.fold_expr(e), fld.new_id(nid)) }
}; };
} }

View file

@ -27,6 +27,9 @@ fn stmt_ends_with_semi(stmt: ast::stmt) -> bool {
ast::stmt_expr(e, _) { ast::stmt_expr(e, _) {
ret expr_requires_semi_to_be_stmt(e); ret expr_requires_semi_to_be_stmt(e);
} }
ast::stmt_semi(e, _) {
ret false;
}
} }
} }

View file

@ -1848,7 +1848,7 @@ class parser {
token::SEMI { token::SEMI {
self.bump(); self.bump();
push(stmts, push(stmts,
@{node: stmt_expr(e, stmt_id) with *stmt}); @{node: stmt_semi(e, stmt_id) with *stmt});
} }
token::RBRACE { token::RBRACE {
expr = some(e); expr = some(e);

View file

@ -682,9 +682,11 @@ fn print_stmt(s: ps, st: ast::stmt) {
ast::stmt_expr(expr, _) { ast::stmt_expr(expr, _) {
space_if_not_bol(s); space_if_not_bol(s);
print_expr(s, expr); print_expr(s, expr);
if expr_requires_semi_to_be_stmt(expr) { }
word(s.s, ";"); ast::stmt_semi(expr, _) {
} space_if_not_bol(s);
print_expr(s, expr);
word(s.s, ";");
} }
} }
if parse::classify::stmt_ends_with_semi(st) { word(s.s, ";"); } if parse::classify::stmt_ends_with_semi(st) { word(s.s, ";"); }

View file

@ -320,6 +320,7 @@ fn visit_stmt<E>(s: @stmt, e: E, v: vt<E>) {
alt s.node { alt s.node {
stmt_decl(d, _) { v.visit_decl(d, e, v); } stmt_decl(d, _) { v.visit_decl(d, e, v); }
stmt_expr(ex, _) { v.visit_expr(ex, e, v); } stmt_expr(ex, _) { v.visit_expr(ex, e, v); }
stmt_semi(ex, _) { v.visit_expr(ex, e, v); }
} }
} }

View file

@ -359,7 +359,7 @@ fn mk_test_wrapper(cx: test_ctxt,
}; };
let call_stmt: ast::stmt = nospan( let call_stmt: ast::stmt = nospan(
ast::stmt_expr(@call_expr, cx.sess.next_node_id())); ast::stmt_semi(@call_expr, cx.sess.next_node_id()));
let wrapper_decl: ast::fn_decl = { let wrapper_decl: ast::fn_decl = {
inputs: ~[], inputs: ~[],

View file

@ -229,7 +229,7 @@ fn simplify_ast(ii: ast::inlined_item) -> ast::inlined_item {
fn drop_nested_items(blk: ast::blk_, fld: fold::ast_fold) -> ast::blk_ { fn drop_nested_items(blk: ast::blk_, fld: fold::ast_fold) -> ast::blk_ {
let stmts_sans_items = do vec::filter(blk.stmts) |stmt| { let stmts_sans_items = do vec::filter(blk.stmts) |stmt| {
alt stmt.node { alt stmt.node {
ast::stmt_expr(_, _) | ast::stmt_expr(_, _) | ast::stmt_semi(_, _) |
ast::stmt_decl(@{node: ast::decl_local(_), span: _}, _) { true } ast::stmt_decl(@{node: ast::decl_local(_), span: _}, _) { true }
ast::stmt_decl(@{node: ast::decl_item(_), span: _}, _) { false } ast::stmt_decl(@{node: ast::decl_item(_), span: _}, _) { false }
} }

View file

@ -405,7 +405,7 @@ fn check_item_path_statement(cx: ty::ctxt, it: @ast::item) {
let visit = item_stopping_visitor(visit::mk_simple_visitor(@{ let visit = item_stopping_visitor(visit::mk_simple_visitor(@{
visit_stmt: fn@(s: @ast::stmt) { visit_stmt: fn@(s: @ast::stmt) {
alt s.node { alt s.node {
ast::stmt_expr(@{id: id, ast::stmt_semi(@{id: id,
node: ast::expr_path(@path), node: ast::expr_path(@path),
span: _}, _) { span: _}, _) {
cx.sess.span_lint( cx.sess.span_lint(

View file

@ -843,7 +843,7 @@ class liveness {
ret self.propagate_through_decl(decl, succ); ret self.propagate_through_decl(decl, succ);
} }
stmt_expr(expr, _) { stmt_expr(expr, _) | stmt_semi(expr, _) {
ret self.propagate_through_expr(expr, succ); ret self.propagate_through_expr(expr, succ);
} }
} }

View file

@ -4131,7 +4131,7 @@ fn trans_stmt(cx: block, s: ast::stmt) -> block {
debuginfo::update_source_pos(cx, s.span); debuginfo::update_source_pos(cx, s.span);
alt s.node { alt s.node {
ast::stmt_expr(e, _) { ast::stmt_expr(e, _) | ast::stmt_semi(e, _) {
bcx = trans_expr(cx, e, ignore); bcx = trans_expr(cx, e, ignore);
} }
ast::stmt_decl(d, _) { ast::stmt_decl(d, _) {

View file

@ -15,7 +15,7 @@ fn collect_ids_block(b: blk, rs: @mut ~[node_id]) {
fn collect_ids_stmt(s: @stmt, rs: @mut ~[node_id]) { fn collect_ids_stmt(s: @stmt, rs: @mut ~[node_id]) {
alt s.node { alt s.node {
stmt_decl(_, id) | stmt_expr(_, id) { stmt_decl(_, id) | stmt_expr(_, id) | stmt_semi(_, id) {
#debug["node_id %s", int::str(id)]; #debug["node_id %s", int::str(id)];
#debug["%s", stmt_to_str(*s)]; #debug["%s", stmt_to_str(*s)];
vec::push(*rs, id); vec::push(*rs, id);

View file

@ -278,7 +278,7 @@ fn node_id_to_poststate(ccx: crate_ctxt, id: node_id) -> poststate {
fn stmt_to_ann(ccx: crate_ctxt, s: stmt) -> ts_ann { fn stmt_to_ann(ccx: crate_ctxt, s: stmt) -> ts_ann {
#debug("stmt_to_ann"); #debug("stmt_to_ann");
alt s.node { alt s.node {
stmt_decl(_, id) | stmt_expr(_, id) { stmt_decl(_, id) | stmt_expr(_, id) | stmt_semi(_, id) {
ret node_id_to_ts_ann(ccx, id); ret node_id_to_ts_ann(ccx, id);
} }
} }

View file

@ -520,7 +520,7 @@ fn find_pre_post_stmt(fcx: fn_ctxt, s: stmt) {
} }
} }
} }
stmt_expr(e, id) { stmt_expr(e, id) | stmt_semi(e, id) {
find_pre_post_expr(fcx, e); find_pre_post_expr(fcx, e);
copy_pre_post(fcx.ccx, id, e); copy_pre_post(fcx.ccx, id, e);
} }

View file

@ -537,7 +537,7 @@ fn find_pre_post_state_stmt(fcx: fn_ctxt, pres: prestate, s: @stmt) -> bool {
} }
} }
} }
stmt_expr(ex, _) { stmt_expr(ex, _) | stmt_semi(ex, _) {
let mut changed = let mut changed =
find_pre_post_state_expr(fcx, pres, ex) | find_pre_post_state_expr(fcx, pres, ex) |
set_prestate(stmt_ann, expr_prestate(fcx.ccx, ex)) | set_prestate(stmt_ann, expr_prestate(fcx.ccx, ex)) |

View file

@ -2255,7 +2255,7 @@ fn expr_is_lval(method_map: typeck::method_map, e: @ast::expr) -> bool {
fn stmt_node_id(s: @ast::stmt) -> ast::node_id { fn stmt_node_id(s: @ast::stmt) -> ast::node_id {
alt s.node { alt s.node {
ast::stmt_decl(_, id) | stmt_expr(_, id) { ast::stmt_decl(_, id) | stmt_expr(_, id) | stmt_semi(_, id) {
ret id; ret id;
} }
} }

View file

@ -1718,6 +1718,10 @@ fn check_stmt(fcx: @fn_ctxt, stmt: @ast::stmt) -> bool {
} }
} }
ast::stmt_expr(expr, id) { ast::stmt_expr(expr, id) {
node_id = id;
bot = check_expr_with(fcx, expr, ty::mk_nil(fcx.ccx.tcx));
}
ast::stmt_semi(expr, id) {
node_id = id; node_id = id;
bot = check_expr(fcx, expr, none); bot = check_expr(fcx, expr, none);
} }
@ -1749,7 +1753,7 @@ fn check_block(fcx0: @fn_ctxt, blk: ast::blk) -> bool {
if bot && !warned && if bot && !warned &&
alt s.node { alt s.node {
ast::stmt_decl(@{node: ast::decl_local(_), _}, _) | ast::stmt_decl(@{node: ast::decl_local(_), _}, _) |
ast::stmt_expr(_, _) { ast::stmt_expr(_, _) | ast::stmt_semi(_, _) {
true true
} }
_ { false } _ { false }

View file

@ -2,13 +2,12 @@
fn compute1() -> float { fn compute1() -> float {
let v = ~[0f, 1f, 2f, 3f]; let v = ~[0f, 1f, 2f, 3f];
// This is actually a (block-style) statement followed by
// a unary tail expression
do vec::foldl(0f, v) |x, y| { x + y } - 10f do vec::foldl(0f, v) |x, y| { x + y } - 10f
//~^ ERROR mismatched types: expected `()`
} }
fn main() { fn main() {
let x = compute1(); let x = compute1();
log(debug, x); log(debug, x);
assert(x == -10f); assert(x == -4f);
} }

View file

@ -1,13 +0,0 @@
fn f(f: fn()) -> int {
f(); 0
}
fn main() {
// Testing that the old rule that statements (even control
// structures) that have non-nil type be semi-terminated _no
// longer_ is required
do f {
}
if true { 0 } else { 0 }
let _x = 0;
}