aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorPatrick Walton <[email protected]>2010-12-21 12:13:51 -0800
committerPatrick Walton <[email protected]>2010-12-21 16:24:17 -0800
commit744b164b7dafbecd84e6f11e139ca054c283e77c (patch)
tree1a0196d4fa25f51facd76c9189bf583f43c9bbe3 /src/comp
parentrustboot: Only bottom out at opaque IL types after finding two cycles. DON'T ... (diff)
downloadrust-744b164b7dafbecd84e6f11e139ca054c283e77c.tar.xz
rust-744b164b7dafbecd84e6f11e139ca054c283e77c.zip
rustc: Move type logic out of typeck so trans doesn't look like it's calling into typeck
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/front/ast.rs5
-rw-r--r--src/comp/middle/trans.rs325
-rw-r--r--src/comp/middle/ty.rs588
-rw-r--r--src/comp/middle/typeck.rs929
-rw-r--r--src/comp/rustc.rc1
5 files changed, 936 insertions, 912 deletions
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 8f1a9638..8159962d 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -1,7 +1,6 @@
import std.map.hashmap;
import std.option;
-import middle.typeck;
import util.common.span;
import util.common.spanned;
import util.common.ty_mach;
@@ -21,7 +20,7 @@ type ty_param = rec(ident ident, def_id id);
// Annotations added during successive passes.
tag ann {
ann_none;
- ann_type(@typeck.ty);
+ ann_type(@middle.ty.t);
}
tag def {
@@ -168,7 +167,7 @@ tag lit_ {
}
// NB: If you change this, you'll probably want to change the corresponding
-// type structure in middle/typeck.rs as well.
+// type structure in middle/ty.rs as well.
type ty_field = rec(ident ident, @ty ty);
type ty_arg = rec(mode mode, @ty ty);
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index 2cf035aa..190b71f0 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -11,11 +11,11 @@ import std.option.none;
import front.ast;
import driver.session;
-import middle.typeck;
+import middle.ty;
import back.x86;
import back.abi;
-import middle.typeck.pat_ty;
+import middle.ty.pat_ty;
import util.common;
import util.common.istr;
@@ -66,7 +66,7 @@ state type crate_ctxt = rec(session.session sess,
hashmap[ast.def_id, ValueRef] item_ids,
hashmap[ast.def_id, @ast.item] items,
hashmap[ast.def_id, @tag_info] tags,
- hashmap[@typeck.ty, ValueRef] tydescs,
+ hashmap[@ty.t, ValueRef] tydescs,
@glue_fns glues,
namegen names,
str path);
@@ -275,27 +275,25 @@ fn T_taskptr() -> TypeRef {
ret T_ptr(T_task());
}
-fn type_of(@crate_ctxt cx, @typeck.ty t) -> TypeRef {
+fn type_of(@crate_ctxt cx, @ty.t t) -> TypeRef {
let TypeRef llty = type_of_inner(cx, t);
check (llty as int != 0);
- llvm.LLVMAddTypeName(cx.llmod, _str.buf(typeck.ty_to_str(t)), llty);
+ llvm.LLVMAddTypeName(cx.llmod, _str.buf(ty.ty_to_str(t)), llty);
ret llty;
}
-fn type_of_fn(@crate_ctxt cx,
- vec[typeck.arg] inputs,
- @typeck.ty output) -> TypeRef {
+fn type_of_fn(@crate_ctxt cx, vec[ty.arg] inputs, @ty.t output) -> TypeRef {
let vec[TypeRef] atys = vec(T_taskptr());
- auto fn_ty = typeck.plain_ty(typeck.ty_fn(inputs, output));
- auto ty_param_count = typeck.count_ty_params(fn_ty);
+ auto fn_ty = ty.plain_ty(ty.ty_fn(inputs, output));
+ auto ty_param_count = ty.count_ty_params(fn_ty);
auto i = 0u;
while (i < ty_param_count) {
atys += T_ptr(T_tydesc());
i += 1u;
}
- for (typeck.arg arg in inputs) {
+ for (ty.arg arg in inputs) {
let TypeRef t = type_of(cx, arg.ty);
alt (arg.mode) {
case (ast.alias) {
@@ -307,7 +305,7 @@ fn type_of_fn(@crate_ctxt cx,
}
auto ret_ty;
- if (typeck.type_is_nil(output)) {
+ if (ty.type_is_nil(output)) {
ret_ty = llvm.LLVMVoidType();
} else {
ret_ty = type_of(cx, output);
@@ -316,13 +314,13 @@ fn type_of_fn(@crate_ctxt cx,
ret T_fn(atys, ret_ty);
}
-fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef {
+fn type_of_inner(@crate_ctxt cx, @ty.t t) -> TypeRef {
alt (t.struct) {
- case (typeck.ty_nil) { ret T_nil(); }
- case (typeck.ty_bool) { ret T_bool(); }
- case (typeck.ty_int) { ret T_int(); }
- case (typeck.ty_uint) { ret T_int(); }
- case (typeck.ty_machine(?tm)) {
+ case (ty.ty_nil) { ret T_nil(); }
+ case (ty.ty_bool) { ret T_bool(); }
+ case (ty.ty_int) { ret T_int(); }
+ case (ty.ty_uint) { ret T_int(); }
+ case (ty.ty_machine(?tm)) {
alt (tm) {
case (common.ty_i8) { ret T_i8(); }
case (common.ty_u8) { ret T_i8(); }
@@ -336,37 +334,37 @@ fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef {
case (common.ty_f64) { ret T_f64(); }
}
}
- case (typeck.ty_char) { ret T_char(); }
- case (typeck.ty_str) { ret T_ptr(T_str()); }
- case (typeck.ty_tag(?tag_id)) {
+ case (ty.ty_char) { ret T_char(); }
+ case (ty.ty_str) { ret T_ptr(T_str()); }
+ case (ty.ty_tag(?tag_id)) {
ret llvm.LLVMResolveTypeHandle(cx.tags.get(tag_id).th.llth);
}
- case (typeck.ty_box(?t)) {
+ case (ty.ty_box(?t)) {
ret T_ptr(T_box(type_of(cx, t)));
}
- case (typeck.ty_vec(?t)) {
+ case (ty.ty_vec(?t)) {
ret T_ptr(T_vec(type_of(cx, t)));
}
- case (typeck.ty_tup(?elts)) {
+ case (ty.ty_tup(?elts)) {
let vec[TypeRef] tys = vec();
- for (@typeck.ty elt in elts) {
+ for (@ty.t elt in elts) {
tys += type_of(cx, elt);
}
ret T_struct(tys);
}
- case (typeck.ty_rec(?fields)) {
+ case (ty.ty_rec(?fields)) {
let vec[TypeRef] tys = vec();
- for (typeck.field f in fields) {
+ for (ty.field f in fields) {
tys += type_of(cx, f.ty);
}
ret T_struct(tys);
}
- case (typeck.ty_fn(?args, ?out)) {
+ case (ty.ty_fn(?args, ?out)) {
ret type_of_fn(cx, args, out);
}
- case (typeck.ty_obj(?meths)) {
+ case (ty.ty_obj(?meths)) {
let vec[TypeRef] mtys = vec();
- for (typeck.method m in meths) {
+ for (ty.method m in meths) {
let TypeRef mty = type_of_fn(cx, m.inputs, m.output);
mtys += T_ptr(mty);
}
@@ -376,18 +374,18 @@ fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef {
T_ptr(T_box(T_nil()))));
ret pair;
}
- case (typeck.ty_var(_)) {
+ case (ty.ty_var(_)) {
log "ty_var in trans.type_of";
fail;
}
- case (typeck.ty_param(_)) {
+ case (ty.ty_param(_)) {
ret T_ptr(T_i8());
}
}
fail;
}
-fn type_of_arg(@crate_ctxt cx, &typeck.arg arg) -> TypeRef {
+fn type_of_arg(@crate_ctxt cx, &ty.arg arg) -> TypeRef {
auto ty = type_of(cx, arg.ty);
if (arg.mode == ast.alias) {
ty = T_ptr(ty);
@@ -568,7 +566,7 @@ fn align_of(TypeRef t) -> ValueRef {
ret llvm.LLVMConstIntCast(lib.llvm.llvm.LLVMAlignOf(t), T_int(), False);
}
-fn trans_malloc(@block_ctxt cx, @typeck.ty t) -> result {
+fn trans_malloc(@block_ctxt cx, @ty.t t) -> result {
auto scope_cx = find_scope_cx(cx);
auto ptr_ty = type_of(cx.fcx.ccx, t);
auto body_ty = lib.llvm.llvm.LLVMGetElementType(ptr_ty);
@@ -587,38 +585,38 @@ fn trans_malloc(@block_ctxt cx, @typeck.ty t) -> result {
// Given a type and a field index into its corresponding type descriptor,
// returns an LLVM ValueRef of that field from the tydesc, generating the
// tydesc if necessary.
-fn field_of_tydesc(@block_ctxt cx, @typeck.ty ty, int field) -> ValueRef {
- auto tydesc = get_tydesc(cx, ty);
+fn field_of_tydesc(@block_ctxt cx, @ty.t t, int field) -> ValueRef {
+ auto tydesc = get_tydesc(cx, t);
ret cx.build.GEP(tydesc, vec(C_int(0), C_int(field)));
}
-fn get_tydesc(&@block_ctxt cx, @typeck.ty ty) -> ValueRef {
+fn get_tydesc(&@block_ctxt cx, @ty.t t) -> ValueRef {
// Is the supplied type a type param? If so, return the passed-in tydesc.
- alt (typeck.type_param(ty)) {
+ alt (ty.type_param(t)) {
case (some[ast.def_id](?id)) { ret cx.fcx.lltydescs.get(id); }
case (none[ast.def_id]) { /* fall through */ }
}
// Does it contain a type param? If so, generate a derived tydesc.
- if (typeck.count_ty_params(ty) > 0u) {
+ if (ty.count_ty_params(t) > 0u) {
log "TODO: trans.get_tydesc(): generate a derived type descriptor";
fail;
}
// Otherwise, generate a tydesc if necessary, and return it.
- if (!cx.fcx.ccx.tydescs.contains_key(ty)) {
- make_tydesc(cx.fcx.ccx, ty);
+ if (!cx.fcx.ccx.tydescs.contains_key(t)) {
+ make_tydesc(cx.fcx.ccx, t);
}
- ret cx.fcx.ccx.tydescs.get(ty);
+ ret cx.fcx.ccx.tydescs.get(t);
}
-fn make_tydesc(@crate_ctxt cx, @typeck.ty ty) {
+fn make_tydesc(@crate_ctxt cx, @ty.t t) {
auto tg = make_take_glue;
- auto take_glue = make_generic_glue(cx, ty, "take", tg);
+ auto take_glue = make_generic_glue(cx, t, "take", tg);
auto dg = make_drop_glue;
- auto drop_glue = make_generic_glue(cx, ty, "drop", dg);
+ auto drop_glue = make_generic_glue(cx, t, "drop", dg);
- auto llty = type_of(cx, ty);
+ auto llty = type_of(cx, t);
auto pvoid = T_ptr(T_i8());
auto glue_fn_ty = T_ptr(T_fn(vec(T_taskptr(), pvoid), T_void()));
auto tydesc = C_struct(vec(C_null(pvoid),
@@ -632,18 +630,18 @@ fn make_tydesc(@crate_ctxt cx, @typeck.ty ty) {
C_null(glue_fn_ty), // obj_drop_glue_off
C_null(glue_fn_ty))); // is_stateful
- auto name = sanitize(cx.names.next("tydesc_" + typeck.ty_to_str(ty)));
+ auto name = sanitize(cx.names.next("tydesc_" + ty.ty_to_str(t)));
auto gvar = llvm.LLVMAddGlobal(cx.llmod, val_ty(tydesc), _str.buf(name));
llvm.LLVMSetInitializer(gvar, tydesc);
llvm.LLVMSetGlobalConstant(gvar, True);
- cx.tydescs.insert(ty, gvar);
+ cx.tydescs.insert(t, gvar);
}
-fn make_generic_glue(@crate_ctxt cx, @typeck.ty t, str name,
+fn make_generic_glue(@crate_ctxt cx, @ty.t t, str name,
val_and_ty_fn helper) -> ValueRef {
auto llfnty = T_fn(vec(T_taskptr(), T_ptr(T_i8())), T_void());
- auto fn_name = cx.names.next("_rust_" + name) + "." + typeck.ty_to_str(t);
+ auto fn_name = cx.names.next("_rust_" + name) + "." + ty.ty_to_str(t);
fn_name = sanitize(fn_name);
auto llfn = decl_fastcall_fn(cx.llmod, fn_name, llfnty);
@@ -651,9 +649,9 @@ fn make_generic_glue(@crate_ctxt cx, @typeck.ty t, str name,
auto bcx = new_top_block_ctxt(fcx);
auto re;
- if (!typeck.type_is_scalar(t)) {
+ if (!ty.type_is_scalar(t)) {
auto llty;
- if (typeck.type_is_structural(t)) {
+ if (ty.type_is_structural(t)) {
llty = T_ptr(type_of(cx, t));
} else {
llty = type_of(cx, t);
@@ -671,11 +669,11 @@ fn make_generic_glue(@crate_ctxt cx, @typeck.ty t, str name,
ret llfn;
}
-fn make_take_glue(@block_ctxt cx, ValueRef v, @typeck.ty t) -> result {
- if (typeck.type_is_boxed(t)) {
+fn make_take_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
+ if (ty.type_is_boxed(t)) {
ret incr_refcnt_of_boxed(cx, v);
- } else if (typeck.type_is_structural(t)) {
+ } else if (ty.type_is_structural(t)) {
ret iter_structural_ty(cx, v, t,
bind incr_all_refcnts(_, _, _));
}
@@ -701,18 +699,17 @@ fn incr_refcnt_of_boxed(@block_ctxt cx, ValueRef box_ptr) -> result {
ret res(next_cx, C_nil());
}
-fn make_drop_glue(@block_ctxt cx, ValueRef v, @typeck.ty t) -> result {
+fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
alt (t.struct) {
- case (typeck.ty_str) {
+ case (ty.ty_str) {
ret decr_refcnt_and_if_zero(cx, v,
bind trans_non_gc_free(_, v),
"free string",
T_int(), C_int(0));
}
- case (typeck.ty_vec(_)) {
- fn hit_zero(@block_ctxt cx, ValueRef v,
- @typeck.ty t) -> result {
+ case (ty.ty_vec(_)) {
+ fn hit_zero(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
auto res = iter_sequence(cx, v, t, bind drop_ty(_,_,_));
// FIXME: switch gc/non-gc on layer of the type.
ret trans_non_gc_free(res.bcx, v);
@@ -723,9 +720,8 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @typeck.ty t) -> result {
T_int(), C_int(0));
}
- case (typeck.ty_box(?body_ty)) {
- fn hit_zero(@block_ctxt cx, ValueRef v,
- @typeck.ty body_ty) -> result {
+ case (ty.ty_box(?body_ty)) {
+ fn hit_zero(@block_ctxt cx, ValueRef v, @ty.t body_ty) -> result {
auto body = cx.build.GEP(v,
vec(C_int(0),
C_int(abi.box_rc_field_body)));
@@ -742,18 +738,18 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @typeck.ty t) -> result {
}
case (_) {
- if (typeck.type_is_structural(t)) {
+ if (ty.type_is_structural(t)) {
ret iter_structural_ty(cx, v, t,
bind drop_ty(_, _, _));
- } else if (typeck.type_is_scalar(t) ||
- typeck.type_is_nil(t)) {
+ } else if (ty.type_is_scalar(t) ||
+ ty.type_is_nil(t)) {
ret res(cx, C_nil());
}
}
}
cx.fcx.ccx.sess.bug("bad type in trans.make_drop_glue_inner: " +
- typeck.ty_to_str(t));
+ ty.ty_to_str(t));
fail;
}
@@ -802,9 +798,9 @@ fn decr_refcnt_and_if_zero(@block_ctxt cx,
fn type_of_variant(@crate_ctxt cx, &ast.variant v) -> TypeRef {
let vec[TypeRef] lltys = vec();
- alt (typeck.ann_to_type(v.ann).struct) {
- case (typeck.ty_fn(?args, _)) {
- for (typeck.arg arg in args) {
+ alt (ty.ann_to_type(v.ann).struct) {
+ case (ty.ty_fn(?args, _)) {
+ for (ty.arg arg in args) {
lltys += vec(type_of(cx, arg.ty));
}
}
@@ -813,13 +809,12 @@ fn type_of_variant(@crate_ctxt cx, &ast.variant v) -> TypeRef {
ret T_struct(lltys);
}
-type val_and_ty_fn =
- fn(@block_ctxt cx, ValueRef v, @typeck.ty t) -> result;
+type val_and_ty_fn = fn(@block_ctxt cx, ValueRef v, @ty.t t) -> result;
// Iterates through the elements of a structural type.
fn iter_structural_ty(@block_ctxt cx,
ValueRef v,
- @typeck.ty t,
+ @ty.t t,
val_and_ty_fn f)
-> result {
let result r = res(cx, C_nil());
@@ -828,8 +823,8 @@ fn iter_structural_ty(@block_ctxt cx,
ValueRef box_cell,
val_and_ty_fn f) -> result {
auto box_ptr = cx.build.Load(box_cell);
- auto tnil = typeck.plain_ty(typeck.ty_nil);
- auto tbox = typeck.plain_ty(typeck.ty_box(tnil));
+ auto tnil = ty.plain_ty(ty.ty_nil);
+ auto tbox = ty.plain_ty(ty.ty_box(tnil));
auto inner_cx = new_sub_block_ctxt(cx, "iter box");
auto next_cx = new_sub_block_ctxt(cx, "next");
@@ -842,9 +837,9 @@ fn iter_structural_ty(@block_ctxt cx,
}
alt (t.struct) {
- case (typeck.ty_tup(?args)) {
+ case (ty.ty_tup(?args)) {
let int i = 0;
- for (@typeck.ty arg in args) {
+ for (@ty.t arg in args) {
auto elt = r.bcx.build.GEP(v, vec(C_int(0), C_int(i)));
r = f(r.bcx,
load_non_structural(r.bcx, elt, arg),
@@ -852,9 +847,9 @@ fn iter_structural_ty(@block_ctxt cx,
i += 1;
}
}
- case (typeck.ty_rec(?fields)) {
+ case (ty.ty_rec(?fields)) {
let int i = 0;
- for (typeck.field fld in fields) {
+ for (ty.field fld in fields) {
auto llfld = r.bcx.build.GEP(v, vec(C_int(0), C_int(i)));
r = f(r.bcx,
load_non_structural(r.bcx, llfld, fld.ty),
@@ -862,7 +857,7 @@ fn iter_structural_ty(@block_ctxt cx,
i += 1;
}
}
- case (typeck.ty_tag(?tid)) {
+ case (ty.ty_tag(?tid)) {
check (cx.fcx.ccx.tags.contains_key(tid));
auto info = cx.fcx.ccx.tags.get(tid);
auto n_variants = _vec.len[tup(ast.def_id,arity)](info.variants);
@@ -907,15 +902,15 @@ fn iter_structural_ty(@block_ctxt cx,
auto llvarty = type_of_variant(cx.fcx.ccx,
variants.(i));
- auto fn_ty = typeck.ann_to_type(variants.(i).ann);
+ auto fn_ty = ty.ann_to_type(variants.(i).ann);
alt (fn_ty.struct) {
- case (typeck.ty_fn(?args, _)) {
+ case (ty.ty_fn(?args, _)) {
auto llvarp = variant_cx.build.
TruncOrBitCast(llunion_ptr,
T_ptr(llvarty));
auto j = 0u;
- for (typeck.arg a in args) {
+ for (ty.arg a in args) {
auto llfldp = variant_cx.build.GEP(llvarp,
vec(C_int(0), C_int(j as int)));
auto llfld =
@@ -943,14 +938,14 @@ fn iter_structural_ty(@block_ctxt cx,
ret res(next_cx, C_nil());
}
- case (typeck.ty_fn(_,_)) {
+ case (ty.ty_fn(_,_)) {
auto box_cell =
cx.build.GEP(v,
vec(C_int(0),
C_int(abi.fn_field_box)));
ret iter_boxpp(cx, box_cell, f);
}
- case (typeck.ty_obj(_)) {
+ case (ty.ty_obj(_)) {
auto box_cell =
cx.build.GEP(v,
vec(C_int(0),
@@ -967,12 +962,12 @@ fn iter_structural_ty(@block_ctxt cx,
// Iterates through the elements of a vec or str.
fn iter_sequence(@block_ctxt cx,
ValueRef v,
- @typeck.ty ty,
+ @ty.t t,
val_and_ty_fn f) -> result {
fn iter_sequence_body(@block_ctxt cx,
ValueRef v,
- @typeck.ty elt_ty,
+ @ty.t elt_ty,
val_and_ty_fn f,
bool trailing_null) -> result {
@@ -1022,12 +1017,12 @@ fn iter_sequence(@block_ctxt cx,
ret res(next_cx, C_nil());
}
- alt (ty.struct) {
- case (typeck.ty_vec(?et)) {
+ alt (t.struct) {
+ case (ty.ty_vec(?et)) {
ret iter_sequence_body(cx, v, et, f, false);
}
- case (typeck.ty_str) {
- auto et = typeck.plain_ty(typeck.ty_machine(common.ty_u8));
+ case (ty.ty_str) {
+ auto et = ty.plain_ty(ty.ty_machine(common.ty_u8));
ret iter_sequence_body(cx, v, et, f, true);
}
case (_) { fail; }
@@ -1038,9 +1033,9 @@ fn iter_sequence(@block_ctxt cx,
fn incr_all_refcnts(@block_ctxt cx,
ValueRef v,
- @typeck.ty t) -> result {
+ @ty.t t) -> result {
- if (!typeck.type_is_scalar(t)) {
+ if (!ty.type_is_scalar(t)) {
auto llrawptr = cx.build.BitCast(v, T_ptr(T_i8()));
auto llfnptr = field_of_tydesc(cx, t, abi.tydesc_field_take_glue_off);
auto llfn = cx.build.Load(llfnptr);
@@ -1051,7 +1046,7 @@ fn incr_all_refcnts(@block_ctxt cx,
fn drop_slot(@block_ctxt cx,
ValueRef slot,
- @typeck.ty t) -> result {
+ @ty.t t) -> result {
auto llptr = load_non_structural(cx, slot, t);
auto re = drop_ty(cx, llptr, t);
@@ -1063,9 +1058,9 @@ fn drop_slot(@block_ctxt cx,
fn drop_ty(@block_ctxt cx,
ValueRef v,
- @typeck.ty t) -> result {
+ @ty.t t) -> result {
- if (!typeck.type_is_scalar(t)) {
+ if (!ty.type_is_scalar(t)) {
auto llrawptr = cx.build.BitCast(v, T_ptr(T_i8()));
auto llfnptr = field_of_tydesc(cx, t, abi.tydesc_field_drop_glue_off);
auto llfn = cx.build.Load(llfnptr);
@@ -1102,21 +1097,21 @@ fn copy_ty(@block_ctxt cx,
bool is_init,
ValueRef dst,
ValueRef src,
- @typeck.ty t) -> result {
- if (typeck.type_is_scalar(t)) {
+ @ty.t t) -> result {
+ if (ty.type_is_scalar(t)) {
ret res(cx, cx.build.Store(src, dst));
- } else if (typeck.type_is_nil(t)) {
+ } else if (ty.type_is_nil(t)) {
ret res(cx, C_nil());
- } else if (typeck.type_is_boxed(t)) {
+ } else if (ty.type_is_boxed(t)) {
auto r = incr_all_refcnts(cx, src, t);
if (! is_init) {
r = drop_ty(r.bcx, r.bcx.build.Load(dst), t);
}
ret res(r.bcx, r.bcx.build.Store(src, dst));
- } else if (typeck.type_is_structural(t)) {
+ } else if (ty.type_is_structural(t)) {
auto r = incr_all_refcnts(cx, src, t);
if (! is_init) {
r = drop_ty(r.bcx, dst, t);
@@ -1128,7 +1123,7 @@ fn copy_ty(@block_ctxt cx,
}
cx.fcx.ccx.sess.bug("unexpected type in trans.copy_ty: " +
- typeck.ty_to_str(t));
+ ty.ty_to_str(t));
fail;
}
@@ -1185,14 +1180,14 @@ impure fn trans_lit(@block_ctxt cx, &ast.lit lit, &ast.ann ann) -> result {
}
}
-fn target_type(@crate_ctxt cx, @typeck.ty t) -> @typeck.ty {
+fn target_type(@crate_ctxt cx, @ty.t t) -> @ty.t {
alt (t.struct) {
- case (typeck.ty_int) {
- auto tm = typeck.ty_machine(cx.sess.get_targ_cfg().int_type);
+ case (ty.ty_int) {
+ auto tm = ty.ty_machine(cx.sess.get_targ_cfg().int_type);
ret @rec(struct=tm with *t);
}
- case (typeck.ty_uint) {
- auto tm = typeck.ty_machine(cx.sess.get_targ_cfg().uint_type);
+ case (ty.ty_uint) {
+ auto tm = ty.ty_machine(cx.sess.get_targ_cfg().uint_type);
ret @rec(struct=tm with *t);
}
case (_) { /* fall through */ }
@@ -1200,7 +1195,7 @@ fn target_type(@crate_ctxt cx, @typeck.ty t) -> @typeck.ty {
ret t;
}
-fn node_ann_type(@crate_ctxt cx, &ast.ann a) -> @typeck.ty {
+fn node_ann_type(@crate_ctxt cx, &ast.ann a) -> @ty.t {
alt (a) {
case (ast.ann_none) {
cx.sess.bug("missing type annotation");
@@ -1235,7 +1230,7 @@ impure fn trans_unary(@block_ctxt cx, ast.unop op,
ret sub;
}
case (ast.box) {
- auto e_ty = typeck.expr_ty(e);
+ auto e_ty = ty.expr_ty(e);
auto e_val = sub.val;
sub = trans_malloc(sub.bcx, node_ann_type(sub.bcx.fcx.ccx, a));
auto box = sub.val;
@@ -1254,8 +1249,8 @@ impure fn trans_unary(@block_ctxt cx, ast.unop op,
vec(C_int(0),
C_int(abi.box_rc_field_body)));
auto e_ty = node_ann_type(sub.bcx.fcx.ccx, a);
- if (typeck.type_is_scalar(e_ty) ||
- typeck.type_is_nil(e_ty)) {
+ if (ty.type_is_scalar(e_ty) ||
+ ty.type_is_nil(e_ty)) {
sub.val = sub.bcx.build.Load(sub.val);
}
ret sub;
@@ -1659,22 +1654,20 @@ impure fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base,
&ast.ident field, &ast.ann ann) -> tup(result, bool) {
auto lv = trans_lval(cx, base);
auto r = lv._0;
- auto ty = typeck.expr_ty(base);
- alt (ty.struct) {
- case (typeck.ty_tup(?fields)) {
- let uint ix = typeck.field_num(cx.fcx.ccx.sess, sp, field);
+ auto t = ty.expr_ty(base);
+ alt (t.struct) {
+ case (ty.ty_tup(?fields)) {
+ let uint ix = ty.field_num(cx.fcx.ccx.sess, sp, field);
auto v = r.bcx.build.GEP(r.val, vec(C_int(0), C_int(ix as int)));
ret tup(res(r.bcx, v), true);
}
- case (typeck.ty_rec(?fields)) {
- let uint ix = typeck.field_idx(cx.fcx.ccx.sess, sp,
- field, fields);
+ case (ty.ty_rec(?fields)) {
+ let uint ix = ty.field_idx(cx.fcx.ccx.sess, sp, field, fields);
auto v = r.bcx.build.GEP(r.val, vec(C_int(0), C_int(ix as int)));
ret tup(res(r.bcx, v), true);
}
- case (typeck.ty_obj(?methods)) {
- let uint ix = typeck.method_idx(cx.fcx.ccx.sess, sp,
- field, methods);
+ case (ty.ty_obj(?methods)) {
+ let uint ix = ty.method_idx(cx.fcx.ccx.sess, sp, field, methods);
auto vtbl = r.bcx.build.GEP(r.val,
vec(C_int(0),
C_int(abi.obj_field_vtbl)));
@@ -1747,10 +1740,10 @@ impure fn trans_cast(@block_ctxt cx, @ast.expr e, &ast.ann ann) -> result {
auto llsrctype = val_ty(e_res.val);
auto t = node_ann_type(cx.fcx.ccx, ann);
auto lldsttype = type_of(cx.fcx.ccx, t);
- if (!typeck.type_is_fp(t)) {
+ if (!ty.type_is_fp(t)) {
if (llvm.LLVMGetIntTypeWidth(lldsttype) >
llvm.LLVMGetIntTypeWidth(llsrctype)) {
- if (typeck.type_is_signed(t)) {
+ if (ty.type_is_signed(t)) {
// Widening signed cast.
e_res.val =
e_res.bcx.build.SExtOrBitCast(e_res.val,
@@ -1774,14 +1767,14 @@ impure fn trans_cast(@block_ctxt cx, @ast.expr e, &ast.ann ann) -> result {
}
-impure fn trans_args(@block_ctxt cx, &vec[@ast.expr] es, @typeck.ty fn_ty)
+impure fn trans_args(@block_ctxt cx, &vec[@ast.expr] es, @ty.t fn_ty)
-> tup(@block_ctxt, vec[ValueRef]) {
let vec[ValueRef] vs = vec(cx.fcx.lltaskptr);
let @block_ctxt bcx = cx;
- let vec[typeck.arg] args = vec(); // FIXME: typestate bug
+ let vec[ty.arg] args = vec(); // FIXME: typestate bug
alt (fn_ty.struct) {
- case (typeck.ty_fn(?a, _)) { args = a; }
+ case (ty.ty_fn(?a, _)) { args = a; }
case (_) { fail; }
}
@@ -1790,7 +1783,7 @@ impure fn trans_args(@block_ctxt cx, &vec[@ast.expr] es, @typeck.ty fn_ty)
auto mode = args.(i).mode;
auto re;
- if (typeck.type_is_structural(typeck.expr_ty(e))) {
+ if (ty.type_is_structural(ty.expr_ty(e))) {
re = trans_expr(bcx, e);
if (mode == ast.val) {
// Until here we've been treating structures by pointer;
@@ -1800,7 +1793,7 @@ impure fn trans_args(@block_ctxt cx, &vec[@ast.expr] es, @typeck.ty fn_ty)
} else {
if (mode == ast.alias) {
let tup(result, bool /* is a pointer? */) pair;
- if (typeck.is_lval(e)) {
+ if (ty.is_lval(e)) {
pair = trans_lval(bcx, e);
} else {
pair = tup(trans_expr(bcx, e), false);
@@ -1836,13 +1829,13 @@ impure fn trans_call(@block_ctxt cx, @ast.expr f,
if (f_res._1) {
faddr = f_res._0.bcx.build.Load(faddr);
}
- auto fn_ty = typeck.expr_ty(f);
- auto ret_ty = typeck.ann_to_type(ann);
+ auto fn_ty = ty.expr_ty(f);
+ auto ret_ty = ty.ann_to_type(ann);
auto args_res = trans_args(f_res._0.bcx, args, fn_ty);
auto real_retval = args_res._0.build.FastCall(faddr, args_res._1);
auto retval;
- if (typeck.type_is_nil(ret_ty)) {
+ if (ty.type_is_nil(ret_ty)) {
retval = C_nil();
} else {
retval = real_retval;
@@ -1851,7 +1844,7 @@ impure fn trans_call(@block_ctxt cx, @ast.expr f,
// Structured returns come back as first-class values. This is nice for
// LLVM but wrong for us; we treat structured values by pointer in
// most of our code here. So spill it to an alloca.
- if (typeck.type_is_structural(ret_ty)) {
+ if (ty.type_is_structural(ret_ty)) {
auto local = args_res._0.build.Alloca(type_of(cx.fcx.ccx, ret_ty));
args_res._0.build.Store(retval, local);
retval = local;
@@ -1867,14 +1860,14 @@ impure fn trans_call(@block_ctxt cx, @ast.expr f,
impure fn trans_tup(@block_ctxt cx, vec[ast.elt] elts,
&ast.ann ann) -> result {
- auto ty = node_ann_type(cx.fcx.ccx, ann);
- auto llty = type_of(cx.fcx.ccx, ty);
+ auto t = node_ann_type(cx.fcx.ccx, ann);
+ auto llty = type_of(cx.fcx.ccx, t);
auto tup_val = cx.build.Alloca(llty);
- find_scope_cx(cx).cleanups += clean(bind drop_ty(_, tup_val, ty));
+ find_scope_cx(cx).cleanups += clean(bind drop_ty(_, tup_val, t));
let int i = 0;
auto r = res(cx, C_nil());
for (ast.elt e in elts) {
- auto t = typeck.expr_ty(e.expr);
+ auto t = ty.expr_ty(e.expr);
auto src_res = trans_expr(r.bcx, e.expr);
auto dst_elt = r.bcx.build.GEP(tup_val, vec(C_int(0), C_int(i)));
r = copy_ty(src_res.bcx, true, dst_elt, src_res.val, t);
@@ -1885,10 +1878,10 @@ impure fn trans_tup(@block_ctxt cx, vec[ast.elt] elts,
impure fn trans_vec(@block_ctxt cx, vec[@ast.expr] args,
&ast.ann ann) -> result {
- auto ty = node_ann_type(cx.fcx.ccx, ann);
- auto unit_ty = ty;
- alt (ty.struct) {
- case (typeck.ty_vec(?t)) {
+ auto t = node_ann_type(cx.fcx.ccx, ann);
+ auto unit_ty = t;
+ alt (t.struct) {
+ case (ty.ty_vec(?t)) {
unit_ty = t;
}
case (_) {
@@ -1904,9 +1897,9 @@ impure fn trans_vec(@block_ctxt cx, vec[@ast.expr] args,
// FIXME: pass tydesc properly.
auto sub = trans_upcall(cx, "upcall_new_vec", vec(data_sz, C_int(0)));
- auto llty = type_of(cx.fcx.ccx, ty);
+ auto llty = type_of(cx.fcx.ccx, t);
auto vec_val = sub.bcx.build.IntToPtr(sub.val, llty);
- find_scope_cx(cx).cleanups += clean(bind drop_ty(_, vec_val, ty));
+ find_scope_cx(cx).cleanups += clean(bind drop_ty(_, vec_val, t));
auto body = sub.bcx.build.GEP(vec_val, vec(C_int(0),
C_int(abi.vec_elt_data)));
@@ -1926,14 +1919,14 @@ impure fn trans_vec(@block_ctxt cx, vec[@ast.expr] args,
impure fn trans_rec(@block_ctxt cx, vec[ast.field] fields,
&ast.ann ann) -> result {
- auto ty = node_ann_type(cx.fcx.ccx, ann);
- auto llty = type_of(cx.fcx.ccx, ty);
+ auto t = node_ann_type(cx.fcx.ccx, ann);
+ auto llty = type_of(cx.fcx.ccx, t);
auto rec_val = cx.build.Alloca(llty);
- find_scope_cx(cx).cleanups += clean(bind drop_ty(_, rec_val, ty));
+ find_scope_cx(cx).cleanups += clean(bind drop_ty(_, rec_val, t));
let int i = 0;
auto r = res(cx, C_nil());
for (ast.field f in fields) {
- auto t = typeck.expr_ty(f.expr);
+ auto t = ty.expr_ty(f.expr);
auto src_res = trans_expr(r.bcx, f.expr);
auto dst_elt = r.bcx.build.GEP(rec_val, vec(C_int(0), C_int(i)));
// FIXME: calculate copy init-ness in typestate.
@@ -2031,7 +2024,7 @@ impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
// possibly load the result (if it's non-structural).
case (_) {
- auto t = typeck.expr_ty(e);
+ auto t = ty.expr_ty(e);
auto sub = trans_lval(cx, e);
ret res(sub._0.bcx,
load_non_structural(sub._0.bcx, sub._0.val, t));
@@ -2047,8 +2040,8 @@ impure fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
fn load_non_structural(@block_ctxt cx,
ValueRef v,
- @typeck.ty t) -> ValueRef {
- if (typeck.type_is_structural(t)) {
+ @ty.t t) -> ValueRef {
+ if (ty.type_is_structural(t)) {
ret v;
} else {
ret cx.build.Load(v);
@@ -2058,9 +2051,9 @@ fn load_non_structural(@block_ctxt cx,
impure fn trans_log(@block_ctxt cx, @ast.expr e) -> result {
auto sub = trans_expr(cx, e);
- auto e_ty = typeck.expr_ty(e);
+ auto e_ty = ty.expr_ty(e);
alt (e_ty.struct) {
- case (typeck.ty_str) {
+ case (ty.ty_str) {
auto v = sub.bcx.build.PtrToInt(sub.val, T_int());
ret trans_upcall(sub.bcx,
"upcall_log_str",
@@ -2099,14 +2092,14 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
auto r = res(cx, C_nil());
alt (e) {
case (some[@ast.expr](?x)) {
- auto t = typeck.expr_ty(x);
+ auto t = ty.expr_ty(x);
r = trans_expr(cx, x);
// A return is an implicit copy into a newborn anonymous
// 'return value' in the caller frame.
r.bcx = incr_all_refcnts(r.bcx, r.val, t).bcx;
- if (typeck.type_is_structural(t)) {
+ if (ty.type_is_structural(t)) {
// We usually treat structurals by-pointer; in particular,
// trans_expr will have given us a structure pointer. But in
// this case we're about to return. LLVM wants a first-class
@@ -2134,7 +2127,7 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
alt (e) {
case (some[@ast.expr](?ex)) {
- if (typeck.type_is_nil(typeck.expr_ty(ex))) {
+ if (ty.type_is_nil(ty.expr_ty(ex))) {
r.bcx.build.RetVoid();
r.val = C_nil();
} else {
@@ -2359,7 +2352,7 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx, &vec[ast.arg] args,
// were passed and whatnot. Apparently mem2reg will mop up.
fn copy_args_to_allocas(@block_ctxt cx, vec[ast.arg] args,
- vec[typeck.arg] arg_tys) {
+ vec[ty.arg] arg_tys) {
let uint arg_n = 0u;
@@ -2382,18 +2375,18 @@ fn is_terminated(@block_ctxt cx) -> bool {
ret llvm.LLVMIsATerminatorInst(inst) as int != 0;
}
-fn arg_tys_of_fn(ast.ann ann) -> vec[typeck.arg] {
- alt (typeck.ann_to_type(ann).struct) {
- case (typeck.ty_fn(?arg_tys, _)) {
+fn arg_tys_of_fn(ast.ann ann) -> vec[ty.arg] {
+ alt (ty.ann_to_type(ann).struct) {
+ case (ty.ty_fn(?arg_tys, _)) {
ret arg_tys;
}
}
fail;
}
-fn ret_ty_of_fn(ast.ann ann) -> @typeck.ty {
- alt (typeck.ann_to_type(ann).struct) {
- case (typeck.ty_fn(_, ?ret_ty)) {
+fn ret_ty_of_fn(ast.ann ann) -> @ty.t {
+ alt (ty.ann_to_type(ann).struct) {
+ case (ty.ty_fn(_, ?ret_ty)) {
ret ret_ty;
}
}
@@ -2498,7 +2491,7 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
id=varg.id));
}
- auto var_ty = typeck.ann_to_type(variant.ann);
+ auto var_ty = ty.ann_to_type(variant.ann);
auto llfnty = type_of(cx, var_ty);
let str s = cx.names.next("_rust_tag") + "." + cx.path;
@@ -2531,7 +2524,7 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id,
// First, generate the union type.
let vec[TypeRef] llargtys = vec();
- for (typeck.arg arg in arg_tys) {
+ for (ty.arg arg in arg_tys) {
llargtys += vec(type_of(cx, arg.ty));
}
@@ -2941,9 +2934,9 @@ fn trans_crate(session.session sess, @ast.crate crate, str output) {
auto intrinsics = declare_intrinsics(llmod);
auto glues = make_glues(llmod);
- auto hasher = typeck.hash_ty;
- auto eqer = typeck.eq_ty;
- auto tydescs = map.mk_hashmap[@typeck.ty,ValueRef](hasher, eqer);
+ auto hasher = ty.hash_ty;
+ auto eqer = ty.eq_ty;
+ auto tydescs = map.mk_hashmap[@ty.t,ValueRef](hasher, eqer);
auto cx = @rec(sess = sess,
llmod = llmod,
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
new file mode 100644
index 00000000..19fb0285
--- /dev/null
+++ b/src/comp/middle/ty.rs
@@ -0,0 +1,588 @@
+import std._str;
+import std._vec;
+import std.option;
+import std.option.none;
+import std.option.some;
+
+import driver.session;
+import front.ast;
+import front.ast.mutability;
+import util.common;
+import util.common.span;
+
+// Data types
+
+type arg = rec(ast.mode mode, @t ty);
+type field = rec(ast.ident ident, @t ty);
+type method = rec(ast.ident ident, vec[arg] inputs, @t output);
+
+// NB: If you change this, you'll probably want to change the corresponding
+// AST structure in front/ast.rs as well.
+type t = rec(sty struct, mutability mut, option.t[str] cname);
+tag sty {
+ ty_nil;
+ ty_bool;
+ ty_int;
+ ty_uint;
+ ty_machine(util.common.ty_mach);
+ ty_char;
+ ty_str;
+ ty_tag(ast.def_id);
+ ty_box(@t);
+ ty_vec(@t);
+ ty_tup(vec[@t]);
+ ty_rec(vec[field]);
+ ty_fn(vec[arg], @t); // TODO: effect
+ ty_obj(vec[method]);
+ ty_var(int); // ephemeral type var
+ ty_local(ast.def_id); // type of a local var
+ ty_param(ast.def_id); // fn type param
+ // TODO: ty_fn_arg(@t), for a possibly-aliased function argument
+}
+
+// Stringification
+
+fn ast_ty_to_str(&@ast.ty ty) -> str {
+
+ fn ast_fn_input_to_str(&rec(ast.mode mode, @ast.ty ty) input) -> str {
+ auto s;
+ if (mode_is_alias(input.mode)) {
+ s = "&";
+ } else {
+ s = "";
+ }
+
+ ret s + ast_ty_to_str(input.ty);
+ }
+
+ fn ast_ty_field_to_str(&ast.ty_field f) -> str {
+ ret ast_ty_to_str(f.ty) + " " + f.ident;
+ }
+
+ auto s;
+ alt (ty.node) {
+ case (ast.ty_nil) { s = "()"; }
+ case (ast.ty_bool) { s = "bool"; }
+ case (ast.ty_int) { s = "int"; }
+ case (ast.ty_uint) { s = "uint"; }
+ case (ast.ty_machine(?tm)) { s = common.ty_mach_to_str(tm); }
+ case (ast.ty_char) { s = "char"; }
+ case (ast.ty_str) { s = "str"; }
+ case (ast.ty_box(?t)) { s = "@" + ast_ty_to_str(t); }
+ case (ast.ty_vec(?t)) { s = "vec[" + ast_ty_to_str(t) + "]"; }
+
+ case (ast.ty_tup(?elts)) {
+ auto f = ast_ty_to_str;
+ s = "tup(";
+ s += _str.connect(_vec.map[@ast.ty,str](f, elts), ",");
+ s += ")";
+ }
+
+ case (ast.ty_rec(?fields)) {
+ auto f = ast_ty_field_to_str;
+ s = "rec(";
+ s += _str.connect(_vec.map[ast.ty_field,str](f, fields), ",");
+ s += ")";
+ }
+
+ case (ast.ty_fn(?inputs, ?output)) {
+ auto f = ast_fn_input_to_str;
+ s = "fn(";
+ auto is = _vec.map[rec(ast.mode mode, @ast.ty ty),str](f, inputs);
+ s += _str.connect(is, ", ");
+ s += ")";
+
+ if (output.node != ast.ty_nil) {
+ s += " -> " + ast_ty_to_str(output);
+ }
+ }
+
+ case (ast.ty_path(?path, _)) {
+ s = path_to_str(path);
+ }
+
+ case (ast.ty_mutable(?t)) {
+ s = "mutable " + ast_ty_to_str(t);
+ }
+
+ case (_) {
+ fail; // FIXME: typestate bug
+ }
+ }
+
+ ret s;
+}
+
+fn name_to_str(&ast.name nm) -> str {
+ auto result = nm.node.ident;
+ if (_vec.len[@ast.ty](nm.node.types) > 0u) {
+ auto f = ast_ty_to_str;
+ result += "[";
+ result += _str.connect(_vec.map[@ast.ty,str](f, nm.node.types), ",");
+ result += "]";
+ }
+ ret result;
+}
+
+fn path_to_str(&ast.path path) -> str {
+ auto f = name_to_str;
+ ret _str.connect(_vec.map[ast.name,str](f, path), ".");
+}
+
+fn ty_to_str(&@t typ) -> str {
+
+ fn fn_input_to_str(&rec(ast.mode mode, @t ty) input) -> str {
+ auto s;
+ if (mode_is_alias(input.mode)) {
+ s = "&";
+ } else {
+ s = "";
+ }
+
+ ret s + ty_to_str(input.ty);
+ }
+
+ fn fn_to_str(option.t[ast.ident] ident,
+ vec[arg] inputs, @t output) -> str {
+ auto f = fn_input_to_str;
+ auto s = "fn";
+ alt (ident) {
+ case (some[ast.ident](?i)) {
+ s += " ";
+ s += i;
+ }
+ case (_) { }
+ }
+
+ s += "(";
+ s += _str.connect(_vec.map[arg,str](f, inputs), ", ");
+ s += ")";
+
+ if (output.struct != ty_nil) {
+ s += " -> " + ty_to_str(output);
+ }
+ ret s;
+ }
+
+ fn method_to_str(&method m) -> str {
+ ret fn_to_str(some[ast.ident](m.ident), m.inputs, m.output) + ";";
+ }
+
+ fn field_to_str(&field f) -> str {
+ ret ty_to_str(f.ty) + " " + f.ident;
+ }
+
+ auto s = "";
+ if (typ.mut == ast.mut) {
+ s += "mutable ";
+ }
+
+ alt (typ.struct) {
+ case (ty_nil) { s = "()"; }
+ case (ty_bool) { s = "bool"; }
+ case (ty_int) { s = "int"; }
+ case (ty_uint) { s = "uint"; }
+ case (ty_machine(?tm)) { s = common.ty_mach_to_str(tm); }
+ case (ty_char) { s = "char"; }
+ case (ty_str) { s = "str"; }
+ case (ty_box(?t)) { s = "@" + ty_to_str(t); }
+ case (ty_vec(?t)) { s = "vec[" + ty_to_str(t) + "]"; }
+
+ case (ty_tup(?elems)) {
+ auto f = ty_to_str;
+ auto strs = _vec.map[@t,str](f, elems);
+ s = "tup(" + _str.connect(strs, ",") + ")";
+ }
+
+ case (ty_rec(?elems)) {
+ auto f = field_to_str;
+ auto strs = _vec.map[field,str](f, elems);
+ s = "rec(" + _str.connect(strs, ",") + ")";
+ }
+
+ case (ty_tag(_)) {
+ // The user should never see this if the cname is set properly!
+ s = "<tag>";
+ }
+
+ case (ty_fn(?inputs, ?output)) {
+ s = fn_to_str(none[ast.ident], inputs, output);
+ }
+
+ case (ty_obj(?meths)) {
+ auto f = method_to_str;
+ auto m = _vec.map[method,str](f, meths);
+ s = "obj {\n\t" + _str.connect(m, "\n\t") + "\n}";
+ }
+
+ case (ty_var(?v)) {
+ s = "<T" + util.common.istr(v) + ">";
+ }
+
+ case (ty_param(?id)) {
+ s = "<P" + util.common.istr(id._0) + ":" + util.common.istr(id._1)
+ + ">";
+ }
+ }
+
+ ret s;
+}
+
+// Type folds
+
+type ty_fold = state obj {
+ fn fold_simple_ty(@t ty) -> @t;
+};
+
+fn fold_ty(ty_fold fld, @t ty) -> @t {
+ fn rewrap(@t orig, &sty new) -> @t {
+ ret @rec(struct=new, mut=orig.mut, cname=orig.cname);
+ }
+
+ alt (ty.struct) {
+ case (ty_nil) { ret fld.fold_simple_ty(ty); }
+ case (ty_bool) { ret fld.fold_simple_ty(ty); }
+ case (ty_int) { ret fld.fold_simple_ty(ty); }
+ case (ty_uint) { ret fld.fold_simple_ty(ty); }
+ case (ty_machine(_)) { ret fld.fold_simple_ty(ty); }
+ case (ty_char) { ret fld.fold_simple_ty(ty); }
+ case (ty_str) { ret fld.fold_simple_ty(ty); }
+ case (ty_tag(_)) { ret fld.fold_simple_ty(ty); }
+ case (ty_box(?subty)) {
+ ret rewrap(ty, ty_box(fold_ty(fld, subty)));
+ }
+ case (ty_vec(?subty)) {
+ ret rewrap(ty, ty_vec(fold_ty(fld, subty)));
+ }
+ case (ty_tup(?subtys)) {
+ let vec[@t] new_subtys = vec();
+ for (@t subty in subtys) {
+ new_subtys += vec(fold_ty(fld, subty));
+ }
+ ret rewrap(ty, ty_tup(new_subtys));
+ }
+ case (ty_rec(?fields)) {
+ let vec[field] new_fields = vec();
+ for (field fl in fields) {
+ auto new_ty = fold_ty(fld, fl.ty);
+ new_fields += vec(rec(ident=fl.ident, ty=new_ty));
+ }
+ ret rewrap(ty, ty_rec(new_fields));
+ }
+ case (ty_fn(?args, ?ret_ty)) {
+ let vec[arg] new_args = vec();
+ for (arg a in args) {
+ auto new_ty = fold_ty(fld, a.ty);
+ new_args += vec(rec(mode=a.mode, ty=new_ty));
+ }
+ ret rewrap(ty, ty_fn(new_args, fold_ty(fld, ret_ty)));
+ }
+ case (ty_obj(?methods)) {
+ let vec[method] new_methods = vec();
+ for (method m in methods) {
+ let vec[arg] new_args = vec();
+ for (arg a in m.inputs) {
+ new_args += vec(rec(mode=a.mode, ty=fold_ty(fld, a.ty)));
+ }
+ new_methods += vec(rec(ident=m.ident, inputs=new_args,
+ output=fold_ty(fld, m.output)));
+ }
+ ret rewrap(ty, ty_obj(new_methods));
+ }
+ case (ty_var(_)) { ret fld.fold_simple_ty(ty); }
+ case (ty_local(_)) { ret fld.fold_simple_ty(ty); }
+ case (ty_param(_)) { ret fld.fold_simple_ty(ty); }
+ }
+
+ ret ty;
+}
+
+// Type utilities
+
+// FIXME: remove me when == works on these tags.
+fn mode_is_alias(ast.mode m) -> bool {
+ alt (m) {
+ case (ast.val) { ret false; }
+ case (ast.alias) { ret true; }
+ }
+ fail;
+}
+
+fn type_is_nil(@t ty) -> bool {
+ alt (ty.struct) {
+ case (ty_nil) { ret true; }
+ case (_) { ret false; }
+ }
+ fail;
+}
+
+fn type_is_structural(@t ty) -> bool {
+ alt (ty.struct) {
+ case (ty_tup(_)) { ret true; }
+ case (ty_rec(_)) { ret true; }
+ case (ty_tag(_)) { ret true; }
+ case (ty_fn(_,_)) { ret true; }
+ case (ty_obj(_)) { ret true; }
+ case (_) { ret false; }
+ }
+ fail;
+}
+
+fn type_is_boxed(@t ty) -> bool {
+ alt (ty.struct) {
+ case (ty_str) { ret true; }
+ case (ty_vec(_)) { ret true; }
+ case (ty_box(_)) { ret true; }
+ case (_) { ret false; }
+ }
+ fail;
+}
+
+fn type_is_scalar(@t ty) -> bool {
+ alt (ty.struct) {
+ case (ty_nil) { ret true; }
+ case (ty_bool) { ret true; }
+ case (ty_int) { ret true; }
+ case (ty_uint) { ret true; }
+ case (ty_machine(_)) { ret true; }
+ case (ty_char) { ret true; }
+ case (_) { ret false; }
+ }
+ fail;
+}
+
+
+fn type_is_integral(@t ty) -> bool {
+ alt (ty.struct) {
+ case (ty_int) { ret true; }
+ case (ty_uint) { ret true; }
+ case (ty_machine(?m)) {
+ alt (m) {
+ case (common.ty_i8) { ret true; }
+ case (common.ty_i16) { ret true; }
+ case (common.ty_i32) { ret true; }
+ case (common.ty_i64) { ret true; }
+
+ case (common.ty_u8) { ret true; }
+ case (common.ty_u16) { ret true; }
+ case (common.ty_u32) { ret true; }
+ case (common.ty_u64) { ret true; }
+ case (_) { ret false; }
+ }
+ }
+ case (ty_char) { ret true; }
+ case (_) { ret false; }
+ }
+ fail;
+}
+
+fn type_is_fp(@t ty) -> bool {
+ alt (ty.struct) {
+ case (ty_machine(?tm)) {
+ alt (tm) {
+ case (common.ty_f32) { ret true; }
+ case (common.ty_f64) { ret true; }
+ case (_) { ret false; }
+ }
+ }
+ case (_) { ret false; }
+ }
+ fail;
+}
+
+fn type_is_signed(@t ty) -> bool {
+ alt (ty.struct) {
+ case (ty_int) { ret true; }
+ case (ty_machine(?tm)) {
+ alt (tm) {
+ case (common.ty_i8) { ret true; }
+ case (common.ty_i16) { ret true; }
+ case (common.ty_i32) { ret true; }
+ case (common.ty_i64) { ret true; }
+ case (_) { ret false; }
+ }
+ }
+ case (_) { ret false; }
+ }
+ fail;
+}
+
+fn type_param(@t ty) -> option.t[ast.def_id] {
+ alt (ty.struct) {
+ case (ty_param(?id)) { ret some[ast.def_id](id); }
+ case (_) { /* fall through */ }
+ }
+ ret none[ast.def_id];
+}
+
+fn plain_ty(&sty st) -> @t {
+ ret @rec(struct=st, mut=ast.imm, cname=none[str]);
+}
+
+fn hash_ty(&@t ty) -> uint {
+ ret _str.hash(ty_to_str(ty));
+}
+
+fn eq_ty(&@t a, &@t b) -> bool {
+ // FIXME: this is gross, but I think it's safe, and I don't think writing
+ // a giant function to handle all the cases is necessary when structural
+ // equality will someday save the day.
+ ret _str.eq(ty_to_str(a), ty_to_str(b));
+}
+
+fn ann_to_type(&ast.ann ann) -> @t {
+ alt (ann) {
+ case (ast.ann_none) {
+ // shouldn't happen, but can until the typechecker is complete
+ ret plain_ty(ty_var(-1)); // FIXME: broken, broken, broken
+ }
+ case (ast.ann_type(?ty)) {
+ ret ty;
+ }
+ }
+}
+
+fn count_ty_params(@t ty) -> uint {
+ state obj ty_param_counter(@mutable vec[ast.def_id] param_ids) {
+ fn fold_simple_ty(@t ty) -> @t {
+ alt (ty.struct) {
+ case (ty_param(?param_id)) {
+ for (ast.def_id other_param_id in *param_ids) {
+ if (param_id._0 == other_param_id._0 &&
+ param_id._1 == other_param_id._1) {
+ ret ty;
+ }
+ }
+ *param_ids += vec(param_id);
+ }
+ case (_) { /* fall through */ }
+ }
+ ret ty;
+ }
+ }
+
+ let vec[ast.def_id] param_ids_inner = vec();
+ let @mutable vec[ast.def_id] param_ids = @mutable param_ids_inner;
+ fold_ty(ty_param_counter(param_ids), ty);
+ ret _vec.len[ast.def_id](*param_ids);
+}
+
+// Type accessors for AST nodes
+
+fn stmt_ty(@ast.stmt s) -> @t {
+ alt (s.node) {
+ case (ast.stmt_expr(?e)) {
+ ret expr_ty(e);
+ }
+ case (_) {
+ ret plain_ty(ty_nil);
+ }
+ }
+}
+
+fn block_ty(&ast.block b) -> @t {
+ alt (b.node.expr) {
+ case (some[@ast.expr](?e)) { ret expr_ty(e); }
+ case (none[@ast.expr]) { ret plain_ty(ty_nil); }
+ }
+}
+
+fn pat_ty(@ast.pat pat) -> @t {
+ alt (pat.node) {
+ case (ast.pat_wild(?ann)) { ret ann_to_type(ann); }
+ case (ast.pat_bind(_, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.pat_tag(_, _, _, ?ann)) { ret ann_to_type(ann); }
+ }
+ fail; // not reached
+}
+
+fn expr_ty(@ast.expr expr) -> @t {
+ alt (expr.node) {
+ case (ast.expr_vec(_, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_tup(_, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_rec(_, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_call(_, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_binary(_, _, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_unary(_, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_lit(_, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_cast(_, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_if(_, _, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_while(_, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_do_while(_, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_alt(_, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_block(_, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_assign(_, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_assign_op(_, _, _, ?ann))
+ { ret ann_to_type(ann); }
+ case (ast.expr_field(_, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_index(_, _, ?ann)) { ret ann_to_type(ann); }
+ case (ast.expr_name(_, _, ?ann)) { ret ann_to_type(ann); }
+ }
+ fail;
+}
+
+// Expression utilities
+
+fn field_num(session.session sess, &span sp, &ast.ident id) -> uint {
+ let uint accum = 0u;
+ let uint i = 0u;
+ for (u8 c in id) {
+ if (i == 0u) {
+ if (c != ('_' as u8)) {
+ sess.span_err(sp,
+ "bad numeric field on tuple: "
+ + "missing leading underscore");
+ }
+ } else {
+ if (('0' as u8) <= c && c <= ('9' as u8)) {
+ accum *= 10u;
+ accum += (c as uint) - ('0' as uint);
+ } else {
+ auto s = "";
+ s += c;
+ sess.span_err(sp,
+ "bad numeric field on tuple: "
+ + " non-digit character: "
+ + s);
+ }
+ }
+ i += 1u;
+ }
+ ret accum;
+}
+
+fn field_idx(session.session sess, &span sp,
+ &ast.ident id, vec[field] fields) -> uint {
+ let uint i = 0u;
+ for (field f in fields) {
+ if (_str.eq(f.ident, id)) {
+ ret i;
+ }
+ i += 1u;
+ }
+ sess.span_err(sp, "unknown field '" + id + "' of record");
+ fail;
+}
+
+fn method_idx(session.session sess, &span sp,
+ &ast.ident id, vec[method] meths) -> uint {
+ let uint i = 0u;
+ for (method m in meths) {
+ if (_str.eq(m.ident, id)) {
+ ret i;
+ }
+ i += 1u;
+ }
+ sess.span_err(sp, "unknown method '" + id + "' of obj");
+ fail;
+}
+
+fn is_lval(@ast.expr expr) -> bool {
+ alt (expr.node) {
+ case (ast.expr_field(_,_,_)) { ret true; }
+ case (ast.expr_index(_,_,_)) { ret true; }
+ case (ast.expr_name(_,_,_)) { ret true; }
+ case (_) { ret false; }
+ }
+}
+
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 3770c0b8..8994d72d 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -7,6 +7,21 @@ import util.common;
import util.common.append;
import util.common.span;
+import middle.ty;
+import middle.ty.ann_to_type;
+import middle.ty.arg;
+import middle.ty.block_ty;
+import middle.ty.expr_ty;
+import middle.ty.field;
+import middle.ty.method;
+import middle.ty.mode_is_alias;
+import middle.ty.pat_ty;
+import middle.ty.path_to_str;
+import middle.ty.plain_ty;
+import middle.ty.ty_to_str;
+import middle.ty.type_is_integral;
+import middle.ty.type_is_scalar;
+
import std._str;
import std._uint;
import std._vec;
@@ -16,42 +31,17 @@ import std.option;
import std.option.none;
import std.option.some;
-type ty_table = hashmap[ast.def_id, @ty];
+type ty_table = hashmap[ast.def_id, @ty.t];
type crate_ctxt = rec(session.session sess,
@ty_table item_types,
mutable int next_var_id);
-type fn_ctxt = rec(@ty ret_ty,
+type fn_ctxt = rec(@ty.t ret_ty,
@ty_table locals,
@crate_ctxt ccx);
-type arg = rec(ast.mode mode, @ty ty);
-type field = rec(ast.ident ident, @ty ty);
-type method = rec(ast.ident ident, vec[arg] inputs, @ty output);
-
-// NB: If you change this, you'll probably want to change the corresponding
-// AST structure in front/ast.rs as well.
-type ty = rec(sty struct, mutability mut, option.t[str] cname);
-tag sty {
- ty_nil;
- ty_bool;
- ty_int;
- ty_uint;
- ty_machine(util.common.ty_mach);
- ty_char;
- ty_str;
- ty_tag(ast.def_id);
- ty_box(@ty);
- ty_vec(@ty);
- ty_tup(vec[@ty]);
- ty_rec(vec[field]);
- ty_fn(vec[arg], @ty); // TODO: effect
- ty_obj(vec[method]);
- ty_var(int); // ephemeral type var
- ty_local(ast.def_id); // type of a local var
- ty_param(ast.def_id); // fn type param
- // TODO: ty_fn_arg(@ty), for a possibly-aliased function argument
-}
+// Used for ast_ty_to_ty() below.
+type ty_getter = fn(ast.def_id) -> @ty.t;
tag type_err {
terr_mismatch;
@@ -64,208 +54,18 @@ tag type_err {
}
tag unify_result {
- ures_ok(@ty);
- ures_err(type_err, @ty, @ty);
-}
-
-// Used for ast_ty_to_ty() below.
-type ty_getter = fn(ast.def_id) -> @ty;
-
-// Error-reporting utility functions
-
-fn ast_ty_to_str(&@ast.ty ty) -> str {
-
- fn ast_fn_input_to_str(&rec(ast.mode mode, @ast.ty ty) input) -> str {
- auto s;
- if (mode_is_alias(input.mode)) {
- s = "&";
- } else {
- s = "";
- }
-
- ret s + ast_ty_to_str(input.ty);
- }
-
- fn ast_ty_field_to_str(&ast.ty_field f) -> str {
- ret ast_ty_to_str(f.ty) + " " + f.ident;
- }
-
- auto s;
- alt (ty.node) {
- case (ast.ty_nil) { s = "()"; }
- case (ast.ty_bool) { s = "bool"; }
- case (ast.ty_int) { s = "int"; }
- case (ast.ty_uint) { s = "uint"; }
- case (ast.ty_machine(?tm)) { s = common.ty_mach_to_str(tm); }
- case (ast.ty_char) { s = "char"; }
- case (ast.ty_str) { s = "str"; }
- case (ast.ty_box(?t)) { s = "@" + ast_ty_to_str(t); }
- case (ast.ty_vec(?t)) { s = "vec[" + ast_ty_to_str(t) + "]"; }
-
- case (ast.ty_tup(?elts)) {
- auto f = ast_ty_to_str;
- s = "tup(";
- s += _str.connect(_vec.map[@ast.ty,str](f, elts), ",");
- s += ")";
- }
-
- case (ast.ty_rec(?fields)) {
- auto f = ast_ty_field_to_str;
- s = "rec(";
- s += _str.connect(_vec.map[ast.ty_field,str](f, fields), ",");
- s += ")";
- }
-
- case (ast.ty_fn(?inputs, ?output)) {
- auto f = ast_fn_input_to_str;
- s = "fn(";
- auto is = _vec.map[rec(ast.mode mode, @ast.ty ty),str](f, inputs);
- s += _str.connect(is, ", ");
- s += ")";
-
- if (output.node != ast.ty_nil) {
- s += " -> " + ast_ty_to_str(output);
- }
- }
-
- case (ast.ty_path(?path, _)) {
- s = path_to_str(path);
- }
-
- case (ast.ty_mutable(?t)) {
- s = "mutable " + ast_ty_to_str(t);
- }
-
- case (_) {
- fail; // FIXME: typestate bug
- }
- }
-
- ret s;
-}
-
-fn name_to_str(&ast.name nm) -> str {
- auto result = nm.node.ident;
- if (_vec.len[@ast.ty](nm.node.types) > 0u) {
- auto f = ast_ty_to_str;
- result += "[";
- result += _str.connect(_vec.map[@ast.ty,str](f, nm.node.types), ",");
- result += "]";
- }
- ret result;
-}
-
-fn path_to_str(&ast.path path) -> str {
- auto f = name_to_str;
- ret _str.connect(_vec.map[ast.name,str](f, path), ".");
-}
-
-fn ty_to_str(&@ty typ) -> str {
-
- fn fn_input_to_str(&rec(ast.mode mode, @ty ty) input) -> str {
- auto s;
- if (mode_is_alias(input.mode)) {
- s = "&";
- } else {
- s = "";
- }
-
- ret s + ty_to_str(input.ty);
- }
-
- fn fn_to_str(option.t[ast.ident] ident,
- vec[arg] inputs, @ty output) -> str {
- auto f = fn_input_to_str;
- auto s = "fn";
- alt (ident) {
- case (some[ast.ident](?i)) {
- s += " ";
- s += i;
- }
- case (_) { }
- }
-
- s += "(";
- s += _str.connect(_vec.map[arg,str](f, inputs), ", ");
- s += ")";
-
- if (output.struct != ty_nil) {
- s += " -> " + ty_to_str(output);
- }
- ret s;
- }
-
- fn method_to_str(&method m) -> str {
- ret fn_to_str(some[ast.ident](m.ident), m.inputs, m.output) + ";";
- }
-
- fn field_to_str(&field f) -> str {
- ret ty_to_str(f.ty) + " " + f.ident;
- }
-
- auto s = "";
- if (typ.mut == ast.mut) {
- s += "mutable ";
- }
-
- alt (typ.struct) {
- case (ty_nil) { s = "()"; }
- case (ty_bool) { s = "bool"; }
- case (ty_int) { s = "int"; }
- case (ty_uint) { s = "uint"; }
- case (ty_machine(?tm)) { s = common.ty_mach_to_str(tm); }
- case (ty_char) { s = "char"; }
- case (ty_str) { s = "str"; }
- case (ty_box(?t)) { s = "@" + ty_to_str(t); }
- case (ty_vec(?t)) { s = "vec[" + ty_to_str(t) + "]"; }
-
- case (ty_tup(?elems)) {
- auto f = ty_to_str;
- auto strs = _vec.map[@ty,str](f, elems);
- s = "tup(" + _str.connect(strs, ",") + ")";
- }
-
- case (ty_rec(?elems)) {
- auto f = field_to_str;
- auto strs = _vec.map[field,str](f, elems);
- s = "rec(" + _str.connect(strs, ",") + ")";
- }
-
- case (ty_tag(_)) {
- // The user should never see this if the cname is set properly!
- s = "<tag>";
- }
-
- case (ty_fn(?inputs, ?output)) {
- s = fn_to_str(none[ast.ident], inputs, output);
- }
-
- case (ty_obj(?meths)) {
- auto f = method_to_str;
- auto m = _vec.map[method,str](f, meths);
- s = "obj {\n\t" + _str.connect(m, "\n\t") + "\n}";
- }
-
- case (ty_var(?v)) {
- s = "<T" + util.common.istr(v) + ">";
- }
-
- case (ty_param(?id)) {
- s = "<P" + util.common.istr(id._0) + ":" + util.common.istr(id._1)
- + ">";
- }
- }
-
- ret s;
+ ures_ok(@ty.t);
+ ures_err(type_err, @ty.t, @ty.t);
}
// Replaces parameter types inside a type with type variables.
-fn generalize_ty(@crate_ctxt cx, @ty t) -> @ty {
+fn generalize_ty(@crate_ctxt cx, @ty.t t) -> @ty.t {
state obj ty_generalizer(@crate_ctxt cx,
- @hashmap[ast.def_id,@ty] ty_params_to_ty_vars) {
- fn fold_simple_ty(@ty t) -> @ty {
+ @hashmap[ast.def_id,@ty.t]
+ ty_params_to_ty_vars) {
+ fn fold_simple_ty(@ty.t t) -> @ty.t {
alt (t.struct) {
- case (ty_param(?pid)) {
+ case (ty.ty_param(?pid)) {
if (ty_params_to_ty_vars.contains_key(pid)) {
ret ty_params_to_ty_vars.get(pid);
}
@@ -279,16 +79,16 @@ fn generalize_ty(@crate_ctxt cx, @ty t) -> @ty {
}
}
- auto generalizer = ty_generalizer(cx, @common.new_def_hash[@ty]());
- ret fold_ty(generalizer, t);
+ auto generalizer = ty_generalizer(cx, @common.new_def_hash[@ty.t]());
+ ret ty.fold_ty(generalizer, t);
}
// Parses the programmer's textual representation of a type into our internal
// notion of a type. `getter` is a function that returns the type
// corresponding to a definition ID.
-fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty {
+fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
fn ast_arg_to_arg(ty_getter getter, &rec(ast.mode mode, @ast.ty ty) arg)
- -> rec(ast.mode mode, @ty ty) {
+ -> rec(ast.mode mode, @ty.t ty) {
ret rec(mode=arg.mode, ty=ast_ty_to_ty(getter, arg.ty));
}
@@ -296,21 +96,21 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty {
auto sty;
auto cname = none[str];
alt (ast_ty.node) {
- case (ast.ty_nil) { sty = ty_nil; }
- case (ast.ty_bool) { sty = ty_bool; }
- case (ast.ty_int) { sty = ty_int; }
- case (ast.ty_uint) { sty = ty_uint; }
- case (ast.ty_machine(?tm)) { sty = ty_machine(tm); }
- case (ast.ty_char) { sty = ty_char; }
- case (ast.ty_str) { sty = ty_str; }
- case (ast.ty_box(?t)) { sty = ty_box(ast_ty_to_ty(getter, t)); }
- case (ast.ty_vec(?t)) { sty = ty_vec(ast_ty_to_ty(getter, t)); }
+ case (ast.ty_nil) { sty = ty.ty_nil; }
+ case (ast.ty_bool) { sty = ty.ty_bool; }
+ case (ast.ty_int) { sty = ty.ty_int; }
+ case (ast.ty_uint) { sty = ty.ty_uint; }
+ case (ast.ty_machine(?tm)) { sty = ty.ty_machine(tm); }
+ case (ast.ty_char) { sty = ty.ty_char; }
+ case (ast.ty_str) { sty = ty.ty_str; }
+ case (ast.ty_box(?t)) { sty = ty.ty_box(ast_ty_to_ty(getter, t)); }
+ case (ast.ty_vec(?t)) { sty = ty.ty_vec(ast_ty_to_ty(getter, t)); }
case (ast.ty_tup(?fields)) {
- let vec[@ty] flds = vec();
+ let vec[@ty.t] flds = vec();
for (@ast.ty field in fields) {
- append[@ty](flds, ast_ty_to_ty(getter, field));
+ append[@ty.t](flds, ast_ty_to_ty(getter, field));
}
- sty = ty_tup(flds);
+ sty = ty.ty_tup(flds);
}
case (ast.ty_rec(?fields)) {
let vec[field] flds = vec();
@@ -318,13 +118,13 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty {
append[field](flds, rec(ident=f.ident,
ty=ast_ty_to_ty(getter, f.ty)));
}
- sty = ty_rec(flds);
+ sty = ty.ty_rec(flds);
}
case (ast.ty_fn(?inputs, ?output)) {
auto f = bind ast_arg_to_arg(getter, _);
auto i = _vec.map[rec(ast.mode mode, @ast.ty ty),arg](f, inputs);
- sty = ty_fn(i, ast_ty_to_ty(getter, output));
+ sty = ty.ty_fn(i, ast_ty_to_ty(getter, output));
}
case (ast.ty_path(?path, ?def)) {
@@ -335,7 +135,7 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty {
// "foo = int" like OCaml?
sty = getter(id).struct;
}
- case (ast.def_ty_arg(?id)) { sty = ty_param(id); }
+ case (ast.def_ty_arg(?id)) { sty = ty.ty_param(id); }
case (_) { fail; }
}
@@ -359,8 +159,8 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty {
// A convenience function to use a crate_ctxt to resolve names for
// ast_ty_to_ty.
-fn ast_ty_to_ty_crate(@crate_ctxt ccx, &@ast.ty ast_ty) -> @ty {
- fn getter(@crate_ctxt ccx, ast.def_id id) -> @ty {
+fn ast_ty_to_ty_crate(@crate_ctxt ccx, &@ast.ty ast_ty) -> @ty.t {
+ fn getter(@crate_ctxt ccx, ast.def_id id) -> @ty.t {
check (ccx.item_types.contains_key(id));
ret ccx.item_types.get(id);
}
@@ -417,7 +217,7 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
fn getter(@ty_item_table id_to_ty_item,
@ty_table item_to_ty,
- ast.def_id id) -> @ty {
+ ast.def_id id) -> @ty.t {
check (id_to_ty_item.contains_key(id));
auto item = id_to_ty_item.get(id);
ret ty_of_item(id_to_ty_item, item_to_ty, item);
@@ -443,31 +243,31 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
fn ty_of_obj(@ty_item_table id_to_ty_item,
@ty_table item_to_ty,
- &ast._obj obj_info) -> @ty {
+ &ast._obj obj_info) -> @ty.t {
auto f = bind ty_of_method(id_to_ty_item, item_to_ty, _);
auto methods =
_vec.map[@ast.method,method](f, obj_info.methods);
- auto t_obj = plain_ty(ty_obj(methods));
+ auto t_obj = plain_ty(ty.ty_obj(methods));
ret t_obj;
}
fn ty_of_obj_ctor(@ty_item_table id_to_ty_item,
@ty_table item_to_ty,
- &ast._obj obj_info) -> @ty {
+ &ast._obj obj_info) -> @ty.t {
auto t_obj = ty_of_obj(id_to_ty_item, item_to_ty, obj_info);
let vec[arg] t_inputs = vec();
for (ast.obj_field f in obj_info.fields) {
auto t_field = getter(id_to_ty_item, item_to_ty, f.id);
append[arg](t_inputs, rec(mode=ast.alias, ty=t_field));
}
- auto t_fn = plain_ty(ty_fn(t_inputs, t_obj));
+ auto t_fn = plain_ty(ty.ty_fn(t_inputs, t_obj));
ret t_fn;
}
fn ty_of_item(@ty_item_table id_to_ty_item,
@ty_table item_to_ty,
- @ast.item it) -> @ty {
+ @ast.item it) -> @ty.t {
auto get = bind getter(id_to_ty_item, item_to_ty, _);
auto convert = bind ast_ty_to_ty(get, _);
@@ -485,7 +285,7 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
auto input_tys = _vec.map[ast.arg,arg](f, fn_info.inputs);
auto output_ty = convert(fn_info.output);
- auto t_fn = plain_ty(ty_fn(input_tys, output_ty));
+ auto t_fn = plain_ty(ty.ty_fn(input_tys, output_ty));
item_to_ty.insert(def_id, t_fn);
ret t_fn;
}
@@ -513,9 +313,9 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
}
case (ast.item_tag(_, _, _, ?def_id)) {
- auto ty = plain_ty(ty_tag(def_id));
- item_to_ty.insert(def_id, ty);
- ret ty;
+ auto t = plain_ty(ty.ty_tag(def_id));
+ item_to_ty.insert(def_id, t);
+ ret t;
}
case (ast.item_mod(_, _, _)) { fail; }
@@ -533,7 +333,7 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
// constructors get turned into functions.
auto result_ty;
if (_vec.len[ast.variant_arg](variant.args) == 0u) {
- result_ty = plain_ty(ty_tag(tag_id));
+ result_ty = plain_ty(ty.ty_tag(tag_id));
} else {
// As above, tell ast_ty_to_ty() that trans_ty_item_to_ty()
// should be called to resolve named types.
@@ -544,7 +344,8 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
auto arg_ty = ast_ty_to_ty(f, va.ty);
args += vec(rec(mode=ast.alias, ty=arg_ty));
}
- result_ty = plain_ty(ty_fn(args, plain_ty(ty_tag(tag_id))));
+ auto tag_t = plain_ty(ty.ty_tag(tag_id));
+ result_ty = plain_ty(ty.ty_fn(args, tag_t));
}
item_to_ty.insert(variant.id, result_ty);
@@ -580,7 +381,7 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
// Second pass: translate the types of all items.
- let @ty_table item_to_ty = @common.new_def_hash[@ty]();
+ let @ty_table item_to_ty = @common.new_def_hash[@ty.t]();
type env = rec(@ty_item_table id_to_ty_item,
@ty_table item_to_ty);
@@ -621,11 +422,11 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
ret @fold.respan[ast.item_](sp, item);
}
- fn get_ctor_obj_methods(@ty t) -> vec[method] {
+ fn get_ctor_obj_methods(@ty.t t) -> vec[method] {
alt (t.struct) {
- case (ty_fn(_,?tobj)) {
+ case (ty.ty_fn(_,?tobj)) {
alt (tobj.struct) {
- case (ty_obj(?tm)) {
+ case (ty.ty_obj(?tm)) {
ret tm;
}
case (_) {
@@ -646,8 +447,8 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
&ast._obj ob, vec[ast.ty_param] ty_params,
ast.def_id id, ast.ann a) -> @ast.item {
check (e.item_to_ty.contains_key(id));
- auto ty = e.item_to_ty.get(id);
- let vec[method] meth_tys = get_ctor_obj_methods(ty);
+ auto t = e.item_to_ty.get(id);
+ let vec[method] meth_tys = get_ctor_obj_methods(t);
let vec[@ast.method] methods = vec();
let uint n = 0u;
@@ -655,8 +456,8 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
let @ast.method meth = ob.methods.(n);
let ast.method_ m_;
let @ast.method m;
- auto meth_tfn = plain_ty(ty_fn(meth_ty.inputs,
- meth_ty.output));
+ auto meth_tfn = plain_ty(ty.ty_fn(meth_ty.inputs,
+ meth_ty.output));
m_ = rec(ann=ast.ann_type(meth_tfn) with meth.node);
m = @rec(node=m_ with *meth);
append[@ast.method](methods, m);
@@ -665,7 +466,7 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
auto ob_ = rec(methods = methods with ob);
auto item = ast.item_obj(i, ob_, ty_params, id,
- ast.ann_type(ty));
+ ast.ann_type(t));
ret @fold.respan[ast.item_](sp, item);
}
@@ -703,367 +504,9 @@ fn collect_item_types(@ast.crate crate) -> tup(@ast.crate, @ty_table) {
ret tup(crate_, item_to_ty);
}
-// Expression utilities
-
-fn field_num(session.session sess, &span sp, &ast.ident id) -> uint {
- let uint accum = 0u;
- let uint i = 0u;
- for (u8 c in id) {
- if (i == 0u) {
- if (c != ('_' as u8)) {
- sess.span_err(sp,
- "bad numeric field on tuple: "
- + "missing leading underscore");
- }
- } else {
- if (('0' as u8) <= c && c <= ('9' as u8)) {
- accum *= 10u;
- accum += (c as uint) - ('0' as uint);
- } else {
- auto s = "";
- s += c;
- sess.span_err(sp,
- "bad numeric field on tuple: "
- + " non-digit character: "
- + s);
- }
- }
- i += 1u;
- }
- ret accum;
-}
-
-fn field_idx(session.session sess, &span sp,
- &ast.ident id, vec[field] fields) -> uint {
- let uint i = 0u;
- for (field f in fields) {
- if (_str.eq(f.ident, id)) {
- ret i;
- }
- i += 1u;
- }
- sess.span_err(sp, "unknown field '" + id + "' of record");
- fail;
-}
-
-fn method_idx(session.session sess, &span sp,
- &ast.ident id, vec[method] meths) -> uint {
- let uint i = 0u;
- for (method m in meths) {
- if (_str.eq(m.ident, id)) {
- ret i;
- }
- i += 1u;
- }
- sess.span_err(sp, "unknown method '" + id + "' of obj");
- fail;
-}
-
-fn is_lval(@ast.expr expr) -> bool {
- alt (expr.node) {
- case (ast.expr_field(_,_,_)) { ret true; }
- case (ast.expr_index(_,_,_)) { ret true; }
- case (ast.expr_name(_,_,_)) { ret true; }
- case (_) { ret false; }
- }
-}
-
-// Type folds
-
-type ty_fold = state obj {
- fn fold_simple_ty(@ty ty) -> @ty;
-};
-
-fn fold_ty(ty_fold fld, @ty t) -> @ty {
- fn rewrap(@ty orig, &sty new) -> @ty {
- ret @rec(struct=new, mut=orig.mut, cname=orig.cname);
- }
-
- alt (t.struct) {
- case (ty_nil) { ret fld.fold_simple_ty(t); }
- case (ty_bool) { ret fld.fold_simple_ty(t); }
- case (ty_int) { ret fld.fold_simple_ty(t); }
- case (ty_uint) { ret fld.fold_simple_ty(t); }
- case (ty_machine(_)) { ret fld.fold_simple_ty(t); }
- case (ty_char) { ret fld.fold_simple_ty(t); }
- case (ty_str) { ret fld.fold_simple_ty(t); }
- case (ty_tag(_)) { ret fld.fold_simple_ty(t); }
- case (ty_box(?subty)) {
- ret rewrap(t, ty_box(fold_ty(fld, subty)));
- }
- case (ty_vec(?subty)) {
- ret rewrap(t, ty_vec(fold_ty(fld, subty)));
- }
- case (ty_tup(?subtys)) {
- let vec[@ty] new_subtys = vec();
- for (@ty subty in subtys) {
- new_subtys += vec(fold_ty(fld, subty));
- }
- ret rewrap(t, ty_tup(new_subtys));
- }
- case (ty_rec(?fields)) {
- let vec[field] new_fields = vec();
- for (field fl in fields) {
- auto new_ty = fold_ty(fld, fl.ty);
- new_fields += vec(rec(ident=fl.ident, ty=new_ty));
- }
- ret rewrap(t, ty_rec(new_fields));
- }
- case (ty_fn(?args, ?ret_ty)) {
- let vec[arg] new_args = vec();
- for (arg a in args) {
- auto new_ty = fold_ty(fld, a.ty);
- new_args += vec(rec(mode=a.mode, ty=new_ty));
- }
- ret rewrap(t, ty_fn(new_args, fold_ty(fld, ret_ty)));
- }
- case (ty_obj(?methods)) {
- let vec[method] new_methods = vec();
- for (method m in methods) {
- let vec[arg] new_args = vec();
- for (arg a in m.inputs) {
- new_args += vec(rec(mode=a.mode, ty=fold_ty(fld, a.ty)));
- }
- new_methods += vec(rec(ident=m.ident, inputs=new_args,
- output=fold_ty(fld, m.output)));
- }
- ret rewrap(t, ty_obj(new_methods));
- }
- case (ty_var(_)) { ret fld.fold_simple_ty(t); }
- case (ty_local(_)) { ret fld.fold_simple_ty(t); }
- case (ty_param(_)) { ret fld.fold_simple_ty(t); }
- }
-
- ret t;
-}
-
-// Type utilities
-
-// FIXME: remove me when == works on these tags.
-fn mode_is_alias(ast.mode m) -> bool {
- alt (m) {
- case (ast.val) { ret false; }
- case (ast.alias) { ret true; }
- }
- fail;
-}
-
-fn type_is_nil(@ty t) -> bool {
- alt (t.struct) {
- case (ty_nil) { ret true; }
- case (_) { ret false; }
- }
- fail;
-}
-
-fn type_is_structural(@ty t) -> bool {
- alt (t.struct) {
- case (ty_tup(_)) { ret true; }
- case (ty_rec(_)) { ret true; }
- case (ty_tag(_)) { ret true; }
- case (ty_fn(_,_)) { ret true; }
- case (ty_obj(_)) { ret true; }
- case (_) { ret false; }
- }
- fail;
-}
-
-fn type_is_boxed(@ty t) -> bool {
- alt (t.struct) {
- case (ty_str) { ret true; }
- case (ty_vec(_)) { ret true; }
- case (ty_box(_)) { ret true; }
- case (_) { ret false; }
- }
- fail;
-}
-
-fn type_is_scalar(@ty t) -> bool {
- alt (t.struct) {
- case (ty_nil) { ret true; }
- case (ty_bool) { ret true; }
- case (ty_int) { ret true; }
- case (ty_uint) { ret true; }
- case (ty_machine(_)) { ret true; }
- case (ty_char) { ret true; }
- case (_) { ret false; }
- }
- fail;
-}
-
-
-fn type_is_integral(@ty t) -> bool {
- alt (t.struct) {
- case (ty_int) { ret true; }
- case (ty_uint) { ret true; }
- case (ty_machine(?m)) {
- alt (m) {
- case (common.ty_i8) { ret true; }
- case (common.ty_i16) { ret true; }
- case (common.ty_i32) { ret true; }
- case (common.ty_i64) { ret true; }
-
- case (common.ty_u8) { ret true; }
- case (common.ty_u16) { ret true; }
- case (common.ty_u32) { ret true; }
- case (common.ty_u64) { ret true; }
- case (_) { ret false; }
- }
- }
- case (ty_char) { ret true; }
- case (_) { ret false; }
- }
- fail;
-}
-
-fn type_is_fp(@ty t) -> bool {
- alt (t.struct) {
- case (ty_machine(?tm)) {
- alt (tm) {
- case (common.ty_f32) { ret true; }
- case (common.ty_f64) { ret true; }
- case (_) { ret false; }
- }
- }
- case (_) { ret false; }
- }
- fail;
-}
-
-fn type_is_signed(@ty t) -> bool {
- alt (t.struct) {
- case (ty_int) { ret true; }
- case (ty_machine(?tm)) {
- alt (tm) {
- case (common.ty_i8) { ret true; }
- case (common.ty_i16) { ret true; }
- case (common.ty_i32) { ret true; }
- case (common.ty_i64) { ret true; }
- case (_) { ret false; }
- }
- }
- case (_) { ret false; }
- }
- fail;
-}
-
-fn type_param(@ty t) -> option.t[ast.def_id] {
- alt (t.struct) {
- case (ty_param(?id)) { ret some[ast.def_id](id); }
- case (_) { /* fall through */ }
- }
- ret none[ast.def_id];
-}
-
-fn plain_ty(&sty st) -> @ty {
- ret @rec(struct=st, mut=ast.imm, cname=none[str]);
-}
-
-fn hash_ty(&@ty t) -> uint {
- ret _str.hash(ty_to_str(t));
-}
-
-fn eq_ty(&@ty a, &@ty b) -> bool {
- // FIXME: this is gross, but I think it's safe, and I don't think writing
- // a giant function to handle all the cases is necessary when structural
- // equality will someday save the day.
- ret _str.eq(ty_to_str(a), ty_to_str(b));
-}
-
-fn ann_to_type(&ast.ann ann) -> @ty {
- alt (ann) {
- case (ast.ann_none) {
- // shouldn't happen, but can until the typechecker is complete
- ret plain_ty(ty_var(-1)); // FIXME: broken, broken, broken
- }
- case (ast.ann_type(?ty)) {
- ret ty;
- }
- }
-}
-
-fn count_ty_params(@ty t) -> uint {
- state obj ty_param_counter(@mutable vec[ast.def_id] param_ids) {
- fn fold_simple_ty(@ty t) -> @ty {
- alt (t.struct) {
- case (ty_param(?param_id)) {
- for (ast.def_id other_param_id in *param_ids) {
- if (param_id._0 == other_param_id._0 &&
- param_id._1 == other_param_id._1) {
- ret t;
- }
- }
- *param_ids += vec(param_id);
- }
- case (_) { /* fall through */ }
- }
- ret t;
- }
- }
-
- let vec[ast.def_id] param_ids_inner = vec();
- let @mutable vec[ast.def_id] param_ids = @mutable param_ids_inner;
- fold_ty(ty_param_counter(param_ids), t);
- ret _vec.len[ast.def_id](*param_ids);
-}
-
-// Type accessors for AST nodes
-
-fn stmt_ty(@ast.stmt s) -> @ty {
- alt (s.node) {
- case (ast.stmt_expr(?e)) {
- ret expr_ty(e);
- }
- case (_) {
- ret plain_ty(ty_nil);
- }
- }
-}
-
-fn block_ty(&ast.block b) -> @ty {
- alt (b.node.expr) {
- case (some[@ast.expr](?e)) { ret expr_ty(e); }
- case (none[@ast.expr]) { ret plain_ty(ty_nil); }
- }
-}
-
-fn pat_ty(@ast.pat pat) -> @ty {
- alt (pat.node) {
- case (ast.pat_wild(?ann)) { ret ann_to_type(ann); }
- case (ast.pat_bind(_, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.pat_tag(_, _, _, ?ann)) { ret ann_to_type(ann); }
- }
- fail; // not reached
-}
-
-fn expr_ty(@ast.expr expr) -> @ty {
- alt (expr.node) {
- case (ast.expr_vec(_, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_tup(_, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_rec(_, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_call(_, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_binary(_, _, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_unary(_, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_lit(_, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_cast(_, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_if(_, _, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_while(_, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_do_while(_, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_alt(_, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_block(_, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_assign(_, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_assign_op(_, _, _, ?ann))
- { ret ann_to_type(ann); }
- case (ast.expr_field(_, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_index(_, _, ?ann)) { ret ann_to_type(ann); }
- case (ast.expr_name(_, _, ?ann)) { ret ann_to_type(ann); }
- }
- fail;
-}
-
// Type unification
-fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
+fn unify(&fn_ctxt fcx, @ty.t expected, @ty.t actual) -> unify_result {
// Wraps the given type in an appropriate cname.
//
// TODO: This doesn't do anything yet. We should carry the cname up from
@@ -1072,7 +515,7 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
// something we'll probably need to develop over time.
// Simple structural type comparison.
- fn struct_cmp(@ty expected, @ty actual) -> unify_result {
+ fn struct_cmp(@ty.t expected, @ty.t actual) -> unify_result {
if (expected.struct == actual.struct) {
ret ures_ok(expected);
}
@@ -1080,28 +523,28 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
ret ures_err(terr_mismatch, expected, actual);
}
- fn unify_step(&fn_ctxt fcx, &hashmap[int,@ty] bindings, @ty expected,
- @ty actual) -> unify_result {
+ fn unify_step(&fn_ctxt fcx, &hashmap[int,@ty.t] bindings, @ty.t expected,
+ @ty.t actual) -> unify_result {
// TODO: rewrite this using tuple pattern matching when available, to
// avoid all this rightward drift and spikiness.
// If the RHS is a variable type, then just do the appropriate
// binding.
alt (actual.struct) {
- case (ty_var(?actual_id)) {
+ case (ty.ty_var(?actual_id)) {
alt (bindings.find(actual_id)) {
- case (some[@ty](?actual_ty)) {
+ case (some[@ty.t](?actual_ty)) {
// FIXME: change the binding here?
// FIXME: "be"
ret unify_step(fcx, bindings, expected, actual_ty);
}
- case (none[@ty]) {
+ case (none[@ty.t]) {
bindings.insert(actual_id, expected);
ret ures_ok(expected);
}
}
}
- case (ty_local(?actual_id)) {
+ case (ty.ty_local(?actual_id)) {
check (fcx.locals.contains_key(actual_id));
auto actual_ty = fcx.locals.get(actual_id);
auto result = unify_step(fcx, bindings, expected, actual_ty);
@@ -1117,17 +560,17 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
}
alt (expected.struct) {
- case (ty_nil) { ret struct_cmp(expected, actual); }
- case (ty_bool) { ret struct_cmp(expected, actual); }
- case (ty_int) { ret struct_cmp(expected, actual); }
- case (ty_uint) { ret struct_cmp(expected, actual); }
- case (ty_machine(_)) { ret struct_cmp(expected, actual); }
- case (ty_char) { ret struct_cmp(expected, actual); }
- case (ty_str) { ret struct_cmp(expected, actual); }
-
- case (ty_tag(?expected_id)) {
+ case (ty.ty_nil) { ret struct_cmp(expected, actual); }
+ case (ty.ty_bool) { ret struct_cmp(expected, actual); }
+ case (ty.ty_int) { ret struct_cmp(expected, actual); }
+ case (ty.ty_uint) { ret struct_cmp(expected, actual); }
+ case (ty.ty_machine(_)) { ret struct_cmp(expected, actual); }
+ case (ty.ty_char) { ret struct_cmp(expected, actual); }
+ case (ty.ty_str) { ret struct_cmp(expected, actual); }
+
+ case (ty.ty_tag(?expected_id)) {
alt (actual.struct) {
- case (ty_tag(?actual_id)) {
+ case (ty.ty_tag(?actual_id)) {
if (expected_id._0 == actual_id._0 &&
expected_id._1 == actual_id._1) {
ret ures_ok(expected);
@@ -1139,16 +582,16 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
ret ures_err(terr_mismatch, expected, actual);
}
- case (ty_box(?expected_sub)) {
+ case (ty.ty_box(?expected_sub)) {
alt (actual.struct) {
- case (ty_box(?actual_sub)) {
+ case (ty.ty_box(?actual_sub)) {
auto result = unify_step(fcx,
bindings,
expected_sub,
actual_sub);
alt (result) {
case (ures_ok(?result_sub)) {
- ret ures_ok(plain_ty(ty_box(result_sub)));
+ ret ures_ok(plain_ty(ty.ty_box(result_sub)));
}
case (_) {
ret result;
@@ -1164,16 +607,16 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
}
}
- case (ty_vec(?expected_sub)) {
+ case (ty.ty_vec(?expected_sub)) {
alt (actual.struct) {
- case (ty_vec(?actual_sub)) {
+ case (ty.ty_vec(?actual_sub)) {
auto result = unify_step(fcx,
bindings,
expected_sub,
actual_sub);
alt (result) {
case (ures_ok(?result_sub)) {
- ret ures_ok(plain_ty(ty_vec(result_sub)));
+ ret ures_ok(plain_ty(ty.ty_vec(result_sub)));
}
case (_) {
ret result;
@@ -1189,11 +632,11 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
}
}
- case (ty_tup(?expected_elems)) {
+ case (ty.ty_tup(?expected_elems)) {
alt (actual.struct) {
- case (ty_tup(?actual_elems)) {
- auto expected_len = _vec.len[@ty](expected_elems);
- auto actual_len = _vec.len[@ty](actual_elems);
+ case (ty.ty_tup(?actual_elems)) {
+ auto expected_len = _vec.len[@ty.t](expected_elems);
+ auto actual_len = _vec.len[@ty.t](actual_elems);
if (expected_len != actual_len) {
auto err = terr_tuple_size(expected_len,
actual_len);
@@ -1202,7 +645,7 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
// TODO: implement an iterator that can iterate over
// two arrays simultaneously.
- let vec[@ty] result_elems = vec();
+ let vec[@ty.t] result_elems = vec();
auto i = 0u;
while (i < expected_len) {
auto expected_elem = expected_elems.(i);
@@ -1218,7 +661,7 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
actual_elem);
alt (result) {
case (ures_ok(?rty)) {
- append[@ty](result_elems,rty);
+ append[@ty.t](result_elems,rty);
}
case (_) {
ret result;
@@ -1228,7 +671,7 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
i += 1u;
}
- ret ures_ok(plain_ty(ty_tup(result_elems)));
+ ret ures_ok(plain_ty(ty.ty_tup(result_elems)));
}
// TODO: ty_var
@@ -1239,9 +682,9 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
}
}
- case (ty_rec(?expected_fields)) {
+ case (ty.ty_rec(?expected_fields)) {
alt (actual.struct) {
- case (ty_rec(?actual_fields)) {
+ case (ty.ty_rec(?actual_fields)) {
auto expected_len = _vec.len[field](expected_fields);
auto actual_len = _vec.len[field](actual_fields);
if (expected_len != actual_len) {
@@ -1289,7 +732,7 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
i += 1u;
}
- ret ures_ok(plain_ty(ty_rec(result_fields)));
+ ret ures_ok(plain_ty(ty.ty_rec(result_fields)));
}
// TODO: ty_var
@@ -1300,9 +743,9 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
}
}
- case (ty_fn(?expected_inputs, ?expected_output)) {
+ case (ty.ty_fn(?expected_inputs, ?expected_output)) {
alt (actual.struct) {
- case (ty_fn(?actual_inputs, ?actual_output)) {
+ case (ty.ty_fn(?actual_inputs, ?actual_output)) {
auto expected_len = _vec.len[arg](expected_inputs);
auto actual_len = _vec.len[arg](actual_inputs);
if (expected_len != actual_len) {
@@ -1360,7 +803,8 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
}
}
- ret ures_ok(plain_ty(ty_fn(result_ins, result_out)));
+ auto t = plain_ty(ty.ty_fn(result_ins, result_out));
+ ret ures_ok(t);
}
case (_) {
@@ -1369,21 +813,21 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
}
}
- case (ty_var(?expected_id)) {
+ case (ty.ty_var(?expected_id)) {
alt (bindings.find(expected_id)) {
- case (some[@ty](?expected_ty)) {
+ case (some[@ty.t](?expected_ty)) {
// FIXME: change the binding here?
// FIXME: "be"
ret unify_step(fcx, bindings, expected_ty, actual);
}
- case (none[@ty]) {
+ case (none[@ty.t]) {
bindings.insert(expected_id, actual);
ret ures_ok(actual);
}
}
}
- case (ty_local(?expected_id)) {
+ case (ty.ty_local(?expected_id)) {
check (fcx.locals.contains_key(expected_id));
auto expected_ty = fcx.locals.get(expected_id);
auto result = unify_step(fcx, bindings, expected_ty, actual);
@@ -1396,9 +840,9 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
ret result;
}
- case (ty_param(?expected_id)) {
+ case (ty.ty_param(?expected_id)) {
alt (actual.struct) {
- case (ty_param(?actual_id)) {
+ case (ty.ty_param(?actual_id)) {
if (expected_id._0 == actual_id._0 &&
expected_id._1 == actual_id._1) {
ret ures_ok(expected);
@@ -1419,14 +863,14 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
fn eq_int(&int a, &int b) -> bool { ret a == b; }
auto hasher = hash_int;
auto eqer = eq_int;
- auto bindings = map.mk_hashmap[int,@ty](hasher, eqer);
+ auto bindings = map.mk_hashmap[int,@ty.t](hasher, eqer);
ret unify_step(fcx, bindings, expected, actual);
}
// Requires that the two types unify, and prints an error message if they
// don't. Returns the unified type.
-fn demand(&fn_ctxt fcx, &span sp, @ty expected, @ty actual) -> @ty {
+fn demand(&fn_ctxt fcx, &span sp, @ty.t expected, @ty.t actual) -> @ty.t {
alt (unify(fcx, expected, actual)) {
case (ures_ok(?ty)) {
ret ty;
@@ -1446,7 +890,7 @@ fn demand(&fn_ctxt fcx, &span sp, @ty expected, @ty actual) -> @ty {
}
// Returns true if the two types unify and false if they don't.
-fn are_compatible(&fn_ctxt fcx, @ty expected, @ty actual) -> bool {
+fn are_compatible(&fn_ctxt fcx, @ty.t expected, @ty.t actual) -> bool {
alt (unify(fcx, expected, actual)) {
case (ures_ok(_)) { ret true; }
case (ures_err(_, _, _)) { ret false; }
@@ -1458,7 +902,7 @@ fn are_compatible(&fn_ctxt fcx, @ty expected, @ty actual) -> bool {
//
// TODO: enforce this via a predicate.
-fn demand_pat(&fn_ctxt fcx, @ty expected, @ast.pat pat) -> @ast.pat {
+fn demand_pat(&fn_ctxt fcx, @ty.t expected, @ast.pat pat) -> @ast.pat {
auto p_1 = ast.pat_wild(ast.ann_none); // FIXME: typestate botch
alt (pat.node) {
@@ -1489,12 +933,12 @@ fn demand_pat(&fn_ctxt fcx, @ty expected, @ast.pat pat) -> @ast.pat {
auto subpats_len = _vec.len[@ast.pat](subpats);
alt (variant_ty.struct) {
- case (ty_tag(_)) {
+ case (ty.ty_tag(_)) {
// Nullary tag variant.
check (subpats_len == 0u);
p_1 = ast.pat_tag(id, subpats, vdef_opt, ast.ann_type(t));
}
- case (ty_fn(?args, ?tag_ty)) {
+ case (ty.ty_fn(?args, ?tag_ty)) {
let vec[@ast.pat] new_subpats = vec();
auto i = 0u;
for (arg a in args) {
@@ -1519,7 +963,7 @@ fn demand_pat(&fn_ctxt fcx, @ty expected, @ast.pat pat) -> @ast.pat {
// TODO: propagate the types downward. This makes the typechecker quadratic,
// but we can mitigate that if expected == actual == unified.
-fn demand_expr(&fn_ctxt fcx, @ty expected, @ast.expr e) -> @ast.expr {
+fn demand_expr(&fn_ctxt fcx, @ty.t expected, @ast.expr e) -> @ast.expr {
// FIXME: botch to work around typestate bug in rustboot
let vec[@ast.expr] v = vec();
auto e_1 = ast.expr_vec(v, ast.ann_none);
@@ -1529,7 +973,7 @@ fn demand_expr(&fn_ctxt fcx, @ty expected, @ast.expr e) -> @ast.expr {
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
let vec[@ast.expr] es_1 = vec();
alt (t.struct) {
- case (ty_vec(?subty)) {
+ case (ty.ty_vec(?subty)) {
for (@ast.expr e_0 in es_0) {
es_1 += vec(demand_expr(fcx, subty, e_0));
}
@@ -1545,7 +989,7 @@ fn demand_expr(&fn_ctxt fcx, @ty expected, @ast.expr e) -> @ast.expr {
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
let vec[ast.elt] elts_1 = vec();
alt (t.struct) {
- case (ty_tup(?subtys)) {
+ case (ty.ty_tup(?subtys)) {
auto i = 0u;
for (ast.elt elt_0 in es_0) {
auto e_1 = demand_expr(fcx, subtys.(i), elt_0.expr);
@@ -1564,7 +1008,7 @@ fn demand_expr(&fn_ctxt fcx, @ty expected, @ast.expr e) -> @ast.expr {
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
let vec[ast.field] fields_1 = vec();
alt (t.struct) {
- case (ty_rec(?field_tys)) {
+ case (ty.ty_rec(?field_tys)) {
auto i = 0u;
for (ast.field field_0 in fields_0) {
check (_str.eq(field_0.ident, field_tys.(i).ident));
@@ -1661,7 +1105,7 @@ fn demand_expr(&fn_ctxt fcx, @ty expected, @ast.expr e) -> @ast.expr {
}
// Type unification over typed blocks.
-fn demand_block(&fn_ctxt fcx, @ty expected, &ast.block bloc) -> ast.block {
+fn demand_block(&fn_ctxt fcx, @ty.t expected, &ast.block bloc) -> ast.block {
alt (bloc.node.expr) {
case (some[@ast.expr](?e_0)) {
auto e_1 = demand_expr(fcx, expected, e_0);
@@ -1671,7 +1115,7 @@ fn demand_block(&fn_ctxt fcx, @ty expected, &ast.block bloc) -> ast.block {
ret fold.respan[ast.block_](bloc.span, block_);
}
case (none[@ast.expr]) {
- demand(fcx, bloc.span, expected, plain_ty(ty_nil));
+ demand(fcx, bloc.span, expected, plain_ty(ty.ty_nil));
ret bloc;
}
}
@@ -1699,18 +1143,16 @@ fn writeback(&fn_ctxt fcx, &ast.block block) -> ast.block {
// AST fragment checking
-fn check_lit(@ast.lit lit) -> @ty {
+fn check_lit(@ast.lit lit) -> @ty.t {
auto sty;
alt (lit.node) {
- case (ast.lit_str(_)) { sty = ty_str; }
- case (ast.lit_char(_)) { sty = ty_char; }
- case (ast.lit_int(_)) { sty = ty_int; }
- case (ast.lit_uint(_)) { sty = ty_uint; }
- case (ast.lit_mach_int(?tm, _)) {
- sty = ty_machine(tm);
- }
- case (ast.lit_nil) { sty = ty_nil; }
- case (ast.lit_bool(_)) { sty = ty_bool; }
+ case (ast.lit_str(_)) { sty = ty.ty_str; }
+ case (ast.lit_char(_)) { sty = ty.ty_char; }
+ case (ast.lit_int(_)) { sty = ty.ty_int; }
+ case (ast.lit_uint(_)) { sty = ty.ty_uint; }
+ case (ast.lit_mach_int(?tm, _)) { sty = ty.ty_machine(tm); }
+ case (ast.lit_nil) { sty = ty.ty_nil; }
+ case (ast.lit_bool(_)) { sty = ty.ty_bool; }
}
ret plain_ty(sty);
@@ -1731,7 +1173,7 @@ fn check_pat(&fn_ctxt fcx, @ast.pat pat) -> @ast.pat {
auto t = fcx.ccx.item_types.get(vdef._1);
alt (t.struct) {
// N-ary variants have function types.
- case (ty_fn(?args, ?tag_ty)) {
+ case (ty.ty_fn(?args, ?tag_ty)) {
auto arg_len = _vec.len[arg](args);
auto subpats_len = _vec.len[@ast.pat](subpats);
if (arg_len != subpats_len) {
@@ -1755,7 +1197,7 @@ fn check_pat(&fn_ctxt fcx, @ast.pat pat) -> @ast.pat {
}
// Nullary variants have tag types.
- case (ty_tag(?tid)) {
+ case (ty.ty_tag(?tid)) {
auto subpats_len = _vec.len[@ast.pat](subpats);
if (subpats_len > 0u) {
// TODO: pluralize properly
@@ -1768,7 +1210,7 @@ fn check_pat(&fn_ctxt fcx, @ast.pat pat) -> @ast.pat {
fail; // TODO: recover
}
- auto ann = ast.ann_type(plain_ty(ty_tag(tid)));
+ auto ann = ast.ann_type(plain_ty(ty.ty_tag(tid)));
new_pat = ast.pat_tag(id, subpats, vdef_opt, ann);
}
}
@@ -1799,12 +1241,12 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
auto t = lhs_t0;
alt (binop) {
- case (ast.eq) { t = plain_ty(ty_bool); }
- case (ast.lt) { t = plain_ty(ty_bool); }
- case (ast.le) { t = plain_ty(ty_bool); }
- case (ast.ne) { t = plain_ty(ty_bool); }
- case (ast.ge) { t = plain_ty(ty_bool); }
- case (ast.gt) { t = plain_ty(ty_bool); }
+ case (ast.eq) { t = plain_ty(ty.ty_bool); }
+ case (ast.lt) { t = plain_ty(ty.ty_bool); }
+ case (ast.le) { t = plain_ty(ty.ty_bool); }
+ case (ast.ne) { t = plain_ty(ty.ty_bool); }
+ case (ast.ge) { t = plain_ty(ty.ty_bool); }
+ case (ast.gt) { t = plain_ty(ty.ty_bool); }
case (_) { /* fall through */ }
}
ret @fold.respan[ast.expr_](expr.span,
@@ -1817,10 +1259,10 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
auto oper_1 = check_expr(fcx, oper);
auto oper_t = expr_ty(oper_1);
alt (unop) {
- case (ast.box) { oper_t = plain_ty(ty_box(oper_t)); }
+ case (ast.box) { oper_t = plain_ty(ty.ty_box(oper_t)); }
case (ast.deref) {
alt (oper_t.struct) {
- case (ty_box(?inner_t)) {
+ case (ty.ty_box(?inner_t)) {
oper_t = inner_t;
}
case (_) {
@@ -1839,7 +1281,7 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
}
case (ast.expr_name(?name, ?defopt, _)) {
- auto t = plain_ty(ty_nil);
+ auto t = plain_ty(ty.ty_nil);
check (defopt != none[ast.def]);
alt (option.get[ast.def](defopt)) {
case (ast.def_arg(?id)) {
@@ -1848,8 +1290,8 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
}
case (ast.def_local(?id)) {
alt (fcx.locals.find(id)) {
- case (some[@ty](?t1)) { t = t1; }
- case (none[@ty]) { t = plain_ty(ty_local(id)); }
+ case (some[@ty.t](?t1)) { t = t1; }
+ case (none[@ty.t]) { t = plain_ty(ty.ty_local(id)); }
}
}
case (ast.def_fn(?id)) {
@@ -1917,7 +1359,7 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
case (ast.expr_if(?cond, ?thn, ?elsopt, _)) {
auto cond_0 = check_expr(fcx, cond);
- auto cond_1 = demand_expr(fcx, plain_ty(ty_bool), cond_0);
+ auto cond_1 = demand_expr(fcx, plain_ty(ty.ty_bool), cond_0);
auto thn_0 = check_block(fcx, thn);
auto thn_t = block_ty(thn_0);
@@ -1933,7 +1375,7 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
}
case (none[ast.block]) {
elsopt_1 = none[ast.block];
- elsopt_t = plain_ty(ty_nil);
+ elsopt_t = plain_ty(ty.ty_nil);
}
}
@@ -1946,17 +1388,17 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
case (ast.expr_while(?cond, ?body, _)) {
auto cond_0 = check_expr(fcx, cond);
- auto cond_1 = demand_expr(fcx, plain_ty(ty_bool), cond_0);
+ auto cond_1 = demand_expr(fcx, plain_ty(ty.ty_bool), cond_0);
auto body_1 = check_block(fcx, body);
- auto ann = ast.ann_type(plain_ty(ty_nil));
+ auto ann = ast.ann_type(plain_ty(ty.ty_nil));
ret @fold.respan[ast.expr_](expr.span,
ast.expr_while(cond_1, body_1, ann));
}
case (ast.expr_do_while(?body, ?cond, _)) {
auto cond_0 = check_expr(fcx, cond);
- auto cond_1 = demand_expr(fcx, plain_ty(ty_bool), cond_0);
+ auto cond_1 = demand_expr(fcx, plain_ty(ty.ty_bool), cond_0);
auto body_1 = check_block(fcx, body);
auto ann = ast.ann_type(block_ty(body_1));
@@ -2030,17 +1472,17 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
append[arg](arg_tys_0, rec(mode=ast.val, ty=expr_ty(a_0)));
}
auto rt_0 = next_ty_var(fcx.ccx);
- auto t_0 = plain_ty(ty_fn(arg_tys_0, rt_0));
+ auto t_0 = plain_ty(ty.ty_fn(arg_tys_0, rt_0));
// Unify and write back to the function.
auto f_1 = demand_expr(fcx, t_0, f_0);
// Take the argument types out of the resulting function type.
auto t_1 = expr_ty(f_1);
- let vec[arg] arg_tys_1 = vec(); // TODO: typestate botch
- let @ty rt_1 = plain_ty(ty_nil); // TODO: typestate botch
+ let vec[arg] arg_tys_1 = vec(); // TODO: typestate botch
+ let @ty.t rt_1 = plain_ty(ty.ty_nil); // TODO: typestate botch
alt (t_1.struct) {
- case (ty_fn(?arg_tys, ?rt)) {
+ case (ty.ty_fn(?arg_tys, ?rt)) {
arg_tys_1 = arg_tys;
rt_1 = rt;
}
@@ -2091,7 +1533,7 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
// FIXME: implement mutable vectors with leading 'mutable' flag
// marking the elements as mutable.
- let @ty t;
+ let @ty.t t;
if (_vec.len[@ast.expr](args) == 0u) {
t = next_ty_var(fcx.ccx);
} else {
@@ -2105,14 +1547,14 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
demand(fcx, expr.span, t, expr_t);
append[@ast.expr](args_1,expr_1);
}
- auto ann = ast.ann_type(plain_ty(ty_vec(t)));
+ auto ann = ast.ann_type(plain_ty(ty.ty_vec(t)));
ret @fold.respan[ast.expr_](expr.span,
ast.expr_vec(args_1, ann));
}
case (ast.expr_tup(?elts, _)) {
let vec[ast.elt] elts_1 = vec();
- let vec[@ty] elts_t = vec();
+ let vec[@ty.t] elts_t = vec();
for (ast.elt e in elts) {
auto expr_1 = check_expr(fcx, e.expr);
@@ -2121,10 +1563,10 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
expr_t = @rec(mut=ast.mut with *expr_t);
}
append[ast.elt](elts_1, rec(expr=expr_1 with e));
- append[@ty](elts_t, expr_t);
+ append[@ty.t](elts_t, expr_t);
}
- auto ann = ast.ann_type(plain_ty(ty_tup(elts_t)));
+ auto ann = ast.ann_type(plain_ty(ty.ty_tup(elts_t)));
ret @fold.respan[ast.expr_](expr.span,
ast.expr_tup(elts_1, ann));
}
@@ -2143,7 +1585,7 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
append[field](fields_t, rec(ident=f.ident, ty=expr_t));
}
- auto ann = ast.ann_type(plain_ty(ty_rec(fields_t)));
+ auto ann = ast.ann_type(plain_ty(ty.ty_rec(fields_t)));
ret @fold.respan[ast.expr_](expr.span,
ast.expr_rec(fields_1, ann));
}
@@ -2152,10 +1594,10 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
auto base_1 = check_expr(fcx, base);
auto base_t = expr_ty(base_1);
alt (base_t.struct) {
- case (ty_tup(?args)) {
- let uint ix = field_num(fcx.ccx.sess,
- expr.span, field);
- if (ix >= _vec.len[@ty](args)) {
+ case (ty.ty_tup(?args)) {
+ let uint ix = ty.field_num(fcx.ccx.sess,
+ expr.span, field);
+ if (ix >= _vec.len[@ty.t](args)) {
fcx.ccx.sess.span_err(expr.span,
"bad index on tuple");
}
@@ -2166,9 +1608,9 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
ann));
}
- case (ty_rec(?fields)) {
- let uint ix = field_idx(fcx.ccx.sess,
- expr.span, field, fields);
+ case (ty.ty_rec(?fields)) {
+ let uint ix = ty.field_idx(fcx.ccx.sess,
+ expr.span, field, fields);
if (ix >= _vec.len[typeck.field](fields)) {
fcx.ccx.sess.span_err(expr.span,
"bad index on record");
@@ -2180,16 +1622,16 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
ann));
}
- case (ty_obj(?methods)) {
- let uint ix = method_idx(fcx.ccx.sess,
- expr.span, field, methods);
+ case (ty.ty_obj(?methods)) {
+ let uint ix = ty.method_idx(fcx.ccx.sess,
+ expr.span, field, methods);
if (ix >= _vec.len[typeck.method](methods)) {
fcx.ccx.sess.span_err(expr.span,
"bad index on obj");
}
auto meth = methods.(ix);
- auto ty = plain_ty(ty_fn(meth.inputs, meth.output));
- auto ann = ast.ann_type(ty);
+ auto t = plain_ty(ty.ty_fn(meth.inputs, meth.output));
+ auto ann = ast.ann_type(t);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_field(base_1,
field,
@@ -2212,7 +1654,7 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
auto idx_t = expr_ty(idx_1);
alt (base_t.struct) {
- case (ty_vec(?t)) {
+ case (ty.ty_vec(?t)) {
if (! type_is_integral(idx_t)) {
fcx.ccx.sess.span_err
(idx.span,
@@ -2225,14 +1667,14 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
idx_1,
ann));
}
- case (ty_str) {
+ case (ty.ty_str) {
if (! type_is_integral(idx_t)) {
fcx.ccx.sess.span_err
(idx.span,
"non-integral type of str index: "
+ ty_to_str(idx_t));
}
- auto t = ty_machine(common.ty_u8);
+ auto t = ty.ty_machine(common.ty_u8);
auto ann = ast.ann_type(plain_ty(t));
ret @fold.respan[ast.expr_](expr.span,
ast.expr_index(base_1,
@@ -2256,8 +1698,8 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
}
}
-fn next_ty_var(@crate_ctxt ccx) -> @ty {
- auto t = plain_ty(ty_var(ccx.next_var_id));
+fn next_ty_var(@crate_ctxt ccx) -> @ty.t {
+ auto t = plain_ty(ty.ty_var(ccx.next_var_id));
ccx.next_var_id += 1;
ret t;
}
@@ -2287,7 +1729,7 @@ fn check_stmt(&fn_ctxt fcx, &@ast.stmt stmt)
alt (local.init) {
case (some[@ast.expr](?expr)) {
auto expr_0 = check_expr(fcx, expr);
- auto lty = plain_ty(ty_local(local.id));
+ auto lty = plain_ty(ty.ty_local(local.id));
auto expr_1 = demand_expr(fcx, lty, expr_0);
init = some[@ast.expr](expr_1);
}
@@ -2312,7 +1754,8 @@ fn check_stmt(&fn_ctxt fcx, &@ast.stmt stmt)
case (ast.stmt_ret(?expr_opt)) {
alt (expr_opt) {
case (none[@ast.expr]) {
- if (!are_compatible(fcx, fcx.ret_ty, plain_ty(ty_nil))) {
+ auto nil = plain_ty(ty.ty_nil);
+ if (!are_compatible(fcx, fcx.ret_ty, nil)) {
fcx.ccx.sess.err("ret; in function "
+ "returning non-nil");
}
@@ -2336,7 +1779,7 @@ fn check_stmt(&fn_ctxt fcx, &@ast.stmt stmt)
case (ast.stmt_check_expr(?expr)) {
auto expr_t = check_expr(fcx, expr);
- demand(fcx, expr.span, plain_ty(ty_bool), expr_ty(expr_t));
+ demand(fcx, expr.span, plain_ty(ty.ty_bool), expr_ty(expr_t));
ret @fold.respan[ast.stmt_](stmt.span,
ast.stmt_check_expr(expr_t));
}
@@ -2375,7 +1818,7 @@ fn check_const(&@crate_ctxt ccx, &span sp, ast.ident ident, @ast.ty t,
// for checking the initializer expression.
auto rty = ann_to_type(ann);
let fn_ctxt fcx = rec(ret_ty = rty,
- locals = @common.new_def_hash[@ty](),
+ locals = @common.new_def_hash[@ty.t](),
ccx = ccx);
auto e_ = check_expr(fcx, e);
// FIXME: necessary? Correct sequence?
@@ -2387,7 +1830,7 @@ fn check_const(&@crate_ctxt ccx, &span sp, ast.ident ident, @ast.ty t,
fn check_fn(&@crate_ctxt ccx, ast.effect effect,
vec[ast.arg] inputs,
@ast.ty output, &ast.block body) -> ast._fn {
- auto local_ty_table = @common.new_def_hash[@ty]();
+ auto local_ty_table = @common.new_def_hash[@ty.t]();
// FIXME: duplicate work: the item annotation already has the arg types
// and return type translated to typeck.ty values. We don't need do to it
@@ -2426,7 +1869,7 @@ fn check_item_fn(&@crate_ctxt ccx, &span sp, ast.ident ident, &ast._fn f,
}
auto output_ty = ast_ty_to_ty_crate(ccx, f.output);
- auto fn_sty = ty_fn(inputs, output_ty);
+ auto fn_sty = ty.ty_fn(inputs, output_ty);
auto fn_ann = ast.ann_type(plain_ty(fn_sty));
auto item = ast.item_fn(ident, f, ty_params, id, fn_ann);
diff --git a/src/comp/rustc.rc b/src/comp/rustc.rc
index ef9be053..8f541415 100644
--- a/src/comp/rustc.rc
+++ b/src/comp/rustc.rc
@@ -14,6 +14,7 @@ mod middle {
mod fold;
mod resolve;
mod trans;
+ mod ty;
mod typeck;
}