Change mutability into a type constructor.
This commit is contained in:
parent
386f363cfe
commit
3e08171fc2
6 changed files with 51 additions and 75 deletions
|
@ -910,6 +910,13 @@ let check_block (cx:Semant.ctxt) : (fn_ctx -> Ast.block -> unit) =
|
||||||
Array.iter check_stmt' block.Common.node
|
Array.iter check_stmt' block.Common.node
|
||||||
|
|
||||||
and check_stmt (stmt:Ast.stmt) : unit =
|
and check_stmt (stmt:Ast.stmt) : unit =
|
||||||
|
try
|
||||||
|
check_stmt_full stmt
|
||||||
|
with
|
||||||
|
Common.Semant_err (None, msg) ->
|
||||||
|
raise (Common.Semant_err ((Some stmt.Common.id), msg))
|
||||||
|
|
||||||
|
and check_stmt_full (stmt:Ast.stmt) : unit =
|
||||||
check_ret stmt;
|
check_ret stmt;
|
||||||
match stmt.Common.node with
|
match stmt.Common.node with
|
||||||
Ast.STMT_spawn (dst, _, _, callee, args) ->
|
Ast.STMT_spawn (dst, _, _, callee, args) ->
|
||||||
|
|
|
@ -152,7 +152,7 @@ tag ty_ {
|
||||||
ty_str;
|
ty_str;
|
||||||
ty_box(@ty);
|
ty_box(@ty);
|
||||||
ty_vec(@ty);
|
ty_vec(@ty);
|
||||||
ty_tup(vec[tup(mutability, @ty)]);
|
ty_tup(vec[@ty]);
|
||||||
ty_fn(vec[rec(mode mode, @ty ty)], @ty); // TODO: effect
|
ty_fn(vec[rec(mode mode, @ty ty)], @ty); // TODO: effect
|
||||||
ty_path(path, option.t[def]);
|
ty_path(path, option.t[def]);
|
||||||
ty_mutable(@ty);
|
ty_mutable(@ty);
|
||||||
|
|
|
@ -96,19 +96,6 @@ impure fn parse_ident(parser p) -> ast.ident {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impure fn parse_possibly_mutable_ty(parser p)
|
|
||||||
-> tup(ast.mutability, @ast.ty) {
|
|
||||||
auto mut;
|
|
||||||
if (p.peek() == token.MUTABLE) {
|
|
||||||
p.bump();
|
|
||||||
mut = ast.mut;
|
|
||||||
} else {
|
|
||||||
mut = ast.imm;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret tup(mut, parse_ty(p));
|
|
||||||
}
|
|
||||||
|
|
||||||
impure fn parse_ty_fn(parser p) -> ast.ty_ {
|
impure fn parse_ty_fn(parser p) -> ast.ty_ {
|
||||||
impure fn parse_fn_input_ty(parser p) -> rec(ast.mode mode, @ast.ty ty) {
|
impure fn parse_fn_input_ty(parser p) -> rec(ast.mode mode, @ast.ty ty) {
|
||||||
auto mode;
|
auto mode;
|
||||||
|
@ -192,11 +179,10 @@ impure fn parse_ty(parser p) -> @ast.ty {
|
||||||
|
|
||||||
case (token.TUP) {
|
case (token.TUP) {
|
||||||
p.bump();
|
p.bump();
|
||||||
auto f = parse_possibly_mutable_ty; // FIXME: trans_const_lval bug
|
auto f = parse_ty; // FIXME: trans_const_lval bug
|
||||||
auto elems =
|
auto elems = parse_seq[@ast.ty] (token.LPAREN,
|
||||||
parse_seq[tup(ast.mutability, @ast.ty)]
|
token.RPAREN,
|
||||||
(token.LPAREN,
|
some(token.COMMA), f, p);
|
||||||
token.RPAREN, some(token.COMMA), f, p);
|
|
||||||
hi = p.get_span();
|
hi = p.get_span();
|
||||||
t = ast.ty_tup(elems.node);
|
t = ast.ty_tup(elems.node);
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,8 +46,7 @@ type ast_fold[ENV] =
|
||||||
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_box,
|
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_box,
|
||||||
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_vec,
|
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_vec,
|
||||||
|
|
||||||
(fn(&ENV e, &span sp,
|
(fn(&ENV e, &span sp, vec[@ty] elts) -> @ty) fold_ty_tup,
|
||||||
vec[tup(mutability, @ty)] elts) -> @ty) fold_ty_tup,
|
|
||||||
|
|
||||||
(fn(&ENV e, &span sp,
|
(fn(&ENV e, &span sp,
|
||||||
vec[rec(ast.mode mode, @ty ty)] inputs,
|
vec[rec(ast.mode mode, @ty ty)] inputs,
|
||||||
|
@ -246,9 +245,9 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
|
||||||
}
|
}
|
||||||
|
|
||||||
case (ast.ty_tup(?elts)) {
|
case (ast.ty_tup(?elts)) {
|
||||||
let vec[tup(mutability, @ty)] elts_ = vec();
|
let vec[@ty] elts_ = vec();
|
||||||
for (tup(mutability, @ty) elt in elts) {
|
for (@ty elt in elts) {
|
||||||
elts_ += tup(elt._0, fold_ty(env, fld, elt._1));
|
append[@ty](elts_,fold_ty(env, fld, elt));
|
||||||
}
|
}
|
||||||
ret fld.fold_ty_tup(env_, t.span, elts);
|
ret fld.fold_ty_tup(env_, t.span, elts);
|
||||||
}
|
}
|
||||||
|
@ -652,7 +651,7 @@ fn identity_fold_ty_vec[ENV](&ENV env, &span sp, @ty t) -> @ty {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn identity_fold_ty_tup[ENV](&ENV env, &span sp,
|
fn identity_fold_ty_tup[ENV](&ENV env, &span sp,
|
||||||
vec[tup(mutability,@ty)] elts) -> @ty {
|
vec[@ty] elts) -> @ty {
|
||||||
ret @respan(sp, ast.ty_tup(elts));
|
ret @respan(sp, ast.ty_tup(elts));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -275,8 +275,8 @@ fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef {
|
||||||
}
|
}
|
||||||
case (typeck.ty_tup(?elts)) {
|
case (typeck.ty_tup(?elts)) {
|
||||||
let vec[TypeRef] tys = vec();
|
let vec[TypeRef] tys = vec();
|
||||||
for (tup(ast.mutability, @typeck.ty) elt in elts) {
|
for (@typeck.ty elt in elts) {
|
||||||
tys += type_of(cx, elt._1);
|
tys += type_of(cx, elt);
|
||||||
}
|
}
|
||||||
ret T_struct(tys);
|
ret T_struct(tys);
|
||||||
}
|
}
|
||||||
|
@ -493,9 +493,9 @@ fn iter_structural_ty(@block_ctxt cx,
|
||||||
alt (t.struct) {
|
alt (t.struct) {
|
||||||
case (typeck.ty_tup(?args)) {
|
case (typeck.ty_tup(?args)) {
|
||||||
let int i = 0;
|
let int i = 0;
|
||||||
for (tup(ast.mutability, @typeck.ty) arg in args) {
|
for (@typeck.ty arg in args) {
|
||||||
auto elt = r.bcx.build.GEP(v, vec(C_int(0), C_int(i)));
|
auto elt = r.bcx.build.GEP(v, vec(C_int(0), C_int(i)));
|
||||||
r = f(r.bcx, elt, arg._1);
|
r = f(r.bcx, elt, arg);
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,7 +40,7 @@ tag sty {
|
||||||
ty_str;
|
ty_str;
|
||||||
ty_box(@ty);
|
ty_box(@ty);
|
||||||
ty_vec(@ty);
|
ty_vec(@ty);
|
||||||
ty_tup(vec[tup(mutability, @ty)]);
|
ty_tup(vec[@ty]);
|
||||||
ty_fn(vec[arg], @ty); // TODO: effect
|
ty_fn(vec[arg], @ty); // TODO: effect
|
||||||
ty_var(int); // ephemeral type var
|
ty_var(int); // ephemeral type var
|
||||||
ty_local(ast.def_id); // type of a local var
|
ty_local(ast.def_id); // type of a local var
|
||||||
|
@ -66,16 +66,6 @@ type ty_getter = fn(ast.def_id) -> @ty;
|
||||||
// Error-reporting utility functions
|
// Error-reporting utility functions
|
||||||
|
|
||||||
fn ast_ty_to_str(&@ast.ty ty) -> str {
|
fn ast_ty_to_str(&@ast.ty ty) -> str {
|
||||||
fn ast_tup_elem_to_str(&tup(mutability, @ast.ty) elem) -> str {
|
|
||||||
auto s;
|
|
||||||
if (elem._0 == ast.mut) {
|
|
||||||
s = "mutable ";
|
|
||||||
} else {
|
|
||||||
s = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
ret s + ast_ty_to_str(elem._1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ast_fn_input_to_str(&rec(ast.mode mode, @ast.ty ty) input) -> str {
|
fn ast_fn_input_to_str(&rec(ast.mode mode, @ast.ty ty) input) -> str {
|
||||||
auto s;
|
auto s;
|
||||||
|
@ -101,11 +91,9 @@ fn ast_ty_to_str(&@ast.ty ty) -> str {
|
||||||
case (ast.ty_vec(?t)) { s = "vec[" + ast_ty_to_str(t) + "]"; }
|
case (ast.ty_vec(?t)) { s = "vec[" + ast_ty_to_str(t) + "]"; }
|
||||||
|
|
||||||
case (ast.ty_tup(?elems)) {
|
case (ast.ty_tup(?elems)) {
|
||||||
auto f = ast_tup_elem_to_str;
|
auto f = ast_ty_to_str;
|
||||||
s = "tup(";
|
s = "tup(";
|
||||||
s +=
|
s += _str.connect(_vec.map[@ast.ty,str](f, elems), ",");
|
||||||
_str.connect(_vec.map[tup(mutability,@ast.ty),str](f, elems),
|
|
||||||
",");
|
|
||||||
s += ")";
|
s += ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,17 +141,7 @@ fn path_to_str(&ast.path path) -> str {
|
||||||
ret _str.connect(_vec.map[ast.name,str](f, path), ".");
|
ret _str.connect(_vec.map[ast.name,str](f, path), ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_to_str(@ty typ) -> str {
|
fn ty_to_str(&@ty typ) -> str {
|
||||||
fn tup_elem_to_str(&tup(mutability, @ty) elem) -> str {
|
|
||||||
auto s;
|
|
||||||
if (elem._0 == ast.mut) {
|
|
||||||
s = "mutable ";
|
|
||||||
} else {
|
|
||||||
s = "";
|
|
||||||
}
|
|
||||||
|
|
||||||
ret s + ty_to_str(elem._1);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fn_input_to_str(&rec(ast.mode mode, @ty ty) input) -> str {
|
fn fn_input_to_str(&rec(ast.mode mode, @ty ty) input) -> str {
|
||||||
auto s;
|
auto s;
|
||||||
|
@ -176,7 +154,11 @@ fn ty_to_str(@ty typ) -> str {
|
||||||
ret s + ty_to_str(input.ty);
|
ret s + ty_to_str(input.ty);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto s;
|
auto s = "";
|
||||||
|
if (typ.mut == ast.mut) {
|
||||||
|
s += "mutable ";
|
||||||
|
}
|
||||||
|
|
||||||
alt (typ.struct) {
|
alt (typ.struct) {
|
||||||
case (ty_nil) { s = "()"; }
|
case (ty_nil) { s = "()"; }
|
||||||
case (ty_bool) { s = "bool"; }
|
case (ty_bool) { s = "bool"; }
|
||||||
|
@ -189,8 +171,8 @@ fn ty_to_str(@ty typ) -> str {
|
||||||
case (ty_vec(?t)) { s = "vec[" + ty_to_str(t) + "]"; }
|
case (ty_vec(?t)) { s = "vec[" + ty_to_str(t) + "]"; }
|
||||||
|
|
||||||
case (ty_tup(?elems)) {
|
case (ty_tup(?elems)) {
|
||||||
auto f = tup_elem_to_str;
|
auto f = ty_to_str;
|
||||||
auto strs = _vec.map[tup(mutability,@ty),str](f, elems);
|
auto strs = _vec.map[@ty,str](f, elems);
|
||||||
s = "tup(" + _str.connect(strs, ",") + ")";
|
s = "tup(" + _str.connect(strs, ",") + ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,9 +216,9 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty {
|
||||||
case (ast.ty_box(?t)) { sty = ty_box(ast_ty_to_ty(getter, t)); }
|
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_vec(?t)) { sty = ty_vec(ast_ty_to_ty(getter, t)); }
|
||||||
case (ast.ty_tup(?fields)) {
|
case (ast.ty_tup(?fields)) {
|
||||||
let vec[tup(mutability,@ty)] flds = vec();
|
let vec[@ty] flds = vec();
|
||||||
for (tup(mutability, @ast.ty) field in fields) {
|
for (@ast.ty field in fields) {
|
||||||
flds += tup(field._0, ast_ty_to_ty(getter, field._1));
|
append[@ty](flds, ast_ty_to_ty(getter, field));
|
||||||
}
|
}
|
||||||
sty = ty_tup(flds);
|
sty = ty_tup(flds);
|
||||||
}
|
}
|
||||||
|
@ -710,10 +692,8 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
|
||||||
case (ty_tup(?expected_elems)) {
|
case (ty_tup(?expected_elems)) {
|
||||||
alt (actual.struct) {
|
alt (actual.struct) {
|
||||||
case (ty_tup(?actual_elems)) {
|
case (ty_tup(?actual_elems)) {
|
||||||
auto expected_len =
|
auto expected_len = _vec.len[@ty](expected_elems);
|
||||||
_vec.len[tup(mutability,@ty)](expected_elems);
|
auto actual_len = _vec.len[@ty](actual_elems);
|
||||||
auto actual_len =
|
|
||||||
_vec.len[tup(mutability,@ty)](actual_elems);
|
|
||||||
if (expected_len != actual_len) {
|
if (expected_len != actual_len) {
|
||||||
auto err = terr_tuple_size(expected_len,
|
auto err = terr_tuple_size(expected_len,
|
||||||
actual_len);
|
actual_len);
|
||||||
|
@ -722,24 +702,23 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result {
|
||||||
|
|
||||||
// TODO: implement an iterator that can iterate over
|
// TODO: implement an iterator that can iterate over
|
||||||
// two arrays simultaneously.
|
// two arrays simultaneously.
|
||||||
let vec[tup(mutability, @ty)] result_elems = vec();
|
let vec[@ty] result_elems = vec();
|
||||||
auto i = 0u;
|
auto i = 0u;
|
||||||
while (i < expected_len) {
|
while (i < expected_len) {
|
||||||
auto expected_elem = expected_elems.(i);
|
auto expected_elem = expected_elems.(i);
|
||||||
auto actual_elem = actual_elems.(i);
|
auto actual_elem = actual_elems.(i);
|
||||||
if (expected_elem._0 != actual_elem._0) {
|
if (expected_elem.mut != actual_elem.mut) {
|
||||||
auto err = terr_tuple_mutability;
|
auto err = terr_tuple_mutability;
|
||||||
ret ures_err(err, expected, actual);
|
ret ures_err(err, expected, actual);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = unify_step(fcx,
|
auto result = unify_step(fcx,
|
||||||
bindings,
|
bindings,
|
||||||
expected_elem._1,
|
expected_elem,
|
||||||
actual_elem._1);
|
actual_elem);
|
||||||
alt (result) {
|
alt (result) {
|
||||||
case (ures_ok(?rty)) {
|
case (ures_ok(?rty)) {
|
||||||
result_elems += vec(tup(expected_elem._0,
|
append[@ty](result_elems,rty);
|
||||||
rty));
|
|
||||||
}
|
}
|
||||||
case (_) {
|
case (_) {
|
||||||
ret result;
|
ret result;
|
||||||
|
@ -1258,12 +1237,17 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
||||||
|
|
||||||
case (ast.expr_tup(?args, _)) {
|
case (ast.expr_tup(?args, _)) {
|
||||||
let vec[tup(mutability, @ast.expr)] args_1 = vec();
|
let vec[tup(mutability, @ast.expr)] args_1 = vec();
|
||||||
let vec[tup(mutability, @ty)] args_t = vec();
|
let vec[@ty] args_t = vec();
|
||||||
|
|
||||||
for (tup(mutability, @ast.expr) arg in args) {
|
for (tup(mutability, @ast.expr) arg in args) {
|
||||||
auto expr_1 = check_expr(fcx, arg._1);
|
auto expr_1 = check_expr(fcx, arg._1);
|
||||||
args_1 += tup(arg._0, expr_1);
|
args_1 += tup(arg._0, expr_1);
|
||||||
args_t += tup(arg._0, expr_ty(expr_1));
|
if (arg._0 == ast.mut) {
|
||||||
|
append[@ty](args_t,@rec(mut=ast.mut
|
||||||
|
with *expr_ty(expr_1)));
|
||||||
|
} else {
|
||||||
|
append[@ty](args_t,expr_ty(expr_1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto ann = ast.ann_type(plain_ty(ty_tup(args_t)));
|
auto ann = ast.ann_type(plain_ty(ty_tup(args_t)));
|
||||||
|
@ -1278,11 +1262,11 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
|
||||||
case (ty_tup(?args)) {
|
case (ty_tup(?args)) {
|
||||||
let uint ix = field_num(fcx.ccx.sess,
|
let uint ix = field_num(fcx.ccx.sess,
|
||||||
expr.span, field);
|
expr.span, field);
|
||||||
if (ix >= _vec.len[tup(mutability,@ty)](args)) {
|
if (ix >= _vec.len[@ty](args)) {
|
||||||
fcx.ccx.sess.span_err(expr.span,
|
fcx.ccx.sess.span_err(expr.span,
|
||||||
"bad index on tuple");
|
"bad index on tuple");
|
||||||
}
|
}
|
||||||
auto ann = ast.ann_type(args.(ix)._1);
|
auto ann = ast.ann_type(args.(ix));
|
||||||
ret @fold.respan[ast.expr_](expr.span,
|
ret @fold.respan[ast.expr_](expr.span,
|
||||||
ast.expr_field(base_1,
|
ast.expr_field(base_1,
|
||||||
field,
|
field,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue