Fix assumption that monomorphized method's impls are crate-local

This commit is contained in:
Marijn Haverbeke 2012-03-08 12:15:02 +01:00
parent 75e6fb4feb
commit 5e647d799e
5 changed files with 39 additions and 15 deletions

View File

@ -671,7 +671,6 @@ fn encode_side_tables_for_ii(ecx: @e::encode_ctxt,
fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
ebml_w: ebml::writer,
id: ast::node_id) {
let ccx = ecx.ccx;
let tcx = ccx.tcx;

View File

@ -17,6 +17,7 @@
export get_iface_methods;
export get_type;
export get_impl_iface;
export get_impl_method;
export get_item_path;
export maybe_get_item_ast;
@ -121,6 +122,12 @@ fn get_impl_iface(tcx: ty::ctxt, def: ast::def_id)
decoder::get_impl_iface(cdata, def.node, tcx)
}
fn get_impl_method(cstore: cstore::cstore, def: ast::def_id, mname: str)
-> ast::def_id {
let cdata = cstore::get_crate_data(cstore, def.crate);
decoder::get_impl_method(cdata, def.node, mname)
}
// Local Variables:
// mode: rust
// fill-column: 78;

View File

@ -19,6 +19,7 @@
export get_type;
export get_type_param_count;
export get_impl_iface;
export get_impl_method;
export lookup_def;
export lookup_item_name;
export get_impl_iface;
@ -256,6 +257,18 @@ fn get_impl_iface(cdata: cmd, id: ast::node_id, tcx: ty::ctxt)
item_impl_iface(lookup_item(id, cdata.data), tcx, cdata)
}
fn get_impl_method(cdata: cmd, id: ast::node_id, name: str) -> ast::def_id {
let items = ebml::get_doc(ebml::new_doc(cdata.data), tag_items);
let found = none;
ebml::tagged_docs(find_item(id, items), tag_item_method) {|mid|
let m_did = parse_def_id(ebml::doc_data(mid));
if item_name(find_item(m_did.node, items)) == name {
found = some(translate_def_id(cdata, m_did));
}
}
option::get(found)
}
fn get_symbol(data: @[u8], id: ast::node_id) -> str {
ret item_symbol(lookup_item(id, data));
}

View File

@ -468,7 +468,7 @@ fn should_inline(attrs: [attribute]) -> bool {
encode_name(ebml_w, m.ident);
encode_symbol(ecx, ebml_w, m.id);
encode_path(ebml_w, impl_path, ast_map::path_name(m.ident));
if should_inline(m.attrs) {
if tps.len() > 0u || m.tps.len() > 0u || should_inline(m.attrs) {
astencode::encode_inlined_item(
ecx, ebml_w, impl_path,
ii_method(local_def(item.id), m));

View File

@ -4,7 +4,8 @@
import type_of::*;
import build::*;
import driver::session::session;
import syntax::{ast, ast_util};
import syntax::ast;
import syntax::ast_util::local_def;
import metadata::csearch;
import back::{link, abi};
import lib::llvm::llvm;
@ -144,6 +145,19 @@ fn trans_vtable_callee(bcx: block, env: callee_env, dict: ValueRef,
generic: generic}
}
fn method_with_name(ccx: crate_ctxt, impl_id: ast::def_id,
name: ast::ident) -> ast::def_id {
if impl_id.crate == ast::local_crate {
alt check ccx.tcx.items.get(impl_id.node) {
ast_map::node_item(@{node: ast::item_impl(_, _, _, ms), _}, _) {
local_def(option::get(vec::find(ms, {|m| m.ident == name})).id)
}
}
} else {
csearch::get_impl_method(ccx.sess.cstore, impl_id, name)
}
}
fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
base: @ast::expr, iface_id: ast::def_id,
n_method: uint, n_param: uint, n_bound: uint,
@ -151,18 +165,9 @@ fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
alt find_dict_in_fn_ctxt(substs, n_param, n_bound) {
typeck::dict_static(impl_did, tys, sub_origins) {
let tcx = bcx.tcx();
if impl_did.crate != ast::local_crate {
ret trans_param_callee(bcx, callee_id, base, iface_id,
n_method, n_param, n_bound);
}
let mname = ty::iface_methods(tcx, iface_id)[n_method].ident;
let mth = alt check tcx.items.get(impl_did.node) {
ast_map::node_item(@{node: ast::item_impl(_, _, _, ms), _}, _) {
option::get(vec::find(ms, {|m| m.ident == mname}))
}
};
ret trans_static_callee(bcx, callee_id, base,
ast_util::local_def(mth.id),
let mth_id = method_with_name(bcx.ccx(), impl_did, mname);
ret trans_static_callee(bcx, callee_id, base, mth_id,
some((tys, sub_origins)));
}
typeck::dict_iface(iid) {
@ -378,7 +383,7 @@ fn trans_iface_wrapper(ccx: @crate_ctxt, pt: path, m: ty::method,
fn trans_iface_vtable(ccx: @crate_ctxt, pt: path, it: @ast::item) {
let new_pt = pt + [path_name(it.ident), path_name(int::str(it.id))];
let i_did = ast_util::local_def(it.id), i = 0u;
let i_did = local_def(it.id), i = 0u;
let ptrs = vec::map(*ty::iface_methods(ccx.tcx, i_did), {|m|
let w = trans_iface_wrapper(ccx, new_pt + [path_name(m.ident)], m, i);
i += 1u;