about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-10-21 14:11:24 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-10-21 14:24:14 +0200
commit71147024962318033ade76ba741d1ecc1dfae3ce (patch)
tree42b750199d41f59916ac0542aa141fb254bd9be0
parent0ce40f60e79598c198851154cc978375ed5e7747 (diff)
Change the way block calls are parsed, mark them as block-calls.
This makes it possible to omit the semicolon after the block, and will
cause the pretty-printer to properly print such calls (if
pretty-printing of blocks wasn't so broken). Block calls (with the
block outside of the parentheses) can now only occur at statement
level, and their value can not be used. When calling a block-style
function that returns a useful value, the block must be put insde the
parentheses.

Issue #1054
-rw-r--r--src/comp/front/test.rs6
-rw-r--r--src/comp/middle/alias.rs4
-rw-r--r--src/comp/middle/fn_usage.rs2
-rw-r--r--src/comp/middle/kind.rs4
-rw-r--r--src/comp/middle/mut.rs2
-rw-r--r--src/comp/middle/trans.rs6
-rw-r--r--src/comp/middle/tstate/auxiliary.rs2
-rw-r--r--src/comp/middle/tstate/collect_locals.rs2
-rw-r--r--src/comp/middle/tstate/pre_post_conditions.rs2
-rw-r--r--src/comp/middle/tstate/states.rs2
-rw-r--r--src/comp/middle/typeck.rs6
-rw-r--r--src/comp/syntax/ast.rs2
-rw-r--r--src/comp/syntax/ast_util.rs2
-rw-r--r--src/comp/syntax/ext/fmt.rs2
-rw-r--r--src/comp/syntax/fold.rs5
-rw-r--r--src/comp/syntax/parse/parser.rs35
-rw-r--r--src/comp/syntax/print/pprust.rs16
-rw-r--r--src/comp/syntax/visit.rs2
18 files changed, 56 insertions, 46 deletions
diff --git a/src/comp/front/test.rs b/src/comp/front/test.rs
index fa48c9fbfb8..0def0979928 100644
--- a/src/comp/front/test.rs
+++ b/src/comp/front/test.rs
@@ -302,7 +302,7 @@ fn mk_test_wrapper(cx: test_ctxt,
                    span: span) -> @ast::expr {
     let call_expr: ast::expr = {
         id: cx.next_node_id(),
-        node: ast::expr_call(@fn_path_expr, []),
+        node: ast::expr_call(@fn_path_expr, [], false),
         span: span
     };
 
@@ -401,7 +401,7 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
     let test_path_expr: ast::expr =
         {id: cx.next_node_id(), node: test_path_expr_, span: dummy_sp()};
 
-    let test_call_expr_: ast::expr_ = ast::expr_call(@test_path_expr, []);
+    let test_call_expr_ = ast::expr_call(@test_path_expr, [], false);
 
     let test_call_expr: ast::expr =
         {id: cx.next_node_id(), node: test_call_expr_, span: dummy_sp()};
@@ -419,7 +419,7 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
 
     let test_main_call_expr_: ast::expr_ =
         ast::expr_call(@test_main_path_expr,
-                       [@args_path_expr, @test_call_expr]);
+                       [@args_path_expr, @test_call_expr], false);
 
     let test_main_call_expr: ast::expr =
         {id: cx.next_node_id(), node: test_main_call_expr_, span: dummy_sp()};
diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs
index 36f6d0f0017..5b96bddfe3f 100644
--- a/src/comp/middle/alias.rs
+++ b/src/comp/middle/alias.rs
@@ -93,7 +93,7 @@ fn visit_fn(cx: @ctx, f: ast::_fn, _tp: [ast::ty_param], sp: span,
 fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
     let handled = true;
     alt ex.node {
-      ast::expr_call(f, args) {
+      ast::expr_call(f, args, _) {
         check_call(*cx, f, args);
         handled = false;
       }
@@ -667,7 +667,7 @@ fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool)
     }
     if is_none(path_def_id(cx, base_root.ex)) {
         alt base_root.ex.node {
-          ast::expr_call(f, args) {
+          ast::expr_call(f, args, _) {
             let fty = ty::expr_ty(cx.tcx, f);
             alt ty::ty_fn_ret_style(cx.tcx, fty) {
               ast::return_ref(mut, arg_n) {
diff --git a/src/comp/middle/fn_usage.rs b/src/comp/middle/fn_usage.rs
index 3f6b2908c20..e7c3033ce1f 100644
--- a/src/comp/middle/fn_usage.rs
+++ b/src/comp/middle/fn_usage.rs
@@ -42,7 +42,7 @@ fn fn_usage_expr(expr: @ast::expr,
         }
       }
 
-      ast::expr_call(f, args) {
+      ast::expr_call(f, args, _) {
         let f_ctx = {unsafe_fn_legal: true,
                      generic_bare_fn_legal: true with ctx};
         v.visit_expr(f, f_ctx, v);
diff --git a/src/comp/middle/kind.rs b/src/comp/middle/kind.rs
index da908f55429..81032c6a91f 100644
--- a/src/comp/middle/kind.rs
+++ b/src/comp/middle/kind.rs
@@ -174,7 +174,7 @@ fn need_shared_or_pinned_ctor(tcx: ty::ctxt, a: @ast::expr, descr: str) {
     fn pinned_ctor(a: @ast::expr) -> bool {
         // FIXME: Technically a lambda block is also a pinned ctor
         alt a.node {
-          ast::expr_call(cexpr, _) {
+          ast::expr_call(cexpr, _, _) {
             // Assuming that if it's a call that it's safe to move in, mostly
             // because I don't know offhand how to ensure that it's a call
             // specifically to a resource constructor
@@ -224,7 +224,7 @@ fn check_expr(tcx: ty::ctxt, e: @ast::expr) {
       ast::expr_fail(option::some(a)) {
         need_expr_kind(tcx, a, ast::kind_shared, "'fail' operand");
       }
-      ast::expr_call(callee, _) {
+      ast::expr_call(callee, _, _) {
         let tpt = ty::expr_ty_params_and_ty(tcx, callee);
 
         // If we have typarams, we're calling an item; we need to check
diff --git a/src/comp/middle/mut.rs b/src/comp/middle/mut.rs
index 9dfddd2ae97..4c286e6cab4 100644
--- a/src/comp/middle/mut.rs
+++ b/src/comp/middle/mut.rs
@@ -150,7 +150,7 @@ fn visit_decl(cx: @ctx, d: @decl, &&e: (), v: visit::vt<()>) {
 
 fn visit_expr(cx: @ctx, ex: @expr, &&e: (), v: visit::vt<()>) {
     alt ex.node {
-      expr_call(f, args) { check_call(cx, f, args); }
+      expr_call(f, args, _) { check_call(cx, f, args); }
       expr_swap(lhs, rhs) {
         check_lval(cx, lhs, msg_assign);
         check_lval(cx, rhs, msg_assign);
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 6f9456dea2a..d47ee487341 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -3147,7 +3147,7 @@ fn expr_is_lval(tcx: ty::ctxt, e: @ast::expr) -> bool {
           ty::ty_rec(_) { true }
         }
       }
-      ast::expr_call(f, _) {
+      ast::expr_call(f, _, _) {
           let fty = ty::expr_ty(tcx, f);
           ast_util::ret_by_ref(ty::ty_fn_ret_style(tcx, fty))
       }
@@ -3198,7 +3198,7 @@ fn trans_lval(cx: @block_ctxt, e: @ast::expr) -> lval_result {
         ret lval_owned(sub.bcx, val);
       }
       // This is a by-ref returning call. Regular calls are not lval
-      ast::expr_call(f, args) {
+      ast::expr_call(f, args, _) {
         let cell = empty_dest_cell();
         let bcx = trans_call(cx, f, args, e.id, by_val(cell));
         ret lval_owned(bcx, *cell);
@@ -4175,7 +4175,7 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
       ast::expr_anon_obj(anon_obj) {
         ret trans_anon_obj(bcx, e.span, anon_obj, e.id, dest);
       }
-      ast::expr_call(f, args) {
+      ast::expr_call(f, args, _) {
         ret trans_call(bcx, f, args, e.id, dest);
       }
       ast::expr_field(_, _) {
diff --git a/src/comp/middle/tstate/auxiliary.rs b/src/comp/middle/tstate/auxiliary.rs
index 6ffd10c02bd..b8544e2b5ad 100644
--- a/src/comp/middle/tstate/auxiliary.rs
+++ b/src/comp/middle/tstate/auxiliary.rs
@@ -607,7 +607,7 @@ fn exprs_to_constr_args(tcx: ty::ctxt, args: [@expr]) -> [@constr_arg_use] {
 
 fn expr_to_constr(tcx: ty::ctxt, e: @expr) -> sp_constr {
     alt e.node {
-      expr_call(operator, args) {
+      expr_call(operator, args, _) {
         alt operator.node {
           expr_path(p) {
             ret respan(e.span,
diff --git a/src/comp/middle/tstate/collect_locals.rs b/src/comp/middle/tstate/collect_locals.rs
index 28d9c288aa7..b3c8d71a3bf 100644
--- a/src/comp/middle/tstate/collect_locals.rs
+++ b/src/comp/middle/tstate/collect_locals.rs
@@ -32,7 +32,7 @@ fn collect_pred(e: @expr, cx: ctxt, v: visit::vt<ctxt>) {
 
       // If it's a call, generate appropriate instances of the
       // call's constraints.
-      expr_call(operator, operands) {
+      expr_call(operator, operands, _) {
         for c: @ty::constr in constraints_expr(cx.tcx, operator) {
             let ct: sp_constr =
                 respan(c.span,
diff --git a/src/comp/middle/tstate/pre_post_conditions.rs b/src/comp/middle/tstate/pre_post_conditions.rs
index dee66e6df4d..d0832142d3e 100644
--- a/src/comp/middle/tstate/pre_post_conditions.rs
+++ b/src/comp/middle/tstate/pre_post_conditions.rs
@@ -309,7 +309,7 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
 
 
     alt e.node {
-      expr_call(operator, operands) {
+      expr_call(operator, operands, _) {
         /* copy */
 
         let args = operands;
diff --git a/src/comp/middle/tstate/states.rs b/src/comp/middle/tstate/states.rs
index 39f87f0f114..2af37f22867 100644
--- a/src/comp/middle/tstate/states.rs
+++ b/src/comp/middle/tstate/states.rs
@@ -335,7 +335,7 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
                                                     vec::len(elts)), elts,
                                       return_val);
       }
-      expr_call(operator, operands) {
+      expr_call(operator, operands, _) {
         ret find_pre_post_state_call(fcx, pres, operator, e.id,
                                      callee_arg_init_ops(fcx, operator.id),
                                      operands,
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 7e4c80d5a27..a20ab23f9f6 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -2072,7 +2072,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
                            out_args, rt, cf, constrs);
         write::ty_only_fixup(fcx, id, ft);
       }
-      ast::expr_call(f, args) {
+      ast::expr_call(f, args, _) {
         bot = check_call_full(fcx, expr.span, f, args, expr.id);
       }
       ast::expr_self_method(ident) {
@@ -2535,7 +2535,7 @@ fn check_pred_expr(fcx: @fn_ctxt, e: @ast::expr) -> bool {
     /* e must be a call expr where all arguments are either
     literals or slots */
     alt e.node {
-      ast::expr_call(operator, operands) {
+      ast::expr_call(operator, operands, _) {
         if !ty::is_pred_ty(fcx.ccx.tcx, expr_ty(fcx.ccx.tcx, operator)) {
             fcx.ccx.tcx.sess.span_err
                 (operator.span,
@@ -2632,7 +2632,7 @@ fn check_constraints(fcx: @fn_ctxt, cs: [@ast::constr], args: [ast::arg]) {
         let call_expr_id = fcx.ccx.tcx.sess.next_node_id();
         let call_expr =
             @{id: call_expr_id,
-              node: ast::expr_call(oper, c_args),
+              node: ast::expr_call(oper, c_args, false),
               span: c.span};
         check_pred_expr(fcx, call_expr);
     }
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index a971653c5f1..9abab553331 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -184,7 +184,7 @@ type expr = {id: node_id, node: expr_, span: span};
 tag expr_ {
     expr_vec([@expr], mutability);
     expr_rec([field], option::t<@expr>);
-    expr_call(@expr, [@expr]);
+    expr_call(@expr, [@expr], bool);
     expr_tup([@expr]);
     expr_self_method(ident);
     expr_bind(@expr, [option::t<@expr>]);
diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs
index 3d4fe27d980..b10ce87a697 100644
--- a/src/comp/syntax/ast_util.rs
+++ b/src/comp/syntax/ast_util.rs
@@ -163,7 +163,7 @@ fn is_exported(i: ident, m: _mod) -> bool {
 }
 
 pure fn is_call_expr(e: @expr) -> bool {
-    alt e.node { expr_call(_, _) { true } _ { false } }
+    alt e.node { expr_call(_, _, _) { true } _ { false } }
 }
 
 fn is_constraint_arg(e: @expr) -> bool {
diff --git a/src/comp/syntax/ext/fmt.rs b/src/comp/syntax/ext/fmt.rs
index b51db707daf..f3fb25acaf9 100644
--- a/src/comp/syntax/ext/fmt.rs
+++ b/src/comp/syntax/ext/fmt.rs
@@ -79,7 +79,7 @@ fn pieces_to_expr(cx: ext_ctxt, sp: span, pieces: [piece], args: [@ast::expr])
     fn make_call(cx: ext_ctxt, sp: span, fn_path: [ast::ident],
                  args: [@ast::expr]) -> @ast::expr {
         let pathexpr = make_path_expr(cx, sp, fn_path);
-        let callexpr = ast::expr_call(pathexpr, args);
+        let callexpr = ast::expr_call(pathexpr, args, false);
         ret @{id: cx.next_id(), node: callexpr, span: sp};
     }
     fn make_rec_expr(cx: ext_ctxt, sp: span,
diff --git a/src/comp/syntax/fold.rs b/src/comp/syntax/fold.rs
index 276967b792b..e79ca1adf98 100644
--- a/src/comp/syntax/fold.rs
+++ b/src/comp/syntax/fold.rs
@@ -348,8 +348,9 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
                      option::map(fld.fold_expr, maybe_expr))
           }
           expr_tup(elts) { expr_tup(vec::map(fld.fold_expr, elts)) }
-          expr_call(f, args) {
-            expr_call(fld.fold_expr(f), fld.map_exprs(fld.fold_expr, args))
+          expr_call(f, args, blk) {
+            expr_call(fld.fold_expr(f), fld.map_exprs(fld.fold_expr, args),
+                      blk)
           }
           expr_self_method(id) { expr_self_method(fld.fold_ident(id)) }
           expr_bind(f, args) {
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index 1a29a033f56..8f632165772 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -977,7 +977,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
             parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA),
                       parse_expr, p);
         hi = es.span.hi;
-        ex = ast::expr_call(f, es.node);
+        ex = ast::expr_call(f, es.node, false);
     } else if p.peek() == token::MOD_SEP ||
                   is_ident(p.peek()) && !is_word(p, "true") &&
                       !is_word(p, "false") {
@@ -1051,7 +1051,7 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
                 let es = parse_seq(token::LPAREN, token::RPAREN,
                                    some(token::COMMA), parse_expr, p);
                 hi = es.span.hi;
-                let nd = ast::expr_call(e, es.node);
+                let nd = ast::expr_call(e, es.node, false);
                 e = mk_expr(p, lo, hi, nd);
             }
           }
@@ -1073,19 +1073,6 @@ fn parse_dot_or_call_expr_with(p: parser, e: @ast::expr) -> @ast::expr {
               t { unexpected(p, t); }
             }
           }
-          token::LBRACE. when is_bar(p.look_ahead(1u)) {
-            p.bump();
-            let blk = parse_fn_block_expr(p);
-            alt e.node {
-              ast::expr_call(f, args) {
-                e = @{node: ast::expr_call(f, args + [blk]) with *e};
-              }
-              _ {
-                e = mk_expr(p, lo, p.get_last_hi_pos(),
-                            ast::expr_call(e, [blk]));
-              }
-            }
-          }
           _ { ret e; }
         }
     }
@@ -1569,7 +1556,6 @@ fn parse_source_stmt(p: parser) -> @ast::stmt {
         let decl = parse_let(p);
         ret @spanned(lo, decl.span.hi, ast::stmt_decl(decl, p.get_id()));
     } else {
-
         let item_attrs;
         alt parse_outer_attrs_or_ext(p) {
           none. { item_attrs = []; }
@@ -1589,7 +1575,6 @@ fn parse_source_stmt(p: parser) -> @ast::stmt {
             }
         }
 
-
         alt maybe_item {
           some(i) {
             let hi = i.span.hi;
@@ -1599,6 +1584,21 @@ fn parse_source_stmt(p: parser) -> @ast::stmt {
           none. {
             // Remainder are line-expr stmts.
             let e = parse_expr(p);
+            // See if it is a block call
+            if p.peek() == token::LBRACE && is_bar(p.look_ahead(1u)) {
+                p.bump();
+                let blk = parse_fn_block_expr(p);
+                alt e.node {
+                  ast::expr_call(f, args, false) {
+                    e = @{node: ast::expr_call(f, args + [blk], true)
+                        with *e};
+                  }
+                  _ {
+                    e = mk_expr(p, lo, p.get_last_hi_pos(),
+                                ast::expr_call(e, [blk], true));
+                  }
+                }
+            }
             ret @spanned(lo, e.span.hi, ast::stmt_expr(e, p.get_id()));
           }
           _ { p.fatal("expected statement"); }
@@ -1624,6 +1624,7 @@ fn expr_has_value(e: @ast::expr) -> bool {
       ast::expr_for(_, _, blk) | ast::expr_do_while(blk, _) {
         !option::is_none(blk.node.expr)
       }
+      ast::expr_call(_, _, true) { false }
       _ { true }
     }
 }
diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs
index 9a7944f47c8..91e3f2ffb59 100644
--- a/src/comp/syntax/print/pprust.rs
+++ b/src/comp/syntax/print/pprust.rs
@@ -727,11 +727,19 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
         commasep_exprs(s, inconsistent, exprs);
         pclose(s);
       }
-      ast::expr_call(func, args) {
+      ast::expr_call(func, args, has_block) {
         print_expr_parens_if_not_bot(s, func);
-        popen(s);
-        commasep_exprs(s, inconsistent, args);
-        pclose(s);
+        let base_args = args, blk = none;
+        if has_block { blk = some(vec::pop(base_args)); }
+        if !has_block || vec::len(base_args) > 0u {
+            popen(s);
+            commasep_exprs(s, inconsistent, base_args);
+            pclose(s);
+        }
+        if has_block {
+            nbsp(s);
+            print_expr(s, option::get(blk));
+        }
       }
       ast::expr_self_method(ident) {
         word(s.s, "self.");
diff --git a/src/comp/syntax/visit.rs b/src/comp/syntax/visit.rs
index 3cd44fe10da..0725611eb04 100644
--- a/src/comp/syntax/visit.rs
+++ b/src/comp/syntax/visit.rs
@@ -245,7 +245,7 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
         visit_expr_opt(base, e, v);
       }
       expr_tup(elts) { for el in elts { v.visit_expr(el, e, v); } }
-      expr_call(callee, args) {
+      expr_call(callee, args, _) {
         visit_exprs(args, e, v);
         v.visit_expr(callee, e, v);
       }