Substitute type parameters more eagerly
This simplifies the typechecker a bit (no more ty_param_substs_opt_and_ty) and is needed for another experiment I'm playing with. I hope it also makes compilation faster (the bots will tell).
This commit is contained in:
parent
964bd485c6
commit
86d473ad1f
|
@ -8,7 +8,7 @@ import syntax::ast_util::local_def;
|
|||
import common::*;
|
||||
import middle::trans::common::crate_ctxt;
|
||||
import middle::ty;
|
||||
import middle::ty::node_id_to_monotype;
|
||||
import middle::ty::node_id_to_type;
|
||||
import front::attr;
|
||||
|
||||
export encode_metadata;
|
||||
|
@ -243,7 +243,7 @@ fn encode_enum_variant_info(ecx: @encode_ctxt, ebml_w: ebml::writer,
|
|||
encode_name(ebml_w, variant.node.name);
|
||||
encode_enum_id(ebml_w, local_def(id));
|
||||
encode_type(ecx, ebml_w,
|
||||
node_id_to_monotype(ecx.ccx.tcx, variant.node.id));
|
||||
node_id_to_type(ecx.ccx.tcx, variant.node.id));
|
||||
if vec::len::<variant_arg>(variant.node.args) > 0u {
|
||||
encode_symbol(ecx, ebml_w, variant.node.id);
|
||||
}
|
||||
|
@ -287,7 +287,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
ebml::start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(item.id));
|
||||
encode_family(ebml_w, 'c' as u8);
|
||||
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_symbol(ecx, ebml_w, item.id);
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
|
@ -301,7 +301,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
impure_fn { 'f' }
|
||||
} as u8);
|
||||
encode_type_param_bounds(ebml_w, ecx, tps);
|
||||
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_symbol(ecx, ebml_w, item.id);
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
encode_def_id(ebml_w, local_def(item.id));
|
||||
encode_family(ebml_w, 'y' as u8);
|
||||
encode_type_param_bounds(ebml_w, ecx, tps);
|
||||
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_name(ebml_w, item.ident);
|
||||
ebml::end_tag(ebml_w);
|
||||
}
|
||||
|
@ -329,7 +329,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
encode_def_id(ebml_w, local_def(item.id));
|
||||
encode_family(ebml_w, 't' as u8);
|
||||
encode_type_param_bounds(ebml_w, ecx, tps);
|
||||
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_name(ebml_w, item.ident);
|
||||
for v: variant in variants {
|
||||
encode_variant_id(ebml_w, local_def(v.node.id));
|
||||
|
@ -338,7 +338,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
encode_enum_variant_info(ecx, ebml_w, item.id, variants, index, tps);
|
||||
}
|
||||
item_res(_, tps, _, _, ctor_id) {
|
||||
let fn_ty = node_id_to_monotype(tcx, ctor_id);
|
||||
let fn_ty = node_id_to_type(tcx, ctor_id);
|
||||
|
||||
ebml::start_tag(ebml_w, tag_items_data_item);
|
||||
encode_def_id(ebml_w, local_def(ctor_id));
|
||||
|
@ -363,7 +363,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
encode_def_id(ebml_w, local_def(item.id));
|
||||
encode_family(ebml_w, 'i' as u8);
|
||||
encode_type_param_bounds(ebml_w, ecx, tps);
|
||||
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_name(ebml_w, item.ident);
|
||||
for m in methods {
|
||||
ebml::start_tag(ebml_w, tag_item_method);
|
||||
|
@ -389,7 +389,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
encode_family(ebml_w, 'f' as u8);
|
||||
encode_type_param_bounds(ebml_w, ecx, tps + m.tps);
|
||||
encode_type(ecx, ebml_w,
|
||||
node_id_to_monotype(tcx, m.id));
|
||||
node_id_to_type(tcx, m.id));
|
||||
encode_name(ebml_w, m.ident);
|
||||
encode_symbol(ecx, ebml_w, m.id);
|
||||
ebml::end_tag(ebml_w);
|
||||
|
@ -400,7 +400,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item,
|
|||
encode_def_id(ebml_w, local_def(item.id));
|
||||
encode_family(ebml_w, 'I' as u8);
|
||||
encode_type_param_bounds(ebml_w, ecx, tps);
|
||||
encode_type(ecx, ebml_w, node_id_to_monotype(tcx, item.id));
|
||||
encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id));
|
||||
encode_name(ebml_w, item.ident);
|
||||
let i = 0u;
|
||||
for mty in *ty::iface_methods(tcx, local_def(item.id)) {
|
||||
|
@ -435,7 +435,7 @@ fn encode_info_for_native_item(ecx: @encode_ctxt, ebml_w: ebml::writer,
|
|||
encode_def_id(ebml_w, local_def(nitem.id));
|
||||
encode_family(ebml_w, letter);
|
||||
encode_type_param_bounds(ebml_w, ecx, tps);
|
||||
encode_type(ecx, ebml_w, node_id_to_monotype(ecx.ccx.tcx, nitem.id));
|
||||
encode_type(ecx, ebml_w, node_id_to_type(ecx.ccx.tcx, nitem.id));
|
||||
encode_symbol(ecx, ebml_w, nitem.id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -59,7 +59,7 @@ fn check_crate(tcx: ty::ctxt, method_map: typeck::method_map,
|
|||
// closure.
|
||||
fn with_appropriate_checker(cx: ctx, id: node_id,
|
||||
b: fn(fn@(ctx, ty::t, sp: span))) {
|
||||
let fty = ty::node_id_to_monotype(cx.tcx, id);
|
||||
let fty = ty::node_id_to_type(cx.tcx, id);
|
||||
alt ty::ty_fn_proto(cx.tcx, fty) {
|
||||
proto_uniq { b(check_send); }
|
||||
proto_box { b(check_copy); }
|
||||
|
@ -168,8 +168,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
|
|||
}
|
||||
}
|
||||
expr_path(_) {
|
||||
let substs = ty::node_id_to_ty_param_substs_opt_and_ty(cx.tcx, e.id);
|
||||
alt substs.substs {
|
||||
alt cx.tcx.node_type_substs.find(e.id) {
|
||||
some(ts) {
|
||||
let did = ast_util::def_id_of_def(cx.tcx.def_map.get(e.id));
|
||||
let bounds = ty::lookup_item_type(cx.tcx, did).bounds;
|
||||
|
|
|
@ -64,7 +64,7 @@ fn find_last_uses(c: @crate, def_map: resolve::def_map,
|
|||
}
|
||||
|
||||
fn ex_is_blockish(cx: ctx, id: node_id) -> bool {
|
||||
alt ty::struct(cx.tcx, ty::node_id_to_monotype(cx.tcx, id)) {
|
||||
alt ty::struct(cx.tcx, ty::node_id_to_type(cx.tcx, id)) {
|
||||
ty::ty_fn({proto: p, _}) if is_blockish(p) { true }
|
||||
_ { false }
|
||||
}
|
||||
|
|
|
@ -268,7 +268,7 @@ fn is_immutable_def(cx: @ctx, def: def) -> option::t<str> {
|
|||
def_arg(_, mode_infer) { some("argument") }
|
||||
def_self(_) { some("self argument") }
|
||||
def_upvar(_, inner, node_id) {
|
||||
let ty = ty::node_id_to_monotype(cx.tcx, node_id);
|
||||
let ty = ty::node_id_to_type(cx.tcx, node_id);
|
||||
let proto = ty::ty_fn_proto(cx.tcx, ty);
|
||||
ret alt proto {
|
||||
proto_any | proto_block { is_immutable_def(cx, *inner) }
|
||||
|
|
|
@ -419,7 +419,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
|||
let rec_fields = collect_record_fields(m, col);
|
||||
// Separate path for extracting and binding record fields
|
||||
if vec::len(rec_fields) > 0u {
|
||||
let rec_ty = ty::node_id_to_monotype(ccx.tcx, pat_id);
|
||||
let rec_ty = ty::node_id_to_type(ccx.tcx, pat_id);
|
||||
let fields =
|
||||
alt ty::struct(ccx.tcx, rec_ty) { ty::ty_rec(fields) { fields } };
|
||||
let rec_vals = [];
|
||||
|
@ -437,7 +437,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
|||
}
|
||||
|
||||
if any_tup_pat(m, col) {
|
||||
let tup_ty = ty::node_id_to_monotype(ccx.tcx, pat_id);
|
||||
let tup_ty = ty::node_id_to_type(ccx.tcx, pat_id);
|
||||
let n_tup_elts =
|
||||
alt ty::struct(ccx.tcx, tup_ty) {
|
||||
ty::ty_tup(elts) { vec::len(elts) }
|
||||
|
@ -492,7 +492,7 @@ fn compile_submatch(bcx: @block_ctxt, m: match, vals: [ValueRef], f: mk_fail,
|
|||
}
|
||||
lit(l) {
|
||||
test_val = Load(bcx, val);
|
||||
let pty = ty::node_id_to_monotype(ccx.tcx, pat_id);
|
||||
let pty = ty::node_id_to_type(ccx.tcx, pat_id);
|
||||
kind = ty::type_is_integral(ccx.tcx, pty) ? switch : compare;
|
||||
}
|
||||
range(_, _) {
|
||||
|
@ -709,7 +709,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
|
|||
alt normalize_pat(bcx_tcx(bcx), pat).node {
|
||||
ast::pat_ident(_,inner) {
|
||||
if make_copy || ccx.copy_map.contains_key(pat.id) {
|
||||
let ty = ty::node_id_to_monotype(ccx.tcx, pat.id);
|
||||
let ty = ty::node_id_to_type(ccx.tcx, pat.id);
|
||||
// FIXME: Could constrain pat_bind to make this
|
||||
// check unnecessary.
|
||||
check (type_has_static_size(ccx, ty));
|
||||
|
@ -737,7 +737,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
|
|||
}
|
||||
}
|
||||
ast::pat_rec(fields, _) {
|
||||
let rec_ty = ty::node_id_to_monotype(ccx.tcx, pat.id);
|
||||
let rec_ty = ty::node_id_to_type(ccx.tcx, pat.id);
|
||||
let rec_fields =
|
||||
alt ty::struct(ccx.tcx, rec_ty) { ty::ty_rec(fields) { fields } };
|
||||
for f: ast::field_pat in fields {
|
||||
|
@ -749,7 +749,7 @@ fn bind_irrefutable_pat(bcx: @block_ctxt, pat: @ast::pat, val: ValueRef,
|
|||
}
|
||||
}
|
||||
ast::pat_tup(elems) {
|
||||
let tup_ty = ty::node_id_to_monotype(ccx.tcx, pat.id);
|
||||
let tup_ty = ty::node_id_to_type(ccx.tcx, pat.id);
|
||||
let i = 0u;
|
||||
for elem in elems {
|
||||
// how to get rid of this check?
|
||||
|
|
|
@ -2048,7 +2048,7 @@ fn trans_lit(cx: @block_ctxt, lit: ast::lit, dest: dest) -> @block_ctxt {
|
|||
|
||||
// Converts an annotation to a type
|
||||
fn node_id_type(cx: @crate_ctxt, id: ast::node_id) -> ty::t {
|
||||
ret ty::node_id_to_monotype(cx.tcx, id);
|
||||
ret ty::node_id_to_type(cx.tcx, id);
|
||||
}
|
||||
|
||||
fn trans_unary(bcx: @block_ctxt, op: ast::unop, e: @ast::expr,
|
||||
|
@ -2057,7 +2057,7 @@ fn trans_unary(bcx: @block_ctxt, op: ast::unop, e: @ast::expr,
|
|||
alt bcx_ccx(bcx).method_map.find(un_expr.id) {
|
||||
some(origin) {
|
||||
let callee_id = ast_util::op_expr_callee_id(un_expr);
|
||||
let fty = ty::node_id_to_monotype(bcx_tcx(bcx), callee_id);
|
||||
let fty = ty::node_id_to_type(bcx_tcx(bcx), callee_id);
|
||||
ret trans_call_inner(bcx, fty, {|bcx|
|
||||
impl::trans_method_callee(bcx, callee_id, e, origin)
|
||||
}, [], un_expr.id, dest);
|
||||
|
@ -2195,7 +2195,7 @@ fn trans_assign_op(bcx: @block_ctxt, ex: @ast::expr, op: ast::binop,
|
|||
alt bcx_ccx(bcx).method_map.find(ex.id) {
|
||||
some(origin) {
|
||||
let callee_id = ast_util::op_expr_callee_id(ex);
|
||||
let fty = ty::node_id_to_monotype(bcx_tcx(bcx), callee_id);
|
||||
let fty = ty::node_id_to_type(bcx_tcx(bcx), callee_id);
|
||||
ret trans_call_inner(bcx, fty, {|bcx|
|
||||
// FIXME provide the already-computed address, not the expr
|
||||
impl::trans_method_callee(bcx, callee_id, dst, origin)
|
||||
|
@ -2317,7 +2317,7 @@ fn trans_binary(bcx: @block_ctxt, op: ast::binop, lhs: @ast::expr,
|
|||
alt bcx_ccx(bcx).method_map.find(ex.id) {
|
||||
some(origin) {
|
||||
let callee_id = ast_util::op_expr_callee_id(ex);
|
||||
let fty = ty::node_id_to_monotype(bcx_tcx(bcx), callee_id);
|
||||
let fty = ty::node_id_to_type(bcx_tcx(bcx), callee_id);
|
||||
ret trans_call_inner(bcx, fty, {|bcx|
|
||||
impl::trans_method_callee(bcx, callee_id, lhs, origin)
|
||||
}, [rhs], ex.id, dest);
|
||||
|
@ -2681,7 +2681,7 @@ fn trans_var(cx: @block_ctxt, def: ast::def, id: ast::node_id)
|
|||
assert (ccx.consts.contains_key(did.node));
|
||||
ret lval_no_env(cx, ccx.consts.get(did.node), owned);
|
||||
} else {
|
||||
let tp = ty::node_id_to_monotype(ccx.tcx, id);
|
||||
let tp = ty::node_id_to_type(ccx.tcx, id);
|
||||
let val = trans_external_path(cx, did, {bounds: @[], ty: tp});
|
||||
ret lval_no_env(cx, load_if_immediate(cx, val, tp), owned_imm);
|
||||
}
|
||||
|
@ -3544,7 +3544,7 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
|
|||
// If it is here, it's not an lval, so this is a user-defined index op
|
||||
let origin = bcx_ccx(bcx).method_map.get(e.id);
|
||||
let callee_id = ast_util::op_expr_callee_id(e);
|
||||
let fty = ty::node_id_to_monotype(tcx, callee_id);
|
||||
let fty = ty::node_id_to_type(tcx, callee_id);
|
||||
ret trans_call_inner(bcx, fty, {|bcx|
|
||||
impl::trans_method_callee(bcx, callee_id, base, origin)
|
||||
}, [idx], e.id, dest);
|
||||
|
|
|
@ -417,7 +417,7 @@ fn build_closure(bcx0: @block_ctxt,
|
|||
vec::iter(cap_vars) { |cap_var|
|
||||
let lv = trans_local_var(bcx, cap_var.def);
|
||||
let nid = ast_util::def_id_of_def(cap_var.def).node;
|
||||
let ty = ty::node_id_to_monotype(tcx, nid);
|
||||
let ty = ty::node_id_to_type(tcx, nid);
|
||||
alt cap_var.mode {
|
||||
capture::cap_ref {
|
||||
assert ck == ty::ck_block;
|
||||
|
|
|
@ -46,7 +46,7 @@ fn trans_impl(cx: @local_ctxt, name: ast::ident, methods: [@ast::method],
|
|||
alt cx.ccx.item_ids.find(m.id) {
|
||||
some(llfn) {
|
||||
trans_fn(extend_path(sub_cx, m.ident), m.span, m.decl, m.body,
|
||||
llfn, impl_self(ty::node_id_to_monotype(cx.ccx.tcx, id)),
|
||||
llfn, impl_self(ty::node_id_to_type(cx.ccx.tcx, id)),
|
||||
tps + m.tps, m.id);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,10 +22,8 @@ import util::ppaux::ty_constr_to_str;
|
|||
import util::ppaux::mode_str;
|
||||
import syntax::print::pprust::*;
|
||||
|
||||
export node_id_to_monotype;
|
||||
export node_id_to_type;
|
||||
export node_id_to_type_params;
|
||||
export node_id_to_ty_param_substs_opt_and_ty;
|
||||
export arg;
|
||||
export args_eq;
|
||||
export ast_constr_to_constr;
|
||||
|
@ -103,7 +101,6 @@ export new_ty_hash;
|
|||
export enum_variants;
|
||||
export iface_methods, store_iface_methods, impl_iface;
|
||||
export enum_variant_with_id;
|
||||
export ty_param_substs_opt_and_ty;
|
||||
export ty_param_bounds_and_ty;
|
||||
export ty_bool;
|
||||
export ty_bot;
|
||||
|
@ -136,7 +133,6 @@ export ty_var;
|
|||
export ty_named;
|
||||
export same_type;
|
||||
export ty_var_id;
|
||||
export ty_param_substs_opt_and_ty_to_monotype;
|
||||
export ty_fn_args;
|
||||
export type_constr;
|
||||
export type_contains_params;
|
||||
|
@ -212,6 +208,7 @@ type ctxt =
|
|||
sess: session::session,
|
||||
def_map: resolve::def_map,
|
||||
node_types: node_type_table,
|
||||
node_type_substs: hashmap<node_id, [t]>,
|
||||
items: ast_map::map,
|
||||
freevars: freevars::freevar_map,
|
||||
tcache: type_cache,
|
||||
|
@ -369,12 +366,7 @@ const idx_first_others: uint = 20u;
|
|||
|
||||
type type_store = interner::interner<@raw_t>;
|
||||
|
||||
// substs is a list of actuals that correspond to ty's
|
||||
// formal parameters
|
||||
type ty_param_substs_opt_and_ty = {substs: option::t<[ty::t]>, ty: ty::t};
|
||||
|
||||
type node_type_table =
|
||||
@smallintmap::smallintmap<ty::ty_param_substs_opt_and_ty>;
|
||||
type node_type_table = @smallintmap::smallintmap<t>;
|
||||
|
||||
fn populate_type_store(cx: ctxt) {
|
||||
intern(cx, ty_nil);
|
||||
|
@ -415,8 +407,6 @@ fn new_ty_hash<V: copy>() -> map::hashmap<t, V> { map::new_uint_hash() }
|
|||
|
||||
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>();
|
||||
fn eq_raw_ty(&&a: @raw_t, &&b: @raw_t) -> bool {
|
||||
ret a.hash == b.hash && a.struct == b.struct;
|
||||
}
|
||||
|
@ -425,7 +415,8 @@ fn mk_ctxt(s: session::session, dm: resolve::def_map, amap: ast_map::map,
|
|||
@{ts: ts,
|
||||
sess: s,
|
||||
def_map: dm,
|
||||
node_types: ntt,
|
||||
node_types: @smallintmap::mk(),
|
||||
node_type_substs: map::new_int_hash(),
|
||||
items: amap,
|
||||
freevars: freevars,
|
||||
tcache: new_def_hash(),
|
||||
|
@ -1442,55 +1433,21 @@ fn constrs_eq(cs: [@constr], ds: [@constr]) -> bool {
|
|||
ret true;
|
||||
}
|
||||
|
||||
// Type lookups
|
||||
fn node_id_to_ty_param_substs_opt_and_ty(cx: ctxt, id: ast::node_id) ->
|
||||
ty_param_substs_opt_and_ty {
|
||||
// Pull out the node type table.
|
||||
alt smallintmap::find(*cx.node_types, id as uint) {
|
||||
none {
|
||||
cx.sess.bug("node_id_to_ty_param_substs_opt_and_ty() called on " +
|
||||
"an untyped node (" + int::to_str(id, 10u) +
|
||||
")");
|
||||
}
|
||||
some(tpot) { ret tpot; }
|
||||
}
|
||||
}
|
||||
|
||||
fn node_id_to_type(cx: ctxt, id: ast::node_id) -> t {
|
||||
ret node_id_to_ty_param_substs_opt_and_ty(cx, id).ty;
|
||||
smallintmap::get(*cx.node_types, id as uint)
|
||||
}
|
||||
|
||||
fn node_id_to_type_params(cx: ctxt, id: ast::node_id) -> [t] {
|
||||
alt node_id_to_ty_param_substs_opt_and_ty(cx, id).substs {
|
||||
alt cx.node_type_substs.find(id) {
|
||||
none { ret []; }
|
||||
some(tps) { ret tps; }
|
||||
some(ts) { ret ts; }
|
||||
}
|
||||
}
|
||||
|
||||
fn node_id_has_type_params(cx: ctxt, id: ast::node_id) -> bool {
|
||||
ret vec::len(node_id_to_type_params(cx, id)) > 0u;
|
||||
ret cx.node_type_substs.contains_key(id);
|
||||
}
|
||||
|
||||
|
||||
// Returns a type with type parameter substitutions performed if applicable
|
||||
fn ty_param_substs_opt_and_ty_to_monotype(cx: ctxt,
|
||||
tpot: ty_param_substs_opt_and_ty) ->
|
||||
t {
|
||||
alt tpot.substs {
|
||||
none { ret tpot.ty; }
|
||||
some(tps) { ret substitute_type_params(cx, tps, tpot.ty); }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Returns the type of an annotation, with type parameter substitutions
|
||||
// performed if applicable
|
||||
fn node_id_to_monotype(cx: ctxt, id: ast::node_id) -> t {
|
||||
let tpot = node_id_to_ty_param_substs_opt_and_ty(cx, id);
|
||||
ret ty_param_substs_opt_and_ty_to_monotype(cx, tpot);
|
||||
}
|
||||
|
||||
|
||||
// Returns the number of distinct type parameters in the given type.
|
||||
fn count_ty_params(cx: ctxt, ty: t) -> uint {
|
||||
fn counter(cx: ctxt, param_indices: @mutable [uint], ty: t) {
|
||||
|
@ -1587,7 +1544,7 @@ fn block_ty(cx: ctxt, b: ast::blk) -> t {
|
|||
// Returns the type of a pattern as a monotype. Like @expr_ty, this function
|
||||
// doesn't provide type parameter substitutions.
|
||||
fn pat_ty(cx: ctxt, pat: @ast::pat) -> t {
|
||||
ret node_id_to_monotype(cx, pat.id);
|
||||
ret node_id_to_type(cx, pat.id);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1598,7 +1555,7 @@ fn pat_ty(cx: ctxt, pat: @ast::pat) -> t {
|
|||
// instead of "fn(t) -> T with T = int". If this isn't what you want, see
|
||||
// expr_ty_params_and_ty() below.
|
||||
fn expr_ty(cx: ctxt, expr: @ast::expr) -> t {
|
||||
ret node_id_to_monotype(cx, expr.id);
|
||||
ret node_id_to_type(cx, expr.id);
|
||||
}
|
||||
|
||||
fn expr_ty_params_and_ty(cx: ctxt, expr: @ast::expr) -> {params: [t], ty: t} {
|
||||
|
@ -1740,7 +1697,6 @@ mod unify {
|
|||
}
|
||||
);
|
||||
|
||||
|
||||
alt smallintmap::find(vb.types, root_a) {
|
||||
none {
|
||||
alt smallintmap::find(vb.types, root_b) {
|
||||
|
@ -2534,7 +2490,6 @@ fn type_err_to_str(err: ty::type_err) -> str {
|
|||
// Replaces type parameters in the given type using the given list of
|
||||
// substitions.
|
||||
fn substitute_type_params(cx: ctxt, substs: [ty::t], typ: t) -> t {
|
||||
|
||||
if !type_contains_params(cx, typ) { ret typ; }
|
||||
// Precondition? idx < vec::len(substs)
|
||||
fn substituter(_cx: ctxt, substs: @[ty::t], idx: uint, _did: def_id)
|
||||
|
@ -2603,7 +2558,7 @@ fn enum_variants(cx: ctxt, id: ast::def_id) -> @[variant_info] {
|
|||
ast_map::node_item(@{node: ast::item_enum(variants, _), _}) {
|
||||
let disr_val = -1;
|
||||
@vec::map(variants, {|variant|
|
||||
let ctor_ty = node_id_to_monotype(cx, variant.node.id);
|
||||
let ctor_ty = node_id_to_type(cx, variant.node.id);
|
||||
let arg_tys = if vec::len(variant.node.args) > 0u {
|
||||
vec::map(ty_fn_args(cx, ctor_ty), {|a| a.ty})
|
||||
} else { [] };
|
||||
|
|
|
@ -10,7 +10,7 @@ import pat_util::*;
|
|||
import middle::ty;
|
||||
import middle::ty::{node_id_to_type, arg, block_ty,
|
||||
expr_ty, field, node_type_table, mk_nil,
|
||||
ty_param_substs_opt_and_ty, ty_param_bounds_and_ty};
|
||||
ty_param_bounds_and_ty};
|
||||
import util::ppaux::ty_to_str;
|
||||
import middle::ty::unify::{ures_ok, ures_err, fix_ok, fix_err};
|
||||
import core::{int, vec, str, option};
|
||||
|
@ -137,33 +137,35 @@ fn ty_param_bounds_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_bounds_and_ty, sp: span)
|
||||
-> ty_param_substs_opt_and_ty {
|
||||
tpt: ty_param_bounds_and_ty, sp: span,
|
||||
id: ast::node_id) {
|
||||
let ty_param_count = vec::len(*tpt.bounds);
|
||||
let vars = vec::init_fn(ty_param_count, {|_i| next_ty_var(fcx)});
|
||||
let ty_substs_len = vec::len(pth.node.types);
|
||||
if ty_substs_len > 0u {
|
||||
let param_var_len = vec::len(vars);
|
||||
if param_var_len == 0u {
|
||||
if ty_param_count == 0u {
|
||||
fcx.ccx.tcx.sess.span_fatal
|
||||
(sp, "this item does not take type parameters");
|
||||
} else if ty_substs_len > param_var_len {
|
||||
} else if ty_substs_len > ty_param_count {
|
||||
fcx.ccx.tcx.sess.span_fatal
|
||||
(sp, "too many type parameter provided for this item");
|
||||
} else if ty_substs_len < param_var_len {
|
||||
} else if ty_substs_len < ty_param_count {
|
||||
fcx.ccx.tcx.sess.span_fatal
|
||||
(sp, "not enough type parameters provided for this item");
|
||||
}
|
||||
vec::iter2(pth.node.types, vars) {|sub, var|
|
||||
let ty_subst = ast_ty_to_ty_crate(fcx.ccx, sub);
|
||||
demand::simple(fcx, pth.span, var, ty_subst);
|
||||
}
|
||||
if ty_param_count == 0u {
|
||||
fcx.ccx.tcx.sess.span_fatal(
|
||||
sp, "this item does not take type parameters");
|
||||
}
|
||||
let substs = vec::map(pth.node.types, {|aty|
|
||||
ast_ty_to_ty_crate(fcx.ccx, aty)
|
||||
});
|
||||
write_ty_substs(fcx.ccx.tcx, id, tpt.ty, substs);
|
||||
} else if ty_param_count > 0u {
|
||||
let vars = vec::init_fn(ty_param_count, {|_i| next_ty_var(fcx)});
|
||||
write_ty_substs(fcx.ccx.tcx, id, tpt.ty, vars);
|
||||
} else {
|
||||
write_ty(fcx.ccx.tcx, id, tpt.ty);
|
||||
}
|
||||
{substs: some(vars), ty: tpt.ty}
|
||||
}
|
||||
|
||||
// Type tests
|
||||
|
@ -547,50 +549,25 @@ fn ast_ty_to_ty_crate_infer(ccx: @crate_ctxt, &&ast_ty: @ast::ty) ->
|
|||
|
||||
|
||||
// Functions that write types into the node type table
|
||||
mod write {
|
||||
fn inner(ntt: node_type_table, node_id: ast::node_id,
|
||||
tpot: ty_param_substs_opt_and_ty) {
|
||||
smallintmap::insert(*ntt, node_id as uint, tpot);
|
||||
}
|
||||
|
||||
// Writes a type parameter count and type pair into the node type table.
|
||||
fn ty(tcx: ty::ctxt, node_id: ast::node_id,
|
||||
tpot: ty_param_substs_opt_and_ty) {
|
||||
assert (!ty::type_contains_vars(tcx, tpot.ty));
|
||||
inner(tcx.node_types, node_id, tpot);
|
||||
}
|
||||
|
||||
// Writes a type parameter count and type pair into the node type table.
|
||||
// This function allows for the possibility of type variables, which will
|
||||
// be rewritten later during the fixup mode.
|
||||
fn ty_fixup(fcx: @fn_ctxt, node_id: ast::node_id,
|
||||
tpot: ty_param_substs_opt_and_ty) {
|
||||
inner(fcx.ccx.tcx.node_types, node_id, tpot);
|
||||
if ty::type_contains_vars(fcx.ccx.tcx, tpot.ty) {
|
||||
fcx.fixups += [node_id];
|
||||
}
|
||||
}
|
||||
|
||||
// Writes a type with no type parameters into the node type table.
|
||||
fn ty_only(tcx: ty::ctxt, node_id: ast::node_id, typ: ty::t) {
|
||||
ty(tcx, node_id, {substs: none::<[ty::t]>, ty: typ});
|
||||
}
|
||||
|
||||
// Writes a type with no type parameters into the node type table. This
|
||||
// function allows for the possibility of type variables.
|
||||
fn ty_only_fixup(fcx: @fn_ctxt, node_id: ast::node_id, typ: ty::t) {
|
||||
ret ty_fixup(fcx, node_id, {substs: none::<[ty::t]>, ty: typ});
|
||||
}
|
||||
|
||||
// Writes a nil type into the node type table.
|
||||
fn nil_ty(tcx: ty::ctxt, node_id: ast::node_id) {
|
||||
ret ty(tcx, node_id, {substs: none::<[ty::t]>, ty: ty::mk_nil(tcx)});
|
||||
}
|
||||
|
||||
// Writes the bottom type into the node type table.
|
||||
fn bot_ty(tcx: ty::ctxt, node_id: ast::node_id) {
|
||||
ret ty(tcx, node_id, {substs: none::<[ty::t]>, ty: ty::mk_bot(tcx)});
|
||||
}
|
||||
fn write_ty(tcx: ty::ctxt, node_id: ast::node_id, ty: ty::t) {
|
||||
smallintmap::insert(*tcx.node_types, node_id as uint, ty);
|
||||
}
|
||||
fn write_substs(tcx: ty::ctxt, node_id: ast::node_id, +substs: [ty::t]) {
|
||||
tcx.node_type_substs.insert(node_id, substs);
|
||||
}
|
||||
fn write_ty_substs(tcx: ty::ctxt, node_id: ast::node_id, ty: ty::t,
|
||||
+substs: [ty::t]) {
|
||||
let ty = if ty::type_contains_params(tcx, ty) {
|
||||
ty::substitute_type_params(tcx, substs, ty)
|
||||
} else { ty };
|
||||
write_ty(tcx, node_id, ty);
|
||||
write_substs(tcx, node_id, substs);
|
||||
}
|
||||
fn write_nil(tcx: ty::ctxt, node_id: ast::node_id) {
|
||||
write_ty(tcx, node_id, ty::mk_nil(tcx));
|
||||
}
|
||||
fn write_bot(tcx: ty::ctxt, node_id: ast::node_id) {
|
||||
write_ty(tcx, node_id, ty::mk_bot(tcx));
|
||||
}
|
||||
|
||||
fn mk_ty_params(tcx: ty::ctxt, atps: [ast::ty_param])
|
||||
|
@ -673,7 +650,7 @@ mod collect {
|
|||
let tpt = {bounds: ty_param_bounds(cx.tcx, m_collect, 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);
|
||||
write_ty(cx.tcx, variant.node.id, result_ty);
|
||||
}
|
||||
}
|
||||
fn convert(cx: @ctxt, it: @ast::item) {
|
||||
|
@ -682,7 +659,7 @@ mod collect {
|
|||
ast::item_mod(_) | ast::item_native_mod(_) {}
|
||||
ast::item_enum(variants, ty_params) {
|
||||
let tpt = ty_of_item(cx.tcx, m_collect, it);
|
||||
write::ty_only(cx.tcx, it.id, tpt.ty);
|
||||
write_ty(cx.tcx, it.id, tpt.ty);
|
||||
get_enum_variant_types(cx, tpt.ty, variants, ty_params);
|
||||
}
|
||||
ast::item_impl(tps, ifce, selfty, ms) {
|
||||
|
@ -696,9 +673,9 @@ mod collect {
|
|||
cx.tcx.tcache.insert(local_def(m.id),
|
||||
{bounds: @(*i_bounds + *bounds),
|
||||
ty: fty});
|
||||
write::ty_only(cx.tcx, m.id, fty);
|
||||
write_ty(cx.tcx, m.id, fty);
|
||||
}
|
||||
write::ty_only(cx.tcx, it.id, ast_ty_to_ty(cx.tcx, m_collect,
|
||||
write_ty(cx.tcx, it.id, ast_ty_to_ty(cx.tcx, m_collect,
|
||||
selfty));
|
||||
alt ifce {
|
||||
some(t) {
|
||||
|
@ -746,15 +723,15 @@ mod collect {
|
|||
inputs: [t_arg], output: ty::mk_nil(cx.tcx),
|
||||
ret_style: ast::return_val, constraints: []
|
||||
});
|
||||
write::ty_only(cx.tcx, it.id, t_res);
|
||||
write::ty_only(cx.tcx, ctor_id, t_ctor);
|
||||
write_ty(cx.tcx, it.id, t_res);
|
||||
write_ty(cx.tcx, ctor_id, t_ctor);
|
||||
cx.tcx.tcache.insert(local_def(ctor_id),
|
||||
{bounds: bounds, ty: t_ctor});
|
||||
write::ty_only(cx.tcx, dtor_id, t_dtor);
|
||||
write_ty(cx.tcx, dtor_id, t_dtor);
|
||||
}
|
||||
ast::item_iface(_, ms) {
|
||||
let tpt = ty_of_item(cx.tcx, m_collect, it);
|
||||
write::ty_only(cx.tcx, it.id, tpt.ty);
|
||||
write_ty(cx.tcx, it.id, tpt.ty);
|
||||
ty::store_iface_methods(cx.tcx, it.id, @vec::map(ms, {|m|
|
||||
ty_of_ty_method(cx.tcx, m_collect, m)
|
||||
}));
|
||||
|
@ -764,7 +741,7 @@ mod collect {
|
|||
// of the item in passing. All we have to do here is to write
|
||||
// it into the node type table.
|
||||
let tpt = ty_of_item(cx.tcx, m_collect, it);
|
||||
write::ty_only(cx.tcx, it.id, tpt.ty);
|
||||
write_ty(cx.tcx, it.id, tpt.ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -778,7 +755,7 @@ mod collect {
|
|||
// FIXME: Native types have no annotation. Should they? --pcw
|
||||
}
|
||||
ast::native_item_fn(_, _) {
|
||||
write::ty_only(cx.tcx, i.id, tpt.ty);
|
||||
write_ty(cx.tcx, i.id, tpt.ty);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -971,28 +948,24 @@ mod writeback {
|
|||
}
|
||||
}
|
||||
fn resolve_type_vars_for_node(wbcx: wb_ctxt, sp: span, id: ast::node_id) {
|
||||
let fcx = wbcx.fcx;
|
||||
let tpot = ty::node_id_to_ty_param_substs_opt_and_ty(fcx.ccx.tcx, id);
|
||||
let new_ty =
|
||||
alt resolve_type_vars_in_type(fcx, sp, tpot.ty) {
|
||||
some(t) { t }
|
||||
none { wbcx.success = false; ret }
|
||||
};
|
||||
let new_substs_opt;
|
||||
alt tpot.substs {
|
||||
none { new_substs_opt = none; }
|
||||
let fcx = wbcx.fcx, tcx = fcx.ccx.tcx;
|
||||
alt resolve_type_vars_in_type(fcx, sp, ty::node_id_to_type(tcx, id)) {
|
||||
some(t) { write_ty(tcx, id, t); }
|
||||
none { wbcx.success = false; ret }
|
||||
}
|
||||
alt tcx.node_type_substs.find(id) {
|
||||
some(substs) {
|
||||
let new_substs: [ty::t] = [];
|
||||
let new_substs = [];
|
||||
for subst: ty::t in substs {
|
||||
alt resolve_type_vars_in_type(fcx, sp, subst) {
|
||||
some(t) { new_substs += [t]; }
|
||||
none { wbcx.success = false; ret; }
|
||||
}
|
||||
}
|
||||
new_substs_opt = some(new_substs);
|
||||
write_substs(tcx, id, new_substs);
|
||||
}
|
||||
none {}
|
||||
}
|
||||
write::ty(fcx.ccx.tcx, id, {substs: new_substs_opt, ty: new_ty});
|
||||
}
|
||||
|
||||
type wb_ctxt =
|
||||
|
@ -1037,7 +1010,7 @@ mod writeback {
|
|||
ty::unify::resolve_type_var(wbcx.fcx.ccx.tcx, some(l.span),
|
||||
wbcx.fcx.var_bindings, var_id);
|
||||
alt fix_rslt {
|
||||
fix_ok(lty) { write::ty_only(wbcx.fcx.ccx.tcx, l.node.id, lty); }
|
||||
fix_ok(lty) { write_ty(wbcx.fcx.ccx.tcx, l.node.id, lty); }
|
||||
fix_err(_) {
|
||||
wbcx.fcx.ccx.tcx.sess.span_err(l.span,
|
||||
"cannot determine a type \
|
||||
|
@ -1185,53 +1158,48 @@ fn valid_range_bounds(from: @ast::expr, to: @ast::expr) -> bool {
|
|||
// their types immediately.
|
||||
fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
|
||||
expected: ty::t) {
|
||||
alt normalize_pat(fcx.ccx.tcx, pat).node {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
alt normalize_pat(tcx, pat).node {
|
||||
ast::pat_wild {
|
||||
alt structure_of(fcx, pat.span, expected) {
|
||||
ty::ty_enum(_, expected_tps) {
|
||||
let path_tpt = {substs: some(expected_tps),
|
||||
ty: expected};
|
||||
write::ty_fixup(fcx, pat.id, path_tpt);
|
||||
write_ty_substs(tcx, pat.id, expected,
|
||||
expected_tps);
|
||||
}
|
||||
_ {
|
||||
write::ty_only_fixup(fcx, pat.id, expected);
|
||||
write_ty(tcx, pat.id, expected);
|
||||
}
|
||||
}
|
||||
}
|
||||
ast::pat_lit(lt) {
|
||||
check_expr_with(fcx, lt, expected);
|
||||
write::ty_only_fixup(fcx, pat.id, expr_ty(fcx.ccx.tcx, lt));
|
||||
write_ty(tcx, pat.id, expr_ty(tcx, lt));
|
||||
}
|
||||
ast::pat_range(begin, end) {
|
||||
check_expr_with(fcx, begin, expected);
|
||||
check_expr_with(fcx, end, expected);
|
||||
let b_ty = resolve_type_vars_if_possible(fcx, expr_ty(fcx.ccx.tcx,
|
||||
begin));
|
||||
if !ty::same_type(fcx.ccx.tcx, b_ty, resolve_type_vars_if_possible(
|
||||
fcx, expr_ty(fcx.ccx.tcx, end))) {
|
||||
fcx.ccx.tcx.sess.span_err(pat.span, "mismatched types in range");
|
||||
} else if !ty::type_is_numeric(fcx.ccx.tcx, b_ty) {
|
||||
fcx.ccx.tcx.sess.span_err(pat.span,
|
||||
"non-numeric type used in range");
|
||||
let b_ty = resolve_type_vars_if_possible(fcx, expr_ty(tcx, begin));
|
||||
if !ty::same_type(tcx, b_ty, resolve_type_vars_if_possible(
|
||||
fcx, expr_ty(tcx, end))) {
|
||||
tcx.sess.span_err(pat.span, "mismatched types in range");
|
||||
} else if !ty::type_is_numeric(tcx, b_ty) {
|
||||
tcx.sess.span_err(pat.span, "non-numeric type used in range");
|
||||
} else if !valid_range_bounds(begin, end) {
|
||||
fcx.ccx.tcx.sess.span_err(begin.span,
|
||||
"lower range bound must be less \
|
||||
than upper");
|
||||
tcx.sess.span_err(begin.span, "lower range bound must be less \
|
||||
than upper");
|
||||
}
|
||||
write::ty_only_fixup(fcx, pat.id, b_ty);
|
||||
write_ty(tcx, pat.id, b_ty);
|
||||
}
|
||||
ast::pat_ident(name, sub) {
|
||||
let vid = lookup_local(fcx, pat.span, pat.id);
|
||||
let typ = ty::mk_var(fcx.ccx.tcx, vid);
|
||||
let typ = ty::mk_var(tcx, vid);
|
||||
typ = demand::simple(fcx, pat.span, expected, typ);
|
||||
let canon_id = map.get(path_to_ident(name));
|
||||
if canon_id != pat.id {
|
||||
let ct =
|
||||
ty::mk_var(fcx.ccx.tcx,
|
||||
lookup_local(fcx, pat.span, canon_id));
|
||||
let ct = ty::mk_var(tcx, lookup_local(fcx, pat.span, canon_id));
|
||||
typ = demand::simple(fcx, pat.span, ct, typ);
|
||||
}
|
||||
write::ty_only_fixup(fcx, pat.id, typ);
|
||||
write_ty(tcx, pat.id, typ);
|
||||
alt sub {
|
||||
some(p) { check_pat(fcx, map, p, expected); }
|
||||
_ {}
|
||||
|
@ -1241,23 +1209,15 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
|
|||
// Typecheck the path.
|
||||
let v_def = lookup_def(fcx, path.span, pat.id);
|
||||
let v_def_ids = ast_util::variant_def_ids(v_def);
|
||||
let enum_tpt = ty::lookup_item_type(fcx.ccx.tcx, v_def_ids.tg);
|
||||
let path_tpot = instantiate_path(fcx, path, enum_tpt, pat.span);
|
||||
let ctor_tpt = ty::lookup_item_type(tcx, v_def_ids.tg);
|
||||
instantiate_path(fcx, path, ctor_tpt, pat.span, pat.id);
|
||||
|
||||
// Take the enum type params out of `expected`.
|
||||
alt structure_of(fcx, pat.span, expected) {
|
||||
ty::ty_enum(_, expected_tps) {
|
||||
// Unify with the expected enum type.
|
||||
let ctor_ty =
|
||||
ty::ty_param_substs_opt_and_ty_to_monotype(fcx.ccx.tcx,
|
||||
path_tpot);
|
||||
|
||||
let path_tpt =
|
||||
demand::with_substs(fcx, pat.span, expected, ctor_ty,
|
||||
expected_tps);
|
||||
path_tpot =
|
||||
{substs: some::<[ty::t]>(path_tpt.substs), ty: path_tpt.ty};
|
||||
|
||||
let ctor_ty = ty::node_id_to_type(tcx, pat.id);
|
||||
demand::with_substs(fcx, pat.span, expected, ctor_ty,
|
||||
expected_tps);
|
||||
// Get the number of arguments in this enum variant.
|
||||
let arg_types =
|
||||
variant_arg_types(fcx.ccx, pat.span, v_def_ids.var,
|
||||
|
@ -1265,68 +1225,59 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
|
|||
let subpats_len = vec::len::<@ast::pat>(subpats);
|
||||
if vec::len::<ty::t>(arg_types) > 0u {
|
||||
// N-ary variant.
|
||||
|
||||
let arg_len = vec::len::<ty::t>(arg_types);
|
||||
if arg_len != subpats_len {
|
||||
// TODO: note definition of enum variant
|
||||
// TODO (issue #448): Wrap a #fmt string over multiple
|
||||
// lines...
|
||||
let s =
|
||||
#fmt["this pattern has %u field%s, but the \
|
||||
corresponding variant has %u field%s",
|
||||
subpats_len,
|
||||
if subpats_len == 1u { "" } else { "s" },
|
||||
arg_len, if arg_len == 1u { "" } else { "s" }];
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span, s);
|
||||
let s = #fmt["this pattern has %u field%s, but the \
|
||||
corresponding variant has %u field%s",
|
||||
subpats_len,
|
||||
if subpats_len == 1u { "" } else { "s" },
|
||||
arg_len,
|
||||
if arg_len == 1u { "" } else { "s" }];
|
||||
tcx.sess.span_fatal(pat.span, s);
|
||||
}
|
||||
|
||||
// TODO: vec::iter2
|
||||
|
||||
let i = 0u;
|
||||
for subpat: @ast::pat in subpats {
|
||||
check_pat(fcx, map, subpat, arg_types[i]);
|
||||
i += 1u;
|
||||
vec::iter2(subpats, arg_types) {|subpat, arg_ty|
|
||||
check_pat(fcx, map, subpat, arg_ty);
|
||||
}
|
||||
} else if subpats_len > 0u {
|
||||
// TODO: note definition of enum variant
|
||||
fcx.ccx.tcx.sess.span_fatal
|
||||
(pat.span,
|
||||
#fmt["this pattern has %u field%s, \
|
||||
but the corresponding \
|
||||
variant has no fields",
|
||||
subpats_len,
|
||||
if subpats_len == 1u {
|
||||
""
|
||||
} else { "s" }]);
|
||||
tcx.sess.span_fatal
|
||||
(pat.span, #fmt["this pattern has %u field%s, \
|
||||
but the corresponding \
|
||||
variant has no fields",
|
||||
subpats_len,
|
||||
if subpats_len == 1u { "" }
|
||||
else { "s" }]);
|
||||
}
|
||||
write::ty_fixup(fcx, pat.id, path_tpot);
|
||||
}
|
||||
_ {
|
||||
// FIXME: Switch expected and actual in this message? I
|
||||
// can never tell.
|
||||
fcx.ccx.tcx.sess.span_fatal
|
||||
tcx.sess.span_fatal
|
||||
(pat.span,
|
||||
#fmt["mismatched types: expected `%s` but found enum",
|
||||
ty_to_str(fcx.ccx.tcx, expected)]);
|
||||
ty_to_str(tcx, expected)]);
|
||||
}
|
||||
}
|
||||
write::ty_fixup(fcx, pat.id, path_tpot);
|
||||
}
|
||||
ast::pat_rec(fields, etc) {
|
||||
let ex_fields;
|
||||
alt structure_of(fcx, pat.span, expected) {
|
||||
ty::ty_rec(fields) { ex_fields = fields; }
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.span_fatal
|
||||
tcx.sess.span_fatal
|
||||
(pat.span,
|
||||
#fmt["mismatched types: expected `%s` but found record",
|
||||
ty_to_str(fcx.ccx.tcx, expected)]);
|
||||
ty_to_str(tcx, expected)]);
|
||||
}
|
||||
}
|
||||
let f_count = vec::len(fields);
|
||||
let ex_f_count = vec::len(ex_fields);
|
||||
if ex_f_count < f_count || !etc && ex_f_count > f_count {
|
||||
fcx.ccx.tcx.sess.span_fatal
|
||||
tcx.sess.span_fatal
|
||||
(pat.span, #fmt["mismatched types: expected a record \
|
||||
with %u fields, found one with %u \
|
||||
fields",
|
||||
|
@ -1339,47 +1290,47 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
|
|||
alt vec::find(ex_fields, bind matches(f.ident, _)) {
|
||||
some(field) { check_pat(fcx, map, f.pat, field.mt.ty); }
|
||||
none {
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span,
|
||||
#fmt["mismatched types: did not \
|
||||
expect a record with a field `%s`",
|
||||
f.ident]);
|
||||
tcx.sess.span_fatal(pat.span,
|
||||
#fmt["mismatched types: did not \
|
||||
expect a record with a field `%s`",
|
||||
f.ident]);
|
||||
}
|
||||
}
|
||||
}
|
||||
write::ty_only_fixup(fcx, pat.id, expected);
|
||||
write_ty(tcx, pat.id, expected);
|
||||
}
|
||||
ast::pat_tup(elts) {
|
||||
let ex_elts;
|
||||
alt structure_of(fcx, pat.span, expected) {
|
||||
ty::ty_tup(elts) { ex_elts = elts; }
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.span_fatal
|
||||
tcx.sess.span_fatal
|
||||
(pat.span,
|
||||
#fmt["mismatched types: expected `%s`, found tuple",
|
||||
ty_to_str(fcx.ccx.tcx, expected)]);
|
||||
ty_to_str(tcx, expected)]);
|
||||
}
|
||||
}
|
||||
let e_count = vec::len(elts);
|
||||
if e_count != vec::len(ex_elts) {
|
||||
fcx.ccx.tcx.sess.span_fatal
|
||||
tcx.sess.span_fatal
|
||||
(pat.span, #fmt["mismatched types: expected a tuple \
|
||||
with %u fields, found one with %u \
|
||||
fields", vec::len(ex_elts), e_count]);
|
||||
}
|
||||
let i = 0u;
|
||||
for elt in elts { check_pat(fcx, map, elt, ex_elts[i]); i += 1u; }
|
||||
write::ty_only_fixup(fcx, pat.id, expected);
|
||||
write_ty(tcx, pat.id, expected);
|
||||
}
|
||||
ast::pat_box(inner) {
|
||||
alt structure_of(fcx, pat.span, expected) {
|
||||
ty::ty_box(e_inner) {
|
||||
check_pat(fcx, map, inner, e_inner.ty);
|
||||
write::ty_only_fixup(fcx, pat.id, expected);
|
||||
write_ty(tcx, pat.id, expected);
|
||||
}
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span,
|
||||
tcx.sess.span_fatal(pat.span,
|
||||
"mismatched types: expected `" +
|
||||
ty_to_str(fcx.ccx.tcx, expected) +
|
||||
ty_to_str(tcx, expected) +
|
||||
"` found box");
|
||||
}
|
||||
}
|
||||
|
@ -1388,12 +1339,12 @@ fn check_pat(fcx: @fn_ctxt, map: pat_util::pat_id_map, pat: @ast::pat,
|
|||
alt structure_of(fcx, pat.span, expected) {
|
||||
ty::ty_uniq(e_inner) {
|
||||
check_pat(fcx, map, inner, e_inner.ty);
|
||||
write::ty_only_fixup(fcx, pat.id, expected);
|
||||
write_ty(tcx, pat.id, expected);
|
||||
}
|
||||
_ {
|
||||
fcx.ccx.tcx.sess.span_fatal(pat.span,
|
||||
tcx.sess.span_fatal(pat.span,
|
||||
"mismatched types: expected `" +
|
||||
ty_to_str(fcx.ccx.tcx, expected) +
|
||||
ty_to_str(tcx, expected) +
|
||||
"` found uniq");
|
||||
}
|
||||
}
|
||||
|
@ -1581,7 +1532,6 @@ fn check_expr_fn_with_unifier(fcx: @fn_ctxt,
|
|||
unify: unifier,
|
||||
expected: ty::t) {
|
||||
let tcx = fcx.ccx.tcx;
|
||||
|
||||
let fty = ty::mk_fn(tcx, ty_of_fn_decl(tcx, m_check_tyvar(fcx),
|
||||
proto, decl));
|
||||
|
||||
|
@ -1589,7 +1539,7 @@ fn check_expr_fn_with_unifier(fcx: @fn_ctxt,
|
|||
expr_to_str(expr),
|
||||
ty_to_str(tcx, fty));
|
||||
|
||||
write::ty_only_fixup(fcx, expr.id, fty);
|
||||
write_ty(tcx, expr.id, fty);
|
||||
|
||||
// Unify the type of the function with the expected type before we
|
||||
// typecheck the body so that we have more information about the
|
||||
|
@ -1672,7 +1622,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
rhs: @ast::expr, id: ast::node_id) -> bool {
|
||||
let t = next_ty_var(fcx);
|
||||
let bot = check_expr_with(fcx, lhs, t) | check_expr_with(fcx, rhs, t);
|
||||
write::ty_only_fixup(fcx, id, ty::mk_nil(fcx.ccx.tcx));
|
||||
write_ty(fcx.ccx.tcx, id, ty::mk_nil(fcx.ccx.tcx));
|
||||
ret bot;
|
||||
}
|
||||
|
||||
|
@ -1708,7 +1658,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
}
|
||||
_ { fcx.ccx.tcx.sess.span_fatal(sp, "calling non-function"); }
|
||||
};
|
||||
write::ty_only_fixup(fcx, id, rt_1);
|
||||
write_ty(fcx.ccx.tcx, id, rt_1);
|
||||
ret bot;
|
||||
}
|
||||
|
||||
|
@ -1725,7 +1675,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
demand::simple(fcx, local.span,
|
||||
ty::node_id_to_type(fcx.ccx.tcx, local.node.id),
|
||||
element_ty);
|
||||
write::nil_ty(fcx.ccx.tcx, node_id);
|
||||
write_nil(fcx.ccx.tcx, node_id);
|
||||
ret bot;
|
||||
}
|
||||
|
||||
|
@ -1754,7 +1704,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
(ty::mk_nil(fcx.ccx.tcx), false)
|
||||
}
|
||||
};
|
||||
write::ty_only_fixup(fcx, id, if_t);
|
||||
write_ty(fcx.ccx.tcx, id, if_t);
|
||||
ret if_bot;
|
||||
}
|
||||
|
||||
|
@ -1773,8 +1723,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
alt lookup_method(fcx, isc, opname, self_t, op_ex.span) {
|
||||
some({method_ty, n_tps: 0u, substs, origin}) {
|
||||
let callee_id = ast_util::op_expr_callee_id(op_ex);
|
||||
write::ty_fixup(fcx, callee_id, {substs: some(substs),
|
||||
ty: method_ty});
|
||||
write_ty_substs(fcx.ccx.tcx, callee_id, method_ty, substs);
|
||||
check_call_or_bind(fcx, op_ex.span, method_ty, args);
|
||||
fcx.ccx.method_map.insert(op_ex.id, origin);
|
||||
some(ty::ty_fn_ret(fcx.ccx.tcx, method_ty))
|
||||
|
@ -1828,7 +1777,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
alt expr.node {
|
||||
ast::expr_lit(lit) {
|
||||
let typ = check_lit(fcx.ccx, lit);
|
||||
write::ty_only_fixup(fcx, id, typ);
|
||||
write_ty(tcx, id, typ);
|
||||
}
|
||||
ast::expr_binary(binop, lhs, rhs) {
|
||||
let lhs_t = next_ty_var(fcx);
|
||||
|
@ -1838,7 +1787,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
if !ast_util::lazy_binop(binop) { bot |= rhs_bot; }
|
||||
|
||||
let result = check_binop(fcx, expr, lhs_t, binop, rhs);
|
||||
write::ty_only_fixup(fcx, id, result);
|
||||
write_ty(tcx, id, result);
|
||||
}
|
||||
ast::expr_assign_op(op, lhs, rhs) {
|
||||
require_impure(tcx.sess, fcx.purity, expr.span);
|
||||
|
@ -1899,15 +1848,14 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
}
|
||||
}
|
||||
}
|
||||
write::ty_only_fixup(fcx, id, oper_t);
|
||||
write_ty(tcx, id, oper_t);
|
||||
}
|
||||
ast::expr_path(pth) {
|
||||
let defn = lookup_def(fcx, pth.span, id);
|
||||
|
||||
let tpt = ty_param_bounds_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);
|
||||
instantiate_path(fcx, pth, tpt, expr.span, expr.id);
|
||||
} else {
|
||||
// The definition doesn't take type parameters. If the programmer
|
||||
// supplied some, that's an error
|
||||
|
@ -1916,7 +1864,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
"this kind of value does not \
|
||||
take type parameters");
|
||||
}
|
||||
write::ty_only_fixup(fcx, id, tpt.ty);
|
||||
write_ty(tcx, id, tpt.ty);
|
||||
}
|
||||
}
|
||||
ast::expr_mac(_) { tcx.sess.bug("unexpanded macro"); }
|
||||
|
@ -1926,10 +1874,10 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
none {/* do nothing */ }
|
||||
some(e) { check_expr_with(fcx, e, ty::mk_str(tcx)); }
|
||||
}
|
||||
write::bot_ty(tcx, id);
|
||||
write_bot(tcx, id);
|
||||
}
|
||||
ast::expr_break { write::bot_ty(tcx, id); bot = true; }
|
||||
ast::expr_cont { write::bot_ty(tcx, id); bot = true; }
|
||||
ast::expr_break { write_bot(tcx, id); bot = true; }
|
||||
ast::expr_cont { write_bot(tcx, id); bot = true; }
|
||||
ast::expr_ret(expr_opt) {
|
||||
bot = true;
|
||||
alt expr_opt {
|
||||
|
@ -1942,23 +1890,23 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
}
|
||||
some(e) { check_expr_with(fcx, e, fcx.ret_ty); }
|
||||
}
|
||||
write::bot_ty(tcx, id);
|
||||
write_bot(tcx, id);
|
||||
}
|
||||
ast::expr_be(e) {
|
||||
// FIXME: prove instead of assert
|
||||
assert (ast_util::is_call_expr(e));
|
||||
check_expr_with(fcx, e, fcx.ret_ty);
|
||||
bot = true;
|
||||
write::nil_ty(tcx, id);
|
||||
write_nil(tcx, id);
|
||||
}
|
||||
ast::expr_log(_, lv, e) {
|
||||
bot = check_expr_with(fcx, lv, ty::mk_mach_uint(tcx, ast::ty_u32));
|
||||
bot |= check_expr(fcx, e);
|
||||
write::nil_ty(tcx, id);
|
||||
write_nil(tcx, id);
|
||||
}
|
||||
ast::expr_check(_, e) {
|
||||
bot = check_pred_expr(fcx, e);
|
||||
write::nil_ty(tcx, id);
|
||||
write_nil(tcx, id);
|
||||
}
|
||||
ast::expr_if_check(cond, thn, elsopt) {
|
||||
bot =
|
||||
|
@ -1970,14 +1918,11 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
}
|
||||
ast::expr_assert(e) {
|
||||
bot = check_expr_with(fcx, e, ty::mk_bool(tcx));
|
||||
write::nil_ty(tcx, id);
|
||||
write_nil(tcx, id);
|
||||
}
|
||||
ast::expr_copy(a) {
|
||||
bot = check_expr_with_unifier(fcx, a, unify, expected);
|
||||
let tpot =
|
||||
ty::node_id_to_ty_param_substs_opt_and_ty(tcx, a.id);
|
||||
write::ty_fixup(fcx, id, tpot);
|
||||
|
||||
write_ty(tcx, id, ty::node_id_to_type(tcx, a.id));
|
||||
}
|
||||
ast::expr_move(lhs, rhs) {
|
||||
require_impure(tcx.sess, fcx.purity, expr.span);
|
||||
|
@ -2014,12 +1959,12 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
ast::expr_while(cond, body) {
|
||||
bot = check_expr_with(fcx, cond, ty::mk_bool(tcx));
|
||||
check_block_no_value(fcx, body);
|
||||
write::ty_only_fixup(fcx, id, ty::mk_nil(tcx));
|
||||
write_ty(tcx, id, ty::mk_nil(tcx));
|
||||
}
|
||||
ast::expr_do_while(body, cond) {
|
||||
bot = check_expr_with(fcx, cond, ty::mk_bool(tcx)) |
|
||||
check_block_no_value(fcx, body);
|
||||
write::ty_only_fixup(fcx, id, block_ty(tcx, body));
|
||||
write_ty(tcx, id, block_ty(tcx, body));
|
||||
}
|
||||
ast::expr_alt(expr, arms) {
|
||||
bot = check_expr(fcx, expr);
|
||||
|
@ -2047,7 +1992,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
}
|
||||
bot |= !arm_non_bot;
|
||||
if !arm_non_bot { result_ty = ty::mk_bot(tcx); }
|
||||
write::ty_only_fixup(fcx, id, result_ty);
|
||||
write_ty(tcx, id, result_ty);
|
||||
}
|
||||
ast::expr_fn(proto, decl, body, captures) {
|
||||
check_expr_fn_with_unifier(fcx, expr, proto, decl, body,
|
||||
|
@ -2069,7 +2014,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
ty_to_str(tcx, expected));
|
||||
check_expr_fn_with_unifier(fcx, expr, proto, decl, body,
|
||||
unify, expected);
|
||||
write::ty_only_fixup(fcx, id, expected);
|
||||
write_ty(tcx, id, expected);
|
||||
}
|
||||
ast::expr_block(b) {
|
||||
// If this is an unchecked block, turn off purity-checking
|
||||
|
@ -2079,7 +2024,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
some(expr) { expr_ty(tcx, expr) }
|
||||
none { ty::mk_nil(tcx) }
|
||||
};
|
||||
write::ty_only_fixup(fcx, id, typ);
|
||||
write_ty(tcx, id, typ);
|
||||
}
|
||||
ast::expr_bind(f, args) {
|
||||
// Call the generic checker.
|
||||
|
@ -2126,7 +2071,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
let ft = ty::mk_fn(tcx, {proto: lower_bound_proto(proto),
|
||||
inputs: out_args, output: rt,
|
||||
ret_style: cf, constraints: constrs});
|
||||
write::ty_only_fixup(fcx, id, ft);
|
||||
write_ty(tcx, id, ft);
|
||||
}
|
||||
ast::expr_call(f, args, _) {
|
||||
bot = check_call_full(fcx, expr.span, f, args, expr.id);
|
||||
|
@ -2162,13 +2107,13 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
}
|
||||
}
|
||||
}
|
||||
write::ty_only_fixup(fcx, id, t_1);
|
||||
write_ty(tcx, id, t_1);
|
||||
}
|
||||
ast::expr_vec(args, mut) {
|
||||
let t: ty::t = next_ty_var(fcx);
|
||||
for e: @ast::expr in args { bot |= check_expr_with(fcx, e, t); }
|
||||
let typ = ty::mk_vec(tcx, {ty: t, mut: mut});
|
||||
write::ty_only_fixup(fcx, id, typ);
|
||||
write_ty(tcx, id, typ);
|
||||
}
|
||||
ast::expr_tup(elts) {
|
||||
let elt_ts = [];
|
||||
|
@ -2179,7 +2124,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
elt_ts += [ety];
|
||||
}
|
||||
let typ = ty::mk_tup(tcx, elt_ts);
|
||||
write::ty_only_fixup(fcx, id, typ);
|
||||
write_ty(tcx, id, typ);
|
||||
}
|
||||
ast::expr_rec(fields, base) {
|
||||
alt base { none {/* no-op */ } some(b_0) { check_expr(fcx, b_0); } }
|
||||
|
@ -2198,7 +2143,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
none {
|
||||
fn get_node(f: spanned<field>) -> field { f.node }
|
||||
let typ = ty::mk_rec(tcx, vec::map(fields_t, get_node));
|
||||
write::ty_only_fixup(fcx, id, typ);
|
||||
write_ty(tcx, id, typ);
|
||||
}
|
||||
some(bexpr) {
|
||||
bot |= check_expr(fcx, bexpr);
|
||||
|
@ -2211,7 +2156,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
"record update has non-record base");
|
||||
}
|
||||
}
|
||||
write::ty_only_fixup(fcx, id, bexpr_t);
|
||||
write_ty(tcx, id, bexpr_t);
|
||||
for f: spanned<ty::field> in fields_t {
|
||||
let found = false;
|
||||
for bf: ty::field in base_fields {
|
||||
|
@ -2244,7 +2189,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
"can't provide type parameters \
|
||||
to a field access");
|
||||
}
|
||||
write::ty_only_fixup(fcx, id, fields[ix].mt.ty);
|
||||
write_ty(tcx, id, fields[ix].mt.ty);
|
||||
handled = true;
|
||||
}
|
||||
_ {}
|
||||
|
@ -2275,13 +2220,13 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
i += 1u;
|
||||
}
|
||||
}
|
||||
write::ty_fixup(fcx, id, {substs: some(substs), ty: fty});
|
||||
write_ty_substs(fcx.ccx.tcx, id, fty, substs);
|
||||
} else if n_tys > 0u {
|
||||
tcx.sess.span_fatal(expr.span,
|
||||
"this method does not take type \
|
||||
parameters");
|
||||
} else {
|
||||
write::ty_only_fixup(fcx, id, fty);
|
||||
write_ty(tcx, id, fty);
|
||||
}
|
||||
fcx.ccx.method_map.insert(id, origin);
|
||||
}
|
||||
|
@ -2292,7 +2237,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
field, ty_to_str(tcx, t_err)];
|
||||
tcx.sess.span_err(expr.span, msg);
|
||||
// NB: Adding a bogus type to allow typechecking to continue
|
||||
write::ty_only_fixup(fcx, id, ty::mk_nil(tcx));
|
||||
write_ty(tcx, id, ty::mk_nil(tcx));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2313,19 +2258,19 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
alt structure_of(fcx, expr.span, base_t) {
|
||||
ty::ty_vec(mt) {
|
||||
require_integral(fcx, idx.span, idx_t);
|
||||
write::ty_only_fixup(fcx, id, mt.ty);
|
||||
write_ty(tcx, id, mt.ty);
|
||||
}
|
||||
ty::ty_str {
|
||||
require_integral(fcx, idx.span, idx_t);
|
||||
let typ = ty::mk_mach_uint(tcx, ast::ty_u8);
|
||||
write::ty_only_fixup(fcx, id, typ);
|
||||
write_ty(tcx, id, typ);
|
||||
}
|
||||
_ {
|
||||
let resolved = structurally_resolved_type(fcx, expr.span,
|
||||
raw_base_t);
|
||||
alt lookup_op_method(fcx, expr, resolved, "[]",
|
||||
[some(idx)]) {
|
||||
some(ret_ty) { write::ty_only_fixup(fcx, id, ret_ty); }
|
||||
some(ret_ty) { write_ty(tcx, id, ret_ty); }
|
||||
_ {
|
||||
tcx.sess.span_fatal(
|
||||
expr.span, "cannot index a value of type `" +
|
||||
|
@ -2337,7 +2282,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
|||
}
|
||||
_ { tcx.sess.unimpl("expr type in typeck::check_expr"); }
|
||||
}
|
||||
if bot { write::ty_only_fixup(fcx, expr.id, ty::mk_bot(tcx)); }
|
||||
if bot { write_ty(tcx, expr.id, ty::mk_bot(tcx)); }
|
||||
|
||||
unify(fcx, expr.span, expected, expr_ty(tcx, expr));
|
||||
ret bot;
|
||||
|
@ -2375,7 +2320,7 @@ fn check_decl_local(fcx: @fn_ctxt, local: @ast::local) -> bool {
|
|||
alt fcx.locals.find(local.node.id) {
|
||||
some(i) {
|
||||
let t = ty::mk_var(fcx.ccx.tcx, i);
|
||||
write::ty_only_fixup(fcx, local.node.id, t);
|
||||
write_ty(fcx.ccx.tcx, local.node.id, t);
|
||||
alt local.node.init {
|
||||
some(init) {
|
||||
bot = check_decl_initializer(fcx, local.node.id, init);
|
||||
|
@ -2411,14 +2356,14 @@ fn check_stmt(fcx: @fn_ctxt, stmt: @ast::stmt) -> bool {
|
|||
bot = check_expr(fcx, expr);
|
||||
}
|
||||
}
|
||||
write::nil_ty(fcx.ccx.tcx, node_id);
|
||||
write_nil(fcx.ccx.tcx, node_id);
|
||||
ret bot;
|
||||
}
|
||||
|
||||
fn check_block_no_value(fcx: @fn_ctxt, blk: ast::blk) -> bool {
|
||||
let bot = check_block(fcx, blk);
|
||||
if !bot {
|
||||
let blkty = ty::node_id_to_monotype(fcx.ccx.tcx, blk.node.id);
|
||||
let blkty = ty::node_id_to_type(fcx.ccx.tcx, blk.node.id);
|
||||
let nilty = ty::mk_nil(fcx.ccx.tcx);
|
||||
demand::simple(fcx, blk.span, nilty, blkty);
|
||||
}
|
||||
|
@ -2448,18 +2393,18 @@ fn check_block(fcx0: @fn_ctxt, blk: ast::blk) -> bool {
|
|||
bot |= check_stmt(fcx, s);
|
||||
}
|
||||
alt blk.node.expr {
|
||||
none { write::nil_ty(fcx.ccx.tcx, blk.node.id); }
|
||||
none { write_nil(fcx.ccx.tcx, blk.node.id); }
|
||||
some(e) {
|
||||
if bot && !warned {
|
||||
fcx.ccx.tcx.sess.span_warn(e.span, "unreachable expression");
|
||||
}
|
||||
bot |= check_expr(fcx, e);
|
||||
let ety = expr_ty(fcx.ccx.tcx, e);
|
||||
write::ty_only_fixup(fcx, blk.node.id, ety);
|
||||
write_ty(fcx.ccx.tcx, blk.node.id, ety);
|
||||
}
|
||||
}
|
||||
if bot {
|
||||
write::ty_only_fixup(fcx, blk.node.id, ty::mk_bot(fcx.ccx.tcx));
|
||||
write_ty(fcx.ccx.tcx, blk.node.id, ty::mk_bot(fcx.ccx.tcx));
|
||||
}
|
||||
ret bot;
|
||||
}
|
||||
|
@ -2697,7 +2642,7 @@ fn check_fn(ccx: @crate_ctxt,
|
|||
let args = ty::ty_fn_args(ccx.tcx, ty::node_id_to_type(ccx.tcx, id));
|
||||
let i = 0u;
|
||||
for arg: ty::arg in args {
|
||||
write::ty_only_fixup(fcx, decl.inputs[i].id, arg.ty);
|
||||
write_ty(ccx.tcx, decl.inputs[i].id, arg.ty);
|
||||
i += 1u;
|
||||
}
|
||||
|
||||
|
@ -2748,7 +2693,7 @@ fn arg_is_argv_ty(tcx: ty::ctxt, a: ty::arg) -> bool {
|
|||
}
|
||||
|
||||
fn check_main_fn_ty(tcx: ty::ctxt, main_id: ast::node_id) {
|
||||
let main_t = ty::node_id_to_monotype(tcx, main_id);
|
||||
let main_t = ty::node_id_to_type(tcx, main_id);
|
||||
alt ty::struct(tcx, main_t) {
|
||||
ty::ty_fn({proto: ast::proto_bare, inputs, output,
|
||||
ret_style: ast::return_val, constraints}) {
|
||||
|
@ -2919,9 +2864,7 @@ mod dict {
|
|||
let cx = fcx.ccx;
|
||||
alt ex.node {
|
||||
ast::expr_path(_) {
|
||||
let substs = ty::node_id_to_ty_param_substs_opt_and_ty(
|
||||
cx.tcx, ex.id);
|
||||
alt substs.substs {
|
||||
alt cx.tcx.node_type_substs.find(ex.id) {
|
||||
some(ts) {
|
||||
let did = ast_util::def_id_of_def(cx.tcx.def_map.get(ex.id));
|
||||
let item_ty = ty::lookup_item_type(cx.tcx, did);
|
||||
|
|
Loading…
Reference in New Issue