Obliterate the callee_id hack

Exprs that could be applications of overloaded operators
(expr_unary, expr_binary, expr_index) relied on the previous node ID
being "reserved" to carry extra typechecking info. This was
incredibly error-prone. Fixed it; now all exprs have two node IDs
(which will be wasted in some cases; future work could make this
an option instead if the extra int field ends up being a performance
problem).

Closes #2804
This commit is contained in:
Tim Chevalier 2012-07-11 14:31:35 -07:00
parent fec8059ed5
commit 78ec6fe30c
21 changed files with 148 additions and 57 deletions

View file

@ -283,9 +283,11 @@ fn mk_test_desc_vec(cx: test_ctxt) -> @ast::expr {
}
let inner_expr = @{id: cx.sess.next_node_id(),
callee_id: cx.sess.next_node_id(),
node: ast::expr_vec(descs, ast::m_imm),
span: dummy_sp()};
ret @{id: cx.sess.next_node_id(),
callee_id: cx.sess.next_node_id(),
node: ast::expr_vstore(inner_expr, ast::vstore_uniq),
span: dummy_sp()};
}
@ -300,6 +302,7 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
nospan(ast::lit_str(@ast_util::path_name_i(path)));
let name_expr: ast::expr =
{id: cx.sess.next_node_id(),
callee_id: cx.sess.next_node_id(),
node: ast::expr_lit(@name_lit),
span: span};
@ -310,6 +313,7 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
let fn_expr: ast::expr =
{id: cx.sess.next_node_id(),
callee_id: cx.sess.next_node_id(),
node: ast::expr_path(fn_path),
span: span};
@ -322,6 +326,7 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
let ignore_expr: ast::expr =
{id: cx.sess.next_node_id(),
callee_id: cx.sess.next_node_id(),
node: ast::expr_lit(@ignore_lit),
span: span};
@ -332,6 +337,7 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
let fail_expr: ast::expr =
{id: cx.sess.next_node_id(),
callee_id: cx.sess.next_node_id(),
node: ast::expr_lit(@fail_lit),
span: span};
@ -342,7 +348,8 @@ fn mk_test_desc_rec(cx: test_ctxt, test: test) -> @ast::expr {
ast::expr_rec(~[name_field, fn_field, ignore_field, fail_field],
option::none);
let desc_rec: ast::expr =
{id: cx.sess.next_node_id(), node: desc_rec_, span: span};
{id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
node: desc_rec_, span: span};
ret @desc_rec;
}
@ -354,6 +361,7 @@ fn mk_test_wrapper(cx: test_ctxt,
span: span) -> @ast::expr {
let call_expr: ast::expr = {
id: cx.sess.next_node_id(),
callee_id: cx.sess.next_node_id(),
node: ast::expr_call(@fn_path_expr, ~[], false),
span: span
};
@ -379,6 +387,7 @@ fn mk_test_wrapper(cx: test_ctxt,
let wrapper_expr: ast::expr = {
id: cx.sess.next_node_id(),
callee_id: cx.sess.next_node_id(),
node: ast::expr_fn(ast::proto_bare, wrapper_decl,
wrapper_body, @~[]),
span: span
@ -444,7 +453,8 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
let args_path_expr_: ast::expr_ = ast::expr_path(args_path);
let args_path_expr: ast::expr =
{id: cx.sess.next_node_id(), node: args_path_expr_, span: dummy_sp()};
{id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
node: args_path_expr_, span: dummy_sp()};
// Call __test::test to generate the vector of test_descs
let test_path = path_node(~[@"tests"]);
@ -452,12 +462,14 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
let test_path_expr_: ast::expr_ = ast::expr_path(test_path);
let test_path_expr: ast::expr =
{id: cx.sess.next_node_id(), node: test_path_expr_, span: dummy_sp()};
{id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
node: test_path_expr_, span: dummy_sp()};
let test_call_expr_ = ast::expr_call(@test_path_expr, ~[], false);
let test_call_expr: ast::expr =
{id: cx.sess.next_node_id(), node: test_call_expr_, span: dummy_sp()};
{id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
node: test_call_expr_, span: dummy_sp()};
// Call std::test::test_main
let test_main_path = path_node(mk_path(cx, ~[@"test", @"test_main"]));
@ -465,16 +477,16 @@ fn mk_test_main_call(cx: test_ctxt) -> @ast::expr {
let test_main_path_expr_: ast::expr_ = ast::expr_path(test_main_path);
let test_main_path_expr: ast::expr =
{id: cx.sess.next_node_id(), node: test_main_path_expr_,
span: dummy_sp()};
{id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
node: test_main_path_expr_, span: dummy_sp()};
let test_main_call_expr_: ast::expr_ =
ast::expr_call(@test_main_path_expr,
~[@args_path_expr, @test_call_expr], false);
let test_main_call_expr: ast::expr =
{id: cx.sess.next_node_id(), node: test_main_call_expr_,
span: dummy_sp()};
{id: cx.sess.next_node_id(), callee_id: cx.sess.next_node_id(),
node: test_main_call_expr_, span: dummy_sp()};
ret @test_main_call_expr;
}

View file

@ -159,7 +159,6 @@ import std::list::{list, cons, nil};
import result::{result, ok, err, extensions};
import syntax::print::pprust;
import util::common::indenter;
import ast_util::op_expr_callee_id;
import ty::to_str;
import driver::session::session;
import dvec::{dvec, extensions};

View file

@ -616,7 +616,7 @@ fn check_loans_in_expr(expr: @ast::expr,
if self.bccx.method_map.contains_key(expr.id) {
self.check_call(expr,
none,
ast_util::op_expr_callee_id(expr),
expr.callee_id,
expr.span,
~[rval]);
}
@ -624,7 +624,7 @@ fn check_loans_in_expr(expr: @ast::expr,
if self.bccx.method_map.contains_key(expr.id) {
self.check_call(expr,
none,
ast_util::op_expr_callee_id(expr),
expr.callee_id,
expr.span,
~[]);
}

View file

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

View file

@ -1475,12 +1475,12 @@ fn trans_unary(bcx: block, op: ast::unop, e: @ast::expr,
// Check for user-defined method call
alt bcx.ccx().maps.method_map.find(un_expr.id) {
some(mentry) {
let callee_id = ast_util::op_expr_callee_id(un_expr);
let fty = node_id_type(bcx, callee_id);
let fty = node_id_type(bcx, un_expr.callee_id);
ret trans_call_inner(
bcx, un_expr.info(), fty,
expr_ty(bcx, un_expr),
|bcx| impl::trans_method_callee(bcx, callee_id, e, mentry),
|bcx| impl::trans_method_callee(bcx, un_expr.callee_id, e,
mentry),
arg_exprs(~[]), dest);
}
_ {}
@ -1703,10 +1703,9 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop,
alt bcx.ccx().maps.method_map.find(ex.id) {
some(origin) {
let bcx = lhs_res.bcx;
let callee_id = ast_util::op_expr_callee_id(ex);
#debug["user-defined method callee_id: %s",
ast_map::node_id_to_str(bcx.tcx().items, callee_id)];
let fty = node_id_type(bcx, callee_id);
ast_map::node_id_to_str(bcx.tcx().items, ex.callee_id)];
let fty = node_id_type(bcx, ex.callee_id);
let dty = expr_ty(bcx, dst);
let target = alloc_ty(bcx, dty);
@ -1717,7 +1716,7 @@ fn trans_assign_op(bcx: block, ex: @ast::expr, op: ast::binop,
|bcx| {
// FIXME (#2528): provide the already-computed address, not
// the expr.
impl::trans_method_callee(bcx, callee_id, dst, origin)
impl::trans_method_callee(bcx, ex.callee_id, dst, origin)
},
arg_exprs(~[src]), save_in(target));
@ -1851,13 +1850,12 @@ fn trans_binary(bcx: block, op: ast::binop, lhs: @ast::expr,
// User-defined operators
alt bcx.ccx().maps.method_map.find(ex.id) {
some(origin) {
let callee_id = ast_util::op_expr_callee_id(ex);
let fty = node_id_type(bcx, callee_id);
let fty = node_id_type(bcx, ex.callee_id);
ret trans_call_inner(
bcx, ex.info(), fty,
expr_ty(bcx, ex),
|bcx| {
impl::trans_method_callee(bcx, callee_id, lhs, origin)
impl::trans_method_callee(bcx, ex.callee_id, lhs, origin)
},
arg_exprs(~[rhs]), dest);
}
@ -3597,12 +3595,12 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
// If it is here, it's not an lval, so this is a user-defined
// index op
let origin = bcx.ccx().maps.method_map.get(e.id);
let callee_id = ast_util::op_expr_callee_id(e);
let fty = node_id_type(bcx, callee_id);
let fty = node_id_type(bcx, e.callee_id);
ret trans_call_inner(
bcx, e.info(), fty,
expr_ty(bcx, e),
|bcx| impl::trans_method_callee(bcx, callee_id, base, origin),
|bcx| impl::trans_method_callee(bcx, e.callee_id, base,
origin),
arg_exprs(~[idx]), dest);
}

View file

@ -893,13 +893,12 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
self_ex: @ast::expr, self_t: ty::t,
opname: str, args: ~[@ast::expr])
-> option<(ty::t, bool)> {
let callee_id = ast_util::op_expr_callee_id(op_ex);
let lkup = method::lookup(fcx, op_ex, self_ex, op_ex.id,
callee_id, @opname, self_t, ~[], false);
op_ex.callee_id, @opname, self_t, ~[], false);
alt lkup.method() {
some(origin) {
let {fty: method_ty, bot: bot} = {
let method_ty = fcx.node_ty(callee_id);
let method_ty = fcx.node_ty(op_ex.callee_id);
check_call_inner(fcx, op_ex.span, op_ex.id,
method_ty, args)
};
@ -1963,7 +1962,9 @@ fn check_constraints(fcx: @fn_ctxt, cs: ~[@ast::constr],
}
ast::carg_lit(l) {
let tmp_node_id = fcx.ccx.tcx.sess.next_node_id();
{id: tmp_node_id, node: ast::expr_lit(l), span: a.span}
{id: tmp_node_id,
callee_id: fcx.ccx.tcx.sess.next_node_id(),
node: ast::expr_lit(l), span: a.span}
}
ast::carg_ident(i) {
if i < num_args {
@ -1976,6 +1977,7 @@ fn check_constraints(fcx: @fn_ctxt, cs: ~[@ast::constr],
(arg_occ_node_id,
ast::def_arg(args[i].id, args[i].mode));
{id: arg_occ_node_id,
callee_id: fcx.ccx.tcx.sess.next_node_id(),
node: ast::expr_path(p),
span: a.span}
} else {
@ -1987,11 +1989,14 @@ fn check_constraints(fcx: @fn_ctxt, cs: ~[@ast::constr],
});
}
let p_op: ast::expr_ = ast::expr_path(c.node.path);
let oper: @ast::expr = @{id: c.node.id, node: p_op, span: c.span};
let oper: @ast::expr = @{id: c.node.id,
callee_id: fcx.ccx.tcx.sess.next_node_id(),
node: p_op, span: c.span};
// Another ephemeral expr
let call_expr_id = fcx.ccx.tcx.sess.next_node_id();
let call_expr =
@{id: call_expr_id,
callee_id: fcx.ccx.tcx.sess.next_node_id(),
node: ast::expr_call(oper, c_args, false),
span: c.span};
check_pred_expr(fcx, call_expr);

View file

@ -415,7 +415,7 @@ class lookup {
let all_substs = {tps: vec::append(cand.self_substs.tps, m_substs)
with cand.self_substs};
self.fcx.write_ty_substs(self.node_id, cand.fty, all_substs);
self.fcx.write_ty_substs(self.node_id, cand.fty, all_substs);
ret cand.entry;
}

View file

@ -233,7 +233,7 @@ fn resolve_expr(ex: @ast::expr, &&fcx: @fn_ctxt, v: visit::vt<@fn_ctxt>) {
if has_trait_bounds(*bounds) {
let callee_id = alt ex.node {
ast::expr_field(_, _, _) { ex.id }
_ { ast_util::op_expr_callee_id(ex) }
_ { ex.callee_id }
};
let substs = fcx.node_ty_substs(callee_id);
let iscs = cx.impl_map.get(ex.id);

View file

@ -105,8 +105,7 @@ fn visit_expr(e: @ast::expr, wbcx: wb_ctxt, v: wb_vt) {
ast::expr_binary(*) | ast::expr_unary(*) | ast::expr_assign_op(*)
| ast::expr_index(*) {
maybe_resolve_type_vars_for_node(wbcx, e.span,
ast_util::op_expr_callee_id(e));
maybe_resolve_type_vars_for_node(wbcx, e.span, e.callee_id);
}
_ { }