Skip to content

Commit

Permalink
Change the way block calls are parsed, mark them as block-calls.
Browse files Browse the repository at this point in the history
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
  • Loading branch information
marijnh committed Oct 21, 2011
1 parent 0ce40f6 commit 7114702
Show file tree
Hide file tree
Showing 18 changed files with 56 additions and 46 deletions.
6 changes: 3 additions & 3 deletions src/comp/front/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
};

Expand Down Expand Up @@ -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()};
Expand All @@ -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()};
Expand Down
4 changes: 2 additions & 2 deletions src/comp/middle/alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion src/comp/middle/fn_usage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions src/comp/middle/kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/comp/middle/mut.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 3 additions & 3 deletions src/comp/middle/trans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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(_, _) {
Expand Down
2 changes: 1 addition & 1 deletion src/comp/middle/tstate/auxiliary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/comp/middle/tstate/collect_locals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion src/comp/middle/tstate/pre_post_conditions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/comp/middle/tstate/states.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 3 additions & 3 deletions src/comp/middle/typeck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
Expand Down
2 changes: 1 addition & 1 deletion src/comp/syntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>]);
Expand Down
2 changes: 1 addition & 1 deletion src/comp/syntax/ast_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion src/comp/syntax/ext/fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 3 additions & 2 deletions src/comp/syntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
35 changes: 18 additions & 17 deletions src/comp/syntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand Down Expand Up @@ -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);
}
}
Expand All @@ -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; }
}
}
Expand Down Expand Up @@ -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 = []; }
Expand All @@ -1589,7 +1575,6 @@ fn parse_source_stmt(p: parser) -> @ast::stmt {
}
}


alt maybe_item {
some(i) {
let hi = i.span.hi;
Expand All @@ -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"); }
Expand All @@ -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 }
}
}
Expand Down
16 changes: 12 additions & 4 deletions src/comp/syntax/print/pprust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.");
Expand Down
2 changes: 1 addition & 1 deletion src/comp/syntax/visit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit 7114702

Please sign in to comment.