提交 19b28503 编写于 作者: P Patrick Walton

rustc: Perform type parameter substitutions when emitting glue for generic...

rustc: Perform type parameter substitutions when emitting glue for generic tags. Un-XFAIL generic-tag.rs.
上级 88f0463c
......@@ -468,7 +468,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \
generic-recursive-tag.rs \
generic-tag-alt.rs \
generic-tag-values.rs \
generic-tag.rs \
integral-indexing.rs \
iter-range.rs \
iter-ret.rs \
......
import std._int;
import std._str;
import std._uint;
import std._vec;
......@@ -61,7 +62,8 @@ fn next(str prefix) -> str {
tag arity { nullary; n_ary; }
type tag_info = rec(type_handle th,
mutable vec[tup(ast.def_id,arity)] variants,
mutable uint size);
mutable uint size,
vec[ast.ty_param] ty_params);
state type crate_ctxt = rec(session.session sess,
ModuleRef llmod,
......@@ -1498,9 +1500,7 @@ fn iter_boxpp(@block_ctxt cx,
i += 1;
}
}
case (ty.ty_tag(?tid, _)) {
// TODO: type params!
case (ty.ty_tag(?tid, ?tps)) {
check (cx.fcx.ccx.tags.contains_key(tid));
auto info = cx.fcx.ccx.tags.get(tid);
auto n_variants = _vec.len[tup(ast.def_id,arity)](info.variants);
......@@ -1559,11 +1559,15 @@ fn iter_boxpp(@block_ctxt cx,
auto llfldp =
variant_cx.build.GEP(llvarp, v);
auto ty_subst = ty.substitute_ty_params(
info.ty_params, tps, a.ty);
auto llfld =
load_scalar_or_boxed(variant_cx,
llfldp, a.ty);
llfldp,
ty_subst);
auto res = f(variant_cx, llfld, a.ty);
auto res = f(variant_cx, llfld, ty_subst);
variant_cx = res.bcx;
j += 1u;
}
......@@ -4433,13 +4437,14 @@ fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt {
cx.items.insert(mid, i);
}
case (ast.item_tag(_, ?variants, _, ?tag_id)) {
case (ast.item_tag(_, ?variants, ?tps, ?tag_id)) {
auto vi = new_def_hash[uint]();
auto navi = new_def_hash[uint]();
let vec[tup(ast.def_id,arity)] variant_info = vec();
cx.tags.insert(tag_id, @rec(th=mk_type_handle(),
mutable variants=variant_info,
mutable size=0u));
mutable size=0u,
ty_params=tps));
cx.items.insert(tag_id, i);
}
......
......@@ -1450,7 +1450,7 @@ fn type_err_to_str(&ty.type_err err) -> str {
}
}
// Type parameter resolution, used in translation
// Type parameter resolution, used in translation and typechecking
fn resolve_ty_params(ty_params_and_ty ty_params_and_polyty,
@t monoty) -> vec[@t] {
......@@ -1492,6 +1492,47 @@ fn unify_actual_param(ast.def_id id, @t expected, @t actual)
ret result_tys;
}
// Performs type parameter replacement using the supplied mapping from
// parameter IDs to types.
fn replace_type_params(@t typ, hashmap[ast.def_id,@t] param_map) -> @t {
state obj param_replacer(hashmap[ast.def_id,@t] param_map) {
fn fold_simple_ty(@t typ) -> @t {
alt (typ.struct) {
case (ty_param(?param_def)) {
if (param_map.contains_key(param_def)) {
ret param_map.get(param_def);
} else {
ret typ;
}
}
case (_) {
ret typ;
}
}
}
}
auto replacer = param_replacer(param_map);
ret fold_ty(replacer, typ);
}
// Substitutes the type parameters specified by @ty_params with the
// corresponding types in @bound in the given type. The two vectors must have
// the same length.
fn substitute_ty_params(vec[ast.ty_param] ty_params, vec[@t] bound, @t ty)
-> @t {
auto ty_param_len = _vec.len[ast.ty_param](ty_params);
check (ty_param_len == _vec.len[@t](bound));
auto bindings = common.new_def_hash[@t]();
auto i = 0u;
while (i < ty_param_len) {
bindings.insert(ty_params.(i).id, bound.(i));
i += 1u;
}
ret replace_type_params(ty, bindings);
}
// Local Variables:
// mode: rust
// fill-column: 78;
......
......@@ -147,27 +147,6 @@ fn ast_arg_to_arg(ty_getter getter, &rec(ast.mode mode, @ast.ty ty) arg)
ret rec(mode=arg.mode, ty=ast_ty_to_ty(getter, arg.ty));
}
fn replace_type_params(@ty.t t, ty_table param_map) -> @ty.t {
state obj param_replacer(ty_table param_map) {
fn fold_simple_ty(@ty.t t) -> @ty.t {
alt (t.struct) {
case (ty.ty_param(?param_def)) {
if (param_map.contains_key(param_def)) {
ret param_map.get(param_def);
} else {
ret t;
}
}
case (_) {
ret t;
}
}
}
}
auto replacer = param_replacer(param_map);
ret ty.fold_ty(replacer, t);
}
fn instantiate(ty_getter getter, ast.def_id id,
vec[@ast.ty] args) -> @ty.t {
// TODO: maybe record cname chains so we can do
......@@ -183,7 +162,7 @@ fn instantiate(ty_getter getter, ast.def_id id,
auto param = params.(i);
param_map.insert(param.id, ast_ty_to_ty(getter, arg));
}
ret replace_type_params(ty_and_params.ty, param_map);
ret ty.replace_type_params(ty_and_params.ty, param_map);
}
auto mut = ast.imm;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册