rustc: Switch to indices for type parameters
This commit is contained in:
parent
e11e8754de
commit
de0175abed
9 changed files with 255 additions and 382 deletions
|
@ -17,7 +17,7 @@ type crate_num = int;
|
|||
type def_num = int;
|
||||
type def_id = tup(crate_num, def_num);
|
||||
|
||||
type ty_param = rec(ident ident, def_id id);
|
||||
type ty_param = ident;
|
||||
|
||||
// Annotations added during successive passes.
|
||||
tag ann {
|
||||
|
@ -39,7 +39,7 @@ tag def {
|
|||
def_upvar(def_id);
|
||||
def_variant(def_id /* tag */, def_id /* variant */);
|
||||
def_ty(def_id);
|
||||
def_ty_arg(def_id);
|
||||
def_ty_arg(uint);
|
||||
def_binding(def_id);
|
||||
def_use(def_id);
|
||||
def_native_ty(def_id);
|
||||
|
@ -59,7 +59,7 @@ fn def_id_of_def(def d) -> def_id {
|
|||
case (def_upvar(?id)) { ret id; }
|
||||
case (def_variant(_, ?id)) { ret id; }
|
||||
case (def_ty(?id)) { ret id; }
|
||||
case (def_ty_arg(?id)) { ret id; }
|
||||
case (def_ty_arg(_)) { fail; }
|
||||
case (def_binding(?id)) { ret id; }
|
||||
case (def_use(?id)) { ret id; }
|
||||
case (def_native_ty(?id)) { ret id; }
|
||||
|
|
|
@ -131,7 +131,7 @@ impure fn parse_sty(@pstate st, str_def sd) -> ty.sty {
|
|||
st.pos = st.pos + 1u;
|
||||
ret ty.ty_tag(def, params);
|
||||
}
|
||||
case ('p') {ret ty.ty_param(parse_def(st, sd));}
|
||||
case ('p') {ret ty.ty_param(parse_int(st) as uint);}
|
||||
case ('@') {ret ty.ty_box(parse_mt(st, sd));}
|
||||
case ('V') {ret ty.ty_vec(parse_mt(st, sd));}
|
||||
case ('P') {ret ty.ty_port(parse_ty(st, sd));}
|
||||
|
@ -351,14 +351,13 @@ fn item_type(&ebml.doc item, int this_cnum) -> @ty.t {
|
|||
ret parse_ty_str(s, bind parse_external_def_id(this_cnum, _));
|
||||
}
|
||||
|
||||
fn item_ty_params(&ebml.doc item, int this_cnum) -> vec[ast.def_id] {
|
||||
let vec[ast.def_id] params = vec();
|
||||
auto tp = metadata.tag_items_data_item_ty_param;
|
||||
fn item_ty_param_count(&ebml.doc item, int this_cnum) -> uint {
|
||||
let uint ty_param_count = 0u;
|
||||
auto tp = metadata.tag_items_data_item_ty_param_count;
|
||||
for each (ebml.doc p in ebml.tagged_docs(item, tp)) {
|
||||
auto ext = parse_def_id(ebml.doc_data(p));
|
||||
_vec.push[ast.def_id](params, tup(this_cnum, ext._1));
|
||||
ty_param_count = ebml.vint_at(ebml.doc_data(p), 0u)._0;
|
||||
}
|
||||
ret params;
|
||||
ret ty_param_count;
|
||||
}
|
||||
|
||||
fn tag_variant_ids(&ebml.doc item, int this_cnum) -> vec[ast.def_id] {
|
||||
|
@ -511,23 +510,23 @@ fn lookup_def(session.session sess, int cnum, vec[ast.ident] path)
|
|||
ret some[ast.def](def);
|
||||
}
|
||||
|
||||
fn get_type(session.session sess, ast.def_id def) -> ty.ty_params_opt_and_ty {
|
||||
fn get_type(session.session sess, ast.def_id def)
|
||||
-> ty.ty_param_count_and_ty {
|
||||
auto external_crate_id = def._0;
|
||||
auto data = sess.get_external_crate(external_crate_id);
|
||||
auto item = lookup_item(def._1, data);
|
||||
auto t = item_type(item, external_crate_id);
|
||||
|
||||
auto tps_opt;
|
||||
auto tp_count;
|
||||
auto kind_ch = item_kind(item);
|
||||
auto has_ty_params = kind_has_type_params(kind_ch);
|
||||
if (has_ty_params) {
|
||||
auto tps = item_ty_params(item, external_crate_id);
|
||||
tps_opt = some[vec[ast.def_id]](tps);
|
||||
tp_count = item_ty_param_count(item, external_crate_id);
|
||||
} else {
|
||||
tps_opt = none[vec[ast.def_id]];
|
||||
tp_count = 0u;
|
||||
}
|
||||
|
||||
ret tup(tps_opt, t);
|
||||
ret tup(tp_count, t);
|
||||
}
|
||||
|
||||
fn get_symbol(session.session sess, ast.def_id def) -> str {
|
||||
|
|
|
@ -1740,8 +1740,7 @@ impure fn parse_block(parser p) -> ast.block {
|
|||
}
|
||||
|
||||
impure fn parse_ty_param(parser p) -> ast.ty_param {
|
||||
auto ident = parse_ident(p);
|
||||
ret rec(ident=ident, id=p.next_def_id());
|
||||
ret parse_ident(p);
|
||||
}
|
||||
|
||||
impure fn parse_ty_params(parser p) -> vec[ast.ty_param] {
|
||||
|
|
|
@ -29,7 +29,7 @@ const uint tag_def_id = 0x07u;
|
|||
const uint tag_items_data = 0x08u;
|
||||
const uint tag_items_data_item = 0x09u;
|
||||
const uint tag_items_data_item_kind = 0x0au;
|
||||
const uint tag_items_data_item_ty_param = 0x0bu;
|
||||
const uint tag_items_data_item_ty_param_count = 0x0bu;
|
||||
const uint tag_items_data_item_type = 0x0cu;
|
||||
const uint tag_items_data_item_symbol = 0x0du;
|
||||
const uint tag_items_data_item_variant = 0x0eu;
|
||||
|
@ -134,7 +134,7 @@ fn sty_str(ty.sty st, def_str ds) -> str {
|
|||
}
|
||||
case (ty.ty_var(?id)) {ret "X" + common.istr(id);}
|
||||
case (ty.ty_native) {ret "E";}
|
||||
case (ty.ty_param(?def)) {ret "p" + ds(def) + "|";}
|
||||
case (ty.ty_param(?id)) {ret "p" + common.uistr(id);}
|
||||
case (ty.ty_type) {ret "Y";}
|
||||
}
|
||||
}
|
||||
|
@ -310,13 +310,10 @@ fn def_to_str(ast.def_id did) -> str {
|
|||
ret #fmt("%d:%d", did._0, did._1);
|
||||
}
|
||||
|
||||
// TODO: We need to encode the "crate numbers" somewhere for diamond imports.
|
||||
fn encode_type_params(&ebml.writer ebml_w, vec[ast.ty_param] tps) {
|
||||
for (ast.ty_param tp in tps) {
|
||||
ebml.start_tag(ebml_w, tag_items_data_item_ty_param);
|
||||
ebml_w.writer.write(_str.bytes(def_to_str(tp.id)));
|
||||
ebml.end_tag(ebml_w);
|
||||
}
|
||||
fn encode_type_param_count(&ebml.writer ebml_w, vec[ast.ty_param] tps) {
|
||||
ebml.start_tag(ebml_w, tag_items_data_item_ty_param_count);
|
||||
ebml.write_vint(ebml_w.writer, _vec.len[ast.ty_param](tps));
|
||||
ebml.end_tag(ebml_w);
|
||||
}
|
||||
|
||||
fn encode_variant_id(&ebml.writer ebml_w, ast.def_id vid) {
|
||||
|
@ -374,7 +371,7 @@ fn encode_tag_variant_info(@trans.crate_ctxt cx, &ebml.writer ebml_w,
|
|||
encode_symbol(cx, ebml_w, variant.node.id);
|
||||
}
|
||||
encode_discriminant(cx, ebml_w, variant.node.id);
|
||||
encode_type_params(ebml_w, ty_params);
|
||||
encode_type_param_count(ebml_w, ty_params);
|
||||
ebml.end_tag(ebml_w);
|
||||
}
|
||||
}
|
||||
|
@ -394,7 +391,7 @@ fn encode_info_for_item(@trans.crate_ctxt cx, &ebml.writer ebml_w,
|
|||
ebml.start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, did);
|
||||
encode_kind(ebml_w, 'f' as u8);
|
||||
encode_type_params(ebml_w, tps);
|
||||
encode_type_param_count(ebml_w, tps);
|
||||
encode_type(ebml_w, trans.node_ann_type(cx, ann));
|
||||
encode_symbol(cx, ebml_w, did);
|
||||
ebml.end_tag(ebml_w);
|
||||
|
@ -415,7 +412,7 @@ fn encode_info_for_item(@trans.crate_ctxt cx, &ebml.writer ebml_w,
|
|||
ebml.start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, did);
|
||||
encode_kind(ebml_w, 'y' as u8);
|
||||
encode_type_params(ebml_w, tps);
|
||||
encode_type_param_count(ebml_w, tps);
|
||||
encode_type(ebml_w, trans.node_ann_type(cx, ann));
|
||||
ebml.end_tag(ebml_w);
|
||||
}
|
||||
|
@ -423,7 +420,7 @@ fn encode_info_for_item(@trans.crate_ctxt cx, &ebml.writer ebml_w,
|
|||
ebml.start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, did);
|
||||
encode_kind(ebml_w, 't' as u8);
|
||||
encode_type_params(ebml_w, tps);
|
||||
encode_type_param_count(ebml_w, tps);
|
||||
encode_type(ebml_w, trans.node_ann_type(cx, ann));
|
||||
for (ast.variant v in variants) {
|
||||
encode_variant_id(ebml_w, v.node.id);
|
||||
|
@ -436,7 +433,7 @@ fn encode_info_for_item(@trans.crate_ctxt cx, &ebml.writer ebml_w,
|
|||
ebml.start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, odid.ctor);
|
||||
encode_kind(ebml_w, 'o' as u8);
|
||||
encode_type_params(ebml_w, tps);
|
||||
encode_type_param_count(ebml_w, tps);
|
||||
auto fn_ty = trans.node_ann_type(cx, ann);
|
||||
encode_type(ebml_w, fn_ty);
|
||||
encode_symbol(cx, ebml_w, odid.ctor);
|
||||
|
@ -445,7 +442,7 @@ fn encode_info_for_item(@trans.crate_ctxt cx, &ebml.writer ebml_w,
|
|||
ebml.start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, odid.ty);
|
||||
encode_kind(ebml_w, 'y' as u8);
|
||||
encode_type_params(ebml_w, tps);
|
||||
encode_type_param_count(ebml_w, tps);
|
||||
encode_type(ebml_w, ty.ty_fn_ret(fn_ty));
|
||||
ebml.end_tag(ebml_w);
|
||||
}
|
||||
|
@ -464,7 +461,7 @@ fn encode_info_for_native_item(@trans.crate_ctxt cx, &ebml.writer ebml_w,
|
|||
case (ast.native_item_fn(_, _, _, ?tps, ?did, ?ann)) {
|
||||
encode_def_id(ebml_w, did);
|
||||
encode_kind(ebml_w, 'F' as u8);
|
||||
encode_type_params(ebml_w, tps);
|
||||
encode_type_param_count(ebml_w, tps);
|
||||
encode_type(ebml_w, trans.node_ann_type(cx, ann));
|
||||
encode_symbol(cx, ebml_w, did);
|
||||
}
|
||||
|
|
|
@ -398,19 +398,22 @@ fn lookup_name_wrapped(&env e, ast.ident i, namespace ns)
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_fn_decl(ast.ident i, &ast.fn_decl decl,
|
||||
fn handle_fn_decl(ast.ident identifier, &ast.fn_decl decl,
|
||||
&vec[ast.ty_param] ty_params) -> option.t[def_wrap] {
|
||||
for (ast.arg a in decl.inputs) {
|
||||
if (_str.eq(a.ident, i)) {
|
||||
if (_str.eq(a.ident, identifier)) {
|
||||
auto t = ast.def_arg(a.id);
|
||||
ret some(def_wrap_other(t));
|
||||
}
|
||||
}
|
||||
|
||||
auto i = 0u;
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
if (_str.eq(tp.ident, i)) {
|
||||
auto t = ast.def_ty_arg(tp.id);
|
||||
if (_str.eq(tp, identifier)) {
|
||||
auto t = ast.def_ty_arg(i);
|
||||
ret some(def_wrap_other(t));
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
ret none[def_wrap];
|
||||
}
|
||||
|
@ -450,53 +453,60 @@ fn lookup_name_wrapped(&env e, ast.ident i, namespace ns)
|
|||
}
|
||||
}
|
||||
|
||||
fn in_scope(&session.session sess, ast.ident i, &scope s, namespace ns)
|
||||
-> option.t[def_wrap] {
|
||||
fn in_scope(&session.session sess, ast.ident identifier, &scope s,
|
||||
namespace ns) -> option.t[def_wrap] {
|
||||
alt (s) {
|
||||
|
||||
case (scope_crate(?c)) {
|
||||
ret check_mod(i, c.node.module, ns);
|
||||
ret check_mod(identifier, c.node.module, ns);
|
||||
}
|
||||
|
||||
case (scope_item(?it)) {
|
||||
alt (it.node) {
|
||||
case (ast.item_fn(_, ?f, ?ty_params, _, _)) {
|
||||
ret handle_fn_decl(i, f.decl, ty_params);
|
||||
ret handle_fn_decl(identifier, f.decl, ty_params);
|
||||
}
|
||||
case (ast.item_obj(_, ?ob, ?ty_params, _, _)) {
|
||||
for (ast.obj_field f in ob.fields) {
|
||||
if (_str.eq(f.ident, i)) {
|
||||
if (_str.eq(f.ident, identifier)) {
|
||||
auto t = ast.def_obj_field(f.id);
|
||||
ret some(def_wrap_other(t));
|
||||
}
|
||||
}
|
||||
|
||||
auto i = 0u;
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
if (_str.eq(tp.ident, i)) {
|
||||
auto t = ast.def_ty_arg(tp.id);
|
||||
if (_str.eq(tp, identifier)) {
|
||||
auto t = ast.def_ty_arg(i);
|
||||
ret some(def_wrap_other(t));
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
case (ast.item_tag(_,?variants,?ty_params,?tag_id,_)) {
|
||||
auto i = 0u;
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
if (_str.eq(tp.ident, i)) {
|
||||
auto t = ast.def_ty_arg(tp.id);
|
||||
if (_str.eq(tp, identifier)) {
|
||||
auto t = ast.def_ty_arg(i);
|
||||
ret some(def_wrap_other(t));
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
case (ast.item_mod(_, ?m, _)) {
|
||||
ret check_mod(i, m, ns);
|
||||
ret check_mod(identifier, m, ns);
|
||||
}
|
||||
case (ast.item_native_mod(_, ?m, _)) {
|
||||
ret check_native_mod(i, m);
|
||||
ret check_native_mod(identifier, m);
|
||||
}
|
||||
case (ast.item_ty(_, _, ?ty_params, _, _)) {
|
||||
auto i = 0u;
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
if (_str.eq(tp.ident, i)) {
|
||||
auto t = ast.def_ty_arg(tp.id);
|
||||
if (_str.eq(tp, identifier)) {
|
||||
auto t = ast.def_ty_arg(i);
|
||||
ret some(def_wrap_other(t));
|
||||
}
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
case (_) { /* fall through */ }
|
||||
|
@ -506,7 +516,7 @@ fn lookup_name_wrapped(&env e, ast.ident i, namespace ns)
|
|||
case (scope_native_item(?it)) {
|
||||
alt (it.node) {
|
||||
case (ast.native_item_fn(_, _, ?decl, ?ty_params, _, _)) {
|
||||
ret handle_fn_decl(i, decl, ty_params);
|
||||
ret handle_fn_decl(identifier, decl, ty_params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -518,7 +528,7 @@ fn lookup_name_wrapped(&env e, ast.ident i, namespace ns)
|
|||
case (scope_loop(?d)) {
|
||||
alt (d.node) {
|
||||
case (ast.decl_local(?local)) {
|
||||
if (_str.eq(local.ident, i)) {
|
||||
if (_str.eq(local.ident, identifier)) {
|
||||
auto lc = ast.def_local(local.id);
|
||||
ret some(def_wrap_other(lc));
|
||||
}
|
||||
|
@ -527,11 +537,11 @@ fn lookup_name_wrapped(&env e, ast.ident i, namespace ns)
|
|||
}
|
||||
|
||||
case (scope_block(?b)) {
|
||||
ret check_block(i, b.node, ns);
|
||||
ret check_block(identifier, b.node, ns);
|
||||
}
|
||||
|
||||
case (scope_arm(?a)) {
|
||||
alt (a.index.find(i)) {
|
||||
alt (a.index.find(identifier)) {
|
||||
case (some[ast.def_id](?did)) {
|
||||
auto t = ast.def_binding(did);
|
||||
ret some[def_wrap](def_wrap_other(t));
|
||||
|
|
|
@ -128,7 +128,8 @@ state type fn_ctxt = rec(ValueRef llfn,
|
|||
hashmap[ast.def_id, ValueRef] llobjfields,
|
||||
hashmap[ast.def_id, ValueRef] lllocals,
|
||||
hashmap[ast.def_id, ValueRef] llupvars,
|
||||
hashmap[ast.def_id, ValueRef] lltydescs,
|
||||
// FIXME: this should probably be just vec[ValueRef]
|
||||
hashmap[uint, ValueRef] lltydescs,
|
||||
@crate_ctxt ccx);
|
||||
|
||||
tag cleanup {
|
||||
|
@ -770,14 +771,11 @@ fn type_of_arg(@crate_ctxt cx, &ty.arg arg) -> TypeRef {
|
|||
ret typ;
|
||||
}
|
||||
|
||||
fn type_of_ty_params_opt_and_ty(@crate_ctxt ccx, ty.ty_params_opt_and_ty tpt)
|
||||
-> TypeRef {
|
||||
fn type_of_ty_param_count_and_ty(@crate_ctxt ccx,
|
||||
ty.ty_param_count_and_ty tpt) -> TypeRef {
|
||||
alt (tpt._1.struct) {
|
||||
case (ty.ty_fn(?proto, ?inputs, ?output)) {
|
||||
auto ty_params = option.get[vec[ast.def_id]](tpt._0);
|
||||
auto ty_param_count = _vec.len[ast.def_id](ty_params);
|
||||
auto llfnty = type_of_fn(ccx, proto, inputs, output,
|
||||
ty_param_count);
|
||||
auto llfnty = type_of_fn(ccx, proto, inputs, output, tpt._0);
|
||||
ret T_fn_pair(ccx.tn, llfnty);
|
||||
}
|
||||
case (_) {
|
||||
|
@ -1121,9 +1119,6 @@ fn static_size_of_tag(@crate_ctxt cx, @ty.t t) -> uint {
|
|||
}
|
||||
}
|
||||
|
||||
// Pull the type parameters out of the corresponding tag item.
|
||||
let vec[ast.def_id] ty_params = tag_ty_params(cx, tid);
|
||||
|
||||
// Compute max(variant sizes).
|
||||
auto max_size = 0u;
|
||||
auto variants = tag_variants(cx, tid);
|
||||
|
@ -1149,7 +1144,7 @@ fn static_size_of_tag(@crate_ctxt cx, @ty.t t) -> uint {
|
|||
auto tup_ty = ty.plain_tup_ty(args);
|
||||
|
||||
// Perform any type parameter substitutions.
|
||||
tup_ty = ty.substitute_ty_params(ty_params, subtys, tup_ty);
|
||||
tup_ty = ty.substitute_type_params(subtys, tup_ty);
|
||||
|
||||
// Here we possibly do a recursive call.
|
||||
auto this_size = llsize_of_real(cx, type_of(cx, tup_ty));
|
||||
|
@ -1215,14 +1210,13 @@ fn dynamic_size_of(@block_ctxt cx, @ty.t t) -> result {
|
|||
let ValueRef max_size = alloca(bcx, T_int());
|
||||
bcx.build.Store(C_int(0), max_size);
|
||||
|
||||
auto ty_params = tag_ty_params(bcx.fcx.ccx, tid);
|
||||
auto variants = tag_variants(bcx.fcx.ccx, tid);
|
||||
for (variant_info variant in variants) {
|
||||
// Perform type substitution on the raw argument types.
|
||||
let vec[@ty.t] raw_tys = variant.args;
|
||||
let vec[@ty.t] tys = vec();
|
||||
for (@ty.t raw_ty in raw_tys) {
|
||||
auto t = ty.substitute_ty_params(ty_params, tps, raw_ty);
|
||||
auto t = ty.substitute_type_params(tps, raw_ty);
|
||||
tys += vec(t);
|
||||
}
|
||||
|
||||
|
@ -1387,7 +1381,6 @@ fn GEP_tag(@block_ctxt cx,
|
|||
vec[@ty.t] ty_substs,
|
||||
int ix)
|
||||
-> result {
|
||||
auto ty_params = tag_ty_params(cx.fcx.ccx, tag_id);
|
||||
auto variant = tag_variant_with_id(cx.fcx.ccx, tag_id, variant_id);
|
||||
|
||||
// Synthesize a tuple type so that GEP_tup_like() can work its magic.
|
||||
|
@ -1397,7 +1390,7 @@ fn GEP_tag(@block_ctxt cx,
|
|||
auto i = 0;
|
||||
let vec[@ty.t] true_arg_tys = vec();
|
||||
for (@ty.t aty in arg_tys) {
|
||||
auto arg_ty = ty.substitute_ty_params(ty_params, ty_substs, aty);
|
||||
auto arg_ty = ty.substitute_type_params(ty_substs, aty);
|
||||
true_arg_tys += vec(arg_ty);
|
||||
if (i == ix) {
|
||||
elem_ty = arg_ty;
|
||||
|
@ -1466,23 +1459,23 @@ fn field_of_tydesc(@block_ctxt cx, @ty.t t, int field) -> result {
|
|||
}
|
||||
|
||||
// Given a type containing ty params, build a vector containing a ValueRef for
|
||||
// each of the ty params it uses (from the current frame), as well as a vec
|
||||
// containing a def_id for each such param. This is used solely for
|
||||
// each of the ty params it uses (from the current frame) and a vector of the
|
||||
// indices of the ty params present in the type. This is used solely for
|
||||
// constructing derived tydescs.
|
||||
fn linearize_ty_params(@block_ctxt cx, @ty.t t)
|
||||
-> tup(vec[ast.def_id], vec[ValueRef]) {
|
||||
fn linearize_ty_params(@block_ctxt cx, @ty.t t) ->
|
||||
tup(vec[uint], vec[ValueRef]) {
|
||||
let vec[ValueRef] param_vals = vec();
|
||||
let vec[ast.def_id] param_defs = vec();
|
||||
let vec[uint] param_defs = vec();
|
||||
type rr = rec(@block_ctxt cx,
|
||||
mutable vec[ValueRef] vals,
|
||||
mutable vec[ast.def_id] defs);
|
||||
mutable vec[uint] defs);
|
||||
|
||||
state obj folder(@rr r) {
|
||||
fn fold_simple_ty(@ty.t t) -> @ty.t {
|
||||
alt(t.struct) {
|
||||
case (ty.ty_param(?pid)) {
|
||||
let bool seen = false;
|
||||
for (ast.def_id d in r.defs) {
|
||||
for (uint d in r.defs) {
|
||||
if (d == pid) {
|
||||
seen = true;
|
||||
}
|
||||
|
@ -1511,11 +1504,11 @@ fn linearize_ty_params(@block_ctxt cx, @ty.t t)
|
|||
fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
|
||||
// Is the supplied type a type param? If so, return the passed-in tydesc.
|
||||
alt (ty.type_param(t)) {
|
||||
case (some[ast.def_id](?id)) {
|
||||
case (some[uint](?id)) {
|
||||
check (cx.fcx.lltydescs.contains_key(id));
|
||||
ret res(cx, cx.fcx.lltydescs.get(id));
|
||||
}
|
||||
case (none[ast.def_id]) { /* fall through */ }
|
||||
case (none[uint]) { /* fall through */ }
|
||||
}
|
||||
|
||||
// Does it contain a type param? If so, generate a derived tydesc.
|
||||
|
@ -1524,7 +1517,7 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
|
|||
if (ty.count_ty_params(t) > 0u) {
|
||||
auto tys = linearize_ty_params(cx, t);
|
||||
|
||||
check (n_params == _vec.len[ast.def_id](tys._0));
|
||||
check (n_params == _vec.len[uint](tys._0));
|
||||
check (n_params == _vec.len[ValueRef](tys._1));
|
||||
|
||||
if (!cx.fcx.ccx.tydescs.contains_key(t)) {
|
||||
|
@ -1566,9 +1559,9 @@ fn get_tydesc(&@block_ctxt cx, @ty.t t) -> result {
|
|||
|
||||
// Otherwise, generate a tydesc if necessary, and return it.
|
||||
if (!cx.fcx.ccx.tydescs.contains_key(t)) {
|
||||
let vec[ast.def_id] defs = vec();
|
||||
let vec[uint] tps = vec();
|
||||
declare_tydesc(cx.fcx.ccx, t);
|
||||
define_tydesc(cx.fcx.ccx, t, defs);
|
||||
define_tydesc(cx.fcx.ccx, t, tps);
|
||||
}
|
||||
ret res(cx, cx.fcx.ccx.tydescs.get(t).tydesc);
|
||||
}
|
||||
|
@ -1624,16 +1617,14 @@ fn declare_tydesc(@crate_ctxt cx, @ty.t t) {
|
|||
}
|
||||
|
||||
// declare_tydesc() above must have been called first.
|
||||
fn define_tydesc(@crate_ctxt cx, @ty.t t, vec[ast.def_id] typaram_defs) {
|
||||
fn define_tydesc(@crate_ctxt cx, @ty.t t, vec[uint] ty_params) {
|
||||
auto info = cx.tydescs.get(t);
|
||||
auto gvar = info.tydesc;
|
||||
|
||||
auto tg = make_take_glue;
|
||||
auto take_glue = make_generic_glue(cx, t, info.take_glue, tg,
|
||||
typaram_defs);
|
||||
auto take_glue = make_generic_glue(cx, t, info.take_glue, tg, ty_params);
|
||||
auto dg = make_drop_glue;
|
||||
auto drop_glue = make_generic_glue(cx, t, info.drop_glue, dg,
|
||||
typaram_defs);
|
||||
auto drop_glue = make_generic_glue(cx, t, info.drop_glue, dg, ty_params);
|
||||
}
|
||||
|
||||
fn declare_generic_glue(@crate_ctxt cx, @ty.t t, str name) -> ValueRef {
|
||||
|
@ -1647,8 +1638,7 @@ fn declare_generic_glue(@crate_ctxt cx, @ty.t t, str name) -> ValueRef {
|
|||
}
|
||||
|
||||
fn make_generic_glue(@crate_ctxt cx, @ty.t t, ValueRef llfn,
|
||||
val_and_ty_fn helper,
|
||||
vec[ast.def_id] typaram_defs) -> ValueRef {
|
||||
val_and_ty_fn helper, vec[uint] ty_params) -> ValueRef {
|
||||
auto fcx = new_fn_ctxt(cx, llfn);
|
||||
auto bcx = new_top_block_ctxt(fcx);
|
||||
auto lltop = bcx.llbb;
|
||||
|
@ -1668,13 +1658,15 @@ fn make_generic_glue(@crate_ctxt cx, @ty.t t, ValueRef llfn,
|
|||
llty = T_ptr(type_of(cx, t));
|
||||
}
|
||||
|
||||
auto ty_param_count = _vec.len[uint](ty_params);
|
||||
|
||||
auto lltyparams = llvm.LLVMGetParam(llfn, 3u);
|
||||
auto p = 0;
|
||||
for (ast.def_id d in typaram_defs) {
|
||||
auto llparam = bcx.build.GEP(lltyparams, vec(C_int(p)));
|
||||
auto p = 0u;
|
||||
while (p < ty_param_count) {
|
||||
auto llparam = bcx.build.GEP(lltyparams, vec(C_int(p as int)));
|
||||
llparam = bcx.build.Load(llparam);
|
||||
bcx.fcx.lltydescs.insert(d, llparam);
|
||||
p += 1;
|
||||
bcx.fcx.lltydescs.insert(ty_params.(p), llparam);
|
||||
p += 1u;
|
||||
}
|
||||
|
||||
auto llrawptr = llvm.LLVMGetParam(llfn, 4u);
|
||||
|
@ -1928,11 +1920,6 @@ fn decr_refcnt_and_if_zero(@block_ctxt cx,
|
|||
|
||||
// Tag information
|
||||
|
||||
// Returns the type parameters of a tag.
|
||||
fn tag_ty_params(@crate_ctxt cx, ast.def_id id) -> vec[ast.def_id] {
|
||||
ret ty.lookup_generic_item_type(cx.sess, cx.type_cache, id)._0;
|
||||
}
|
||||
|
||||
type variant_info = rec(vec[@ty.t] args, @ty.t ctor_ty, ast.def_id id);
|
||||
|
||||
// Returns information about the variants in a tag.
|
||||
|
@ -2105,8 +2092,6 @@ fn iter_structural_ty_full(@block_ctxt cx,
|
|||
|
||||
auto next_cx = new_sub_block_ctxt(bcx, "tag-iter-next");
|
||||
|
||||
auto ty_params = tag_ty_params(bcx.fcx.ccx, tid);
|
||||
|
||||
auto i = 0u;
|
||||
for (variant_info variant in variants) {
|
||||
auto variant_cx = new_sub_block_ctxt(bcx,
|
||||
|
@ -2133,8 +2118,8 @@ fn iter_structural_ty_full(@block_ctxt cx,
|
|||
auto llfldp_b = rslt.val;
|
||||
variant_cx = rslt.bcx;
|
||||
|
||||
auto ty_subst = ty.substitute_ty_params(
|
||||
ty_params, tps, a.ty);
|
||||
auto ty_subst =
|
||||
ty.substitute_type_params(tps, a.ty);
|
||||
|
||||
auto llfld_a =
|
||||
load_if_immediate(variant_cx,
|
||||
|
@ -3642,16 +3627,16 @@ fn lval_val(@block_ctxt cx, ValueRef val) -> lval_result {
|
|||
}
|
||||
|
||||
fn trans_external_path(@block_ctxt cx, ast.def_id did,
|
||||
ty.ty_params_opt_and_ty tpt) -> lval_result {
|
||||
ty.ty_param_count_and_ty tpt) -> lval_result {
|
||||
auto ccx = cx.fcx.ccx;
|
||||
auto name = creader.get_symbol(ccx.sess, did);
|
||||
auto v = get_extern_const(ccx.externs, ccx.llmod,
|
||||
name, type_of_ty_params_opt_and_ty(ccx, tpt));
|
||||
name, type_of_ty_param_count_and_ty(ccx, tpt));
|
||||
ret lval_val(cx, v);
|
||||
}
|
||||
|
||||
fn lval_generic_fn(@block_ctxt cx,
|
||||
ty.ty_params_and_ty tpt,
|
||||
ty.ty_param_count_and_ty tpt,
|
||||
ast.def_id fn_id,
|
||||
&ast.ann ann)
|
||||
-> lval_result {
|
||||
|
@ -3662,12 +3647,11 @@ fn lval_generic_fn(@block_ctxt cx,
|
|||
lv = lval_val(cx, cx.fcx.ccx.fn_pairs.get(fn_id));
|
||||
} else {
|
||||
// External reference.
|
||||
auto tpot = tup(some[vec[ast.def_id]](tpt._0), tpt._1);
|
||||
lv = trans_external_path(cx, fn_id, tpot);
|
||||
lv = trans_external_path(cx, fn_id, tpt);
|
||||
}
|
||||
|
||||
auto monoty;
|
||||
auto tys;
|
||||
let vec[@ty.t] tys;
|
||||
alt (ann) {
|
||||
case (ast.ann_none) {
|
||||
cx.fcx.ccx.sess.bug("no type annotation for path!");
|
||||
|
@ -3750,17 +3734,17 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
|
|||
ret lval_mem(cx, cx.fcx.llobjfields.get(did));
|
||||
}
|
||||
case (ast.def_fn(?did)) {
|
||||
auto tyt = ty.lookup_generic_item_type(cx.fcx.ccx.sess,
|
||||
auto tyt = ty.lookup_item_type(cx.fcx.ccx.sess,
|
||||
cx.fcx.ccx.type_cache, did);
|
||||
ret lval_generic_fn(cx, tyt, did, ann);
|
||||
}
|
||||
case (ast.def_obj(?did)) {
|
||||
auto tyt = ty.lookup_generic_item_type(cx.fcx.ccx.sess,
|
||||
auto tyt = ty.lookup_item_type(cx.fcx.ccx.sess,
|
||||
cx.fcx.ccx.type_cache, did);
|
||||
ret lval_generic_fn(cx, tyt, did, ann);
|
||||
}
|
||||
case (ast.def_variant(?tid, ?vid)) {
|
||||
auto v_tyt = ty.lookup_generic_item_type(cx.fcx.ccx.sess,
|
||||
auto v_tyt = ty.lookup_item_type(cx.fcx.ccx.sess,
|
||||
cx.fcx.ccx.type_cache, vid);
|
||||
alt (v_tyt._1.struct) {
|
||||
case (ty.ty_fn(_, _, _)) {
|
||||
|
@ -3801,7 +3785,7 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
|
|||
ret lval_mem(cx, cx.fcx.ccx.consts.get(did));
|
||||
}
|
||||
case (ast.def_native_fn(?did)) {
|
||||
auto tyt = ty.lookup_generic_item_type(cx.fcx.ccx.sess,
|
||||
auto tyt = ty.lookup_item_type(cx.fcx.ccx.sess,
|
||||
cx.fcx.ccx.type_cache, did);
|
||||
ret lval_generic_fn(cx, tyt, did, ann);
|
||||
}
|
||||
|
@ -5500,7 +5484,7 @@ fn new_fn_ctxt(@crate_ctxt cx,
|
|||
let hashmap[ast.def_id, ValueRef] llobjfields = new_def_hash[ValueRef]();
|
||||
let hashmap[ast.def_id, ValueRef] lllocals = new_def_hash[ValueRef]();
|
||||
let hashmap[ast.def_id, ValueRef] llupvars = new_def_hash[ValueRef]();
|
||||
let hashmap[ast.def_id, ValueRef] lltydescs = new_def_hash[ValueRef]();
|
||||
let hashmap[uint, ValueRef] lltydescs = common.new_uint_hash[ValueRef]();
|
||||
|
||||
let BasicBlockRef llallocas =
|
||||
llvm.LLVMAppendBasicBlock(llfndecl, _str.buf("allocas"));
|
||||
|
@ -5541,11 +5525,13 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx,
|
|||
cx.llself = some[self_vt](rec(v = cx.llenv, t = tt._1));
|
||||
}
|
||||
case (none[tup(TypeRef, @ty.t)]) {
|
||||
auto i = 0u;
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
auto llarg = llvm.LLVMGetParam(cx.llfn, arg_n);
|
||||
check (llarg as int != 0);
|
||||
cx.lltydescs.insert(tp.id, llarg);
|
||||
cx.lltydescs.insert(i, llarg);
|
||||
arg_n += 1u;
|
||||
i += 1u;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5695,7 +5681,7 @@ fn populate_fn_ctxt_from_llself(@fn_ctxt fcx, self_vt llself) {
|
|||
vec(C_int(0),
|
||||
C_int(i)));
|
||||
lltyparam = bcx.build.Load(lltyparam);
|
||||
fcx.lltydescs.insert(p.id, lltyparam);
|
||||
fcx.lltydescs.insert(i as uint, lltyparam);
|
||||
i += 1;
|
||||
}
|
||||
|
||||
|
@ -5889,7 +5875,7 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
|
|||
bcx = body_typarams.bcx;
|
||||
let int i = 0;
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
auto typaram = bcx.fcx.lltydescs.get(tp.id);
|
||||
auto typaram = bcx.fcx.lltydescs.get(i as uint);
|
||||
auto capture = GEP_tup_like(bcx, typarams_ty, body_typarams.val,
|
||||
vec(0, i));
|
||||
bcx = capture.bcx;
|
||||
|
@ -5951,8 +5937,10 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
|
|||
fn_args, ty_params);
|
||||
|
||||
let vec[@ty.t] ty_param_substs = vec();
|
||||
i = 0u;
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
ty_param_substs += vec(plain_ty(ty.ty_param(tp.id)));
|
||||
ty_param_substs += vec(plain_ty(ty.ty_param(i)));
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
auto arg_tys = arg_tys_of_fn(variant.node.ann);
|
||||
|
@ -6905,7 +6893,7 @@ fn trans_vec_append_glue(@crate_ctxt cx) {
|
|||
llobjfields=new_def_hash[ValueRef](),
|
||||
lllocals=new_def_hash[ValueRef](),
|
||||
llupvars=new_def_hash[ValueRef](),
|
||||
lltydescs=new_def_hash[ValueRef](),
|
||||
lltydescs=common.new_uint_hash[ValueRef](),
|
||||
ccx=cx);
|
||||
|
||||
auto bcx = new_top_block_ctxt(fcx);
|
||||
|
|
|
@ -57,7 +57,7 @@ tag sty {
|
|||
ty_obj(vec[method]);
|
||||
ty_var(int); // ephemeral type var
|
||||
ty_local(ast.def_id); // type of a local var
|
||||
ty_param(ast.def_id); // fn/tag type param
|
||||
ty_param(uint); // fn/tag type param
|
||||
ty_type;
|
||||
ty_native;
|
||||
// TODO: ty_fn_arg(@t), for a possibly-aliased function argument
|
||||
|
@ -68,10 +68,8 @@ tag sty {
|
|||
type unify_handler = obj {
|
||||
fn resolve_local(ast.def_id id) -> @t;
|
||||
fn record_local(ast.def_id id, @t ty);
|
||||
fn unify_expected_param(ast.def_id id, @t expected, @t actual)
|
||||
-> unify_result;
|
||||
fn unify_actual_param(ast.def_id id, @t expected, @t actual)
|
||||
-> unify_result;
|
||||
fn unify_expected_param(uint id, @t expected, @t actual) -> unify_result;
|
||||
fn unify_actual_param(uint id, @t expected, @t actual) -> unify_result;
|
||||
};
|
||||
|
||||
tag type_err {
|
||||
|
@ -94,8 +92,8 @@ tag unify_result {
|
|||
}
|
||||
|
||||
|
||||
type ty_params_opt_and_ty = tup(option.t[vec[ast.def_id]], @ty.t);
|
||||
type type_cache = hashmap[ast.def_id,ty_params_opt_and_ty];
|
||||
type ty_param_count_and_ty = tup(uint, @t);
|
||||
type type_cache = hashmap[ast.def_id,ty_param_count_and_ty];
|
||||
|
||||
|
||||
// Stringification
|
||||
|
@ -248,8 +246,7 @@ fn ty_to_str(&@t typ) -> str {
|
|||
}
|
||||
|
||||
case (ty_param(?id)) {
|
||||
s += "<P" + util.common.istr(id._0) + ":" +
|
||||
util.common.istr(id._1) + ">";
|
||||
s += "'" + _str.unsafe_from_bytes(vec(('a' as u8) + (id as u8)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -558,12 +555,12 @@ fn type_is_signed(@t ty) -> bool {
|
|||
fail;
|
||||
}
|
||||
|
||||
fn type_param(@t ty) -> option.t[ast.def_id] {
|
||||
fn type_param(@t ty) -> option.t[uint] {
|
||||
alt (ty.struct) {
|
||||
case (ty_param(?id)) { ret some[ast.def_id](id); }
|
||||
case (_) { /* fall through */ }
|
||||
case (ty_param(?id)) { ret some[uint](id); }
|
||||
case (_) { /* fall through */ }
|
||||
}
|
||||
ret none[ast.def_id];
|
||||
ret none[uint];
|
||||
}
|
||||
|
||||
fn plain_ty(&sty st) -> @t {
|
||||
|
@ -605,18 +602,21 @@ fn ann_to_type(&ast.ann ann) -> @t {
|
|||
}
|
||||
}
|
||||
|
||||
// Returns the number of distinct type parameters in the given type.
|
||||
fn count_ty_params(@t ty) -> uint {
|
||||
state obj ty_param_counter(@mutable vec[ast.def_id] param_ids) {
|
||||
state obj ty_param_counter(@mutable vec[uint] param_indices) {
|
||||
fn fold_simple_ty(@t ty) -> @t {
|
||||
alt (ty.struct) {
|
||||
case (ty_param(?param_id)) {
|
||||
for (ast.def_id other_param_id in *param_ids) {
|
||||
if (param_id._0 == other_param_id._0 &&
|
||||
param_id._1 == other_param_id._1) {
|
||||
ret ty;
|
||||
case (ty_param(?param_idx)) {
|
||||
auto seen = false;
|
||||
for (uint other_param_idx in *param_indices) {
|
||||
if (param_idx == other_param_idx) {
|
||||
seen = true;
|
||||
}
|
||||
}
|
||||
*param_ids += vec(param_id);
|
||||
if (!seen) {
|
||||
*param_indices += vec(param_idx);
|
||||
}
|
||||
}
|
||||
case (_) { /* fall through */ }
|
||||
}
|
||||
|
@ -624,10 +624,10 @@ fn count_ty_params(@t ty) -> uint {
|
|||
}
|
||||
}
|
||||
|
||||
let vec[ast.def_id] param_ids_inner = vec();
|
||||
let @mutable vec[ast.def_id] param_ids = @mutable param_ids_inner;
|
||||
fold_ty(ty_param_counter(param_ids), ty);
|
||||
ret _vec.len[ast.def_id](*param_ids);
|
||||
let vec[uint] v = vec(); // FIXME: typechecker botch
|
||||
let @mutable vec[uint] param_indices = @mutable v;
|
||||
fold_ty(ty_param_counter(param_indices), ty);
|
||||
ret _vec.len[uint](*param_indices);
|
||||
}
|
||||
|
||||
// Type accessors for substructures of types
|
||||
|
@ -674,59 +674,50 @@ fn is_fn_ty(@t fty) -> bool {
|
|||
|
||||
// Type accessors for AST nodes
|
||||
|
||||
// Given an item, returns the associated type as well as a list of the IDs of
|
||||
// its type parameters.
|
||||
type ty_params_and_ty = tup(vec[ast.def_id], @t);
|
||||
fn native_item_ty(@ast.native_item it) -> ty_params_and_ty {
|
||||
auto ty_params;
|
||||
// Given an item, returns the associated type as well as the number of type
|
||||
// parameters it has.
|
||||
fn native_item_ty(@ast.native_item it) -> ty_param_count_and_ty {
|
||||
auto ty_param_count;
|
||||
auto result_ty;
|
||||
alt (it.node) {
|
||||
case (ast.native_item_fn(_, _, _, ?tps, _, ?ann)) {
|
||||
ty_params = tps;
|
||||
ty_param_count = _vec.len[ast.ty_param](tps);
|
||||
result_ty = ann_to_type(ann);
|
||||
}
|
||||
}
|
||||
let vec[ast.def_id] ty_param_ids = vec();
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
ty_param_ids += vec(tp.id);
|
||||
}
|
||||
ret tup(ty_param_ids, result_ty);
|
||||
ret tup(ty_param_count, result_ty);
|
||||
}
|
||||
|
||||
fn item_ty(@ast.item it) -> ty_params_and_ty {
|
||||
let vec[ast.ty_param] ty_params;
|
||||
fn item_ty(@ast.item it) -> ty_param_count_and_ty {
|
||||
auto ty_param_count;
|
||||
auto result_ty;
|
||||
alt (it.node) {
|
||||
case (ast.item_const(_, _, _, _, ?ann)) {
|
||||
ty_params = vec();
|
||||
ty_param_count = 0u;
|
||||
result_ty = ann_to_type(ann);
|
||||
}
|
||||
case (ast.item_fn(_, _, ?tps, _, ?ann)) {
|
||||
ty_params = tps;
|
||||
ty_param_count = _vec.len[ast.ty_param](tps);
|
||||
result_ty = ann_to_type(ann);
|
||||
}
|
||||
case (ast.item_mod(_, _, _)) {
|
||||
fail; // modules are typeless
|
||||
}
|
||||
case (ast.item_ty(_, _, ?tps, _, ?ann)) {
|
||||
ty_params = tps;
|
||||
ty_param_count = _vec.len[ast.ty_param](tps);
|
||||
result_ty = ann_to_type(ann);
|
||||
}
|
||||
case (ast.item_tag(_, _, ?tps, ?did, ?ann)) {
|
||||
ty_params = tps;
|
||||
ty_param_count = _vec.len[ast.ty_param](tps);
|
||||
result_ty = ann_to_type(ann);
|
||||
}
|
||||
case (ast.item_obj(_, _, ?tps, _, ?ann)) {
|
||||
ty_params = tps;
|
||||
ty_param_count = _vec.len[ast.ty_param](tps);
|
||||
result_ty = ann_to_type(ann);
|
||||
}
|
||||
}
|
||||
|
||||
let vec[ast.def_id] ty_param_ids = vec();
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
ty_param_ids += vec(tp.id);
|
||||
}
|
||||
ret tup(ty_param_ids, result_ty);
|
||||
ret tup(ty_param_count, result_ty);
|
||||
}
|
||||
|
||||
fn stmt_ty(@ast.stmt s) -> @t {
|
||||
|
@ -1608,24 +1599,25 @@ fn type_err_to_str(&ty.type_err err) -> str {
|
|||
|
||||
// Type parameter resolution, used in translation and typechecking
|
||||
|
||||
fn resolve_ty_params(ty_params_and_ty ty_params_and_polyty,
|
||||
fn resolve_ty_params(ty_param_count_and_ty ty_params_and_polyty,
|
||||
@t monoty) -> vec[@t] {
|
||||
obj resolve_ty_params_handler(@hashmap[ast.def_id,@t] bindings) {
|
||||
// TODO: Use a vector, not a hashmap here.
|
||||
obj resolve_ty_params_handler(@hashmap[uint,@t] bindings) {
|
||||
fn resolve_local(ast.def_id id) -> @t { log "resolve local"; fail; }
|
||||
fn record_local(ast.def_id id, @t ty) { log "record local"; fail; }
|
||||
fn unify_expected_param(ast.def_id id, @t expected, @t actual)
|
||||
fn unify_expected_param(uint id, @t expected, @t actual)
|
||||
-> unify_result {
|
||||
bindings.insert(id, actual);
|
||||
ret ures_ok(actual);
|
||||
}
|
||||
fn unify_actual_param(ast.def_id id, @t expected, @t actual)
|
||||
fn unify_actual_param(uint id, @t expected, @t actual)
|
||||
-> unify_result {
|
||||
bindings.insert(id, expected);
|
||||
ret ures_ok(expected);
|
||||
}
|
||||
}
|
||||
|
||||
auto bindings = @new_def_hash[@t]();
|
||||
auto bindings = @common.new_uint_hash[@t]();
|
||||
auto handler = resolve_ty_params_handler(bindings);
|
||||
|
||||
auto unify_res = unify(ty_params_and_polyty._1, monoty, handler);
|
||||
|
@ -1639,10 +1631,12 @@ fn resolve_ty_params(ty_params_and_ty ty_params_and_polyty,
|
|||
}
|
||||
|
||||
let vec[@t] result_tys = vec();
|
||||
auto ty_param_ids = ty_params_and_polyty._0;
|
||||
for (ast.def_id tp in ty_param_ids) {
|
||||
check (bindings.contains_key(tp));
|
||||
result_tys += vec(bindings.get(tp));
|
||||
auto ty_param_count = ty_params_and_polyty._0;
|
||||
auto i = 0u;
|
||||
while (i < ty_param_count) {
|
||||
check (bindings.contains_key(i));
|
||||
result_tys += vec(bindings.get(i));
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
ret result_tys;
|
||||
|
@ -1650,45 +1644,19 @@ fn resolve_ty_params(ty_params_and_ty ty_params_and_polyty,
|
|||
|
||||
// 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 substitute_type_params(vec[@t] bindings, @t typ) -> @t {
|
||||
state obj param_replacer(vec[@t] bindings) {
|
||||
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;
|
||||
}
|
||||
case (ty_param(?param_index)) { ret bindings.(param_index); }
|
||||
case (_) { ret typ; }
|
||||
}
|
||||
}
|
||||
}
|
||||
auto replacer = param_replacer(param_map);
|
||||
auto replacer = param_replacer(bindings);
|
||||
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.def_id] ty_params, vec[@t] bound, @t ty)
|
||||
-> @t {
|
||||
auto ty_param_len = _vec.len[ast.def_id](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), bound.(i));
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
ret replace_type_params(ty, bindings);
|
||||
}
|
||||
|
||||
|
||||
fn def_has_ty_params(&ast.def def) -> bool {
|
||||
alt (def) {
|
||||
|
@ -1712,7 +1680,7 @@ fn def_has_ty_params(&ast.def def) -> bool {
|
|||
// If the given item is in an external crate, looks up its type and adds it to
|
||||
// the type cache. Returns the type parameters and type.
|
||||
fn lookup_item_type(session.session sess, &type_cache cache,
|
||||
ast.def_id did) -> ty_params_opt_and_ty {
|
||||
ast.def_id did) -> ty_param_count_and_ty {
|
||||
if (did._0 == sess.get_targ_crate_num()) {
|
||||
// The item is in this crate. The caller should have added it to the
|
||||
// type cache already; we simply return it.
|
||||
|
@ -1729,14 +1697,6 @@ fn lookup_item_type(session.session sess, &type_cache cache,
|
|||
ret tyt;
|
||||
}
|
||||
|
||||
// A convenience function to retrive type parameters and a type when it's
|
||||
// known that the item supports generics (functions, variants, objects).
|
||||
fn lookup_generic_item_type(session.session sess, &type_cache cache,
|
||||
ast.def_id did) -> ty_params_and_ty {
|
||||
auto tp_opt_and_ty = lookup_item_type(sess, cache, did);
|
||||
ret tup(option.get[vec[ast.def_id]](tp_opt_and_ty._0), tp_opt_and_ty._1);
|
||||
}
|
||||
|
||||
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
|
|
|
@ -22,7 +22,7 @@ import middle.ty.plain_ty;
|
|||
import middle.ty.ty_to_str;
|
||||
import middle.ty.type_is_integral;
|
||||
import middle.ty.type_is_scalar;
|
||||
import middle.ty.ty_params_opt_and_ty;
|
||||
import middle.ty.ty_param_count_and_ty;
|
||||
import middle.ty.ty_nil;
|
||||
|
||||
import std._str;
|
||||
|
@ -59,7 +59,7 @@ type fn_ctxt = rec(@ty.t ret_ty,
|
|||
@crate_ctxt ccx);
|
||||
|
||||
// Used for ast_ty_to_ty() below.
|
||||
type ty_getter = fn(ast.def_id) -> ty.ty_params_opt_and_ty;
|
||||
type ty_getter = fn(ast.def_id) -> ty.ty_param_count_and_ty;
|
||||
|
||||
// Turns a type into an ann_type, using defaults for other fields.
|
||||
fn triv_ann(@ty.t t) -> ann {
|
||||
|
@ -75,8 +75,7 @@ fn boring_ann() -> ann {
|
|||
// Replaces parameter types inside a type with type variables.
|
||||
fn generalize_ty(@crate_ctxt cx, @ty.t t) -> @ty.t {
|
||||
state obj ty_generalizer(@crate_ctxt cx,
|
||||
@hashmap[ast.def_id,@ty.t]
|
||||
ty_params_to_ty_vars) {
|
||||
@hashmap[uint,@ty.t] ty_params_to_ty_vars) {
|
||||
fn fold_simple_ty(@ty.t t) -> @ty.t {
|
||||
alt (t.struct) {
|
||||
case (ty.ty_param(?pid)) {
|
||||
|
@ -93,7 +92,7 @@ fn generalize_ty(@crate_ctxt cx, @ty.t t) -> @ty.t {
|
|||
}
|
||||
}
|
||||
|
||||
auto generalizer = ty_generalizer(cx, @common.new_def_hash[@ty.t]());
|
||||
auto generalizer = ty_generalizer(cx, @common.new_uint_hash[@ty.t]());
|
||||
ret ty.fold_ty(generalizer, t);
|
||||
}
|
||||
|
||||
|
@ -101,57 +100,39 @@ fn generalize_ty(@crate_ctxt cx, @ty.t t) -> @ty.t {
|
|||
// expression.
|
||||
fn substitute_ty_params(&@crate_ctxt ccx,
|
||||
@ty.t typ,
|
||||
vec[ast.def_id] ty_params,
|
||||
uint ty_param_count,
|
||||
vec[@ty.t] supplied,
|
||||
&span sp) -> @ty.t {
|
||||
state obj ty_substituter(@crate_ctxt ccx,
|
||||
vec[ast.def_id] ty_params,
|
||||
vec[@ty.t] supplied) {
|
||||
state obj ty_substituter(@crate_ctxt ccx, vec[@ty.t] supplied) {
|
||||
fn fold_simple_ty(@ty.t typ) -> @ty.t {
|
||||
alt (typ.struct) {
|
||||
case (ty.ty_param(?pid)) {
|
||||
// Find the index of the type parameter.
|
||||
auto ty_param_len = _vec.len[ast.def_id](ty_params);
|
||||
auto i = 0u;
|
||||
while (i < ty_param_len &&
|
||||
!common.def_eq(pid, ty_params.(i))) {
|
||||
i += 1u;
|
||||
}
|
||||
if (i == ty_param_len) {
|
||||
log "substitute_ty_params(): " +
|
||||
"no ty param for param id!";
|
||||
fail;
|
||||
}
|
||||
|
||||
// Substitute it in.
|
||||
ret supplied.(i);
|
||||
}
|
||||
case (ty.ty_param(?pid)) { ret supplied.(pid); }
|
||||
case (_) { ret typ; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto ty_param_len = _vec.len[ast.def_id](ty_params);
|
||||
auto supplied_len = _vec.len[@ty.t](supplied);
|
||||
if (ty_param_len != supplied_len) {
|
||||
ccx.sess.span_err(sp, "expected " + _uint.to_str(ty_param_len, 10u) +
|
||||
if (ty_param_count != supplied_len) {
|
||||
ccx.sess.span_err(sp, "expected " +
|
||||
_uint.to_str(ty_param_count, 10u) +
|
||||
" type parameter(s) but found " +
|
||||
_uint.to_str(supplied_len, 10u) + " parameter(s)");
|
||||
fail;
|
||||
}
|
||||
|
||||
auto substituter = ty_substituter(ccx, ty_params, supplied);
|
||||
auto substituter = ty_substituter(ccx, supplied);
|
||||
ret ty.fold_ty(substituter, typ);
|
||||
}
|
||||
|
||||
|
||||
// Returns the type parameters and the type for the given definition.
|
||||
fn ty_params_and_ty_for_def(@fn_ctxt fcx, &ast.def defn)
|
||||
-> ty_params_opt_and_ty {
|
||||
// Returns the type parameter count and the type for the given definition.
|
||||
fn ty_param_count_and_ty_for_def(@fn_ctxt fcx, &ast.def defn)
|
||||
-> ty_param_count_and_ty {
|
||||
alt (defn) {
|
||||
case (ast.def_arg(?id)) {
|
||||
check (fcx.locals.contains_key(id));
|
||||
ret tup(none[vec[ast.def_id]], fcx.locals.get(id));
|
||||
ret tup(0u, fcx.locals.get(id));
|
||||
}
|
||||
case (ast.def_local(?id)) {
|
||||
auto t;
|
||||
|
@ -159,11 +140,11 @@ fn ty_params_and_ty_for_def(@fn_ctxt fcx, &ast.def defn)
|
|||
case (some[@ty.t](?t1)) { t = t1; }
|
||||
case (none[@ty.t]) { t = plain_ty(ty.ty_local(id)); }
|
||||
}
|
||||
ret tup(none[vec[ast.def_id]], t);
|
||||
ret tup(0u, t);
|
||||
}
|
||||
case (ast.def_obj_field(?id)) {
|
||||
check (fcx.locals.contains_key(id));
|
||||
ret tup(none[vec[ast.def_id]], fcx.locals.get(id));
|
||||
ret tup(0u, fcx.locals.get(id));
|
||||
}
|
||||
case (ast.def_fn(?id)) {
|
||||
ret ty.lookup_item_type(fcx.ccx.sess, fcx.ccx.type_cache, id);
|
||||
|
@ -179,7 +160,7 @@ fn ty_params_and_ty_for_def(@fn_ctxt fcx, &ast.def defn)
|
|||
}
|
||||
case (ast.def_binding(?id)) {
|
||||
check (fcx.locals.contains_key(id));
|
||||
ret tup(none[vec[ast.def_id]], fcx.locals.get(id));
|
||||
ret tup(0u, fcx.locals.get(id));
|
||||
}
|
||||
case (ast.def_obj(?id)) {
|
||||
ret ty.lookup_item_type(fcx.ccx.sess, fcx.ccx.type_cache, id);
|
||||
|
@ -188,7 +169,7 @@ fn ty_params_and_ty_for_def(@fn_ctxt fcx, &ast.def defn)
|
|||
case (ast.def_mod(_)) {
|
||||
// Hopefully part of a path.
|
||||
// TODO: return a type that's more poisonous, perhaps?
|
||||
ret tup(none[vec[ast.def_id]], plain_ty(ty.ty_nil));
|
||||
ret tup(0u, plain_ty(ty.ty_nil));
|
||||
}
|
||||
|
||||
case (ast.def_ty(_)) {
|
||||
|
@ -205,10 +186,10 @@ fn ty_params_and_ty_for_def(@fn_ctxt fcx, &ast.def defn)
|
|||
}
|
||||
|
||||
// Instantiates the given path, which must refer to an item with the given
|
||||
// type parameters and type.
|
||||
fn instantiate_path(@fn_ctxt fcx, &ast.path pth, &ty_params_opt_and_ty tpt,
|
||||
// number of type parameters and type.
|
||||
fn instantiate_path(@fn_ctxt fcx, &ast.path pth, &ty_param_count_and_ty tpt,
|
||||
&span sp) -> ast.ann {
|
||||
auto ty_params = tpt._0;
|
||||
auto ty_param_count = tpt._0;
|
||||
auto t = tpt._1;
|
||||
|
||||
auto ty_substs_opt;
|
||||
|
@ -222,61 +203,25 @@ fn instantiate_path(@fn_ctxt fcx, &ast.path pth, &ty_params_opt_and_ty tpt,
|
|||
}
|
||||
ty_substs_opt = some[vec[@ty.t]](ty_substs);
|
||||
|
||||
alt (ty_params) {
|
||||
case (none[vec[ast.def_id]]) {
|
||||
fcx.ccx.sess.span_err(sp, "this kind of item may not take " +
|
||||
"type parameters");
|
||||
fail;
|
||||
}
|
||||
case (some[vec[ast.def_id]](?tps)) {
|
||||
t = substitute_ty_params(fcx.ccx, t, tps, ty_substs, sp);
|
||||
}
|
||||
if (ty_param_count == 0u) {
|
||||
fcx.ccx.sess.span_err(sp, "this item does not take type " +
|
||||
"parameters");
|
||||
fail;
|
||||
}
|
||||
|
||||
t = substitute_ty_params(fcx.ccx, t, ty_param_count, ty_substs, sp);
|
||||
} else {
|
||||
ty_substs_opt = none[vec[@ty.t]];
|
||||
|
||||
alt (ty_params) {
|
||||
case (none[vec[ast.def_id]]) { /* nothing */ }
|
||||
case (some[vec[ast.def_id]](_)) {
|
||||
// We will acquire the type parameters through
|
||||
// unification.
|
||||
t = generalize_ty(fcx.ccx, t);
|
||||
}
|
||||
if (ty_param_count > 0u) {
|
||||
// We will acquire the type parameters through unification.
|
||||
t = generalize_ty(fcx.ccx, t);
|
||||
}
|
||||
}
|
||||
|
||||
ret ast.ann_type(t, ty_substs_opt, none[@ts_ann]);
|
||||
}
|
||||
|
||||
// Returns the type parameters and polytype of an item, if it's an item that
|
||||
// supports type parameters.
|
||||
//
|
||||
// TODO: This function is a little silly in the presence of the new
|
||||
// lookup_item_type(); remove this in favor of lookup_item_type() if possible.
|
||||
fn ty_params_for_item(@crate_ctxt ccx, &ast.def d)
|
||||
-> option.t[ty.ty_params_and_ty] {
|
||||
auto did;
|
||||
alt (d) {
|
||||
case (ast.def_fn(?id)) { did = id; }
|
||||
case (ast.def_obj(?id)) { did = id; }
|
||||
case (ast.def_obj_field(_)) { ret none[ty.ty_params_and_ty]; }
|
||||
case (ast.def_mod(_)) { ret none[ty.ty_params_and_ty]; }
|
||||
case (ast.def_const(_)) { ret none[ty.ty_params_and_ty]; }
|
||||
case (ast.def_arg(_)) { ret none[ty.ty_params_and_ty]; }
|
||||
case (ast.def_local(_)) { ret none[ty.ty_params_and_ty]; }
|
||||
case (ast.def_variant(_, ?vid)) { did = vid; }
|
||||
case (ast.def_ty(_)) { ret none[ty.ty_params_and_ty]; }
|
||||
case (ast.def_ty_arg(_)) { ret none[ty.ty_params_and_ty]; }
|
||||
case (ast.def_binding(_)) { ret none[ty.ty_params_and_ty]; }
|
||||
case (ast.def_use(_)) { ret none[ty.ty_params_and_ty]; }
|
||||
case (ast.def_native_ty(_)) { ret none[ty.ty_params_and_ty]; }
|
||||
case (ast.def_native_fn(?id)) { did = id; }
|
||||
}
|
||||
|
||||
auto tpt = ty.lookup_generic_item_type(ccx.sess, ccx.type_cache, did);
|
||||
ret some[ty.ty_params_and_ty](tpt);
|
||||
}
|
||||
|
||||
// Parses the programmer's textual representation of a type into our internal
|
||||
// notion of a type. `getter` is a function that returns the type
|
||||
// corresponding to a definition ID.
|
||||
|
@ -295,25 +240,20 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
|
|||
// TODO: maybe record cname chains so we can do
|
||||
// "foo = int" like OCaml?
|
||||
auto params_opt_and_ty = getter(id);
|
||||
alt (params_opt_and_ty._0) {
|
||||
case (none[vec[ast.def_id]]) {
|
||||
// FIXME: Session error. This is completely user-unfriendly.
|
||||
log "item has no type parameters";
|
||||
fail;
|
||||
}
|
||||
case (some[vec[ast.def_id]](?params)) {
|
||||
auto num_type_args = _vec.len[@ast.ty](args);
|
||||
check(num_type_args == _vec.len[ast.def_id](params));
|
||||
|
||||
auto param_map = common.new_def_hash[@ty.t]();
|
||||
for each (uint i in _uint.range(0u, num_type_args)) {
|
||||
auto arg = args.(i);
|
||||
auto param = params.(i);
|
||||
param_map.insert(param, ast_ty_to_ty(getter, arg));
|
||||
}
|
||||
ret ty.replace_type_params(params_opt_and_ty._1, param_map);
|
||||
}
|
||||
if (params_opt_and_ty._0 == 0u) {
|
||||
ret params_opt_and_ty._1;
|
||||
}
|
||||
|
||||
// The typedef is type-parametric. Do the type substitution.
|
||||
//
|
||||
// TODO: Make sure the number of supplied bindings matches the number
|
||||
// of type parameters in the typedef. Emit a friendly error otherwise.
|
||||
let vec[@ty.t] param_bindings = vec();
|
||||
for (@ast.ty ast_ty in args) {
|
||||
param_bindings += vec(ast_ty_to_ty(getter, ast_ty));
|
||||
}
|
||||
ret ty.substitute_type_params(param_bindings, params_opt_and_ty._1);
|
||||
}
|
||||
|
||||
auto mut = ast.imm;
|
||||
|
@ -403,7 +343,7 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
|
|||
// A convenience function to use a crate_ctxt to resolve names for
|
||||
// ast_ty_to_ty.
|
||||
fn ast_ty_to_ty_crate(@crate_ctxt ccx, &@ast.ty ast_ty) -> @ty.t {
|
||||
fn getter(@crate_ctxt ccx, ast.def_id id) -> ty.ty_params_opt_and_ty {
|
||||
fn getter(@crate_ctxt ccx, ast.def_id id) -> ty.ty_param_count_and_ty {
|
||||
ret ty.lookup_item_type(ccx.sess, ccx.type_cache, id);
|
||||
}
|
||||
auto f = bind getter(ccx, _);
|
||||
|
@ -422,14 +362,6 @@ fn ast_ty_to_ty_crate(@crate_ctxt ccx, &@ast.ty ast_ty) -> @ty.t {
|
|||
// We then annotate the AST with the resulting types and return the annotated
|
||||
// AST, along with a table mapping item IDs to their types.
|
||||
|
||||
fn ty_params_to_def_ids(vec[ast.ty_param] tps) -> vec[ast.def_id] {
|
||||
let vec[ast.def_id] result = vec();
|
||||
for (ast.ty_param tp in tps) {
|
||||
result += vec(tp.id);
|
||||
}
|
||||
ret result;
|
||||
}
|
||||
|
||||
fn ty_of_fn_decl(@ty_item_table id_to_ty_item,
|
||||
ty.type_cache type_cache,
|
||||
fn(&@ast.ty ast_ty) -> @ty.t convert,
|
||||
|
@ -437,12 +369,12 @@ fn ty_of_fn_decl(@ty_item_table id_to_ty_item,
|
|||
&ast.fn_decl decl,
|
||||
ast.proto proto,
|
||||
vec[ast.ty_param] ty_params,
|
||||
ast.def_id def_id) -> ty.ty_params_opt_and_ty {
|
||||
ast.def_id def_id) -> ty.ty_param_count_and_ty {
|
||||
auto input_tys = _vec.map[ast.arg,arg](ty_of_arg, decl.inputs);
|
||||
auto output_ty = convert(decl.output);
|
||||
auto t_fn = plain_ty(ty.ty_fn(proto, input_tys, output_ty));
|
||||
auto params_opt = some[vec[ast.def_id]](ty_params_to_def_ids(ty_params));
|
||||
auto tpt = tup(params_opt, t_fn);
|
||||
auto ty_param_count = _vec.len[ast.ty_param](ty_params);
|
||||
auto tpt = tup(ty_param_count, t_fn);
|
||||
type_cache.insert(def_id, tpt);
|
||||
ret tpt;
|
||||
}
|
||||
|
@ -454,12 +386,12 @@ fn ty_of_native_fn_decl(@ty_item_table id_to_ty_item,
|
|||
&ast.fn_decl decl,
|
||||
ast.native_abi abi,
|
||||
vec[ast.ty_param] ty_params,
|
||||
ast.def_id def_id) -> ty.ty_params_opt_and_ty {
|
||||
ast.def_id def_id) -> ty.ty_param_count_and_ty {
|
||||
auto input_tys = _vec.map[ast.arg,arg](ty_of_arg, decl.inputs);
|
||||
auto output_ty = convert(decl.output);
|
||||
auto t_fn = plain_ty(ty.ty_native_fn(abi, input_tys, output_ty));
|
||||
auto params_opt = some[vec[ast.def_id]](ty_params_to_def_ids(ty_params));
|
||||
auto tpt = tup(params_opt, t_fn);
|
||||
auto ty_param_count = _vec.len[ast.ty_param](ty_params);
|
||||
auto tpt = tup(ty_param_count, t_fn);
|
||||
type_cache.insert(def_id, tpt);
|
||||
ret tpt;
|
||||
}
|
||||
|
@ -470,7 +402,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
fn getter(session.session sess,
|
||||
@ty_item_table id_to_ty_item,
|
||||
ty.type_cache type_cache,
|
||||
ast.def_id id) -> ty.ty_params_opt_and_ty {
|
||||
ast.def_id id) -> ty.ty_param_count_and_ty {
|
||||
|
||||
if (id._0 != sess.get_targ_crate_num()) {
|
||||
// This is a type we need to load in from the crate reader.
|
||||
|
@ -520,16 +452,15 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
ty.type_cache type_cache,
|
||||
&ast.ident id,
|
||||
&ast._obj obj_info,
|
||||
vec[ast.ty_param] ty_params) -> ty.ty_params_opt_and_ty {
|
||||
vec[ast.ty_param] ty_params) -> ty.ty_param_count_and_ty {
|
||||
auto f = bind ty_of_method(sess, id_to_ty_item, type_cache, _);
|
||||
auto methods =
|
||||
_vec.map[@ast.method,method](f, obj_info.methods);
|
||||
|
||||
auto t_obj = @rec(struct=ty.ty_obj(ty.sort_methods(methods)),
|
||||
cname=some[str](id));
|
||||
auto params = ty_params_to_def_ids(ty_params);
|
||||
auto params_opt = some[vec[ast.def_id]](params);
|
||||
ret tup(params_opt, t_obj);
|
||||
auto ty_param_count = _vec.len[ast.ty_param](ty_params);
|
||||
ret tup(ty_param_count, t_obj);
|
||||
}
|
||||
|
||||
fn ty_of_obj_ctor(session.session sess,
|
||||
|
@ -539,7 +470,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
&ast._obj obj_info,
|
||||
ast.def_id obj_ty_id,
|
||||
vec[ast.ty_param] ty_params)
|
||||
-> ty.ty_params_opt_and_ty {
|
||||
-> ty.ty_param_count_and_ty {
|
||||
auto t_obj = ty_of_obj(sess, id_to_ty_item, type_cache,
|
||||
id, obj_info, ty_params);
|
||||
let vec[arg] t_inputs = vec();
|
||||
|
@ -558,7 +489,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
fn ty_of_item(session.session sess,
|
||||
@ty_item_table id_to_ty_item,
|
||||
ty.type_cache type_cache,
|
||||
@ast.item it) -> ty.ty_params_opt_and_ty {
|
||||
@ast.item it) -> ty.ty_param_count_and_ty {
|
||||
|
||||
auto get = bind getter(sess, id_to_ty_item, type_cache, _);
|
||||
auto convert = bind ast_ty_to_ty(get, _);
|
||||
|
@ -567,7 +498,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
|
||||
case (ast.item_const(?ident, ?t, _, ?def_id, _)) {
|
||||
auto typ = convert(t);
|
||||
type_cache.insert(def_id, tup(none[vec[ast.def_id]], typ));
|
||||
type_cache.insert(def_id, tup(0u, typ));
|
||||
}
|
||||
|
||||
case (ast.item_fn(?ident, ?fn_info, ?tps, ?def_id, _)) {
|
||||
|
@ -597,9 +528,8 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
// Tell ast_ty_to_ty() that we want to perform a recursive
|
||||
// call to resolve any named types.
|
||||
auto typ = convert(ty);
|
||||
auto params = ty_params_to_def_ids(tps);
|
||||
auto params_opt = some[vec[ast.def_id]](params);
|
||||
auto tpt = tup(params_opt, typ);
|
||||
auto ty_param_count = _vec.len[ast.ty_param](tps);
|
||||
auto tpt = tup(ty_param_count, typ);
|
||||
type_cache.insert(def_id, tpt);
|
||||
ret tpt;
|
||||
}
|
||||
|
@ -607,14 +537,17 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
case (ast.item_tag(_, _, ?tps, ?def_id, _)) {
|
||||
// Create a new generic polytype.
|
||||
let vec[@ty.t] subtys = vec();
|
||||
|
||||
auto i = 0u;
|
||||
for (ast.ty_param tp in tps) {
|
||||
subtys += vec(plain_ty(ty.ty_param(tp.id)));
|
||||
subtys += vec(plain_ty(ty.ty_param(i)));
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
auto t = plain_ty(ty.ty_tag(def_id, subtys));
|
||||
|
||||
auto params = ty_params_to_def_ids(tps);
|
||||
auto params_opt = some[vec[ast.def_id]](params);
|
||||
auto tpt = tup(params_opt, t);
|
||||
auto ty_param_count = _vec.len[ast.ty_param](tps);
|
||||
auto tpt = tup(ty_param_count, t);
|
||||
type_cache.insert(def_id, tpt);
|
||||
ret tpt;
|
||||
}
|
||||
|
@ -628,7 +561,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
@ty_item_table id_to_ty_item,
|
||||
ty.type_cache type_cache,
|
||||
@ast.native_item it,
|
||||
ast.native_abi abi) -> ty.ty_params_opt_and_ty {
|
||||
ast.native_abi abi) -> ty.ty_param_count_and_ty {
|
||||
alt (it.node) {
|
||||
case (ast.native_item_fn(?ident, ?lname, ?fn_decl,
|
||||
?params, ?def_id, _)) {
|
||||
|
@ -645,7 +578,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
}
|
||||
|
||||
auto t = @rec(struct=ty.ty_native, cname=none[str]);
|
||||
auto tpt = tup(none[vec[ast.def_id]], t);
|
||||
auto tpt = tup(0u, t);
|
||||
type_cache.insert(def_id, tpt);
|
||||
ret tpt;
|
||||
}
|
||||
|
@ -663,12 +596,13 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
|
||||
// Create a set of parameter types shared among all the variants.
|
||||
let vec[@ty.t] ty_param_tys = vec();
|
||||
auto i = 0u;
|
||||
for (ast.ty_param tp in ty_params) {
|
||||
ty_param_tys += vec(plain_ty(ty.ty_param(tp.id)));
|
||||
ty_param_tys += vec(plain_ty(ty.ty_param(i)));
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
auto params = ty_params_to_def_ids(ty_params);
|
||||
auto params_opt = some[vec[ast.def_id]](params);
|
||||
auto ty_param_count = _vec.len[ast.ty_param](ty_params);
|
||||
|
||||
for (ast.variant variant in variants) {
|
||||
// Nullary tag constructors get turned into constants; n-ary tag
|
||||
|
@ -690,7 +624,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
result_ty = plain_ty(ty.ty_fn(ast.proto_fn, args, tag_t));
|
||||
}
|
||||
|
||||
auto tpt = tup(params_opt, result_ty);
|
||||
auto tpt = tup(ty_param_count, result_ty);
|
||||
type_cache.insert(variant.node.id, tpt);
|
||||
auto variant_t = rec(ann=triv_ann(result_ty)
|
||||
with variant.node
|
||||
|
@ -743,7 +677,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
|
|||
|
||||
|
||||
// Second pass: translate the types of all items.
|
||||
auto type_cache = common.new_def_hash[ty.ty_params_opt_and_ty]();
|
||||
auto type_cache = common.new_def_hash[ty.ty_param_count_and_ty]();
|
||||
|
||||
type env = rec(session.session sess,
|
||||
@ty_item_table id_to_ty_item,
|
||||
|
@ -920,25 +854,21 @@ fn unify(&@fn_ctxt fcx, @ty.t expected, @ty.t actual) -> ty.unify_result {
|
|||
fn record_local(ast.def_id id, @ty.t t) {
|
||||
fcx.locals.insert(id, t);
|
||||
}
|
||||
fn unify_expected_param(ast.def_id id, @ty.t expected, @ty.t actual)
|
||||
fn unify_expected_param(uint id, @ty.t expected, @ty.t actual)
|
||||
-> ty.unify_result {
|
||||
alt (actual.struct) {
|
||||
case (ty.ty_param(?actual_id)) {
|
||||
if (id._0 == actual_id._0 && id._1 == actual_id._1) {
|
||||
ret ty.ures_ok(expected);
|
||||
}
|
||||
if (id == actual_id) { ret ty.ures_ok(expected); }
|
||||
}
|
||||
case (_) { /* fall through */ }
|
||||
}
|
||||
ret ty.ures_err(ty.terr_mismatch, expected, actual);
|
||||
}
|
||||
fn unify_actual_param(ast.def_id id, @ty.t expected, @ty.t actual)
|
||||
fn unify_actual_param(uint id, @ty.t expected, @ty.t actual)
|
||||
-> ty.unify_result {
|
||||
alt (expected.struct) {
|
||||
case (ty.ty_param(?expected_id)) {
|
||||
if (id._0 == expected_id._0 && id._1 == expected_id._1) {
|
||||
ret ty.ures_ok(actual);
|
||||
}
|
||||
if (id == expected_id) { ret ty.ures_ok(actual); }
|
||||
}
|
||||
case (_) { /* fall through */ }
|
||||
}
|
||||
|
@ -1087,7 +1017,7 @@ mod Pushdown {
|
|||
// Figure out the type parameters of the tag.
|
||||
auto tag_id = option.get[ast.variant_def](vdef_opt)._0;
|
||||
|
||||
auto tpt = ty.lookup_generic_item_type(fcx.ccx.sess,
|
||||
auto tpt = ty.lookup_item_type(fcx.ccx.sess,
|
||||
fcx.ccx.type_cache, tag_id);
|
||||
auto ty_params = tpt._0;
|
||||
|
||||
|
@ -1367,15 +1297,10 @@ mod Pushdown {
|
|||
alt (tps_opt) {
|
||||
case (none[vec[@ty.t]]) {
|
||||
auto defn = option.get[ast.def](d);
|
||||
alt (ty_params_for_item(fcx.ccx, defn)) {
|
||||
case (none[ty.ty_params_and_ty]) {
|
||||
ty_params_opt = none[vec[@ty.t]];
|
||||
}
|
||||
case (some[ty.ty_params_and_ty](?tpt)) {
|
||||
auto tps = ty.resolve_ty_params(tpt, t);
|
||||
ty_params_opt = some[vec[@ty.t]](tps);
|
||||
}
|
||||
}
|
||||
auto tpt =
|
||||
ty_param_count_and_ty_for_def(fcx, defn);
|
||||
auto tps = ty.resolve_ty_params(tpt, t);
|
||||
ty_params_opt = some[vec[@ty.t]](tps);
|
||||
}
|
||||
case (some[vec[@ty.t]](?tps)) {
|
||||
ty_params_opt = some[vec[@ty.t]](tps);
|
||||
|
@ -1841,7 +1766,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
|||
auto t = plain_ty(ty.ty_nil);
|
||||
check (defopt != none[ast.def]);
|
||||
auto defn = option.get[ast.def](defopt);
|
||||
auto tpt = ty_params_and_ty_for_def(fcx, defn);
|
||||
auto tpt = ty_param_count_and_ty_for_def(fcx, defn);
|
||||
auto ann = instantiate_path(fcx, pth, tpt, expr.span);
|
||||
ret @fold.respan[ast.expr_](expr.span,
|
||||
ast.expr_path(pth, defopt, ann));
|
||||
|
@ -2217,13 +2142,8 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
|||
auto this_obj_id = fcx.ccx.this_obj;
|
||||
alt (this_obj_id) {
|
||||
case (some[ast.def_id](?def_id)) {
|
||||
auto this_obj_tpt = fcx.ccx.type_cache.find(def_id);
|
||||
alt (this_obj_tpt) {
|
||||
case (some[ty_params_opt_and_ty](?tpt)) {
|
||||
this_obj_ty = tpt._1;
|
||||
}
|
||||
case (_) { fail; }
|
||||
}
|
||||
this_obj_ty = ty.lookup_item_type(fcx.ccx.sess,
|
||||
fcx.ccx.type_cache, def_id)._1;
|
||||
}
|
||||
case (_) { fail; }
|
||||
}
|
||||
|
|
|
@ -796,7 +796,7 @@ impure fn print_type_params(ps s, vec[ast.ty_param] params) {
|
|||
if (_vec.len[ast.ty_param](params) > 0u) {
|
||||
wrd(s.s, "[");
|
||||
impure fn printParam(ps s, &ast.ty_param param) {
|
||||
wrd(s.s, param.ident);
|
||||
wrd(s.s, param);
|
||||
}
|
||||
auto f = printParam;
|
||||
commasep[ast.ty_param](s, params, f);
|
||||
|
|
Loading…
Reference in a new issue