Skip to content

Commit

Permalink
Obliterate the callee_id hack
Browse files Browse the repository at this point in the history
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 rust-lang#2804
  • Loading branch information
catamorphism committed Jul 13, 2012
1 parent fec8059 commit 78ec6fe
Show file tree
Hide file tree
Showing 21 changed files with 148 additions and 57 deletions.
2 changes: 1 addition & 1 deletion src/fuzzer/fuzzer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ fn find_rust_files(&files: ~[str], path: str) {

fn common_exprs() -> ~[ast::expr] {
fn dse(e: ast::expr_) -> ast::expr {
{ id: 0, node: e, span: ast_util::dummy_sp() }
{ id: 0, callee_id: -1, node: e, span: ast_util::dummy_sp() }
}

fn dsl(l: ast::lit_) -> ast::lit {
Expand Down
3 changes: 2 additions & 1 deletion src/libsyntax/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,8 @@ enum blk_check_mode { default_blk, unchecked_blk, unsafe_blk, }
enum expr_check_mode { claimed_expr, checked_expr, }

#[auto_serialize]
type expr = {id: node_id, node: expr_, span: span};
type expr = {id: node_id, callee_id: node_id, node: expr_, span: span};
// Extra node ID is only used for index, assign_op, unary, binary

#[auto_serialize]
enum alt_mode { alt_check, alt_exhaustive, }
Expand Down
13 changes: 1 addition & 12 deletions src/libsyntax/ast_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,11 +272,6 @@ pure fn unguarded_pat(a: arm) -> option<~[@pat]> {
if is_unguarded(a) { some(/* FIXME (#2543) */ copy a.pats) } else { none }
}

// Provides an extra node_id to hang callee information on, in case the
// operator is deferred to a user-supplied method. The parser is responsible
// for reserving this id.
fn op_expr_callee_id(e: @expr) -> node_id { e.id - 1 }

pure fn class_item_ident(ci: @class_member) -> ident {
alt ci.node {
instance_var(i,_,_,_,_) { /* FIXME (#2543) */ copy i }
Expand Down Expand Up @@ -455,14 +450,8 @@ fn id_visitor(vfn: fn@(node_id)) -> visit::vt<()> {
},

visit_expr: fn@(e: @expr) {
vfn(e.callee_id);
vfn(e.id);
alt e.node {
expr_index(*) | expr_assign_op(*) |
expr_unary(*) | expr_binary(*) {
vfn(ast_util::op_expr_callee_id(e));
}
_ { /* fallthrough */ }
}
},

visit_ty: fn@(t: @ty) {
Expand Down
3 changes: 2 additions & 1 deletion src/libsyntax/ext/auto_serialize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ impl helpers for ext_ctxt {
}

fn expr(span: span, node: ast::expr_) -> @ast::expr {
@{id: self.next_id(), node: node, span: span}
@{id: self.next_id(), callee_id: self.next_id(),
node: node, span: span}
}

fn var_ref(span: span, name: ast::ident) -> @ast::expr {
Expand Down
7 changes: 4 additions & 3 deletions src/libsyntax/ext/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@ import base::ext_ctxt;

fn mk_expr(cx: ext_ctxt, sp: codemap::span, expr: ast::expr_) ->
@ast::expr {
ret @{id: cx.next_id(), node: expr, span: sp};
ret @{id: cx.next_id(), callee_id: cx.next_id(),
node: expr, span: sp};
}

fn mk_lit(cx: ext_ctxt, sp: span, lit: ast::lit_) -> @ast::expr {
let sp_lit = @{node: lit, span: sp};
ret @{id: cx.next_id(), node: ast::expr_lit(sp_lit), span: sp};
mk_expr(cx, sp, ast::expr_lit(sp_lit))
}
fn mk_str(cx: ext_ctxt, sp: span, s: str) -> @ast::expr {
let lit = ast::lit_str(@s);
Expand Down Expand Up @@ -62,7 +63,7 @@ fn mk_call(cx: ext_ctxt, sp: span, fn_path: ~[ast::ident],
fn mk_base_vec_e(cx: ext_ctxt, sp: span, exprs: ~[@ast::expr]) ->
@ast::expr {
let vecexpr = ast::expr_vec(exprs, ast::m_imm);
ret @{id: cx.next_id(), node: vecexpr, span: sp};
mk_expr(cx, sp, vecexpr)
}
fn mk_vstore_e(cx: ext_ctxt, sp: span, expr: @ast::expr, vst: ast::vstore) ->
@ast::expr {
Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/ext/concat_idents.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
}

ret @{id: cx.next_id(),
callee_id: cx.next_id(),
node: ast::expr_path(@{span: sp, global: false, idents: ~[@res],
rp: none, types: ~[]}),
span: sp};
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/ext/log_syntax.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ fn expand_syntax_ext(cx: ext_ctxt, sp: codemap::span, arg: ast::mac_arg,
);

//trivial expression
ret @{id: cx.next_id(), node: ast::expr_rec(~[], option::none),
span: sp};
ret @{id: cx.next_id(), callee_id: cx.next_id(),
node: ast::expr_rec(~[], option::none), span: sp};
}
2 changes: 1 addition & 1 deletion src/libsyntax/ext/simplext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import base::*;
import fold::*;
import ast_util::respan;
import ast::{ident, path, ty, blk_, expr, expr_path,
expr_vec, expr_mac, mac_invoc, node_id};
expr_vec, expr_mac, mac_invoc, node_id, expr_index};

export add_new_extension;

Expand Down
1 change: 1 addition & 0 deletions src/libsyntax/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -688,6 +688,7 @@ impl of ast_fold for ast_fold_precursor {
fn fold_expr(&&x: @expr) -> @expr {
let (n, s) = self.fold_expr(x.node, x.span, self as ast_fold);
ret @{id: self.new_id(x.id),
callee_id: self.new_id(x.callee_id),
node: n,
span: self.new_span(s)};
}
Expand Down
10 changes: 7 additions & 3 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import print::pprust::expr_to_str;

import result::result;
import either::{either, left, right};
import std::map::{hashmap, str_hash};
Expand Down Expand Up @@ -758,11 +760,13 @@ class parser {
}

fn mk_expr(lo: uint, hi: uint, +node: expr_) -> @expr {
ret @{id: self.get_id(), node: node, span: mk_sp(lo, hi)};
ret @{id: self.get_id(), callee_id: self.get_id(),
node: node, span: mk_sp(lo, hi)};
}

fn mk_mac_expr(lo: uint, hi: uint, m: mac_) -> @expr {
ret @{id: self.get_id(),
callee_id: self.get_id(),
node: expr_mac({node: m, span: mk_sp(lo, hi)}),
span: mk_sp(lo, hi)};
}
Expand All @@ -772,7 +776,8 @@ class parser {
let lv_lit = @{node: lit_uint(i as u64, ty_u32),
span: span};

ret @{id: self.get_id(), node: expr_lit(lv_lit), span: span};
ret @{id: self.get_id(), callee_id: self.get_id(),
node: expr_lit(lv_lit), span: span};
}

fn mk_pexpr(lo: uint, hi: uint, node: expr_) -> pexpr {
Expand Down Expand Up @@ -1112,7 +1117,6 @@ class parser {
let ix = self.parse_expr();
hi = ix.span.hi;
self.expect(token::RBRACKET);
self.get_id(); // see ast_util::op_expr_callee_id
e = self.mk_pexpr(lo, hi, expr_index(self.to_expr(e), ix));
}

Expand Down
28 changes: 20 additions & 8 deletions src/rustc/front/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()};
}
Expand All @@ -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};

Expand All @@ -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};

Expand All @@ -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};

Expand All @@ -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};

Expand All @@ -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;
}

Expand All @@ -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
};
Expand All @@ -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
Expand Down Expand Up @@ -444,37 +453,40 @@ 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"]);

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"]));

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;
}
Expand Down
1 change: 0 additions & 1 deletion src/rustc/middle/borrowck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down
4 changes: 2 additions & 2 deletions src/rustc/middle/borrowck/check_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -616,15 +616,15 @@ 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]);
}
ast::expr_unary(*) | ast::expr_index(*)
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,
~[]);
}
Expand Down
1 change: 1 addition & 0 deletions src/rustc/middle/lint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
24 changes: 11 additions & 13 deletions src/rustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
_ {}
Expand Down Expand Up @@ -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);
Expand All @@ -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));

Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
}

Expand Down
Loading

0 comments on commit 78ec6fe

Please sign in to comment.