From 7c1f683c6d93cdb5fee8a664cd6b5ff2397e1d04 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 6 Jan 2012 10:23:55 +0100 Subject: [PATCH] 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. --- src/comp/middle/trans_impl.rs | 3 ++- src/comp/middle/typeck.rs | 7 +++---- src/libcore/vec.rs | 10 ++++++++++ src/test/run-pass/iface-generic.rs | 4 ++++ 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/comp/middle/trans_impl.rs b/src/comp/middle/trans_impl.rs index bddfbb03e6e4..6db94fba367e 100644 --- a/src/comp/middle/trans_impl.rs +++ b/src/comp/middle/trans_impl.rs @@ -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; diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 7037fa3ff30b..d75b04d07872 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -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; diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 32bb2f46a491..11dcce00d4cf 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -195,6 +195,16 @@ fn tail(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(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. diff --git a/src/test/run-pass/iface-generic.rs b/src/test/run-pass/iface-generic.rs index 07727035a28a..4ac80490b78d 100644 --- a/src/test/run-pass/iface-generic.rs +++ b/src/test/run-pass/iface-generic.rs @@ -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 { fn map(f: block(T) -> U) -> [U]; @@ -32,4 +35,5 @@ fn main() { assert foo([1]) == ["hi"]; assert bar::([4, 5]) == ["4", "5"]; assert bar::(["x", "y"]) == ["x", "y"]; + assert bar::<(), [()]>([()]) == ["()"]; }