aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorPatrick Walton <[email protected]>2011-02-24 19:24:12 -0800
committerPatrick Walton <[email protected]>2011-02-24 19:25:05 -0800
commit19b2850388f634b500e612d8f24bbcb8c0fa2f3c (patch)
tree095312cd808b89226569f7bd4594b285e277d15a /src/comp
parentSupport the awful alt-else form in rustboot's cexp grammar, at least transien... (diff)
downloadrust-19b2850388f634b500e612d8f24bbcb8c0fa2f3c.tar.xz
rust-19b2850388f634b500e612d8f24bbcb8c0fa2f3c.zip
rustc: Perform type parameter substitutions when emitting glue for generic tags. Un-XFAIL generic-tag.rs.
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/middle/trans.rs21
-rw-r--r--src/comp/middle/ty.rs43
-rw-r--r--src/comp/middle/typeck.rs23
3 files changed, 56 insertions, 31 deletions
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index a3a1d83f..467aaa0d 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.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);
}
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 5535879e..02a7ffc2 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -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;
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 0d583c5e..40fd0f15 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -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;