diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 9419b9f647e..6c0b5a2e8b1 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -243,12 +243,7 @@ type stmt = spanned; #[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] diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index c6fb9349ad5..568f00b0dfb 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -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 } } } diff --git a/src/libsyntax/ext/auto_serialize.rs b/src/libsyntax/ext/auto_serialize.rs index d2d685f8f7d..8685bce4c1b 100644 --- a/src/libsyntax/ext/auto_serialize.rs +++ b/src/libsyntax/ext/auto_serialize.rs @@ -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} } diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index c949c2e17aa..fd17403b695 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -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)) } }; } diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 9b36b77407e..4fcb761fa06 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -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; - } } } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 747ca07bee5..97185b6dfb9 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 5f2aada9fc6..171ad240635 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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, ";"); } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 48f2e57de1c..d2e5b1d1f21 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -320,7 +320,6 @@ fn visit_stmt(s: @stmt, e: E, v: vt) { 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); } } } diff --git a/src/rustc/front/test.rs b/src/rustc/front/test.rs index ce101a5ce4e..61b2816c2e6 100644 --- a/src/rustc/front/test.rs +++ b/src/rustc/front/test.rs @@ -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: ~[], diff --git a/src/rustc/middle/astencode.rs b/src/rustc/middle/astencode.rs index 3b9b4549817..5cc6e9881ae 100644 --- a/src/rustc/middle/astencode.rs +++ b/src/rustc/middle/astencode.rs @@ -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 } } diff --git a/src/rustc/middle/lint.rs b/src/rustc/middle/lint.rs index 3c8083e7f76..c3206bafd31 100644 --- a/src/rustc/middle/lint.rs +++ b/src/rustc/middle/lint.rs @@ -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( diff --git a/src/rustc/middle/liveness.rs b/src/rustc/middle/liveness.rs index fd6033c5b9d..fdd18a21a1d 100644 --- a/src/rustc/middle/liveness.rs +++ b/src/rustc/middle/liveness.rs @@ -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); } } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 457ffd8e401..a958079b327 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -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, _) { diff --git a/src/rustc/middle/tstate/annotate.rs b/src/rustc/middle/tstate/annotate.rs index e6beae9e014..9dd1157a56f 100644 --- a/src/rustc/middle/tstate/annotate.rs +++ b/src/rustc/middle/tstate/annotate.rs @@ -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); diff --git a/src/rustc/middle/tstate/auxiliary.rs b/src/rustc/middle/tstate/auxiliary.rs index d50e445482a..13d82cefe13 100644 --- a/src/rustc/middle/tstate/auxiliary.rs +++ b/src/rustc/middle/tstate/auxiliary.rs @@ -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); } } diff --git a/src/rustc/middle/tstate/pre_post_conditions.rs b/src/rustc/middle/tstate/pre_post_conditions.rs index 197ed4b3108..9f2e12cff2d 100644 --- a/src/rustc/middle/tstate/pre_post_conditions.rs +++ b/src/rustc/middle/tstate/pre_post_conditions.rs @@ -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); } diff --git a/src/rustc/middle/tstate/states.rs b/src/rustc/middle/tstate/states.rs index adf1efc8562..85b66dfd389 100644 --- a/src/rustc/middle/tstate/states.rs +++ b/src/rustc/middle/tstate/states.rs @@ -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)) | diff --git a/src/rustc/middle/ty.rs b/src/rustc/middle/ty.rs index c5ad6f9a00a..f60ede09cec 100644 --- a/src/rustc/middle/ty.rs +++ b/src/rustc/middle/ty.rs @@ -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; } } diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs index 08927d60fb8..0f0cb2903cb 100644 --- a/src/rustc/middle/typeck/check.rs +++ b/src/rustc/middle/typeck/check.rs @@ -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 } diff --git a/src/test/compile-fail/block-arg-as-stmt-with-value.rs b/src/test/run-pass/block-arg-as-stmt-with-value.rs similarity index 58% rename from src/test/compile-fail/block-arg-as-stmt-with-value.rs rename to src/test/run-pass/block-arg-as-stmt-with-value.rs index b8e34aefd6f..630c0c95511 100644 --- a/src/test/compile-fail/block-arg-as-stmt-with-value.rs +++ b/src/test/run-pass/block-arg-as-stmt-with-value.rs @@ -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); } diff --git a/src/test/run-pass/typed-statements-dont-need-semis.rs b/src/test/run-pass/typed-statements-dont-need-semis.rs new file mode 100644 index 00000000000..e2556f793af --- /dev/null +++ b/src/test/run-pass/typed-statements-dont-need-semis.rs @@ -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; +} \ No newline at end of file