aboutsummaryrefslogtreecommitdiff
path: root/src/comp/middle/ty.rs
diff options
context:
space:
mode:
authorPatrick Walton <[email protected]>2011-03-17 17:39:47 -0700
committerPatrick Walton <[email protected]>2011-03-17 17:39:47 -0700
commit5eca7129e3857e3506d12de7591238f8a7d55da1 (patch)
tree54701099b4b723539074b662daaf3290e63d51e0 /src/comp/middle/ty.rs
parentrustc: Typo: mutabliity -> mutability (diff)
downloadrust-5eca7129e3857e3506d12de7591238f8a7d55da1.tar.xz
rust-5eca7129e3857e3506d12de7591238f8a7d55da1.zip
rustc: Switch mutability from being a type constructor to a field annotation
Diffstat (limited to 'src/comp/middle/ty.rs')
-rw-r--r--src/comp/middle/ty.rs158
1 files changed, 100 insertions, 58 deletions
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 56a9c226..3d10462a 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -17,15 +17,17 @@ import util.common.span;
// Data types
type arg = rec(ast.mode mode, @t ty);
-type field = rec(ast.ident ident, @t ty);
+type field = rec(ast.ident ident, mt mt);
type method = rec(ast.proto proto,
ast.ident ident,
vec[arg] inputs,
@t output);
+type mt = rec(@t ty, ast.mutability mut);
+
// 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);
+type t = rec(sty struct, option.t[str] cname);
tag sty {
ty_nil;
ty_bool;
@@ -35,11 +37,11 @@ tag sty {
ty_char;
ty_str;
ty_tag(ast.def_id, vec[@t]);
- ty_box(@t);
- ty_vec(@t);
+ ty_box(mt);
+ ty_vec(mt);
ty_port(@t);
ty_chan(@t);
- ty_tup(vec[@t]);
+ ty_tup(vec[mt]);
ty_rec(vec[field]);
ty_fn(ast.proto, vec[arg], @t); // TODO: effect
ty_native_fn(ast.native_abi, vec[arg], @t); // TODO: effect
@@ -65,6 +67,8 @@ type unify_handler = obj {
tag type_err {
terr_mismatch;
+ terr_box_mutability;
+ terr_vec_mutability;
terr_tuple_size(uint, uint);
terr_tuple_mutability;
terr_record_size(uint, uint);
@@ -138,14 +142,20 @@ fn ty_to_str(&@t typ) -> str {
}
fn field_to_str(&field f) -> str {
- ret ty_to_str(f.ty) + " " + f.ident;
+ ret mt_to_str(f.mt) + " " + f.ident;
}
- auto s = "";
- if (typ.mut == ast.mut) {
- s += "mutable ";
+ fn mt_to_str(&mt m) -> str {
+ auto mstr;
+ alt (m.mut) {
+ case (ast.mut) { mstr = "mutable "; }
+ case (ast.imm) { mstr = ""; }
+ }
+
+ ret mstr + ty_to_str(m.ty);
}
+ auto s = "";
alt (typ.struct) {
case (ty_native) { s += "native"; }
case (ty_nil) { s += "()"; }
@@ -155,15 +165,15 @@ fn ty_to_str(&@t typ) -> str {
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_box(?tm)) { s += "@" + mt_to_str(tm); }
+ case (ty_vec(?tm)) { s += "vec[" + mt_to_str(tm) + "]"; }
case (ty_port(?t)) { s += "port[" + ty_to_str(t) + "]"; }
case (ty_chan(?t)) { s += "chan[" + ty_to_str(t) + "]"; }
case (ty_type) { s += "type"; }
case (ty_tup(?elems)) {
- auto f = ty_to_str;
- auto strs = _vec.map[@t,str](f, elems);
+ auto f = mt_to_str;
+ auto strs = _vec.map[mt,str](f, elems);
s += "tup(" + _str.connect(strs, ",") + ")";
}
@@ -224,7 +234,7 @@ type ty_fold = state obj {
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);
+ ret @rec(struct=new, cname=orig.cname);
}
alt (ty.struct) {
@@ -237,11 +247,11 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
case (ty_str) { ret fld.fold_simple_ty(ty); }
case (ty_type) { ret fld.fold_simple_ty(ty); }
case (ty_native) { ret fld.fold_simple_ty(ty); }
- case (ty_box(?subty)) {
- ret rewrap(ty, ty_box(fold_ty(fld, subty)));
+ case (ty_box(?tm)) {
+ ret rewrap(ty, ty_box(rec(ty=fold_ty(fld, tm.ty), mut=tm.mut)));
}
- case (ty_vec(?subty)) {
- ret rewrap(ty, ty_vec(fold_ty(fld, subty)));
+ case (ty_vec(?tm)) {
+ ret rewrap(ty, ty_vec(rec(ty=fold_ty(fld, tm.ty), mut=tm.mut)));
}
case (ty_port(?subty)) {
ret rewrap(ty, ty_port(fold_ty(fld, subty)));
@@ -256,18 +266,20 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
}
ret rewrap(ty, ty_tag(tid, new_subtys));
}
- case (ty_tup(?subtys)) {
- let vec[@t] new_subtys = vec();
- for (@t subty in subtys) {
- new_subtys += vec(fold_ty(fld, subty));
+ case (ty_tup(?mts)) {
+ let vec[mt] new_mts = vec();
+ for (mt tm in mts) {
+ auto new_subty = fold_ty(fld, tm.ty);
+ new_mts += vec(rec(ty=new_subty, mut=tm.mut));
}
- ret rewrap(ty, ty_tup(new_subtys));
+ ret rewrap(ty, ty_tup(new_mts));
}
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));
+ auto new_ty = fold_ty(fld, fl.mt.ty);
+ auto new_mt = rec(ty=new_ty, mut=fl.mt.mut);
+ new_fields += vec(rec(ident=fl.ident, mt=new_mt));
}
ret rewrap(ty, ty_rec(new_fields));
}
@@ -351,8 +363,8 @@ fn type_is_sequence(@t ty) -> bool {
fn sequence_element_type(@t ty) -> @t {
alt (ty.struct) {
- case (ty_str) { ret plain_ty(ty_machine(common.ty_u8)); }
- case (ty_vec(?e)) { ret e; }
+ case (ty_str) { ret plain_ty(ty_machine(common.ty_u8)); }
+ case (ty_vec(?mt)) { ret mt.ty; }
}
fail;
}
@@ -372,11 +384,11 @@ fn type_is_tup_like(@t ty) -> bool {
fn get_element_type(@t ty, uint i) -> @t {
check (type_is_tup_like(ty));
alt (ty.struct) {
- case (ty_tup(?tys)) {
- ret tys.(i);
+ case (ty_tup(?mts)) {
+ ret mts.(i).ty;
}
case (ty_rec(?flds)) {
- ret flds.(i).ty;
+ ret flds.(i).mt.ty;
}
}
fail;
@@ -427,17 +439,17 @@ fn type_is_native(@t ty) -> bool {
fn type_has_dynamic_size(@t ty) -> bool {
alt (ty.struct) {
- case (ty_tup(?ts)) {
+ case (ty_tup(?mts)) {
auto i = 0u;
- while (i < _vec.len[@t](ts)) {
- if (type_has_dynamic_size(ts.(i))) { ret true; }
+ while (i < _vec.len[mt](mts)) {
+ if (type_has_dynamic_size(mts.(i).ty)) { ret true; }
i += 1u;
}
}
case (ty_rec(?fields)) {
auto i = 0u;
while (i < _vec.len[field](fields)) {
- if (type_has_dynamic_size(fields.(i).ty)) { ret true; }
+ if (type_has_dynamic_size(fields.(i).mt.ty)) { ret true; }
i += 1u;
}
}
@@ -518,7 +530,19 @@ fn type_param(@t ty) -> option.t[ast.def_id] {
}
fn plain_ty(&sty st) -> @t {
- ret @rec(struct=st, mut=ast.imm, cname=none[str]);
+ ret @rec(struct=st, cname=none[str]);
+}
+
+fn plain_box_ty(@t subty) -> @t {
+ ret plain_ty(ty_box(rec(ty=subty, mut=ast.imm)));
+}
+
+fn plain_tup_ty(vec[@t] elem_tys) -> @t {
+ let vec[ty.mt] mts = vec();
+ for (@ty.t typ in elem_tys) {
+ mts += vec(rec(ty=typ, mut=ast.imm));
+ }
+ ret plain_ty(ty_tup(mts));
}
fn hash_ty(&@t ty) -> uint {
@@ -703,7 +727,7 @@ fn pat_ty(@ast.pat pat) -> @t {
fn expr_ty(@ast.expr expr) -> @t {
alt (expr.node) {
- case (ast.expr_vec(_, ?ann)) { ret ann_to_type(ann); }
+ 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_bind(_, _, ?ann)) { ret ann_to_type(ann); }
@@ -1131,16 +1155,23 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
ret ures_err(terr_mismatch, expected, actual);
}
- case (ty.ty_box(?expected_sub)) {
+ case (ty.ty_box(?expected_mt)) {
alt (actual.struct) {
- case (ty.ty_box(?actual_sub)) {
+ case (ty.ty_box(?actual_mt)) {
+ if (expected_mt.mut != actual_mt.mut) {
+ ret ures_err(terr_box_mutability, expected,
+ actual);
+ }
+
auto result = unify_step(bindings,
- expected_sub,
- actual_sub,
+ expected_mt.ty,
+ actual_mt.ty,
handler);
alt (result) {
case (ures_ok(?result_sub)) {
- ret ures_ok(plain_ty(ty.ty_box(result_sub)));
+ auto mt = rec(ty=result_sub,
+ mut=expected_mt.mut);
+ ret ures_ok(plain_ty(ty.ty_box(mt)));
}
case (_) {
ret result;
@@ -1154,16 +1185,23 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
}
}
- case (ty.ty_vec(?expected_sub)) {
+ case (ty.ty_vec(?expected_mt)) {
alt (actual.struct) {
- case (ty.ty_vec(?actual_sub)) {
+ case (ty.ty_vec(?actual_mt)) {
+ if (expected_mt.mut != actual_mt.mut) {
+ ret ures_err(terr_vec_mutability, expected,
+ actual);
+ }
+
auto result = unify_step(bindings,
- expected_sub,
- actual_sub,
+ expected_mt.ty,
+ actual_mt.ty,
handler);
alt (result) {
case (ures_ok(?result_sub)) {
- ret ures_ok(plain_ty(ty.ty_vec(result_sub)));
+ auto mt = rec(ty=result_sub,
+ mut=expected_mt.mut);
+ ret ures_ok(plain_ty(ty.ty_vec(mt)));
}
case (_) {
ret result;
@@ -1226,8 +1264,8 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
case (ty.ty_tup(?expected_elems)) {
alt (actual.struct) {
case (ty.ty_tup(?actual_elems)) {
- auto expected_len = _vec.len[@ty.t](expected_elems);
- auto actual_len = _vec.len[@ty.t](actual_elems);
+ auto expected_len = _vec.len[ty.mt](expected_elems);
+ auto actual_len = _vec.len[ty.mt](actual_elems);
if (expected_len != actual_len) {
auto err = terr_tuple_size(expected_len,
actual_len);
@@ -1236,7 +1274,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
// TODO: implement an iterator that can iterate over
// two arrays simultaneously.
- let vec[@ty.t] result_elems = vec();
+ let vec[ty.mt] result_elems = vec();
auto i = 0u;
while (i < expected_len) {
auto expected_elem = expected_elems.(i);
@@ -1247,12 +1285,14 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
}
auto result = unify_step(bindings,
- expected_elem,
- actual_elem,
+ expected_elem.ty,
+ actual_elem.ty,
handler);
alt (result) {
case (ures_ok(?rty)) {
- _vec.push[@ty.t](result_elems,rty);
+ auto mt = rec(ty=rty,
+ mut=expected_elem.mut);
+ result_elems += vec(mt);
}
case (_) {
ret result;
@@ -1289,14 +1329,14 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
while (i < expected_len) {
auto expected_field = expected_fields.(i);
auto actual_field = actual_fields.(i);
- if (expected_field.ty.mut
- != actual_field.ty.mut) {
+ if (expected_field.mt.mut
+ != actual_field.mt.mut) {
auto err = terr_record_mutability;
ret ures_err(err, expected, actual);
}
if (!_str.eq(expected_field.ident,
- actual_field.ident)) {
+ actual_field.ident)) {
auto err =
terr_record_fields(expected_field.ident,
actual_field.ident);
@@ -1304,14 +1344,16 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
}
auto result = unify_step(bindings,
- expected_field.ty,
- actual_field.ty,
+ expected_field.mt.ty,
+ actual_field.mt.ty,
handler);
alt (result) {
case (ures_ok(?rty)) {
+ auto mt = rec(ty=rty,
+ mut=expected_field.mt.mut);
_vec.push[field]
(result_fields,
- rec(ty=rty with expected_field));
+ rec(mt=mt with expected_field));
}
case (_) {
ret result;