diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index a177f30187f..5e34d481e0c 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -48,6 +48,11 @@ tag pat_ { pat_tag(ident, vec[@pat], ann); } +tag mutability { + mut; + imm; +} + tag binop { add; sub; @@ -105,7 +110,7 @@ type arm = rec(@pat pat, block block); type expr = spanned[expr_]; tag expr_ { expr_vec(vec[@expr], ann); - expr_tup(vec[tup(bool /* mutability */, @expr)], ann); + expr_tup(vec[tup(mutability, @expr)], ann); expr_rec(vec[tup(ident,@expr)], ann); expr_call(@expr, vec[@expr], ann); expr_binary(binop, @expr, @expr, ann); @@ -147,7 +152,7 @@ tag ty_ { ty_str; ty_box(@ty); ty_vec(@ty); - ty_tup(vec[tup(bool /* mutability */, @ty)]); + ty_tup(vec[tup(mutability, @ty)]); ty_fn(vec[rec(mode mode, @ty ty)], @ty); // TODO: effect ty_path(path, option.t[def]); ty_mutable(@ty); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index ab0f795d6dd..e88760f6dca 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -96,13 +96,14 @@ impure fn parse_ident(parser p) -> ast.ident { } } -impure fn parse_possibly_mutable_ty(parser p) -> tup(bool, @ast.ty) { +impure fn parse_possibly_mutable_ty(parser p) + -> tup(ast.mutability, @ast.ty) { auto mut; if (p.peek() == token.MUTABLE) { p.bump(); - mut = true; + mut = ast.mut; } else { - mut = false; + mut = ast.imm; } ret tup(mut, parse_ty(p)); @@ -192,8 +193,10 @@ impure fn parse_ty(parser p) -> @ast.ty { case (token.TUP) { p.bump(); auto f = parse_possibly_mutable_ty; // FIXME: trans_const_lval bug - auto elems = parse_seq[tup(bool, @ast.ty)](token.LPAREN, - token.RPAREN, some(token.COMMA), f, p); + auto elems = + parse_seq[tup(ast.mutability, @ast.ty)] + (token.LPAREN, + token.RPAREN, some(token.COMMA), f, p); hi = p.get_span(); t = ast.ty_tup(elems.node); } @@ -346,13 +349,14 @@ impure fn parse_name(parser p, ast.ident id) -> ast.name { ret spanned(lo, tys.span, rec(ident=id, types=tys.node)); } -impure fn parse_possibly_mutable_expr(parser p) -> tup(bool, @ast.expr) { +impure fn parse_possibly_mutable_expr(parser p) + -> tup(ast.mutability, @ast.expr) { auto mut; if (p.peek() == token.MUTABLE) { p.bump(); - mut = true; + mut = ast.mut; } else { - mut = false; + mut = ast.imm; } ret tup(mut, parse_expr(p)); @@ -409,10 +413,12 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr { case (token.TUP) { p.bump(); auto pf = parse_possibly_mutable_expr; - auto es = parse_seq[tup(bool, @ast.expr)](token.LPAREN, - token.RPAREN, - some(token.COMMA), - pf, p); + auto es = + parse_seq[tup(ast.mutability, @ast.expr)] + (token.LPAREN, + token.RPAREN, + some(token.COMMA), + pf, p); hi = es.span; ex = ast.expr_tup(es.node, ast.ann_none); } diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index 1caaa00e7d3..7b64738033b 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -13,6 +13,7 @@ import front.ast; import front.ast.ident; import front.ast.name; import front.ast.path; +import front.ast.mutability; import front.ast.ty; import front.ast.expr; import front.ast.stmt; @@ -46,7 +47,7 @@ type ast_fold[ENV] = (fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_vec, (fn(&ENV e, &span sp, - vec[tup(bool, @ty)] elts) -> @ty) fold_ty_tup, + vec[tup(mutability, @ty)] elts) -> @ty) fold_ty_tup, (fn(&ENV e, &span sp, vec[rec(ast.mode mode, @ty ty)] inputs, @@ -62,7 +63,7 @@ type ast_fold[ENV] = vec[@expr] es, ann a) -> @expr) fold_expr_vec, (fn(&ENV e, &span sp, - vec[tup(bool,@expr)] es, + vec[tup(mutability,@expr)] es, ann a) -> @expr) fold_expr_tup, (fn(&ENV e, &span sp, @@ -245,8 +246,8 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty { } case (ast.ty_tup(?elts)) { - let vec[tup(bool, @ty)] elts_ = vec(); - for (tup(bool, @ty) elt in elts) { + let vec[tup(mutability, @ty)] elts_ = vec(); + for (tup(mutability, @ty) elt in elts) { elts_ += tup(elt._0, fold_ty(env, fld, elt._1)); } ret fld.fold_ty_tup(env_, t.span, elts); @@ -335,8 +336,8 @@ fn fold_exprs[ENV](&ENV env, ast_fold[ENV] fld, vec[@expr] es) -> vec[@expr] { ret exprs; } -fn fold_tup_entry[ENV](&ENV env, ast_fold[ENV] fld, &tup(bool,@expr) e) - -> tup(bool,@expr) { +fn fold_tup_entry[ENV](&ENV env, ast_fold[ENV] fld, + &tup(mutability,@expr) e) -> tup(mutability,@expr) { ret tup(e._0, fold_expr(env, fld, e._1)); } @@ -360,8 +361,8 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr { } case (ast.expr_tup(?es, ?t)) { - let vec[tup(bool,@expr)] entries = vec(); - for (tup(bool,@expr) entry in es) { + let vec[tup(mutability,@expr)] entries = vec(); + for (tup(mutability,@expr) entry in es) { entries += fold_tup_entry[ENV](env, fld, entry); } ret fld.fold_expr_tup(env_, e.span, entries, t); @@ -650,8 +651,8 @@ fn identity_fold_ty_vec[ENV](&ENV env, &span sp, @ty t) -> @ty { ret @respan(sp, ast.ty_vec(t)); } -fn identity_fold_ty_tup[ENV](&ENV env, &span sp, vec[tup(bool,@ty)] elts) - -> @ty { +fn identity_fold_ty_tup[ENV](&ENV env, &span sp, + vec[tup(mutability,@ty)] elts) -> @ty { ret @respan(sp, ast.ty_tup(elts)); } @@ -678,7 +679,8 @@ fn identity_fold_expr_vec[ENV](&ENV env, &span sp, vec[@expr] es, ret @respan(sp, ast.expr_vec(es, a)); } -fn identity_fold_expr_tup[ENV](&ENV env, &span sp, vec[tup(bool, @expr)] es, +fn identity_fold_expr_tup[ENV](&ENV env, &span sp, + vec[tup(mutability, @expr)] es, ann a) -> @expr { ret @respan(sp, ast.expr_tup(es, a)); } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 2f078f04aec..01e73a6ef45 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -275,7 +275,7 @@ fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef { } case (typeck.ty_tup(?elts)) { let vec[TypeRef] tys = vec(); - for (tup(bool, @typeck.ty) elt in elts) { + for (tup(ast.mutability, @typeck.ty) elt in elts) { tys += type_of(cx, elt._1); } ret T_struct(tys); @@ -493,7 +493,7 @@ fn iter_structural_ty(@block_ctxt cx, alt (t.struct) { case (typeck.ty_tup(?args)) { let int i = 0; - for (tup(bool, @typeck.ty) arg in args) { + for (tup(ast.mutability, @typeck.ty) arg in args) { auto elt = r.bcx.build.GEP(v, vec(C_int(0), C_int(i))); r = f(r.bcx, elt, arg._1); i += 1; @@ -1184,13 +1184,13 @@ impure fn trans_call(@block_ctxt cx, @ast.expr f, args_res._0.build.FastCall(f_res._0.val, args_res._1)); } -impure fn trans_tup(@block_ctxt cx, vec[tup(bool, @ast.expr)] args, +impure fn trans_tup(@block_ctxt cx, vec[tup(ast.mutability, @ast.expr)] args, &ast.ann ann) -> result { auto ty = node_type(cx.fcx.ccx, ann); auto tup_val = cx.build.Alloca(ty); let int i = 0; auto r = res(cx, C_nil()); - for (tup(bool, @ast.expr) arg in args) { + for (tup(ast.mutability, @ast.expr) arg in args) { auto t = typeck.expr_ty(arg._1); auto src_res = trans_expr(r.bcx, arg._1); auto dst_elt = r.bcx.build.GEP(tup_val, vec(C_int(0), C_int(i))); diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 0fd72d9e66f..31917959d1c 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1,5 +1,6 @@ import front.ast; import front.ast.ann; +import front.ast.mutability; import middle.fold; import driver.session; import util.common; @@ -28,7 +29,7 @@ type arg = rec(ast.mode mode, @ty ty); // 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, bool mut, option.t[str] cname); +type ty = rec(sty struct, mutability mut, option.t[str] cname); tag sty { ty_nil; ty_bool; @@ -39,7 +40,7 @@ tag sty { ty_str; ty_box(@ty); ty_vec(@ty); - ty_tup(vec[tup(bool /* mutability */, @ty)]); + ty_tup(vec[tup(mutability, @ty)]); ty_fn(vec[arg], @ty); // TODO: effect ty_var(int); // ephemeral type var ty_local(ast.def_id); // type of a local var @@ -65,9 +66,9 @@ type ty_getter = fn(ast.def_id) -> @ty; // Error-reporting utility functions fn ast_ty_to_str(&@ast.ty ty) -> str { - fn ast_tup_elem_to_str(&tup(bool, @ast.ty) elem) -> str { + fn ast_tup_elem_to_str(&tup(mutability, @ast.ty) elem) -> str { auto s; - if (elem._0) { + if (elem._0 == ast.mut) { s = "mutable "; } else { s = ""; @@ -102,7 +103,9 @@ fn ast_ty_to_str(&@ast.ty ty) -> str { case (ast.ty_tup(?elems)) { auto f = ast_tup_elem_to_str; s = "tup("; - s += _str.connect(_vec.map[tup(bool,@ast.ty),str](f, elems), ","); + s += + _str.connect(_vec.map[tup(mutability,@ast.ty),str](f, elems), + ","); s += ")"; } @@ -151,9 +154,9 @@ fn path_to_str(&ast.path path) -> str { } fn ty_to_str(@ty typ) -> str { - fn tup_elem_to_str(&tup(bool, @ty) elem) -> str { + fn tup_elem_to_str(&tup(mutability, @ty) elem) -> str { auto s; - if (elem._0) { + if (elem._0 == ast.mut) { s = "mutable "; } else { s = ""; @@ -187,7 +190,7 @@ fn ty_to_str(@ty typ) -> str { case (ty_tup(?elems)) { auto f = tup_elem_to_str; - auto strs = _vec.map[tup(bool,@ty),str](f, elems); + auto strs = _vec.map[tup(mutability,@ty),str](f, elems); s = "tup(" + _str.connect(strs, ",") + ")"; } @@ -217,7 +220,7 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty { ret rec(mode=arg.mode, ty=ast_ty_to_ty(getter, arg.ty)); } - auto mut = false; + auto mut = ast.imm; auto sty; auto cname = none[str]; alt (ast_ty.node) { @@ -231,8 +234,8 @@ 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_vec(?t)) { sty = ty_vec(ast_ty_to_ty(getter, t)); } case (ast.ty_tup(?fields)) { - let vec[tup(bool,@ty)] flds = vec(); - for (tup(bool, @ast.ty) field in fields) { + let vec[tup(mutability,@ty)] flds = vec(); + for (tup(mutability, @ast.ty) field in fields) { flds += tup(field._0, ast_ty_to_ty(getter, field._1)); } sty = ty_tup(flds); @@ -258,7 +261,7 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty { } case (ast.ty_mutable(?t)) { - mut = true; + mut = ast.mut; auto t0 = ast_ty_to_ty(getter, t); sty = t0.struct; cname = t0.cname; @@ -534,7 +537,7 @@ fn type_is_signed(@ty t) -> bool { } fn plain_ty(&sty st) -> @ty { - ret @rec(struct=st, mut=false, cname=none[str]); + ret @rec(struct=st, mut=ast.imm, cname=none[str]); } fn ann_to_type(&ast.ann ann) -> @ty { @@ -708,9 +711,9 @@ fn unify(&fn_ctxt fcx, @ty expected, @ty actual) -> unify_result { alt (actual.struct) { case (ty_tup(?actual_elems)) { auto expected_len = - _vec.len[tup(bool,@ty)](expected_elems); + _vec.len[tup(mutability,@ty)](expected_elems); auto actual_len = - _vec.len[tup(bool,@ty)](actual_elems); + _vec.len[tup(mutability,@ty)](actual_elems); if (expected_len != actual_len) { auto err = terr_tuple_size(expected_len, actual_len); @@ -719,7 +722,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[tup(bool, @ty)] result_elems = vec(); + let vec[tup(mutability, @ty)] result_elems = vec(); auto i = 0u; while (i < expected_len) { auto expected_elem = expected_elems.(i); @@ -1254,10 +1257,10 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr { } case (ast.expr_tup(?args, _)) { - let vec[tup(bool, @ast.expr)] args_1 = vec(); - let vec[tup(bool, @ty)] args_t = vec(); + let vec[tup(mutability, @ast.expr)] args_1 = vec(); + let vec[tup(mutability, @ty)] args_t = vec(); - for (tup(bool, @ast.expr) arg in args) { + for (tup(mutability, @ast.expr) arg in args) { auto expr_1 = check_expr(fcx, arg._1); args_1 += tup(arg._0, expr_1); args_t += tup(arg._0, expr_ty(expr_1)); @@ -1275,7 +1278,7 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr { case (ty_tup(?args)) { let uint ix = field_num(fcx.ccx.sess, expr.span, field); - if (ix >= _vec.len[tup(bool,@ty)](args)) { + if (ix >= _vec.len[tup(mutability,@ty)](args)) { fcx.ccx.sess.span_err(expr.span, "bad index on tuple"); }