diff options
| author | Graydon Hoare <graydon@mozilla.com> | 2011-07-29 16:40:23 -0700 |
|---|---|---|
| committer | Graydon Hoare <graydon@mozilla.com> | 2011-07-29 16:40:30 -0700 |
| commit | 59c441a66a86d04087f15aaa9d624fb3c24fcb54 (patch) | |
| tree | b21b5af66371deab773ec64271ec15dcff6646ff | |
| parent | a684f6078f7f67ae7f6396b3f8f58cc6e78bdc4c (diff) | |
| download | rust-59c441a66a86d04087f15aaa9d624fb3c24fcb54.tar.gz rust-59c441a66a86d04087f15aaa9d624fb3c24fcb54.zip | |
Encode, decode, and thread through typechecking all the param kinds, not just the counts.
| -rw-r--r-- | src/comp/metadata/common.rs | 4 | ||||
| -rw-r--r-- | src/comp/metadata/csearch.rs | 2 | ||||
| -rw-r--r-- | src/comp/metadata/decoder.rs | 64 | ||||
| -rw-r--r-- | src/comp/metadata/encoder.rs | 60 | ||||
| -rw-r--r-- | src/comp/middle/kind.rs | 5 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 16 | ||||
| -rw-r--r-- | src/comp/middle/ty.rs | 11 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 85 |
8 files changed, 143 insertions, 104 deletions
diff --git a/src/comp/metadata/common.rs b/src/comp/metadata/common.rs index e8fce2da7df..065f4dc66bc 100644 --- a/src/comp/metadata/common.rs +++ b/src/comp/metadata/common.rs @@ -20,9 +20,9 @@ const tag_items_data: uint = 0x08u; const tag_items_data_item: uint = 0x09u; -const tag_items_data_item_kind: uint = 0x0au; +const tag_items_data_item_family: uint = 0x0au; -const tag_items_data_item_ty_param_count: uint = 0x0bu; +const tag_items_data_item_ty_param_kinds: uint = 0x0bu; const tag_items_data_item_type: uint = 0x0cu; diff --git a/src/comp/metadata/csearch.rs b/src/comp/metadata/csearch.rs index a6086704183..7a397fff317 100644 --- a/src/comp/metadata/csearch.rs +++ b/src/comp/metadata/csearch.rs @@ -35,7 +35,7 @@ fn get_tag_variants(tcx: ty::ctxt, def: ast::def_id) -> ty::variant_info[] { ret decoder::get_tag_variants(cdata, def, tcx, resolver) } -fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_count_and_ty { +fn get_type(tcx: ty::ctxt, def: ast::def_id) -> ty::ty_param_kinds_and_ty { let cstore = tcx.sess.get_cstore(); let cnum = def.crate; let cdata = cstore::get_crate_data(cstore, cnum).data; diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index ab9c07981b9..45c9dcf3b37 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -20,6 +20,7 @@ export get_symbol; export get_tag_variants; export get_type; export get_type_param_count; +export get_type_param_kinds; export lookup_defs; export get_crate_attributes; export list_crate_metadata; @@ -77,9 +78,9 @@ fn lookup_item(item_id: int, data: &@u8[]) -> ebmlivec::doc { ret find_item(item_id, items); } -fn item_kind(item: &ebmlivec::doc) -> u8 { - let kind = ebmlivec::get_doc(item, tag_items_data_item_kind); - ret ebmlivec::doc_as_uint(kind) as u8; +fn item_family(item: &ebmlivec::doc) -> u8 { + let fam = ebmlivec::get_doc(item, tag_items_data_item_family); + ret ebmlivec::doc_as_uint(fam) as u8; } fn item_symbol(item: &ebmlivec::doc) -> str { @@ -113,13 +114,24 @@ fn item_type(item: &ebmlivec::doc, this_cnum: ast::crate_num, tcx: ty::ctxt, def_parser, tcx); } -fn item_ty_param_count(item: &ebmlivec::doc) -> uint { - let ty_param_count: uint = 0u; - let tp = tag_items_data_item_ty_param_count; - for each p: ebmlivec::doc in ebmlivec::tagged_docs(item, tp) { - ty_param_count = ebmlivec::vint_at(ebmlivec::doc_data(p), 0u).val; +fn item_ty_param_kinds(item: &ebmlivec::doc) -> ast::kind[] { + let ks: ast::kind[] = ~[]; + let tp = tag_items_data_item_ty_param_kinds; + for each p: ebmlivec::doc in ebmlivec::tagged_docs(item, tp) { + let dat : u8[] = ebmlivec::doc_data(p); + let vi = ebmlivec::vint_at(dat, 0u); + let i = 0u; + while i < vi.val { + let k = alt dat.(vi.next + i) as char { + 'u' { ast::kind_unique } + 's' { ast::kind_shared } + 'p' { ast::kind_pinned } + }; + ks += ~[k]; + i += 1u; + } } - ret ty_param_count; + ret ks; } fn tag_variant_ids(item: &ebmlivec::doc, this_cnum: ast::crate_num) -> @@ -162,11 +174,11 @@ fn lookup_defs(data: &@u8[], cnum: ast::crate_num, path: &ast::ident[]) -> fn lookup_def(cnum: ast::crate_num, data: @u8[], did_: &ast::def_id) -> ast::def { let item = lookup_item(did_.node, data); - let kind_ch = item_kind(item); + let fam_ch = item_family(item); let did = {crate: cnum, node: did_.node}; // We treat references to tags as references to types. let def = - alt kind_ch as char { + alt fam_ch as char { 'c' { ast::def_const(did) } 'f' { ast::def_fn(did, ast::impure_fn) } 'p' { ast::def_fn(did, ast::pure_fn) } @@ -186,22 +198,26 @@ fn lookup_def(cnum: ast::crate_num, data: @u8[], did_: &ast::def_id) -> } fn get_type(data: @u8[], def: ast::def_id, tcx: &ty::ctxt, - extres: &external_resolver) -> ty::ty_param_count_and_ty { + extres: &external_resolver) -> ty::ty_param_kinds_and_ty { let this_cnum = def.crate; let node_id = def.node; let item = lookup_item(node_id, data); let t = item_type(item, this_cnum, tcx, extres); - let tp_count; - let kind_ch = item_kind(item); - let has_ty_params = kind_has_type_params(kind_ch); + let tp_kinds : ast::kind[]; + let fam_ch = item_family(item); + let has_ty_params = family_has_type_params(fam_ch); if has_ty_params { - tp_count = item_ty_param_count(item); - } else { tp_count = 0u; } - ret {count: tp_count, ty: t}; + tp_kinds = item_ty_param_kinds(item); + } else { tp_kinds = ~[]; } + ret {kinds: tp_kinds, ty: t}; } fn get_type_param_count(data: @u8[], id: ast::node_id) -> uint { - ret item_ty_param_count(lookup_item(id, data)); + ret ivec::len(get_type_param_kinds(data, id)); +} + +fn get_type_param_kinds(data: @u8[], id: ast::node_id) -> ast::kind[] { + ret item_ty_param_kinds(lookup_item(id, data)); } fn get_symbol(data: @u8[], id: ast::node_id) -> str { @@ -235,8 +251,8 @@ fn get_tag_variants(data: &@u8[], def: ast::def_id, tcx: &ty::ctxt, ret infos; } -fn kind_has_type_params(kind_ch: u8) -> bool { - ret alt kind_ch as char { +fn family_has_type_params(fam_ch: u8) -> bool { + ret alt fam_ch as char { 'c' { false } 'f' { true } 'p' { true } @@ -260,11 +276,11 @@ fn read_path(d: &ebmlivec::doc) -> {path: str, pos: uint} { fn describe_def(items: &ebmlivec::doc, id: ast::def_id) -> str { if id.crate != ast::local_crate { ret "external"; } - ret item_kind_to_str(item_kind(find_item(id.node, items))); + ret item_family_to_str(item_family(find_item(id.node, items))); } -fn item_kind_to_str(kind: u8) -> str { - alt kind as char { +fn item_family_to_str(fam: u8) -> str { + alt fam as char { 'c' { ret "const"; } 'f' { ret "fn"; } 'p' { ret "pred"; } diff --git a/src/comp/metadata/encoder.rs b/src/comp/metadata/encoder.rs index f6ad31a41b9..b9a1fa3886a 100644 --- a/src/comp/metadata/encoder.rs +++ b/src/comp/metadata/encoder.rs @@ -160,17 +160,25 @@ fn encode_item_paths(ebml_w: &ebmlivec::writer, crate: &@crate) -> // Item info table encoding -fn encode_kind(ebml_w: &ebmlivec::writer, c: u8) { - ebmlivec::start_tag(ebml_w, tag_items_data_item_kind); +fn encode_family(ebml_w: &ebmlivec::writer, c: u8) { + ebmlivec::start_tag(ebml_w, tag_items_data_item_family); ebml_w.writer.write(~[c]); ebmlivec::end_tag(ebml_w); } fn def_to_str(did: &def_id) -> str { ret #fmt("%d:%d", did.crate, did.node); } -fn encode_type_param_count(ebml_w: &ebmlivec::writer, tps: &ty_param[]) { - ebmlivec::start_tag(ebml_w, tag_items_data_item_ty_param_count); +fn encode_type_param_kinds(ebml_w: &ebmlivec::writer, tps: &ty_param[]) { + ebmlivec::start_tag(ebml_w, tag_items_data_item_ty_param_kinds); ebmlivec::write_vint(ebml_w.writer, ivec::len[ty_param](tps)); + for tp: ty_param in tps { + let c = alt tp.kind { + kind_unique. { 'u' } + kind_shared. { 's' } + kind_pinned. { 'p' } + }; + ebml_w.writer.write(~[c as u8]); + } ebmlivec::end_tag(ebml_w); } @@ -218,7 +226,7 @@ fn encode_tag_variant_info(ecx: &@encode_ctxt, ebml_w: &ebmlivec::writer, index += ~[{val: variant.node.id, pos: ebml_w.writer.tell()}]; ebmlivec::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(variant.node.id)); - encode_kind(ebml_w, 'v' as u8); + encode_family(ebml_w, 'v' as u8); encode_tag_id(ebml_w, local_def(id)); encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, variant.node.id)); @@ -226,7 +234,7 @@ fn encode_tag_variant_info(ecx: &@encode_ctxt, ebml_w: &ebmlivec::writer, encode_symbol(ecx, ebml_w, variant.node.id); } encode_discriminant(ecx, ebml_w, variant.node.id); - encode_type_param_count(ebml_w, ty_params); + encode_type_param_kinds(ebml_w, ty_params); ebmlivec::end_tag(ebml_w); } } @@ -237,7 +245,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: &ebmlivec::writer, item_const(_, _) { ebmlivec::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - encode_kind(ebml_w, 'c' as u8); + encode_family(ebml_w, 'c' as u8); encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id)); encode_symbol(ecx, ebml_w, item.id); ebmlivec::end_tag(ebml_w); @@ -245,10 +253,10 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: &ebmlivec::writer, item_fn(fd, tps) { ebmlivec::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - encode_kind(ebml_w, + encode_family(ebml_w, alt fd.decl.purity { pure_fn. { 'p' } impure_fn. { 'f' } } as u8); - encode_type_param_count(ebml_w, tps); + encode_type_param_kinds(ebml_w, tps); encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id)); encode_symbol(ecx, ebml_w, item.id); ebmlivec::end_tag(ebml_w); @@ -256,28 +264,28 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: &ebmlivec::writer, item_mod(_) { ebmlivec::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - encode_kind(ebml_w, 'm' as u8); + encode_family(ebml_w, 'm' as u8); ebmlivec::end_tag(ebml_w); } item_native_mod(_) { ebmlivec::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - encode_kind(ebml_w, 'n' as u8); + encode_family(ebml_w, 'n' as u8); ebmlivec::end_tag(ebml_w); } item_ty(_, tps) { ebmlivec::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - encode_kind(ebml_w, 'y' as u8); - encode_type_param_count(ebml_w, tps); + encode_family(ebml_w, 'y' as u8); + encode_type_param_kinds(ebml_w, tps); encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id)); ebmlivec::end_tag(ebml_w); } item_tag(variants, tps) { ebmlivec::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - encode_kind(ebml_w, 't' as u8); - encode_type_param_count(ebml_w, tps); + encode_family(ebml_w, 't' as u8); + encode_type_param_kinds(ebml_w, tps); encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, item.id)); for v: variant in variants { encode_variant_id(ebml_w, local_def(v.node.id)); @@ -290,8 +298,8 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: &ebmlivec::writer, ebmlivec::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(ctor_id)); - encode_kind(ebml_w, 'y' as u8); - encode_type_param_count(ebml_w, tps); + encode_family(ebml_w, 'y' as u8); + encode_type_param_kinds(ebml_w, tps); encode_type(ecx, ebml_w, ty::ty_fn_ret(ecx.ccx.tcx, fn_ty)); encode_symbol(ecx, ebml_w, item.id); ebmlivec::end_tag(ebml_w); @@ -299,8 +307,8 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: &ebmlivec::writer, index += ~[{val: ctor_id, pos: ebml_w.writer.tell()}]; ebmlivec::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(ctor_id)); - encode_kind(ebml_w, 'f' as u8); - encode_type_param_count(ebml_w, tps); + encode_family(ebml_w, 'f' as u8); + encode_type_param_kinds(ebml_w, tps); encode_type(ecx, ebml_w, fn_ty); encode_symbol(ecx, ebml_w, ctor_id); ebmlivec::end_tag(ebml_w); @@ -310,16 +318,16 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: &ebmlivec::writer, ebmlivec::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(item.id)); - encode_kind(ebml_w, 'y' as u8); - encode_type_param_count(ebml_w, tps); + encode_family(ebml_w, 'y' as u8); + encode_type_param_kinds(ebml_w, tps); encode_type(ecx, ebml_w, ty::ty_fn_ret(ecx.ccx.tcx, fn_ty)); ebmlivec::end_tag(ebml_w); index += ~[{val: ctor_id, pos: ebml_w.writer.tell()}]; ebmlivec::start_tag(ebml_w, tag_items_data_item); encode_def_id(ebml_w, local_def(ctor_id)); - encode_kind(ebml_w, 'f' as u8); - encode_type_param_count(ebml_w, tps); + encode_family(ebml_w, 'f' as u8); + encode_type_param_kinds(ebml_w, tps); encode_type(ecx, ebml_w, fn_ty); encode_symbol(ecx, ebml_w, ctor_id); ebmlivec::end_tag(ebml_w); @@ -333,14 +341,14 @@ fn encode_info_for_native_item(ecx: &@encode_ctxt, ebml_w: &ebmlivec::writer, alt nitem.node { native_item_ty. { encode_def_id(ebml_w, local_def(nitem.id)); - encode_kind(ebml_w, 'T' as u8); + encode_family(ebml_w, 'T' as u8); encode_type(ecx, ebml_w, ty::mk_native(ecx.ccx.tcx, local_def(nitem.id))); } native_item_fn(_, _, tps) { encode_def_id(ebml_w, local_def(nitem.id)); - encode_kind(ebml_w, 'F' as u8); - encode_type_param_count(ebml_w, tps); + encode_family(ebml_w, 'F' as u8); + encode_type_param_kinds(ebml_w, tps); encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, nitem.id)); encode_symbol(ecx, ebml_w, nitem.id); } diff --git a/src/comp/middle/kind.rs b/src/comp/middle/kind.rs index 9893eb7dde7..1590a8fc095 100644 --- a/src/comp/middle/kind.rs +++ b/src/comp/middle/kind.rs @@ -138,6 +138,11 @@ fn check_expr(tcx: &ty::ctxt, e: &@ast::expr) { ast::expr_move(a, b) { need_shared_lhs_rhs(tcx, a, b, "<-"); } ast::expr_assign(a, b) { need_shared_lhs_rhs(tcx, a, b, "="); } ast::expr_swap(a, b) { need_shared_lhs_rhs(tcx, a, b, "<->"); } + ast::expr_call(callee, args) { + // FIXME: when ready, start checking param kinds against args. + // This will break stdlib again. + // let tpt = ty::expr_ty_params_and_ty(tcx, callee); + } _ { } } } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index fb981889f7b..5a8efa4f2db 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -296,11 +296,12 @@ fn type_of_arg(cx: @local_ctxt, sp: &span, arg: &ty::arg) -> TypeRef { ret typ; } -fn type_of_ty_param_count_and_ty(lcx: @local_ctxt, sp: &span, - tpt: &ty::ty_param_count_and_ty) -> TypeRef { +fn type_of_ty_param_kinds_and_ty(lcx: @local_ctxt, sp: &span, + tpt: &ty::ty_param_kinds_and_ty) -> TypeRef { alt ty::struct(lcx.ccx.tcx, tpt.ty) { ty::ty_fn(_, _, _, _, _) { - let llfnty = type_of_fn_from_ty(lcx.ccx, sp, tpt.ty, tpt.count); + let llfnty = type_of_fn_from_ty(lcx.ccx, sp, tpt.ty, + std::ivec::len(tpt.kinds)); ret T_fn_pair(*lcx.ccx, llfnty); } _ { @@ -3970,14 +3971,14 @@ fn lval_val(cx: &@block_ctxt, val: ValueRef) -> lval_result { } fn trans_external_path(cx: &@block_ctxt, did: &ast::def_id, - tpt: &ty::ty_param_count_and_ty) -> ValueRef { + tpt: &ty::ty_param_kinds_and_ty) -> ValueRef { let lcx = cx.fcx.lcx; let name = csearch::get_symbol(lcx.ccx.sess.get_cstore(), did); ret get_extern_const(lcx.ccx.externs, lcx.ccx.llmod, name, - type_of_ty_param_count_and_ty(lcx, cx.sp, tpt)); + type_of_ty_param_kinds_and_ty(lcx, cx.sp, tpt)); } -fn lval_generic_fn(cx: &@block_ctxt, tpt: &ty::ty_param_count_and_ty, +fn lval_generic_fn(cx: &@block_ctxt, tpt: &ty::ty_param_kinds_and_ty, fn_id: &ast::def_id, id: ast::node_id) -> lval_result { let lv; if fn_id.crate == ast::local_crate { @@ -4101,10 +4102,11 @@ fn trans_var(cx: &@block_ctxt, sp: &span, id: ast::node_id) -> ret lval_mem(cx, ccx.consts.get(did.node)); } else { let tp = ty::node_id_to_monotype(ccx.tcx, id); + let k: ast::kind[] = ~[]; ret lval_val(cx, load_if_immediate(cx, trans_external_path(cx, did, - {count: 0u, + {kinds: k, ty: tp}), tp)); } diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 37ca0632cab..c25821b2b63 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -44,6 +44,7 @@ export def_has_ty_params; export eq_ty; export expr_has_ty_params; export expr_ty; +export expr_ty_params_and_ty; export fold_ty; export field; export field_idx; @@ -113,7 +114,7 @@ export t; export tag_variants; export tag_variant_with_id; export ty_param_substs_opt_and_ty; -export ty_param_count_and_ty; +export ty_param_kinds_and_ty; export ty_native_fn; export ty_bool; export ty_bot; @@ -304,9 +305,9 @@ tag type_err { terr_constr_mismatch(@type_constr, @type_constr); } -type ty_param_count_and_ty = {count: uint, ty: t}; +type ty_param_kinds_and_ty = {kinds: ast::kind[], ty: t}; -type type_cache = hashmap[ast::def_id, ty_param_count_and_ty]; +type type_cache = hashmap[ast::def_id, ty_param_kinds_and_ty]; const idx_nil: uint = 0u; @@ -400,7 +401,7 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map, freevars: freevars::freevar_map) -> ctxt { let ntt: node_type_table = @smallintmap::mk[ty::ty_param_substs_opt_and_ty](); - let tcache = new_def_hash[ty::ty_param_count_and_ty](); + let tcache = new_def_hash[ty::ty_param_kinds_and_ty](); let ts = @interner::mk[@raw_t](hash_raw_ty, eq_raw_ty); let cx = @{ts: ts, @@ -2832,7 +2833,7 @@ fn tag_variant_with_id(cx: &ctxt, tag_id: &ast::def_id, // 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(cx: ctxt, did: ast::def_id) -> ty_param_count_and_ty { +fn lookup_item_type(cx: ctxt, did: ast::def_id) -> ty_param_kinds_and_ty { if did.crate == ast::local_crate { // The item is in this crate. The caller should have added it to the // type cache already; we simply return it. diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index dc32e006287..e6077e2ff0d 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -25,7 +25,7 @@ import middle::ty::node_type_table; import middle::ty::pat_ty; import middle::ty::ty_param_substs_opt_and_ty; import util::ppaux::ty_to_str; -import middle::ty::ty_param_count_and_ty; +import middle::ty::ty_param_kinds_and_ty; import middle::ty::ty_nil; import middle::ty::unify::ures_ok; import middle::ty::unify::ures_err; @@ -78,7 +78,7 @@ type fn_ctxt = // Used for ast_ty_to_ty() below. -type ty_getter = fn(&ast::def_id) -> ty::ty_param_count_and_ty ; +type ty_getter = fn(&ast::def_id) -> ty::ty_param_kinds_and_ty ; fn lookup_local(fcx: &@fn_ctxt, sp: &span, id: ast::node_id) -> int { alt fcx.locals.find(id) { @@ -103,23 +103,24 @@ fn lookup_def(fcx: &@fn_ctxt, sp: &span, id: ast::node_id) -> ast::def { } // Returns the type parameter count and the type for the given definition. -fn ty_param_count_and_ty_for_def(fcx: &@fn_ctxt, sp: &span, defn: &ast::def) - -> ty_param_count_and_ty { +fn ty_param_kinds_and_ty_for_def(fcx: &@fn_ctxt, sp: &span, defn: &ast::def) + -> ty_param_kinds_and_ty { + let no_kinds: ast::kind[] = ~[]; alt defn { ast::def_arg(id) { assert (fcx.locals.contains_key(id.node)); let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, id.node)); - ret {count: 0u, ty: typ}; + ret {kinds: no_kinds, ty: typ}; } ast::def_local(id) { assert (fcx.locals.contains_key(id.node)); let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, id.node)); - ret {count: 0u, ty: typ}; + ret {kinds: no_kinds, ty: typ}; } ast::def_obj_field(id) { assert (fcx.locals.contains_key(id.node)); let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, id.node)); - ret {count: 0u, ty: typ}; + ret {kinds: no_kinds, ty: typ}; } ast::def_fn(id, _) { ret ty::lookup_item_type(fcx.ccx.tcx, id); } ast::def_native_fn(id) { ret ty::lookup_item_type(fcx.ccx.tcx, id); } @@ -128,13 +129,13 @@ fn ty_param_count_and_ty_for_def(fcx: &@fn_ctxt, sp: &span, defn: &ast::def) ast::def_binding(id) { assert (fcx.locals.contains_key(id.node)); let typ = ty::mk_var(fcx.ccx.tcx, lookup_local(fcx, sp, id.node)); - ret {count: 0u, ty: typ}; + ret {kinds: no_kinds, ty: typ}; } ast::def_mod(_) { // Hopefully part of a path. // TODO: return a type that's more poisonous, perhaps? - ret {count: 0u, ty: ty::mk_nil(fcx.ccx.tcx)}; + ret {kinds: no_kinds, ty: ty::mk_nil(fcx.ccx.tcx)}; } ast::def_ty(_) { fcx.ccx.tcx.sess.span_fatal(sp, "expected value but found type"); @@ -151,9 +152,9 @@ fn ty_param_count_and_ty_for_def(fcx: &@fn_ctxt, sp: &span, defn: &ast::def) // Instantiates the given path, which must refer to an item with the given // number of type parameters and type. fn instantiate_path(fcx: &@fn_ctxt, pth: &ast::path, - tpt: &ty_param_count_and_ty, sp: &span) -> + tpt: &ty_param_kinds_and_ty, sp: &span) -> ty_param_substs_opt_and_ty { - let ty_param_count = tpt.count; + let ty_param_count = ivec::len(tpt.kinds); let bind_result = bind_params_in_type(sp, fcx.ccx.tcx, bind next_ty_var_id(fcx), tpt.ty, ty_param_count); @@ -287,7 +288,9 @@ fn ast_ty_to_ty(tcx: &ty::ctxt, getter: &ty_getter, ast_ty: &@ast::ty) -> // "foo = int" like OCaml? let params_opt_and_ty = getter(id); - if params_opt_and_ty.count == 0u { ret params_opt_and_ty.ty; } + if ivec::len(params_opt_and_ty.kinds) == 0u { + ret params_opt_and_ty.ty; + } // The typedef is type-parametric. Do the type substitution. // @@ -421,7 +424,7 @@ fn ast_ty_to_ty(tcx: &ty::ctxt, getter: &ty_getter, ast_ty: &@ast::ty) -> // ast_ty_to_ty. fn ast_ty_to_ty_crate(ccx: @crate_ctxt, ast_ty: &@ast::ty) -> ty::t { fn getter(ccx: @crate_ctxt, id: &ast::def_id) -> - ty::ty_param_count_and_ty { + ty::ty_param_kinds_and_ty { ret ty::lookup_item_type(ccx.tcx, id); } let f = bind getter(ccx, _); @@ -512,11 +515,20 @@ mod collect { } ret tps; } + + fn ty_param_kinds(tps: &ast::ty_param[]) -> ast::kind[] { + let k: ast::kind[] = ~[]; + for p: ast::ty_param in tps { + k += ~[p.kind] + } + ret k; + } + fn ty_of_fn_decl(cx: &@ctxt, convert: &fn(&@ast::ty) -> ty::t , ty_of_arg: &fn(&ast::arg) -> arg , decl: &ast::fn_decl, proto: ast::proto, ty_params: &ast::ty_param[], def_id: &option::t[ast::def_id]) -> - ty::ty_param_count_and_ty { + ty::ty_param_kinds_and_ty { let input_tys = ~[]; for a: ast::arg in decl.inputs { input_tys += ~[ty_of_arg(a)]; } let output_ty = convert(decl.output); @@ -528,8 +540,7 @@ mod collect { let t_fn = ty::mk_fn(cx.tcx, proto_to_ty_proto(proto), input_tys, output_ty, decl.cf, out_constrs); - let ty_param_count = ivec::len[ast::ty_param](ty_params); - let tpt = {count: ty_param_count, ty: t_fn}; + let tpt = {kinds: ty_param_kinds(ty_params), ty: t_fn}; alt def_id { some(did) { cx.tcx.tcache.insert(did, tpt); } _ { } } ret tpt; } @@ -537,18 +548,17 @@ mod collect { ty_of_arg: &fn(&ast::arg) -> arg , decl: &ast::fn_decl, abi: ast::native_abi, ty_params: &ast::ty_param[], def_id: &ast::def_id) - -> ty::ty_param_count_and_ty { + -> ty::ty_param_kinds_and_ty { let input_tys = ~[]; for a: ast::arg in decl.inputs { input_tys += ~[ty_of_arg(a)]; } let output_ty = convert(decl.output); let t_fn = ty::mk_native_fn(cx.tcx, abi, input_tys, output_ty); - let ty_param_count = ivec::len[ast::ty_param](ty_params); - let tpt = {count: ty_param_count, ty: t_fn}; + let tpt = {kinds: ty_param_kinds(ty_params), ty: t_fn}; cx.tcx.tcache.insert(def_id, tpt); ret tpt; } - fn getter(cx: @ctxt, id: &ast::def_id) -> ty::ty_param_count_and_ty { + fn getter(cx: @ctxt, id: &ast::def_id) -> ty::ty_param_kinds_and_ty { if id.crate != ast::local_crate { // This is a type we need to load in from the crate reader. ret csearch::get_type(cx.tcx, id); @@ -603,15 +613,15 @@ mod collect { constrs: out_constrs}; } fn ty_of_obj(cx: @ctxt, id: &ast::ident, ob: &ast::_obj, - ty_params: &ast::ty_param[]) -> ty::ty_param_count_and_ty { + ty_params: &ast::ty_param[]) -> ty::ty_param_kinds_and_ty { let methods = get_obj_method_types(cx, ob); let t_obj = ty::mk_obj(cx.tcx, ty::sort_methods(methods)); t_obj = ty::rename(cx.tcx, t_obj, id); - ret {count: ivec::len(ty_params), ty: t_obj}; + ret {kinds: ty_param_kinds(ty_params), ty: t_obj}; } fn ty_of_obj_ctor(cx: @ctxt, id: &ast::ident, ob: &ast::_obj, ctor_id: ast::node_id, ty_params: &ast::ty_param[]) -> - ty::ty_param_count_and_ty { + ty::ty_param_kinds_and_ty { let t_obj = ty_of_obj(cx, id, ob, ty_params); let t_inputs: arg[] = ~[]; @@ -624,17 +634,18 @@ mod collect { let t_fn = ty::mk_fn(cx.tcx, ast::proto_fn, t_inputs, t_obj.ty, ast::return, ~[]); - let tpt = {count: t_obj.count, ty: t_fn}; + let tpt = {kinds: ty_param_kinds(ty_params), ty: t_fn}; cx.tcx.tcache.insert(local_def(ctor_id), tpt); ret tpt; } - fn ty_of_item(cx: &@ctxt, it: &@ast::item) -> ty::ty_param_count_and_ty { + fn ty_of_item(cx: &@ctxt, it: &@ast::item) -> ty::ty_param_kinds_and_ty { let get = bind getter(cx, _); let convert = bind ast_ty_to_ty(cx.tcx, get, _); + let no_kinds: ast::kind[] = ~[]; alt it.node { ast::item_const(t, _) { let typ = convert(t); - let tpt = {count: 0u, ty: typ}; + let tpt = {kinds: no_kinds, ty: typ}; cx.tcx.tcache.insert(local_def(it.id), tpt); ret tpt; } @@ -657,15 +668,14 @@ mod collect { // call to resolve any named types. let typ = convert(t); - let ty_param_count = ivec::len[ast::ty_param](tps); - let tpt = {count: ty_param_count, ty: typ}; + let tpt = {kinds: ty_param_kinds(tps), ty: typ}; cx.tcx.tcache.insert(local_def(it.id), tpt); ret tpt; } ast::item_res(f, _, tps, _) { let t_arg = ty_of_arg(cx, f.decl.inputs.(0)); let t_res = - {count: ivec::len(tps), + {kinds: ty_param_kinds(tps), ty: ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty, mk_ty_params(cx, tps))}; @@ -674,12 +684,9 @@ mod collect { } ast::item_tag(_, tps) { // Create a new generic polytype. - - let ty_param_count = ivec::len[ast::ty_param](tps); - let subtys: ty::t[] = mk_ty_params(cx, tps); let t = ty::mk_tag(cx.tcx, local_def(it.id), subtys); - let tpt = {count: ty_param_count, ty: t}; + let tpt = {kinds: ty_param_kinds(tps), ty: t}; cx.tcx.tcache.insert(local_def(it.id), tpt); ret tpt; } @@ -688,7 +695,8 @@ mod collect { } } fn ty_of_native_item(cx: &@ctxt, it: &@ast::native_item, - abi: ast::native_abi) -> ty::ty_param_count_and_ty { + abi: ast::native_abi) -> ty::ty_param_kinds_and_ty { + let no_kinds: ast::kind[] = ~[]; alt it.node { ast::native_item_fn(_, fn_decl, params) { let get = bind getter(cx, _); @@ -703,7 +711,7 @@ mod collect { none. { } } let t = ty::mk_native(cx.tcx, ast::local_def(it.id)); - let tpt = {count: 0u, ty: t}; + let tpt = {kinds: no_kinds, ty: t}; cx.tcx.tcache.insert(local_def(it.id), tpt); ret tpt; } @@ -714,7 +722,6 @@ mod collect { ty_params: &ast::ty_param[]) { // Create a set of parameter types shared among all the variants. - let ty_param_count = ivec::len[ast::ty_param](ty_params); let ty_param_tys: ty::t[] = mk_ty_params(cx, ty_params); for variant: ast::variant in variants { // Nullary tag constructors get turned into constants; n-ary tag @@ -739,7 +746,7 @@ mod collect { ty::mk_fn(cx.tcx, ast::proto_fn, args, tag_t, ast::return, ~[]); } - let tpt = {count: ty_param_count, ty: result_ty}; + let tpt = {kinds: ty_param_kinds(ty_params), ty: result_ty}; cx.tcx.tcache.insert(local_def(variant.node.id), tpt); write::ty_only(cx.tcx, variant.node.id, result_ty); } @@ -819,7 +826,7 @@ mod collect { write::ty_only(cx.tcx, it.id, t_res); write::ty_only(cx.tcx, ctor_id, t_ctor); cx.tcx.tcache.insert(local_def(ctor_id), - {count: ivec::len(tps), ty: t_ctor}); + {kinds: ty_param_kinds(tps), ty: t_ctor}); write::ty_only(cx.tcx, dtor_id, t_dtor); } _ { @@ -1792,7 +1799,7 @@ fn check_expr(fcx: &@fn_ctxt, expr: &@ast::expr) -> bool { } ast::expr_path(pth) { let defn = lookup_def(fcx, pth.span, id); - let tpt = ty_param_count_and_ty_for_def(fcx, expr.span, defn); + let tpt = ty_param_kinds_and_ty_for_def(fcx, expr.span, defn); if ty::def_has_ty_params(defn) { let path_tpot = instantiate_path(fcx, pth, tpt, expr.span); write::ty_fixup(fcx, id, path_tpot); |
