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

This is a subtle rule that no longer seems to be required.
This commit is contained in:
Brian Anderson 2012-07-03 16:06:09 -07:00
parent 3f59a4bc64
commit 0f5eaef5fb
21 changed files with 32 additions and 35 deletions

View File

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

View File

@ -38,7 +38,6 @@ pure fn stmt_id(s: stmt) -> node_id {
alt s.node {
stmt_decl(_, 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 {
@{node: ast::stmt_semi(expr, self.next_id()),
@{node: ast::stmt_expr(expr, self.next_id()),
span: expr.span}
}

View File

@ -315,7 +315,6 @@ fn noop_fold_stmt(s: stmt_, fld: ast_fold) -> stmt_ {
ret alt s {
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_semi(e, nid) { stmt_semi(fld.fold_expr(e), fld.new_id(nid)) }
};
}

View File

@ -27,9 +27,6 @@ fn stmt_ends_with_semi(stmt: ast::stmt) -> bool {
ast::stmt_expr(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 {
self.bump();
push(stmts,
@{node: stmt_semi(e, stmt_id) with *stmt});
@{node: stmt_expr(e, stmt_id) with *stmt});
}
token::RBRACE {
expr = some(e);

View File

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

View File

@ -320,7 +320,6 @@ fn visit_stmt<E>(s: @stmt, e: E, v: vt<E>) {
alt s.node {
stmt_decl(d, _) { v.visit_decl(d, 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(
ast::stmt_semi(@call_expr, cx.sess.next_node_id()));
ast::stmt_expr(@call_expr, cx.sess.next_node_id()));
let wrapper_decl: ast::fn_decl = {
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_ {
let stmts_sans_items = do vec::filter(blk.stmts) |stmt| {
alt stmt.node {
ast::stmt_expr(_, _) | ast::stmt_semi(_, _) |
ast::stmt_expr(_, _) |
ast::stmt_decl(@{node: ast::decl_local(_), span: _}, _) { true }
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(@{
visit_stmt: fn@(s: @ast::stmt) {
alt s.node {
ast::stmt_semi(@{id: id,
ast::stmt_expr(@{id: id,
node: ast::expr_path(@path),
span: _}, _) {
cx.sess.span_lint(

View File

@ -843,7 +843,7 @@ class liveness {
ret self.propagate_through_decl(decl, succ);
}
stmt_expr(expr, _) | stmt_semi(expr, _) {
stmt_expr(expr, _) {
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);
alt s.node {
ast::stmt_expr(e, _) | ast::stmt_semi(e, _) {
ast::stmt_expr(e, _) {
bcx = trans_expr(cx, e, ignore);
}
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]) {
alt s.node {
stmt_decl(_, id) | stmt_expr(_, id) | stmt_semi(_, id) {
stmt_decl(_, id) | stmt_expr(_, id) {
#debug["node_id %s", int::str(id)];
#debug["%s", stmt_to_str(*s)];
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 {
#debug("stmt_to_ann");
alt s.node {
stmt_decl(_, id) | stmt_expr(_, id) | stmt_semi(_, id) {
stmt_decl(_, id) | stmt_expr(_, 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_semi(e, id) {
stmt_expr(e, id) {
find_pre_post_expr(fcx, 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_semi(ex, _) {
stmt_expr(ex, _) {
let mut changed =
find_pre_post_state_expr(fcx, pres, 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 {
alt s.node {
ast::stmt_decl(_, id) | stmt_expr(_, id) | stmt_semi(_, id) {
ast::stmt_decl(_, id) | stmt_expr(_, id) {
ret id;
}
}

View File

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

View File

@ -2,12 +2,13 @@
fn compute1() -> float {
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
//~^ ERROR mismatched types: expected `()`
}
fn main() {
let x = compute1();
log(debug, x);
assert(x == -4f);
assert(x == -10f);
}

View File

@ -0,0 +1,13 @@
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;
}