Properly replace iface tps with impl tps in static method calls
Un-xfail iface-generic.rs
This commit is contained in:
@@ -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
|
// The awkwardness below mostly stems from the fact that we're mixing
|
||||||
// monomorphized and non-monomorphized functions at the moment. If
|
// monomorphized and non-monomorphized functions at the moment. If
|
||||||
// monomorphizing becomes the only approach, this'll be much simpler.
|
// monomorphizing becomes the only approach, this'll be much simpler.
|
||||||
if (option::is_some(substs) || tys.len() > 0u) &&
|
if fn_id.crate == ast::local_crate {
|
||||||
fn_id.crate == ast::local_crate {
|
|
||||||
let mono = alt substs {
|
let mono = alt substs {
|
||||||
some((stys, vtables)) {
|
some((stys, vtables)) {
|
||||||
if (stys.len() + tys.len()) > 0u {
|
if stys.len() > 0u {
|
||||||
monomorphic_fn(ccx, fn_id, stys + tys, some(vtables))
|
monomorphic_fn(ccx, fn_id, stys, some(vtables))
|
||||||
} else { none }
|
} else { none }
|
||||||
}
|
}
|
||||||
none {
|
none {
|
||||||
@@ -2160,7 +2159,10 @@ fn lval_static_fn(bcx: block, fn_id: ast::def_id, id: ast::node_id,
|
|||||||
bcx.fcx, vtables);
|
bcx.fcx, vtables);
|
||||||
monomorphic_fn(ccx, fn_id, tys, some(rvtables))
|
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) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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,
|
fn trans_monomorphized_callee(bcx: block, callee_id: ast::node_id,
|
||||||
base: @ast::expr, iface_id: ast::def_id,
|
base: @ast::expr, iface_id: ast::def_id,
|
||||||
n_method: uint, n_param: uint, n_bound: uint,
|
n_method: uint, n_param: uint, n_bound: uint,
|
||||||
substs: param_substs) -> lval_maybe_callee {
|
substs: param_substs) -> lval_maybe_callee {
|
||||||
alt find_vtable_in_fn_ctxt(substs, n_param, n_bound) {
|
alt find_vtable_in_fn_ctxt(substs, n_param, n_bound) {
|
||||||
typeck::vtable_static(impl_did, tys, sub_origins) {
|
typeck::vtable_static(impl_did, impl_substs, sub_origins) {
|
||||||
let tcx = bcx.tcx();
|
let ccx = bcx.ccx();
|
||||||
let mname = ty::iface_methods(tcx, iface_id)[n_method].ident;
|
let mname = ty::iface_methods(ccx.tcx, iface_id)[n_method].ident;
|
||||||
let mth_id = method_with_name(bcx.ccx(), impl_did, mname);
|
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,
|
ret trans_static_callee(bcx, callee_id, base, mth_id,
|
||||||
some((tys, sub_origins)));
|
some((ty_substs, sub_origins)));
|
||||||
}
|
}
|
||||||
typeck::vtable_iface(iid, tps) {
|
typeck::vtable_iface(iid, tps) {
|
||||||
ret trans_iface_callee(bcx, base, callee_id, n_method);
|
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
|
// Vtables are stored in a flat array, finding the right one is
|
||||||
// somewhat awkward
|
// somewhat awkward
|
||||||
for bounds in *ps.bounds {
|
for bounds in *ps.bounds {
|
||||||
i += 1u;
|
|
||||||
if i >= n_param { break; }
|
if i >= n_param { break; }
|
||||||
for bound in *bounds {
|
for bound in *bounds {
|
||||||
alt bound { ty::bound_iface(_) { vtable_off += 1u; } _ {} }
|
alt bound { ty::bound_iface(_) { vtable_off += 1u; } _ {} }
|
||||||
}
|
}
|
||||||
|
i += 1u;
|
||||||
}
|
}
|
||||||
option::get(ps.vtables)[vtable_off]
|
option::get(ps.vtables)[vtable_off]
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user