rustc: Thread a self type through trans_impl; fix cross-crate trait issue

This commit is contained in:
Patrick Walton 2012-10-05 17:49:13 -07:00
parent d8287f0e41
commit 38aab8e400
3 changed files with 27 additions and 10 deletions

View File

@ -1848,19 +1848,25 @@ fn trans_item(ccx: @crate_ctxt, item: ast::item) {
}
}
ast::item_impl(tps, trait_refs, _, ms) => {
meth::trans_impl(ccx, *path, item.ident, ms, tps);
meth::trans_impl(ccx, *path, item.ident, ms, tps, None);
// Translate any methods that have provided implementations.
for trait_refs.each |trait_ref_ptr| {
let trait_def = ccx.tcx.def_map.get(trait_ref_ptr.ref_id);
// XXX: Cross-crate default methods.
match ccx.tcx.items.get(def_id_of_def(trait_def).node) {
let trait_id = def_id_of_def(trait_def);
if trait_id.crate != ast::local_crate {
loop;
}
match ccx.tcx.items.get(trait_id.node) {
ast_map::node_item(trait_item, _) => {
match trait_item.node {
ast::item_trait(tps, _, trait_methods) => {
// XXX: ty_self is wrong here. Get the real type.
trans_trait(ccx, tps, trait_methods, path,
item.ident);
item.ident, ty::mk_self(ccx.tcx));
}
_ => {
ccx.tcx.sess.impossible_case(item.span,
@ -1922,15 +1928,16 @@ fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
// If there are ty params, the ctor will get monomorphized
// Translate methods
meth::trans_impl(ccx, *path, ident, struct_def.methods, tps);
meth::trans_impl(ccx, *path, ident, struct_def.methods, tps, None);
}
fn trans_trait(ccx: @crate_ctxt, tps: ~[ast::ty_param],
trait_methods: ~[ast::trait_method],
path: @ast_map::path, ident: ast::ident) {
path: @ast_map::path, ident: ast::ident,
self_ty: ty::t) {
// Translate any methods that have provided implementations
let (_, provided_methods) = ast_util::split_trait_methods(trait_methods);
meth::trans_impl(ccx, *path, ident, provided_methods, tps);
meth::trans_impl(ccx, *path, ident, provided_methods, tps, Some(self_ty));
}
// Translate a module. Doing this amounts to translating the items in the

View File

@ -27,7 +27,8 @@ be generated once they are invoked with specific type parameters,
see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
*/
fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
methods: ~[@ast::method], tps: ~[ast::ty_param]) {
methods: ~[@ast::method], tps: ~[ast::ty_param],
self_ty: Option<ty::t>) {
let _icx = ccx.insn_ctxt("impl::trans_impl");
if tps.len() > 0u { return; }
let sub_path = vec::append_one(path, path_name(name));
@ -35,7 +36,7 @@ fn trans_impl(ccx: @crate_ctxt, path: path, name: ast::ident,
if method.tps.len() == 0u {
let llfn = get_item_val(ccx, method.id);
let path = vec::append_one(sub_path, path_name(method.ident));
trans_method(ccx, path, *method, None, llfn);
trans_method(ccx, path, *method, None, self_ty, llfn);
}
}
}
@ -49,12 +50,16 @@ Translates a (possibly monomorphized) method body.
- `method`: the AST node for the method
- `param_substs`: if this is a generic method, the current values for
type parameters and so forth, else none
- `base_self_ty`: optionally, the explicit self type for this method. This
will be none if this is not a default method and must always be present
if this is a default method.
- `llfn`: the LLVM ValueRef for the method
*/
fn trans_method(ccx: @crate_ctxt,
path: path,
method: &ast::method,
param_substs: Option<param_substs>,
base_self_ty: Option<ty::t>,
llfn: ValueRef) {
// figure out how self is being passed
@ -65,7 +70,11 @@ fn trans_method(ccx: @crate_ctxt,
_ => {
// determine the (monomorphized) type that `self` maps to for
// this method
let self_ty = ty::node_id_to_type(ccx.tcx, method.self_id);
let self_ty;
match base_self_ty {
None => self_ty = ty::node_id_to_type(ccx.tcx, method.self_id),
Some(provided_self_ty) => self_ty = provided_self_ty
}
let self_ty = match param_substs {
None => self_ty,
Some({tys: ref tys, _}) => ty::subst_tps(ccx.tcx, *tys, self_ty)

View File

@ -156,9 +156,10 @@ fn monomorphic_fn(ccx: @crate_ctxt,
d
}
ast_map::node_method(mth, _, _) => {
// XXX: What should the self type be here?
let d = mk_lldecl();
set_inline_hint_if_appr(mth.attrs, d);
meth::trans_method(ccx, pt, mth, psubsts, d);
meth::trans_method(ccx, pt, mth, psubsts, None, d);
d
}
ast_map::node_ctor(_, tps, ctor, parent_id, _) => {