Encode, decode, and thread through typechecking all the param kinds, not just the counts.
This commit is contained in:
parent
a684f6078f
commit
59c441a66a
8 changed files with 143 additions and 104 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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"; }
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue