From 38aab8e40034ae21b7c801ae8532ec1f5ae5022d Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 5 Oct 2012 17:49:13 -0700 Subject: [PATCH] rustc: Thread a self type through trans_impl; fix cross-crate trait issue --- src/rustc/middle/trans/base.rs | 19 +++++++++++++------ src/rustc/middle/trans/meth.rs | 15 ++++++++++++--- src/rustc/middle/trans/monomorphize.rs | 3 ++- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index ce4ec72a582..24774add4dc 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -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 diff --git a/src/rustc/middle/trans/meth.rs b/src/rustc/middle/trans/meth.rs index 6710a64054d..65605f0e466 100644 --- a/src/rustc/middle/trans/meth.rs +++ b/src/rustc/middle/trans/meth.rs @@ -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) { 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, + base_self_ty: Option, 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) diff --git a/src/rustc/middle/trans/monomorphize.rs b/src/rustc/middle/trans/monomorphize.rs index cd8cffa297a..17eaf591c9f 100644 --- a/src/rustc/middle/trans/monomorphize.rs +++ b/src/rustc/middle/trans/monomorphize.rs @@ -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, _) => {