From 47f35c9d34b55d143e5368bd917c013afabeb5a8 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 9 Mar 2012 08:44:53 +0100 Subject: [PATCH] Properly replace iface tps with impl tps in static method calls Un-xfail iface-generic.rs --- src/rustc/middle/trans/base.rs | 12 +++++++----- src/rustc/middle/trans/impl.rs | 24 +++++++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index c3d2f886d42..ef4e17bb368 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -2145,12 +2145,11 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id, // The awkwardness below mostly stems from the fact that we're mixing // monomorphized and non-monomorphized functions at the moment. If // monomorphizing becomes the only approach, this'll be much simpler. - if (option::is_some(substs) || tys.len() > 0u) && - fn_id.crate == ast::local_crate { + if fn_id.crate == ast::local_crate { let mono = alt substs { some((stys, vtables)) { - if (stys.len() + tys.len()) > 0u { - monomorphic_fn(ccx, fn_id, stys + tys, some(vtables)) + if stys.len() > 0u { + monomorphic_fn(ccx, fn_id, stys, some(vtables)) } else { none } } none { @@ -2160,7 +2159,10 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id, bcx.fcx, vtables); monomorphic_fn(ccx, fn_id, tys, some(rvtables)) } - none { monomorphic_fn(ccx, fn_id, tys, none) } + none { + if tys.len() == 0u { none } + else { monomorphic_fn(ccx, fn_id, tys, none) } + } } } }; diff --git a/src/rustc/middle/trans/impl.rs b/src/rustc/middle/trans/impl.rs index 85ba984bed9..11242c02ca5 100644 --- a/src/rustc/middle/trans/impl.rs +++ b/src/rustc/middle/trans/impl.rs @@ -106,17 +106,31 @@ fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id, } } +fn method_ty_param_count(ccx: crate_ctxt, m_id: ast::def_id) -> uint { + if m_id.crate == ast::local_crate { + alt check ccx.tcx.items.get(m_id.node) { + ast_map::node_method(m, _, _) { vec::len(m.tps) } + } + } else { + csearch::get_type_param_count(ccx.sess.cstore, m_id) + } +} + 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, substs: param_substs) -> lval_maybe_callee { alt find_vtable_in_fn_ctxt(substs, n_param, n_bound) { - typeck::vtable_static(impl_did, tys, sub_origins) { - let tcx = bcx.tcx(); - let mname = ty::iface_methods(tcx, iface_id)[n_method].ident; + typeck::vtable_static(impl_did, impl_substs, sub_origins) { + let ccx = bcx.ccx(); + let mname = ty::iface_methods(ccx.tcx, iface_id)[n_method].ident; let mth_id = method_with_name(bcx.ccx(), impl_did, mname); + let n_m_tps = method_ty_param_count(ccx, mth_id); + let node_substs = node_id_type_params(bcx, callee_id); + let ty_substs = impl_substs + + vec::tail_n(node_substs, node_substs.len() - n_m_tps); ret trans_static_callee(bcx, callee_id, base, mth_id, - some((tys, sub_origins))); + some((ty_substs, sub_origins))); } typeck::vtable_iface(iid, tps) { ret trans_iface_callee(bcx, base, callee_id, n_method); @@ -155,11 +169,11 @@ fn find_vtable_in_fn_ctxt(ps: param_substs, n_param: uint, n_bound: uint) // Vtables are stored in a flat array, finding the right one is // somewhat awkward for bounds in *ps.bounds { - i += 1u; if i >= n_param { break; } for bound in *bounds { alt bound { ty::bound_iface(_) { vtable_off += 1u; } _ {} } } + i += 1u; } option::get(ps.vtables)[vtable_off] }