rustc: Perform type parameter substitutions when emitting glue for generic tags. Un-XFAIL generic-tag.rs.
This commit is contained in:
parent
88f0463c2b
commit
19b2850388
4 changed files with 56 additions and 32 deletions
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -1,3 +1,4 @@
|
|||
import std._int;
|
||||
import std._str;
|
||||
import std._uint;
|
||||
import std._vec;
|
||||
|
|
@ -61,7 +62,8 @@ type glue_fns = rec(ValueRef activate_glue,
|
|||
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_structural_ty(@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_structural_ty(@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 resolve_ty_params(ty_params_and_ty ty_params_and_polyty,
|
|||
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_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
|
|||
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 ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
|
|||
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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue