Fix bug in method type parameter passing

It would occasionally pass the wrong type parameter, when calling
a generic method from a generic impl on a bounded param type.
This commit is contained in:
Marijn Haverbeke 2012-01-06 10:23:55 +01:00
parent 295df68faf
commit 7c1f683c6d
4 changed files with 19 additions and 5 deletions

View File

@ -55,7 +55,8 @@ fn trans_dict_callee(bcx: @block_ctxt, e: @ast::expr, base: @ast::expr,
let generic = none;
if vec::len(*method.tps) > 0u {
let tydescs = [], tis = [];
for t in ty::node_id_to_type_params(tcx, e.id) {
let tptys = ty::node_id_to_type_params(tcx, e.id);
for t in vec::tail_n(tptys, vec::len(tptys) - vec::len(*method.tps)) {
// TODO: Doesn't always escape.
let ti = none;
let td = get_tydesc(bcx, t, true, tps_normal, ti).result;

View File

@ -1037,8 +1037,8 @@ mod writeback {
};
let new_substs_opt;
alt tpot.substs {
none::<[ty::t]>. { new_substs_opt = none::<[ty::t]>; }
some::<[ty::t]>(substs) {
none. { new_substs_opt = none; }
some(substs) {
let new_substs: [ty::t] = [];
for subst: ty::t in substs {
alt resolve_type_vars_in_type(fcx, sp, subst) {
@ -1046,7 +1046,7 @@ mod writeback {
none. { wbcx.success = false; ret; }
}
}
new_substs_opt = some::<[ty::t]>(new_substs);
new_substs_opt = some(new_substs);
}
}
write::ty(fcx.ccx.tcx, id, {substs: new_substs_opt, ty: new_ty});
@ -1568,7 +1568,6 @@ fn lookup_method(fcx: @fn_ctxt, isc: resolve::iscopes,
}
bound_n += 1u;
}
_ {}
}
}
ret none;

View File

@ -195,6 +195,16 @@ fn tail<T: copy>(v: [const T]) : is_not_empty(v) -> [T] {
ret slice(v, 1u, len(v));
}
/*
Function tail_n
Returns all but the first N elements of a vector
*/
fn tail_n<T: copy>(v: [const T], n: uint) -> [T] {
slice(v, n, len(v))
}
// FIXME: This name is sort of confusing next to init_fn, etc
// but this is the name haskell uses for this function,
// along with head/tail/last.

View File

@ -9,6 +9,9 @@ impl of to_str for int {
impl of to_str for str {
fn to_str() -> str { self }
}
impl of to_str for () {
fn to_str() -> str { "()" }
}
iface map<T> {
fn map<U>(f: block(T) -> U) -> [U];
@ -32,4 +35,5 @@ fn main() {
assert foo([1]) == ["hi"];
assert bar::<int, [int]>([4, 5]) == ["4", "5"];
assert bar::<str, [str]>(["x", "y"]) == ["x", "y"];
assert bar::<(), [()]>([()]) == ["()"];
}