aboutsummaryrefslogtreecommitdiff
path: root/src/comp
diff options
context:
space:
mode:
authorLindsey Kuper <[email protected]>2011-03-18 12:32:54 -0700
committerLindsey Kuper <[email protected]>2011-03-18 12:32:54 -0700
commit6dee1ac161a22a4bc1e49c5dac3c7bbba1ff97f0 (patch)
treef423d576e977e7a258f09e50e5a51702525782e2 /src/comp
parentIgnore emacs autosave files. (diff)
parentrustc: Add a span_unimpl() for debugging (diff)
downloadrust-6dee1ac161a22a4bc1e49c5dac3c7bbba1ff97f0.tar.xz
rust-6dee1ac161a22a4bc1e49c5dac3c7bbba1ff97f0.zip
Merge branch 'master' of git://github.com/graydon/rust
Diffstat (limited to 'src/comp')
-rw-r--r--src/comp/back/x86.rs6
-rw-r--r--src/comp/driver/rustc.rs4
-rw-r--r--src/comp/driver/session.rs9
-rw-r--r--src/comp/front/ast.rs15
-rw-r--r--src/comp/front/eval.rs7
-rw-r--r--src/comp/front/extfmt.rs4
-rw-r--r--src/comp/front/lexer.rs14
-rw-r--r--src/comp/front/parser.rs124
-rw-r--r--src/comp/front/token.rs5
-rw-r--r--src/comp/middle/fold.rs98
-rw-r--r--src/comp/middle/trans.rs236
-rw-r--r--src/comp/middle/ty.rs265
-rw-r--r--src/comp/middle/typeck.rs180
-rw-r--r--src/comp/pretty/pp.rs14
-rw-r--r--src/comp/pretty/pprust.rs59
-rw-r--r--src/comp/util/common.rs9
16 files changed, 583 insertions, 466 deletions
diff --git a/src/comp/back/x86.rs b/src/comp/back/x86.rs
index 0ed79db4..345603bb 100644
--- a/src/comp/back/x86.rs
+++ b/src/comp/back/x86.rs
@@ -212,10 +212,10 @@ fn upcall_glue(int n_args) -> vec[str] {
+ store_esp_to_rust_sp_second_arg()
+ load_esp_from_runtime_sp_second_arg()
- + vec("subl $" + wstr(n_args + 1) + ", %esp # esp -= args",
+ + vec("subl $" + wstr(n_args) + ", %esp # esp -= args",
"andl $~0xf, %esp # align esp down")
- + _vec.init_fn[str](carg, (n_args + 1) as uint)
+ + _vec.init_fn[str](carg, (n_args) as uint)
+ vec("movl %edx, %edi # save task from edx to edi",
"call *%ecx # call *%ecx",
@@ -268,7 +268,7 @@ fn get_module_asm() -> str {
rust_yield_glue()))
+ _vec.init_fn[str](bind decl_upcall_glue(align, prefix, _),
- abi.n_upcall_glues as uint);
+ (abi.n_upcall_glues + 1) as uint);
ret _str.connect(glues, "\n\n");
}
diff --git a/src/comp/driver/rustc.rs b/src/comp/driver/rustc.rs
index 312166c4..f0ce9a95 100644
--- a/src/comp/driver/rustc.rs
+++ b/src/comp/driver/rustc.rs
@@ -203,8 +203,8 @@ impure fn main(vec[str] args) {
alt (output_file) {
case (none[str]) {
let vec[str] parts = _str.split(ifile, '.' as u8);
- parts = _vec.pop[str](parts);
- parts += ".bc";
+ _vec.pop[str](parts);
+ parts += vec(".bc");
auto ofile = _str.concat(parts);
compile_input(sess, env, ifile, ofile, shared,
library_search_paths);
diff --git a/src/comp/driver/session.rs b/src/comp/driver/session.rs
index e23dbeed..605774fe 100644
--- a/src/comp/driver/session.rs
+++ b/src/comp/driver/session.rs
@@ -45,6 +45,15 @@ obj session(cfg targ) {
fail;
}
+ fn span_unimpl(span sp, str msg) {
+ log #fmt("%s:%u:%u:%u:%u: error: unimplemented %s",
+ sp.filename,
+ sp.lo.line, sp.lo.col,
+ sp.hi.line, sp.hi.col,
+ msg);
+ fail;
+ }
+
fn unimpl(str msg) {
log #fmt("error: unimplemented %s", msg);
fail;
diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs
index 1970f788..ec93db55 100644
--- a/src/comp/front/ast.rs
+++ b/src/comp/front/ast.rs
@@ -91,6 +91,7 @@ tag pat_ {
tag mutability {
mut;
imm;
+ maybe_mut;
}
tag opacity {
@@ -168,7 +169,6 @@ tag unop {
bitnot;
not;
neg;
- _mutable;
}
fn unop_to_str(unop op) -> str {
@@ -178,7 +178,6 @@ fn unop_to_str(unop op) -> str {
case (bitnot) {ret "~";}
case (not) {ret "!";}
case (neg) {ret "-";}
- case (_mutable) {ret "mutable";}
}
}
@@ -215,7 +214,7 @@ type field = rec(mutability mut, ident ident, @expr expr);
type expr = spanned[expr_];
tag expr_ {
- expr_vec(vec[@expr], ann);
+ expr_vec(vec[@expr], mutability, ann);
expr_tup(vec[elt], ann);
expr_rec(vec[field], option.t[@expr], ann);
expr_call(@expr, vec[@expr], ann);
@@ -263,7 +262,8 @@ tag lit_ {
// NB: If you change this, you'll probably want to change the corresponding
// type structure in middle/ty.rs as well.
-type ty_field = rec(ident ident, @ty ty);
+type mt = rec(@ty ty, mutability mut);
+type ty_field = rec(ident ident, mt mt);
type ty_arg = rec(mode mode, @ty ty);
// TODO: effect
type ty_method = rec(proto proto, ident ident,
@@ -277,16 +277,15 @@ tag ty_ {
ty_machine(util.common.ty_mach);
ty_char;
ty_str;
- ty_box(@ty);
- ty_vec(@ty);
+ ty_box(mt);
+ ty_vec(mt);
ty_port(@ty);
ty_chan(@ty);
- ty_tup(vec[@ty]);
+ ty_tup(vec[mt]);
ty_rec(vec[ty_field]);
ty_fn(proto, vec[ty_arg], @ty); // TODO: effect
ty_obj(vec[ty_method]);
ty_path(path, option.t[def]);
- ty_mutable(@ty);
ty_type;
ty_constr(@ty, vec[@constr]);
}
diff --git a/src/comp/front/eval.rs b/src/comp/front/eval.rs
index ac249848..4cf3765f 100644
--- a/src/comp/front/eval.rs
+++ b/src/comp/front/eval.rs
@@ -13,7 +13,6 @@ import front.parser.new_parser;
import front.parser.parse_mod_items;
import util.common;
import util.common.filename;
-import util.common.append;
import util.common.span;
import util.common.new_str_hash;
@@ -394,7 +393,7 @@ impure fn eval_crate_directive(parser p,
auto im = ast.item_mod(id, m0, next_id);
auto i = @spanned(cdir.span, cdir.span, im);
ast.index_item(index, i);
- append[@ast.item](items, i);
+ _vec.push[@ast.item](items, i);
}
case (ast.cdir_dir_mod(?id, ?dir_opt, ?cdirs)) {
@@ -412,11 +411,11 @@ impure fn eval_crate_directive(parser p,
auto im = ast.item_mod(id, m0, p.next_def_id());
auto i = @spanned(cdir.span, cdir.span, im);
ast.index_item(index, i);
- append[@ast.item](items, i);
+ _vec.push[@ast.item](items, i);
}
case (ast.cdir_view_item(?vi)) {
- append[@ast.view_item](view_items, vi);
+ _vec.push[@ast.view_item](view_items, vi);
ast.index_view_item(index, vi);
}
diff --git a/src/comp/front/extfmt.rs b/src/comp/front/extfmt.rs
index 255614d0..0a32a851 100644
--- a/src/comp/front/extfmt.rs
+++ b/src/comp/front/extfmt.rs
@@ -113,7 +113,7 @@ fn parse_fmt_string(str s) -> vec[piece] {
fn flush_buf(str buf, &vec[piece] pieces) -> str {
if (_str.byte_len(buf) > 0u) {
auto piece = piece_string(buf);
- pieces += piece;
+ pieces += vec(piece);
}
ret "";
}
@@ -133,7 +133,7 @@ fn parse_fmt_string(str s) -> vec[piece] {
} else {
buf = flush_buf(buf, pieces);
auto res = parse_conversion(s, i, lim);
- pieces += res._0;
+ pieces += vec(res._0);
i = res._1;
}
} else {
diff --git a/src/comp/front/lexer.rs b/src/comp/front/lexer.rs
index 95fd32c7..403558e2 100644
--- a/src/comp/front/lexer.rs
+++ b/src/comp/front/lexer.rs
@@ -420,7 +420,7 @@ impure fn next_token(reader rdr) -> token.token {
if (is_alpha(c) || c == '_') {
while (is_alnum(c) || c == '_') {
- accum_str += (c as u8);
+ _str.push_byte(accum_str, (c as u8));
rdr.bump();
c = rdr.curr();
}
@@ -580,23 +580,23 @@ impure fn next_token(reader rdr) -> token.token {
alt (rdr.next()) {
case ('n') {
rdr.bump();
- accum_str += '\n' as u8;
+ _str.push_byte(accum_str, '\n' as u8);
}
case ('r') {
rdr.bump();
- accum_str += '\r' as u8;
+ _str.push_byte(accum_str, '\r' as u8);
}
case ('t') {
rdr.bump();
- accum_str += '\t' as u8;
+ _str.push_byte(accum_str, '\t' as u8);
}
case ('\\') {
rdr.bump();
- accum_str += '\\' as u8;
+ _str.push_byte(accum_str, '\\' as u8);
}
case ('"') {
rdr.bump();
- accum_str += '"' as u8;
+ _str.push_byte(accum_str, '"' as u8);
}
// FIXME: unicode numeric escapes.
case (?c2) {
@@ -607,7 +607,7 @@ impure fn next_token(reader rdr) -> token.token {
}
}
case (_) {
- accum_str += rdr.curr() as u8;
+ _str.push_byte(accum_str, rdr.curr() as u8);
}
}
rdr.bump();
diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs
index a5c79926..028b8a31 100644
--- a/src/comp/front/parser.rs
+++ b/src/comp/front/parser.rs
@@ -9,7 +9,6 @@ import std.map.hashmap;
import driver.session;
import util.common;
import util.common.filename;
-import util.common.append;
import util.common.span;
import util.common.new_str_hash;
@@ -190,6 +189,11 @@ impure fn parse_ty_fn(ast.proto proto, parser p,
if (p.peek() == token.BINOP(token.AND)) {
p.bump();
mode = ast.alias;
+
+ if (p.peek() == token.MUTABLE) {
+ p.bump();
+ // TODO: handle mutable alias args
+ }
} else {
mode = ast.val;
}
@@ -263,10 +267,16 @@ impure fn parse_ty_obj(parser p, &mutable ast.span hi) -> ast.ty_ {
ret ast.ty_obj(meths.node);
}
+impure fn parse_mt(parser p) -> ast.mt {
+ auto mut = parse_mutability(p);
+ auto t = parse_ty(p);
+ ret rec(ty=t, mut=mut);
+}
+
impure fn parse_ty_field(parser p) -> ast.ty_field {
- auto ty = parse_ty(p);
+ auto mt = parse_mt(p);
auto id = parse_ident(p);
- ret rec(ident=id, ty=ty);
+ ret rec(ident=id, mt=mt);
}
impure fn parse_constr_arg(parser p) -> @ast.constr_arg {
@@ -303,7 +313,7 @@ impure fn parse_constrs(parser p) -> common.spanned[vec[@ast.constr]] {
case (token.IDENT(_)) {
auto constr = parse_ty_constr(p);
hi = constr.span;
- append[@ast.constr](constrs, constr);
+ _vec.push[@ast.constr](constrs, constr);
if (p.peek() == token.COMMA) {
p.bump();
more = false;
@@ -361,25 +371,25 @@ impure fn parse_ty(parser p) -> @ast.ty {
case (token.AT) {
p.bump();
- auto t0 = parse_ty(p);
- hi = t0.span;
- t = ast.ty_box(t0);
+ auto mt = parse_mt(p);
+ hi = mt.ty.span;
+ t = ast.ty_box(mt);
}
case (token.VEC) {
p.bump();
expect(p, token.LBRACKET);
- t = ast.ty_vec(parse_ty(p));
+ t = ast.ty_vec(parse_mt(p));
hi = p.get_span();
expect(p, token.RBRACKET);
}
case (token.TUP) {
p.bump();
- auto f = parse_ty; // FIXME: trans_const_lval bug
- auto elems = parse_seq[@ast.ty] (token.LPAREN,
- token.RPAREN,
- some(token.COMMA), f, p);
+ auto f = parse_mt; // FIXME: trans_const_lval bug
+ auto elems = parse_seq[ast.mt] (token.LPAREN,
+ token.RPAREN,
+ some(token.COMMA), f, p);
hi = elems.span;
t = ast.ty_tup(elems.node);
}
@@ -396,13 +406,6 @@ impure fn parse_ty(parser p) -> @ast.ty {
t = ast.ty_rec(elems.node);
}
- case (token.MUTABLE) {
- p.bump();
- auto t0 = parse_ty(p);
- hi = t0.span;
- t = ast.ty_mutable(t0);
- }
-
case (token.FN) {
auto flo = p.get_span();
p.bump();
@@ -464,20 +467,22 @@ impure fn parse_arg(parser p) -> ast.arg {
if (p.peek() == token.BINOP(token.AND)) {
m = ast.alias;
p.bump();
+
+ if (p.peek() == token.MUTABLE) {
+ // TODO: handle mutable alias args
+ p.bump();
+ }
}
let @ast.ty t = parse_ty(p);
let ast.ident i = parse_ident(p);
ret rec(mode=m, ty=t, ident=i, id=p.next_def_id());
}
-impure fn parse_seq[T](token.token bra,
- token.token ket,
- option.t[token.token] sep,
- (impure fn(parser) -> T) f,
- parser p) -> util.common.spanned[vec[T]] {
+impure fn parse_seq_to_end[T](token.token ket,
+ option.t[token.token] sep,
+ (impure fn(parser) -> T) f,
+ parser p) -> vec[T] {
let bool first = true;
- auto lo = p.get_span();
- expect(p, bra);
let vec[T] v = vec();
while (p.peek() != ket) {
alt(sep) {
@@ -495,9 +500,20 @@ impure fn parse_seq[T](token.token bra,
let T t = f(p);
v += vec(t);
}
- auto hi = p.get_span();
expect(p, ket);
- ret spanned(lo, hi, v);
+ ret v;
+}
+
+impure fn parse_seq[T](token.token bra,
+ token.token ket,
+ option.t[token.token] sep,
+ (impure fn(parser) -> T) f,
+ parser p) -> util.common.spanned[vec[T]] {
+ auto lo = p.get_span();
+ expect(p, bra);
+ auto result = parse_seq_to_end[T](ket, sep, f, p);
+ auto hi = p.get_span();
+ ret spanned(lo, hi, result);
}
impure fn parse_lit(parser p) -> ast.lit {
@@ -573,7 +589,7 @@ impure fn parse_path(parser p, greed g) -> ast.path {
alt (p.peek()) {
case (token.IDENT(?i)) {
hi = p.get_span();
- ids += i;
+ ids += vec(i);
p.bump();
if (p.peek() == token.DOT) {
if (g == GREEDY) {
@@ -596,16 +612,20 @@ impure fn parse_path(parser p, greed g) -> ast.path {
ret spanned(lo, tys.span, rec(idents=ids, types=tys.node));
}
-impure fn parse_mutabliity(parser p) -> ast.mutability {
+impure fn parse_mutability(parser p) -> ast.mutability {
if (p.peek() == token.MUTABLE) {
p.bump();
+ if (p.peek() == token.QUES) {
+ p.bump();
+ ret ast.maybe_mut;
+ }
ret ast.mut;
}
ret ast.imm;
}
impure fn parse_field(parser p) -> ast.field {
- auto m = parse_mutabliity(p);
+ auto m = parse_mutability(p);
auto i = parse_ident(p);
expect(p, token.EQ);
auto e = parse_expr(p);
@@ -651,7 +671,7 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
case (token.TUP) {
p.bump();
impure fn parse_elt(parser p) -> ast.elt {
- auto m = parse_mutabliity(p);
+ auto m = parse_mutability(p);
auto e = parse_expr(p);
ret rec(mut=m, expr=e);
}
@@ -668,12 +688,15 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
case (token.VEC) {
p.bump();
auto pf = parse_expr;
- auto es = parse_seq[@ast.expr](token.LPAREN,
- token.RPAREN,
- some(token.COMMA),
- pf, p);
- hi = es.span;
- ex = ast.expr_vec(es.node, ast.ann_none);
+
+ expect(p, token.LPAREN);
+ auto mut = parse_mutability(p);
+
+ auto es = parse_seq_to_end[@ast.expr](token.RPAREN,
+ some(token.COMMA),
+ pf, p);
+ hi = p.get_span();
+ ex = ast.expr_vec(es, mut, ast.ann_none);
}
case (token.REC) {
@@ -699,7 +722,7 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr {
}
case (token.COMMA) {
p.bump();
- fields += parse_field(p);
+ fields += vec(parse_field(p));
}
case (?t) {
unexpected(p, t);
@@ -877,7 +900,7 @@ impure fn extend_expr_by_ident(parser p, span lo, span hi,
case (ast.expr_path(?pth, ?def, ?ann)) {
if (_vec.len[@ast.ty](pth.node.types) == 0u) {
auto idents_ = pth.node.idents;
- idents_ += i;
+ idents_ += vec(i);
auto tys = parse_ty_args(p, hi);
auto pth_ = spanned(pth.span, tys.span,
rec(idents=idents_,
@@ -1005,13 +1028,6 @@ impure fn parse_prefix_expr(parser p) -> @ast.expr {
ex = ast.expr_unary(ast.box, e, ast.ann_none);
}
- case (token.MUTABLE) {
- p.bump();
- auto e = parse_prefix_expr(p);
- hi = e.span;
- ex = ast.expr_unary(ast._mutable, e, ast.ann_none);
- }
-
case (_) {
ret parse_dot_or_call_expr(p);
}
@@ -1559,7 +1575,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool {
}
case (ast.stmt_expr(?e)) {
alt (e.node) {
- case (ast.expr_vec(_,_)) { ret true; }
+ case (ast.expr_vec(_,_,_)) { ret true; }
case (ast.expr_tup(_,_)) { ret true; }
case (ast.expr_rec(_,_,_)) { ret true; }
case (ast.expr_call(_,_,_)) { ret true; }
@@ -1723,6 +1739,7 @@ impure fn parse_item_fn_or_iter(parser p, ast.effect eff) -> @ast.item {
impure fn parse_obj_field(parser p) -> ast.obj_field {
+ auto mut = parse_mutability(p); // TODO: store this, use it in typeck
auto ty = parse_ty(p);
auto ident = parse_ident(p);
ret rec(ty=ty, ident=ident, id=p.next_def_id(), ann=ast.ann_none);
@@ -1763,8 +1780,8 @@ impure fn parse_item_obj(parser p, ast.layer lyr) -> @ast.item {
dtor = some[ast.block](parse_block(p));
}
case (_) {
- append[@ast.method](meths,
- parse_method(p));
+ _vec.push[@ast.method](meths,
+ parse_method(p));
}
}
}
@@ -2161,12 +2178,11 @@ impure fn parse_rest_import_name(parser p, ast.ident first,
-> @ast.view_item {
auto lo = p.get_span();
auto hi = lo;
- let vec[ast.ident] identifiers = vec();
- identifiers += first;
+ let vec[ast.ident] identifiers = vec(first);
while (p.peek() != token.SEMI) {
expect(p, token.DOT);
auto i = parse_ident(p);
- identifiers += i;
+ identifiers += vec(i);
}
p.bump();
auto defined_id;
@@ -2402,7 +2418,7 @@ impure fn parse_crate_directives(parser p, token.token term)
while (p.peek() != term) {
auto cdir = @parse_crate_directive(p);
- append[@ast.crate_directive](cdirs, cdir);
+ _vec.push[@ast.crate_directive](cdirs, cdir);
}
ret cdirs;
diff --git a/src/comp/front/token.rs b/src/comp/front/token.rs
index 8c594054..62c6406a 100644
--- a/src/comp/front/token.rs
+++ b/src/comp/front/token.rs
@@ -3,6 +3,7 @@ import util.common.ty_mach_to_str;
import util.common.new_str_hash;
import std._int;
import std._uint;
+import std._str;
tag binop {
PLUS;
@@ -302,8 +303,8 @@ fn to_str(token t) -> str {
case (LIT_CHAR(?c)) {
// FIXME: escape and encode.
auto tmp = "'";
- tmp += c as u8;
- tmp += '\'' as u8;
+ _str.push_byte(tmp, c as u8);
+ _str.push_byte(tmp, '\'' as u8);
ret tmp;
}
diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs
index 73b2cab3..703c7ea4 100644
--- a/src/comp/middle/fold.rs
+++ b/src/comp/middle/fold.rs
@@ -7,7 +7,6 @@ import util.common.new_str_hash;
import util.common.spanned;
import util.common.span;
import util.common.ty_mach;
-import util.common.append;
import front.ast;
import front.ast.fn_decl;
@@ -29,6 +28,7 @@ import front.ast.arm;
import front.ast.def;
import front.ast.def_id;
import front.ast.ann;
+import front.ast.mt;
import std._uint;
import std._vec;
@@ -47,10 +47,10 @@ type ast_fold[ENV] =
(fn(&ENV e, &span sp, ty_mach tm) -> @ty) fold_ty_machine,
(fn(&ENV e, &span sp) -> @ty) fold_ty_char,
(fn(&ENV e, &span sp) -> @ty) fold_ty_str,
- (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, &mt tm) -> @ty) fold_ty_box,
+ (fn(&ENV e, &span sp, &mt tm) -> @ty) fold_ty_vec,
- (fn(&ENV e, &span sp, vec[@ty] elts) -> @ty) fold_ty_tup,
+ (fn(&ENV e, &span sp, vec[mt] elts) -> @ty) fold_ty_tup,
(fn(&ENV e, &span sp,
vec[ast.ty_field] elts) -> @ty) fold_ty_rec,
@@ -66,13 +66,13 @@ type ast_fold[ENV] =
(fn(&ENV e, &span sp, ast.path p,
&option.t[def] d) -> @ty) fold_ty_path,
- (fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_mutable,
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_chan,
(fn(&ENV e, &span sp, @ty t) -> @ty) fold_ty_port,
// Expr folds.
(fn(&ENV e, &span sp,
- vec[@expr] es, ann a) -> @expr) fold_expr_vec,
+ vec[@expr] es, ast.mutability mut,
+ ann a) -> @expr) fold_expr_vec,
(fn(&ENV e, &span sp,
vec[ast.elt] es, ann a) -> @expr) fold_expr_tup,
@@ -318,7 +318,7 @@ type ast_fold[ENV] =
fn fold_path[ENV](&ENV env, ast_fold[ENV] fld, &path p) -> path {
let vec[@ast.ty] tys_ = vec();
for (@ast.ty t in p.node.types) {
- append[@ast.ty](tys_, fold_ty(env, fld, t));
+ _vec.push[@ast.ty](tys_, fold_ty(env, fld, t));
}
let ast.path_ p_ = rec(idents=p.node.idents, types=tys_);
ret fld.fold_path(env, p.span, p_);
@@ -344,20 +344,21 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
case (ast.ty_char) { ret fld.fold_ty_char(env_, t.span); }
case (ast.ty_str) { ret fld.fold_ty_str(env_, t.span); }
- case (ast.ty_box(?ty)) {
- auto ty_ = fold_ty(env, fld, ty);
- ret fld.fold_ty_box(env_, t.span, ty_);
+ case (ast.ty_box(?tm)) {
+ auto ty_ = fold_ty(env, fld, tm.ty);
+ ret fld.fold_ty_box(env_, t.span, rec(ty=ty_, mut=tm.mut));
}
- case (ast.ty_vec(?ty)) {
- auto ty_ = fold_ty(env, fld, ty);
- ret fld.fold_ty_vec(env_, t.span, ty_);
+ case (ast.ty_vec(?tm)) {
+ auto ty_ = fold_ty(env, fld, tm.ty);
+ ret fld.fold_ty_vec(env_, t.span, rec(ty=ty_, mut=tm.mut));
}
case (ast.ty_tup(?elts)) {
- let vec[@ty] elts_ = vec();
- for (@ty elt in elts) {
- append[@ty](elts_,fold_ty(env, fld, elt));
+ let vec[mt] elts_ = vec();
+ for (mt elt in elts) {
+ auto ty_ = fold_ty(env, fld, elt.ty);
+ _vec.push[mt](elts_, rec(ty=ty_, mut=elt.mut));
}
ret fld.fold_ty_tup(env_, t.span, elts_);
}
@@ -365,8 +366,9 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
case (ast.ty_rec(?flds)) {
let vec[ast.ty_field] flds_ = vec();
for (ast.ty_field f in flds) {
- append[ast.ty_field]
- (flds_, rec(ty=fold_ty(env, fld, f.ty) with f));
+ auto ty_ = fold_ty(env, fld, f.mt.ty);
+ _vec.push[ast.ty_field]
+ (flds_, rec(mt=rec(ty=ty_, mut=f.mt.mut) with f));
}
ret fld.fold_ty_rec(env_, t.span, flds_);
}
@@ -378,7 +380,7 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
m.inputs, m.output);
alt (tfn.node) {
case (ast.ty_fn(?p, ?ins, ?out)) {
- append[ast.ty_method]
+ _vec.push[ast.ty_method]
(meths_, rec(proto=p, inputs=ins, output=out
with m));
}
@@ -392,11 +394,6 @@ fn fold_ty[ENV](&ENV env, ast_fold[ENV] fld, @ty t) -> @ty {
ret fld.fold_ty_path(env_, t.span, pth_, ref_opt);
}
- case (ast.ty_mutable(?ty)) {
- auto ty_ = fold_ty(env, fld, ty);
- ret fld.fold_ty_mutable(env_, t.span, ty_);
- }
-
case (ast.ty_fn(?proto, ?inputs, ?output)) {
ret fold_ty_fn(env_, fld, t.span, proto, inputs, output);
}
@@ -494,7 +491,7 @@ fn fold_pat[ENV](&ENV env, ast_fold[ENV] fld, @ast.pat p) -> @ast.pat {
fn fold_exprs[ENV](&ENV env, ast_fold[ENV] fld, vec[@expr] es) -> vec[@expr] {
let vec[@expr] exprs = vec();
for (@expr e in es) {
- append[@expr](exprs, fold_expr(env, fld, e));
+ _vec.push[@expr](exprs, fold_expr(env, fld, e));
}
ret exprs;
}
@@ -517,15 +514,15 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
}
alt (e.node) {
- case (ast.expr_vec(?es, ?t)) {
+ case (ast.expr_vec(?es, ?mut, ?t)) {
auto ees = fold_exprs(env_, fld, es);
- ret fld.fold_expr_vec(env_, e.span, ees, t);
+ ret fld.fold_expr_vec(env_, e.span, ees, mut, t);
}
case (ast.expr_tup(?es, ?t)) {
let vec[ast.elt] elts = vec();
for (ast.elt e in es) {
- elts += fold_tup_elt[ENV](env, fld, e);
+ elts += vec(fold_tup_elt[ENV](env, fld, e));
}
ret fld.fold_expr_tup(env_, e.span, elts, t);
}
@@ -534,7 +531,7 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
let vec[ast.field] fields = vec();
let option.t[@expr] b = none[@expr];
for (ast.field f in fs) {
- fields += fold_rec_field(env, fld, f);
+ fields += vec(fold_rec_field(env, fld, f));
}
alt (base) {
case (none[@ast.expr]) { }
@@ -557,7 +554,7 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr {
for (option.t[@ast.expr] t_opt in args_opt) {
alt (t_opt) {
case (none[@ast.expr]) {
- aargs_opt += none[@ast.expr];
+ aargs_opt += vec(none[@ast.expr]);
}
case (some[@ast.expr](?e)) {
aargs_opt += vec(some(fold_expr(env_, fld, e)));
@@ -779,7 +776,7 @@ fn fold_block[ENV](&ENV env, ast_fold[ENV] fld, &block blk) -> block {
let vec[@ast.stmt] stmts = vec();
for (@ast.stmt s in blk.node.stmts) {
auto new_stmt = fold_stmt[ENV](env_, fld, s);
- append[@ast.stmt](stmts, new_stmt);
+ _vec.push[@ast.stmt](stmts, new_stmt);
ast.index_stmt(index, new_stmt);
}
@@ -812,7 +809,7 @@ fn fold_fn_decl[ENV](&ENV env, ast_fold[ENV] fld,
&ast.fn_decl decl) -> ast.fn_decl {
let vec[ast.arg] inputs = vec();
for (ast.arg a in decl.inputs) {
- inputs += fold_arg(env, fld, a);
+ inputs += vec(fold_arg(env, fld, a));
}
auto output = fold_ty[ENV](env, fld, decl.output);
ret fld.fold_fn_decl(env, decl.effect, inputs, output);
@@ -846,7 +843,7 @@ fn fold_obj[ENV](&ENV env, ast_fold[ENV] fld, &ast._obj ob) -> ast._obj {
let vec[ast.obj_field] fields = vec();
let vec[@ast.method] meths = vec();
for (ast.obj_field f in ob.fields) {
- fields += fold_obj_field(env, fld, f);
+ fields += vec(fold_obj_field(env, fld, f));
}
let option.t[block] dtor = none[block];
alt (ob.dtor) {
@@ -867,7 +864,7 @@ fn fold_obj[ENV](&ENV env, ast_fold[ENV] fld, &ast._obj ob) -> ast._obj {
m.node.ann),
span=m.span);
let ENV _env = fld.update_env_for_item(env, i);
- append[@ast.method](meths, fold_method(_env, fld, m));
+ _vec.push[@ast.method](meths, fold_method(_env, fld, m));
}
ret fld.fold_obj(env, fields, meths, dtor);
}
@@ -944,8 +941,8 @@ fn fold_item[ENV](&ENV env, ast_fold[ENV] fld, @item i) -> @item {
auto new_ty = fold_ty[ENV](env_, fld, va.ty);
new_args += vec(rec(ty=new_ty, id=va.id));
}
- new_variants += rec(name=v.name, args=new_args, id=v.id,
- ann=v.ann);
+ new_variants += vec(rec(name=v.name, args=new_args, id=v.id,
+ ann=v.ann));
}
ret fld.fold_item_tag(env_, i.span, ident, new_variants,
ty_params, id);
@@ -969,13 +966,13 @@ fn fold_mod[ENV](&ENV e, ast_fold[ENV] fld, &ast._mod m) -> ast._mod {
for (@view_item vi in m.view_items) {
auto new_vi = fold_view_item[ENV](e, fld, vi);
- append[@view_item](view_items, new_vi);
+ _vec.push[@view_item](view_items, new_vi);
ast.index_view_item(index, new_vi);
}
for (@item i in m.items) {
auto new_item = fold_item[ENV](e, fld, i);
- append[@item](items, new_item);
+ _vec.push[@item](items, new_item);
ast.index_item(index, new_item);
}
@@ -1009,12 +1006,12 @@ fn fold_native_mod[ENV](&ENV e, ast_fold[ENV] fld,
for (@view_item vi in m.view_items) {
auto new_vi = fold_view_item[ENV](e, fld, vi);
- append[@view_item](view_items, new_vi);
+ _vec.push[@view_item](view_items, new_vi);
}
for (@native_item i in m.items) {
auto new_item = fold_native_item[ENV](e, fld, i);
- append[@native_item](items, new_item);
+ _vec.push[@native_item](items, new_item);
ast.index_native_item(index, new_item);
}
@@ -1078,16 +1075,16 @@ fn identity_fold_ty_str[ENV](&ENV env, &span sp) -> @ty {
ret @respan(sp, ast.ty_str);
}
-fn identity_fold_ty_box[ENV](&ENV env, &span sp, @ty t) -> @ty {
- ret @respan(sp, ast.ty_box(t));
+fn identity_fold_ty_box[ENV](&ENV env, &span sp, &mt tm) -> @ty {
+ ret @respan(sp, ast.ty_box(tm));
}
-fn identity_fold_ty_vec[ENV](&ENV env, &span sp, @ty t) -> @ty {
- ret @respan(sp, ast.ty_vec(t));
+fn identity_fold_ty_vec[ENV](&ENV env, &span sp, &mt tm) -> @ty {
+ ret @respan(sp, ast.ty_vec(tm));
}
fn identity_fold_ty_tup[ENV](&ENV env, &span sp,
- vec[@ty] elts) -> @ty {
+ vec[mt] elts) -> @ty {
ret @respan(sp, ast.ty_tup(elts));
}
@@ -1113,10 +1110,6 @@ fn identity_fold_ty_path[ENV](&ENV env, &span sp, ast.path p,
ret @respan(sp, ast.ty_path(p, d));
}
-fn identity_fold_ty_mutable[ENV](&ENV env, &span sp, @ty t) -> @ty {
- ret @respan(sp, ast.ty_mutable(t));
-}
-
fn identity_fold_ty_chan[ENV](&ENV env, &span sp, @ty t) -> @ty {
ret @respan(sp, ast.ty_chan(t));
}
@@ -1128,8 +1121,8 @@ fn identity_fold_ty_port[ENV](&ENV env, &span sp, @ty t) -> @ty {
// Expr identities.
fn identity_fold_expr_vec[ENV](&ENV env, &span sp, vec[@expr] es,
- ann a) -> @expr {
- ret @respan(sp, ast.expr_vec(es, a));
+ ast.mutability mut, ann a) -> @expr {
+ ret @respan(sp, ast.expr_vec(es, mut, a));
}
fn identity_fold_expr_tup[ENV](&ENV env, &span sp,
@@ -1529,11 +1522,10 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] {
fold_ty_obj = bind identity_fold_ty_obj[ENV](_,_,_),
fold_ty_fn = bind identity_fold_ty_fn[ENV](_,_,_,_,_),
fold_ty_path = bind identity_fold_ty_path[ENV](_,_,_,_),
- fold_ty_mutable = bind identity_fold_ty_mutable[ENV](_,_,_),
fold_ty_chan = bind identity_fold_ty_chan[ENV](_,_,_),
fold_ty_port = bind identity_fold_ty_port[ENV](_,_,_),
- fold_expr_vec = bind identity_fold_expr_vec[ENV](_,_,_,_),
+ fold_expr_vec = bind identity_fold_expr_vec[ENV](_,_,_,_,_),
fold_expr_tup = bind identity_fold_expr_tup[ENV](_,_,_,_),
fold_expr_rec = bind identity_fold_expr_rec[ENV](_,_,_,_,_),
fold_expr_call = bind identity_fold_expr_call[ENV](_,_,_,_,_),
diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs
index d0569afc..2ef619cb 100644
--- a/src/comp/middle/trans.rs
+++ b/src/comp/middle/trans.rs
@@ -20,7 +20,6 @@ import middle.ty.pat_ty;
import middle.ty.plain_ty;
import util.common;
-import util.common.append;
import util.common.istr;
import util.common.new_def_hash;
import util.common.new_str_hash;
@@ -476,7 +475,7 @@ fn type_of_explicit_args(@crate_ctxt cx,
for (ty.arg arg in inputs) {
if (ty.type_has_dynamic_size(arg.ty)) {
check (arg.mode == ast.alias);
- atys += T_typaram_ptr(cx.tn);
+ atys += vec(T_typaram_ptr(cx.tn));
} else {
let TypeRef t;
alt (arg.mode) {
@@ -487,7 +486,7 @@ fn type_of_explicit_args(@crate_ctxt cx,
t = type_of_inner(cx, arg.ty, false);
}
}
- atys += t;
+ atys += vec(t);
}
}
ret atys;
@@ -510,22 +509,22 @@ fn type_of_fn_full(@crate_ctxt cx,
// Arg 0: Output pointer.
if (ty.type_has_dynamic_size(output)) {
- atys += T_typaram_ptr(cx.tn);
+ atys += vec(T_typaram_ptr(cx.tn));
} else {
- atys += T_ptr(type_of_inner(cx, output, false));
+ atys += vec(T_ptr(type_of_inner(cx, output, false)));
}
// Arg 1: Task pointer.
- atys += T_taskptr(cx.tn);
+ atys += vec(T_taskptr(cx.tn));
// Arg 2: Env (closure-bindings / self-obj)
alt (obj_self) {
case (some[TypeRef](?t)) {
check (t as int != 0);
- atys += t;
+ atys += vec(t);
}
case (_) {
- atys += T_opaque_closure_ptr(cx.tn);
+ atys += vec(T_opaque_closure_ptr(cx.tn));
}
}
@@ -533,7 +532,7 @@ fn type_of_fn_full(@crate_ctxt cx,
if (obj_self == none[TypeRef]) {
auto i = 0u;
while (i < ty_param_count) {
- atys += T_ptr(T_tydesc(cx.tn));
+ atys += vec(T_ptr(T_tydesc(cx.tn)));
i += 1u;
}
}
@@ -542,10 +541,11 @@ fn type_of_fn_full(@crate_ctxt cx,
// If it's an iter, the 'output' type of the iter is actually the
// *input* type of the function we're given as our iter-block
// argument.
- atys += T_fn_pair(cx.tn,
+ atys +=
+ vec(T_fn_pair(cx.tn,
type_of_fn_full(cx, ast.proto_fn, none[TypeRef],
vec(rec(mode=ast.val, ty=output)),
- plain_ty(ty.ty_nil), 0u));
+ plain_ty(ty.ty_nil), 0u)));
}
// ... then explicit args.
@@ -568,12 +568,12 @@ fn type_of_native_fn(@crate_ctxt cx, ast.native_abi abi,
@ty.t output) -> TypeRef {
let vec[TypeRef] atys = vec();
if (abi == ast.native_abi_rust) {
- atys += T_taskptr(cx.tn);
+ atys += vec(T_taskptr(cx.tn));
auto t = ty.ty_native_fn(abi, inputs, output);
auto ty_param_count = ty.count_ty_params(plain_ty(t));
auto i = 0u;
while (i < ty_param_count) {
- atys += T_ptr(T_tydesc(cx.tn));
+ atys += vec(T_ptr(T_tydesc(cx.tn)));
i += 1u;
}
}
@@ -614,23 +614,23 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
llty = T_tag(cx.tn, size);
}
}
- case (ty.ty_box(?t)) {
- llty = T_ptr(T_box(type_of_inner(cx, t, true)));
+ case (ty.ty_box(?mt)) {
+ llty = T_ptr(T_box(type_of_inner(cx, mt.ty, true)));
}
- case (ty.ty_vec(?t)) {
- llty = T_ptr(T_vec(type_of_inner(cx, t, true)));
+ case (ty.ty_vec(?mt)) {
+ llty = T_ptr(T_vec(type_of_inner(cx, mt.ty, true)));
}
case (ty.ty_tup(?elts)) {
let vec[TypeRef] tys = vec();
- for (@ty.t elt in elts) {
- tys += type_of_inner(cx, elt, boxed);
+ for (ty.mt elt in elts) {
+ tys += vec(type_of_inner(cx, elt.ty, boxed));
}
llty = T_struct(tys);
}
case (ty.ty_rec(?fields)) {
let vec[TypeRef] tys = vec();
for (ty.field f in fields) {
- tys += type_of_inner(cx, f.ty, boxed);
+ tys += vec(type_of_inner(cx, f.mt.ty, boxed));
}
llty = T_struct(tys);
}
@@ -650,7 +650,7 @@ fn type_of_inner(@crate_ctxt cx, @ty.t t, bool boxed) -> TypeRef {
type_of_fn_full(cx, m.proto,
some[TypeRef](self_ty),
m.inputs, m.output, 0u);
- mtys += T_ptr(mty);
+ mtys += vec(T_ptr(mty));
}
let TypeRef vtbl = T_struct(mtys);
let TypeRef pair = T_struct(vec(T_ptr(vtbl),
@@ -832,8 +832,7 @@ fn decl_upcall_glue(ModuleRef llmod, type_names tn, uint _n) -> ValueRef {
let int n = _n as int;
let str s = abi.upcall_glue_name(n);
let vec[TypeRef] args =
- vec(T_int(), // callee
- T_int()) // taskptr
+ vec(T_int()) // callee
+ _vec.init_elt[TypeRef](T_int(), n as uint);
ret decl_fastcall_fn(llmod, s, T_fn(args, T_int()));
@@ -864,16 +863,16 @@ fn trans_upcall2(builder b, @glue_fns glues, ValueRef lltaskptr,
&hashmap[str, ValueRef] upcalls,
type_names tn, ModuleRef llmod, str name,
vec[ValueRef] args) -> ValueRef {
- let int n = _vec.len[ValueRef](args) as int;
+ let int n = (_vec.len[ValueRef](args) as int) + 1;
let ValueRef llupcall = get_upcall(upcalls, tn, llmod, name, n);
llupcall = llvm.LLVMConstPointerCast(llupcall, T_int());
let ValueRef llglue = glues.upcall_glues.(n);
let vec[ValueRef] call_args = vec(llupcall);
- call_args += b.PtrToInt(lltaskptr, T_int());
+ call_args += vec( b.PtrToInt(lltaskptr, T_int()));
for (ValueRef a in args) {
- call_args += b.ZExtOrBitCast(a, T_int());
+ call_args += vec(b.ZExtOrBitCast(a, T_int()));
}
ret b.FastCall(llglue, call_args);
@@ -972,8 +971,7 @@ fn static_size_of_tag(@crate_ctxt cx, @ty.t t) -> uint {
auto max_size = 0u;
auto variants = tag_variants(cx, tid);
for (ast.variant variant in variants) {
- let vec[@ty.t] tys = variant_types(cx, variant);
- auto tup_ty = ty.plain_ty(ty.ty_tup(tys));
+ auto tup_ty = ty.plain_tup_ty(variant_types(cx, variant));
// Perform any type parameter substitutions.
tup_ty = ty.substitute_ty_params(ty_params, subtys, tup_ty);
@@ -1022,12 +1020,16 @@ fn dynamic_size_of(@block_ctxt cx, @ty.t t) -> result {
ret res(szptr.bcx, szptr.bcx.build.Load(szptr.val));
}
case (ty.ty_tup(?elts)) {
- ret align_elements(cx, elts);
+ let vec[@ty.t] tys = vec();
+ for (ty.mt mt in elts) {
+ tys += vec(mt.ty);
+ }
+ ret align_elements(cx, tys);
}
case (ty.ty_rec(?flds)) {
let vec[@ty.t] tys = vec();
for (ty.field f in flds) {
- tys += vec(f.ty);
+ tys += vec(f.mt.ty);
}
ret align_elements(cx, tys);
}
@@ -1073,8 +1075,8 @@ fn dynamic_align_of(@block_ctxt cx, @ty.t t) -> result {
case (ty.ty_tup(?elts)) {
auto a = C_int(1);
auto bcx = cx;
- for (@ty.t e in elts) {
- auto align = align_of(bcx, e);
+ for (ty.mt e in elts) {
+ auto align = align_of(bcx, e.ty);
bcx = align.bcx;
a = umax(bcx, a, align.val);
}
@@ -1084,7 +1086,7 @@ fn dynamic_align_of(@block_ctxt cx, @ty.t t) -> result {
auto a = C_int(1);
auto bcx = cx;
for (ty.field f in flds) {
- auto align = align_of(bcx, f.ty);
+ auto align = align_of(bcx, f.mt.ty);
bcx = align.bcx;
a = umax(bcx, a, align.val);
}
@@ -1112,7 +1114,7 @@ fn GEP_tup_like(@block_ctxt cx, @ty.t t,
if (! ty.type_has_dynamic_size(t)) {
let vec[ValueRef] v = vec();
for (int i in ixs) {
- v += C_int(i);
+ v += vec(C_int(i));
}
ret res(cx, cx.build.GEP(base, v));
}
@@ -1159,8 +1161,8 @@ fn GEP_tup_like(@block_ctxt cx, @ty.t t,
let vec[@ty.t] prefix = vec();
let int i = 0;
while (i < ix) {
- append[@ty.t](prefix, ty.get_element_type(t, i as uint));
- i +=1 ;
+ _vec.push[@ty.t](prefix, ty.get_element_type(t, i as uint));
+ i += 1 ;
}
auto selected = ty.get_element_type(t, i as uint);
@@ -1184,7 +1186,7 @@ fn GEP_tup_like(@block_ctxt cx, @ty.t t,
// flattened the incoming structure.
auto s = split_type(t, ixs, 0u);
- auto prefix_ty = plain_ty(ty.ty_tup(s.prefix));
+ auto prefix_ty = ty.plain_tup_ty(s.prefix);
auto bcx = cx;
auto sz = size_of(bcx, prefix_ty);
bcx = sz.bcx;
@@ -1228,7 +1230,8 @@ fn GEP_tag(@block_ctxt cx,
i += 1;
}
- auto tup_ty = ty.plain_ty(ty.ty_tup(true_arg_tys));
+
+ auto tup_ty = ty.plain_tup_ty(true_arg_tys);
// Cast the blob pointer to the appropriate type, if we need to (i.e. if
// the blob pointer isn't dynamically sized).
@@ -1268,8 +1271,8 @@ fn trans_raw_malloc(@block_ctxt cx, TypeRef llptr_ty, ValueRef llsize)
fn trans_malloc_boxed(@block_ctxt cx, @ty.t t) -> result {
// Synthesize a fake box type structurally so we have something
// to measure the size of.
- auto boxed_body = plain_ty(ty.ty_tup(vec(plain_ty(ty.ty_int), t)));
- auto box_ptr = plain_ty(ty.ty_box(t));
+ auto boxed_body = ty.plain_tup_ty(vec(plain_ty(ty.ty_int), t));
+ auto box_ptr = ty.plain_box_ty(t);
auto sz = size_of(cx, boxed_body);
auto llty = type_of(cx.fcx.ccx, box_ptr);
ret trans_raw_malloc(sz.bcx, llty, sz.val);
@@ -1310,8 +1313,8 @@ fn linearize_ty_params(@block_ctxt cx, @ty.t t)
}
}
if (!seen) {
- r.vals += r.cx.fcx.lltydescs.get(pid);
- r.defs += pid;
+ r.vals += vec(r.cx.fcx.lltydescs.get(pid));
+ r.defs += vec(pid);
}
}
case (_) { }
@@ -1567,7 +1570,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
T_int(), C_int(0));
}
- case (ty.ty_box(?body_ty)) {
+ case (ty.ty_box(?body_mt)) {
fn hit_zero(@block_ctxt cx, ValueRef v,
@ty.t body_ty) -> result {
auto body = cx.build.GEP(v,
@@ -1580,7 +1583,7 @@ fn make_drop_glue(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
ret trans_non_gc_free(res.bcx, v);
}
ret decr_refcnt_and_if_zero(cx, v,
- bind hit_zero(_, v, body_ty),
+ bind hit_zero(_, v, body_mt.ty),
"free box",
T_int(), C_int(0));
}
@@ -1832,7 +1835,7 @@ fn iter_structural_ty_full(@block_ctxt cx,
auto box_a_ptr = cx.build.Load(box_a_cell);
auto box_b_ptr = cx.build.Load(box_b_cell);
auto tnil = plain_ty(ty.ty_nil);
- auto tbox = plain_ty(ty.ty_box(tnil));
+ auto tbox = ty.plain_box_ty(tnil);
auto inner_cx = new_sub_block_ctxt(cx, "iter box");
auto next_cx = new_sub_block_ctxt(cx, "next");
@@ -1847,15 +1850,15 @@ fn iter_structural_ty_full(@block_ctxt cx,
alt (t.struct) {
case (ty.ty_tup(?args)) {
let int i = 0;
- for (@ty.t arg in args) {
+ for (ty.mt arg in args) {
r = GEP_tup_like(r.bcx, t, av, vec(0, i));
auto elt_a = r.val;
r = GEP_tup_like(r.bcx, t, bv, vec(0, i));
auto elt_b = r.val;
r = f(r.bcx,
- load_scalar_or_boxed(r.bcx, elt_a, arg),
- load_scalar_or_boxed(r.bcx, elt_b, arg),
- arg);
+ load_scalar_or_boxed(r.bcx, elt_a, arg.ty),
+ load_scalar_or_boxed(r.bcx, elt_b, arg.ty),
+ arg.ty);
i += 1;
}
}
@@ -1867,9 +1870,9 @@ fn iter_structural_ty_full(@block_ctxt cx,
r = GEP_tup_like(r.bcx, t, bv, vec(0, i));
auto llfld_b = r.val;
r = f(r.bcx,
- load_scalar_or_boxed(r.bcx, llfld_a, fld.ty),
- load_scalar_or_boxed(r.bcx, llfld_b, fld.ty),
- fld.ty);
+ load_scalar_or_boxed(r.bcx, llfld_a, fld.mt.ty),
+ load_scalar_or_boxed(r.bcx, llfld_b, fld.mt.ty),
+ fld.mt.ty);
i += 1;
}
}
@@ -2107,8 +2110,8 @@ fn iter_sequence(@block_ctxt cx,
}
alt (t.struct) {
- case (ty.ty_vec(?et)) {
- ret iter_sequence_body(cx, v, et, f, false);
+ case (ty.ty_vec(?elt)) {
+ ret iter_sequence_body(cx, v, elt.ty, f, false);
}
case (ty.ty_str) {
auto et = plain_ty(ty.ty_machine(common.ty_u8));
@@ -2365,7 +2368,7 @@ fn trans_unary(@block_ctxt cx, ast.unop op,
auto box_ty = node_ann_type(sub.bcx.fcx.ccx, a);
sub = trans_malloc_boxed(sub.bcx, e_ty);
find_scope_cx(cx).cleanups +=
- clean(bind drop_ty(_, sub.val, box_ty));
+ vec(clean(bind drop_ty(_, sub.val, box_ty)));
auto box = sub.val;
auto rc = sub.bcx.build.GEP(box,
@@ -2398,9 +2401,6 @@ fn trans_unary(@block_ctxt cx, ast.unop op,
}
ret res(sub.bcx, val);
}
- case (ast._mutable) {
- ret trans_expr(cx, e);
- }
}
fail;
}
@@ -2646,7 +2646,8 @@ fn trans_vec_add(@block_ctxt cx, @ty.t t,
r = copy_ty(r.bcx, INIT, tmp, lhs, t);
auto bcx = trans_vec_append(r.bcx, t, tmp, rhs).bcx;
tmp = load_scalar_or_boxed(bcx, tmp, t);
- find_scope_cx(cx).cleanups += clean(bind drop_ty(_, tmp, t));
+ find_scope_cx(cx).cleanups +=
+ vec(clean(bind drop_ty(_, tmp, t)));
ret res(bcx, tmp);
}
@@ -2698,12 +2699,12 @@ fn autoderef(@block_ctxt cx, ValueRef v, @ty.t t) -> result {
while (true) {
alt (t1.struct) {
- case (ty.ty_box(?inner)) {
+ case (ty.ty_box(?mt)) {
auto body = cx.build.GEP(v1,
vec(C_int(0),
C_int(abi.box_rc_field_body)));
- t1 = inner;
- v1 = load_scalar_or_boxed(cx, body, inner);
+ t1 = mt.ty;
+ v1 = load_scalar_or_boxed(cx, body, t1);
}
case (_) {
ret res(cx, v1);
@@ -2717,8 +2718,8 @@ fn autoderefed_ty(@ty.t t) -> @ty.t {
while (true) {
alt (t1.struct) {
- case (ty.ty_box(?inner)) {
- t1 = inner;
+ case (ty.ty_box(?mt)) {
+ t1 = mt.ty;
}
case (_) {
ret t1;
@@ -2800,9 +2801,9 @@ fn join_results(@block_ctxt parent_cx,
for (result r in ins) {
if (! is_terminated(r.bcx)) {
- live += r;
- vals += r.val;
- bbs += r.bcx.llbb;
+ live += vec(r);
+ vals += vec(r.val);
+ bbs += vec(r.bcx.llbb);
}
}
@@ -2875,7 +2876,8 @@ fn trans_for(@block_ctxt cx,
cx.build.Br(scope_cx.llbb);
auto local_res = alloc_local(scope_cx, local);
auto bcx = copy_ty(local_res.bcx, INIT, local_res.val, curr, t).bcx;
- scope_cx.cleanups += clean(bind drop_slot(_, local_res.val, t));
+ scope_cx.cleanups +=
+ vec(clean(bind drop_slot(_, local_res.val, t)));
bcx = trans_block(bcx, body).bcx;
bcx.build.Br(next_cx.llbb);
ret res(next_cx, C_nil());
@@ -3245,7 +3247,8 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval)
llvm.LLVMSetValueName(dst, _str.buf(id));
bcx.fcx.lllocals.insert(def_id, dst);
- bcx.cleanups += clean(bind drop_slot(_, dst, ty));
+ bcx.cleanups +=
+ vec(clean(bind drop_slot(_, dst, ty)));
ret copy_ty(bcx, INIT, dst, llval, ty);
}
@@ -3368,7 +3371,7 @@ fn lval_generic_fn(@block_ctxt cx,
for (@ty.t t in tys) {
auto td = get_tydesc(bcx, t);
bcx = td.bcx;
- append[ValueRef](tydescs, td.val);
+ _vec.push[ValueRef](tydescs, td.val);
}
auto gen = rec( item_type = tpt._1,
tydescs = tydescs );
@@ -3481,7 +3484,7 @@ fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base,
r = autoderef(r.bcx, r.val, t);
t = autoderefed_ty(t);
alt (t.struct) {
- case (ty.ty_tup(?fields)) {
+ case (ty.ty_tup(_)) {
let uint ix = ty.field_num(cx.fcx.ccx.sess, sp, field);
auto v = GEP_tup_like(r.bcx, t, r.val, vec(0, ix as int));
ret lval_mem(v.bcx, v.val);
@@ -3621,7 +3624,7 @@ fn trans_bind_thunk(@crate_ctxt cx,
auto fcx = new_fn_ctxt(cx, llthunk);
auto bcx = new_top_block_ctxt(fcx);
- auto llclosure_ptr_ty = type_of(cx, plain_ty(ty.ty_box(closure_ty)));
+ auto llclosure_ptr_ty = type_of(cx, ty.plain_box_ty(closure_ty));
auto llclosure = bcx.build.PointerCast(fcx.llenv, llclosure_ptr_ty);
auto lltarget = GEP_tup_like(bcx, closure_ty, llclosure,
@@ -3692,7 +3695,7 @@ fn trans_bind_thunk(@crate_ctxt cx,
val = bcx.build.PointerCast(val, llout_arg_ty);
}
- llargs += val;
+ llargs += vec(val);
b += 1;
}
@@ -3706,7 +3709,7 @@ fn trans_bind_thunk(@crate_ctxt cx,
llout_arg_ty);
}
- llargs += passed_arg;
+ llargs += vec(passed_arg);
a += 1u;
}
}
@@ -3750,7 +3753,7 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
case (none[@ast.expr]) {
}
case (some[@ast.expr](?e)) {
- append[@ast.expr](bound, e);
+ _vec.push[@ast.expr](bound, e);
}
}
}
@@ -3786,14 +3789,14 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
auto arg = trans_expr(bcx, e);
bcx = arg.bcx;
- append[ValueRef](bound_vals, arg.val);
- append[@ty.t](bound_tys, ty.expr_ty(e));
+ _vec.push[ValueRef](bound_vals, arg.val);
+ _vec.push[@ty.t](bound_tys, ty.expr_ty(e));
i += 1u;
}
// Synthesize a closure type.
- let @ty.t bindings_ty = plain_ty(ty.ty_tup(bound_tys));
+ let @ty.t bindings_ty = ty.plain_tup_ty(bound_tys);
// NB: keep this in sync with T_closure_ptr; we're making
// a ty.t structure that has the same "shape" as the LLVM type
@@ -3807,9 +3810,9 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
vec(tydesc_ty,
outgoing_fty,
bindings_ty,
- plain_ty(ty.ty_tup(captured_tys)));
+ ty.plain_tup_ty(captured_tys));
- let @ty.t closure_ty = plain_ty(ty.ty_tup(closure_tys));
+ let @ty.t closure_ty = ty.plain_tup_ty(closure_tys);
auto r = trans_malloc_boxed(bcx, closure_ty);
auto box = r.val;
@@ -3914,7 +3917,7 @@ fn trans_bind(@block_ctxt cx, @ast.expr f,
pair_box);
find_scope_cx(cx).cleanups +=
- clean(bind drop_slot(_, pair_v, pair_ty));
+ vec(clean(bind drop_slot(_, pair_v, pair_ty)));
ret res(bcx, pair_v);
}
@@ -3959,23 +3962,24 @@ fn trans_args(@block_ctxt cx,
}
}
if (ty.type_has_dynamic_size(retty)) {
- llargs += bcx.build.PointerCast(llretslot,
- T_typaram_ptr(cx.fcx.ccx.tn));
+ llargs += vec(bcx.build.PointerCast(llretslot,
+ T_typaram_ptr(cx.fcx.ccx.tn)));
} else if (ty.count_ty_params(retty) != 0u) {
// It's possible that the callee has some generic-ness somewhere in
// its return value -- say a method signature within an obj or a fn
// type deep in a structure -- which the caller has a concrete view
// of. If so, cast the caller's view of the restlot to the callee's
// view, for the sake of making a type-compatible call.
- llargs += cx.build.PointerCast(llretslot,
- T_ptr(type_of(bcx.fcx.ccx, retty)));
+ llargs +=
+ vec(cx.build.PointerCast(llretslot,
+ T_ptr(type_of(bcx.fcx.ccx, retty))));
} else {
- llargs += llretslot;
+ llargs += vec(llretslot);
}
// Arg 1: Task pointer.
- llargs += bcx.fcx.lltaskptr;
+ llargs += vec(bcx.fcx.lltaskptr);
// Arg 2: Env (closure-bindings / self-obj)
alt (llobj) {
@@ -3983,10 +3987,10 @@ fn trans_args(@block_ctxt cx,
// Every object is always found in memory,
// and not-yet-loaded (as part of an lval x.y
// doted method-call).
- llargs += bcx.build.Load(ob);
+ llargs += vec(bcx.build.Load(ob));
}
case (_) {
- llargs += llenv;
+ llargs += vec(llenv);
}
}
@@ -3997,7 +4001,7 @@ fn trans_args(@block_ctxt cx,
alt (lliterbody) {
case (none[ValueRef]) {}
case (some[ValueRef](?lli)) {
- llargs += lli;
+ llargs += vec(lli);
}
}
@@ -4054,7 +4058,7 @@ fn trans_args(@block_ctxt cx,
val = bcx.build.PointerCast(val, lldestty);
}
- llargs += val;
+ llargs += vec(val);
i += 1u;
}
@@ -4116,7 +4120,8 @@ fn trans_call(@block_ctxt cx, @ast.expr f,
// Retval doesn't correspond to anything really tangible in the frame,
// but it's a ref all the same, so we put a note here to drop it when
// we're done in this scope.
- find_scope_cx(cx).cleanups += clean(bind drop_ty(_, retval, ret_ty));
+ find_scope_cx(cx).cleanups +=
+ vec(clean(bind drop_ty(_, retval, ret_ty)));
}
ret res(bcx, retval);
@@ -4130,7 +4135,8 @@ fn trans_tup(@block_ctxt cx, vec[ast.elt] elts,
auto tup_val = tup_res.val;
bcx = tup_res.bcx;
- find_scope_cx(cx).cleanups += clean(bind drop_ty(_, tup_val, t));
+ find_scope_cx(cx).cleanups +=
+ vec(clean(bind drop_ty(_, tup_val, t)));
let int i = 0;
for (ast.elt e in elts) {
@@ -4150,8 +4156,8 @@ fn trans_vec(@block_ctxt cx, vec[@ast.expr] args,
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 (ty.ty_vec(?mt)) {
+ unit_ty = mt.ty;
}
case (_) {
cx.fcx.ccx.sess.bug("non-vec type in trans_vec");
@@ -4171,14 +4177,15 @@ fn trans_vec(@block_ctxt cx, vec[@ast.expr] args,
auto llty = type_of(bcx.fcx.ccx, t);
auto vec_val = vi2p(bcx, sub.val, llty);
- find_scope_cx(bcx).cleanups += clean(bind drop_ty(_, vec_val, t));
+ find_scope_cx(bcx).cleanups +=
+ vec(clean(bind drop_ty(_, vec_val, t)));
auto body = bcx.build.GEP(vec_val, vec(C_int(0),
C_int(abi.vec_elt_data)));
auto pseudo_tup_ty =
- plain_ty(ty.ty_tup(_vec.init_elt[@ty.t](unit_ty,
- _vec.len[@ast.expr](args))));
+ ty.plain_tup_ty(_vec.init_elt[@ty.t](unit_ty,
+ _vec.len[@ast.expr](args)));
let int i = 0;
for (@ast.expr e in args) {
@@ -4226,7 +4233,8 @@ fn trans_rec(@block_ctxt cx, vec[ast.field] fields,
auto rec_val = rec_res.val;
bcx = rec_res.bcx;
- find_scope_cx(cx).cleanups += clean(bind drop_ty(_, rec_val, t));
+ find_scope_cx(cx).cleanups +=
+ vec(clean(bind drop_ty(_, rec_val, t)));
let int i = 0;
auto base_val = C_nil();
@@ -4246,7 +4254,7 @@ fn trans_rec(@block_ctxt cx, vec[ast.field] fields,
}
for (ty.field tf in ty_fields) {
- auto e_ty = tf.ty;
+ auto e_ty = tf.mt.ty;
auto dst_res = GEP_tup_like(bcx, t, rec_val, vec(0, i));
bcx = dst_res.bcx;
@@ -4352,7 +4360,7 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result {
ret trans_cast(cx, e, ann);
}
- case (ast.expr_vec(?args, ?ann)) {
+ case (ast.expr_vec(?args, _, ?ann)) {
ret trans_vec(cx, args, ann);
}
@@ -4499,7 +4507,7 @@ fn trans_put(@block_ctxt cx, &option.t[@ast.expr] e) -> result {
llarg = bcx.build.Load(llarg);
}
- llargs += llarg;
+ llargs += vec(llarg);
}
}
@@ -4557,7 +4565,7 @@ fn init_local(@block_ctxt cx, @ast.local local) -> result {
auto bcx = cx;
find_scope_cx(cx).cleanups +=
- clean(bind drop_slot(_, llptr, ty));
+ vec(clean(bind drop_slot(_, llptr, ty)));
alt (local.init) {
case (some[@ast.expr](?e)) {
@@ -4903,7 +4911,7 @@ fn populate_fn_ctxt_from_llself(@block_ctxt cx, ValueRef llself) -> result {
// Synthesize a tuple type for the fields so that GEP_tup_like() can work
// its magic.
- auto fields_tup_ty = ty.plain_ty(ty.ty_tup(field_tys));
+ auto fields_tup_ty = ty.plain_tup_ty(field_tys);
auto n_typarams = _vec.len[ast.ty_param](bcx.fcx.ccx.obj_typarams);
let TypeRef llobj_box_ty = T_obj_ptr(bcx.fcx.ccx.tn, n_typarams);
@@ -5026,7 +5034,7 @@ fn trans_vtbl(@crate_ctxt cx, TypeRef self_ty,
trans_fn(mcx, m.node.meth, m.node.id, some[TypeRef](self_ty),
ty_params, m.node.ann);
- methods += llfn;
+ methods += vec(llfn);
}
auto vtbl = C_struct(methods);
auto gvar = llvm.LLVMAddGlobal(cx.llmod,
@@ -5085,22 +5093,22 @@ fn trans_obj(@crate_ctxt cx, &ast._obj ob, ast.def_id oid,
// Malloc a box for the body and copy args in.
let vec[@ty.t] obj_fields = vec();
for (ty.arg a in arg_tys) {
- append[@ty.t](obj_fields, a.ty);
+ _vec.push[@ty.t](obj_fields, a.ty);
}
// Synthesize an obj body type.
auto tydesc_ty = plain_ty(ty.ty_type);
let vec[@ty.t] tps = vec();
for (ast.ty_param tp in ty_params) {
- append[@ty.t](tps, tydesc_ty);
+ _vec.push[@ty.t](tps, tydesc_ty);
}
- let @ty.t typarams_ty = plain_ty(ty.ty_tup(tps));
- let @ty.t fields_ty = plain_ty(ty.ty_tup(obj_fields));
- let @ty.t body_ty = plain_ty(ty.ty_tup(vec(tydesc_ty,
- typarams_ty,
- fields_ty)));
- let @ty.t boxed_body_ty = plain_ty(ty.ty_box(body_ty));
+ let @ty.t typarams_ty = ty.plain_tup_ty(tps);
+ let @ty.t fields_ty = ty.plain_tup_ty(obj_fields);
+ let @ty.t body_ty = ty.plain_tup_ty(vec(tydesc_ty,
+ typarams_ty,
+ fields_ty));
+ let @ty.t boxed_body_ty = ty.plain_box_ty(body_ty);
// Malloc a box for the body.
auto box = trans_malloc_boxed(bcx, body_ty);
@@ -6090,7 +6098,7 @@ fn make_glues(ModuleRef llmod, type_names tn) -> @glue_fns {
upcall_glues =
_vec.init_fn[ValueRef](bind decl_upcall_glue(llmod, tn, _),
- abi.n_upcall_glues as uint),
+ abi.n_upcall_glues + 1 as uint),
no_op_type_glue = decl_no_op_type_glue(llmod, tn),
memcpy_glue = decl_memcpy_glue(llmod),
bzero_glue = decl_bzero_glue(llmod),
diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs
index 0c540f5c..5fdb4dc2 100644
--- a/src/comp/middle/ty.rs
+++ b/src/comp/middle/ty.rs
@@ -11,22 +11,23 @@ import driver.session;
import front.ast;
import front.ast.mutability;
import util.common;
-import util.common.append;
import util.common.new_def_hash;
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;
@@ -36,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
@@ -66,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);
@@ -139,44 +142,51 @@ 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 = ""; }
+ case (ast.maybe_mut) { mstr = "mutable? "; }
+ }
+
+ ret mstr + ty_to_str(m.ty);
}
+ auto s = "";
alt (typ.struct) {
- case (ty_native) { s = "native"; }
- 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_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_native) { s += "native"; }
+ 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(?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);
- s = "tup(" + _str.connect(strs, ",") + ")";
+ auto f = mt_to_str;
+ auto strs = _vec.map[mt,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, ",") + ")";
+ s += "rec(" + _str.connect(strs, ",") + ")";
}
case (ty_tag(?id, ?tps)) {
// The user should never see this if the cname is set properly!
- s = "<tag#" + util.common.istr(id._0) + ":" +
+ s += "<tag#" + util.common.istr(id._0) + ":" +
util.common.istr(id._1) + ">";
if (_vec.len[@t](tps) > 0u) {
auto f = ty_to_str;
@@ -186,31 +196,31 @@ fn ty_to_str(&@t typ) -> str {
}
case (ty_fn(?proto, ?inputs, ?output)) {
- s = fn_to_str(proto, none[ast.ident], inputs, output);
+ s += fn_to_str(proto, none[ast.ident], inputs, output);
}
case (ty_native_fn(_, ?inputs, ?output)) {
- s = fn_to_str(ast.proto_fn, none[ast.ident], inputs, output);
+ s += fn_to_str(ast.proto_fn, 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}";
+ s += "obj {\n\t" + _str.connect(m, "\n\t") + "\n}";
}
case (ty_var(?v)) {
- s = "<T" + util.common.istr(v) + ">";
+ s += "<T" + util.common.istr(v) + ">";
}
case (ty_local(?id)) {
- s = "<L" + util.common.istr(id._0) + ":" + util.common.istr(id._1)
- + ">";
+ s += "<L" + util.common.istr(id._0) + ":" +
+ util.common.istr(id._1) + ">";
}
case (ty_param(?id)) {
- s = "<P" + util.common.istr(id._0) + ":" + util.common.istr(id._1)
- + ">";
+ s += "<P" + util.common.istr(id._0) + ":" +
+ util.common.istr(id._1) + ">";
}
}
@@ -225,7 +235,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) {
@@ -238,11 +248,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)));
@@ -257,18 +267,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));
}
@@ -352,8 +364,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;
}
@@ -373,11 +385,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;
@@ -410,6 +422,7 @@ fn type_is_scalar(@t ty) -> bool {
case (ty_machine(_)) { ret true; }
case (ty_char) { ret true; }
case (ty_type) { ret true; }
+ case (ty_native) { ret true; }
case (_) { ret false; }
}
fail;
@@ -427,17 +440,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 +531,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 +728,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); }
@@ -756,7 +781,7 @@ fn field_num(session.session sess, &span sp, &ast.ident id) -> uint {
accum += (c as uint) - ('0' as uint);
} else {
auto s = "";
- s += c;
+ s += _str.unsafe_from_byte(c);
sess.span_err(sp,
"bad numeric field on tuple: "
+ " non-digit character: "
@@ -794,6 +819,14 @@ fn method_idx(session.session sess, &span sp,
fail;
}
+fn sort_methods(vec[method] meths) -> vec[method] {
+ fn method_lteq(&method a, &method b) -> bool {
+ ret _str.lteq(a.ident, b.ident);
+ }
+
+ ret std.sort.merge_sort[method](bind method_lteq(_,_), meths);
+}
+
fn is_lval(@ast.expr expr) -> bool {
alt (expr.node) {
case (ast.expr_field(_,_,_)) { ret true; }
@@ -826,6 +859,21 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
ret ures_err(terr_mismatch, expected, actual);
}
+ // Unifies two mutability flags.
+ fn unify_mut(ast.mutability expected, ast.mutability actual)
+ -> option.t[ast.mutability] {
+ if (expected == actual) {
+ ret some[ast.mutability](expected);
+ }
+ if (expected == ast.maybe_mut) {
+ ret some[ast.mutability](actual);
+ }
+ if (actual == ast.maybe_mut) {
+ ret some[ast.mutability](expected);
+ }
+ ret none[ast.mutability];
+ }
+
tag fn_common_res {
fn_common_res_err(unify_result);
fn_common_res_ok(vec[arg], @t);
@@ -1104,7 +1152,7 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
alt (result) {
case (ures_ok(?rty)) {
- append[@ty.t](result_tps, rty);
+ _vec.push[@ty.t](result_tps, rty);
}
case (_) {
ret result;
@@ -1123,16 +1171,26 @@ 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)) {
+ auto mut;
+ alt (unify_mut(expected_mt.mut, actual_mt.mut)) {
+ case (none[ast.mutability]) {
+ ret ures_err(terr_box_mutability, expected,
+ actual);
+ }
+ case (some[ast.mutability](?m)) { mut = m; }
+ }
+
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=mut);
+ ret ures_ok(plain_ty(ty.ty_box(mt)));
}
case (_) {
ret result;
@@ -1146,16 +1204,26 @@ 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)) {
+ auto mut;
+ alt (unify_mut(expected_mt.mut, actual_mt.mut)) {
+ case (none[ast.mutability]) {
+ ret ures_err(terr_vec_mutability, expected,
+ actual);
+ }
+ case (some[ast.mutability](?m)) { mut = m; }
+ }
+
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=mut);
+ ret ures_ok(plain_ty(ty.ty_vec(mt)));
}
case (_) {
ret result;
@@ -1218,8 +1286,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);
@@ -1228,23 +1296,30 @@ 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);
auto actual_elem = actual_elems.(i);
- if (expected_elem.mut != actual_elem.mut) {
- auto err = terr_tuple_mutability;
- ret ures_err(err, expected, actual);
+
+ auto mut;
+ alt (unify_mut(expected_elem.mut,
+ actual_elem.mut)) {
+ case (none[ast.mutability]) {
+ auto err = terr_tuple_mutability;
+ ret ures_err(err, expected, actual);
+ }
+ case (some[ast.mutability](?m)) { mut = m; }
}
auto result = unify_step(bindings,
- expected_elem,
- actual_elem,
+ expected_elem.ty,
+ actual_elem.ty,
handler);
alt (result) {
case (ures_ok(?rty)) {
- append[@ty.t](result_elems,rty);
+ auto mt = rec(ty=rty, mut=mut);
+ result_elems += vec(mt);
}
case (_) {
ret result;
@@ -1281,14 +1356,19 @@ 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) {
- auto err = terr_record_mutability;
- ret ures_err(err, expected, actual);
+
+ auto mut;
+ alt (unify_mut(expected_field.mt.mut,
+ actual_field.mt.mut)) {
+ case (none[ast.mutability]) {
+ ret ures_err(terr_record_mutability,
+ expected, actual);
+ }
+ case (some[ast.mutability](?m)) { mut = m; }
}
if (!_str.eq(expected_field.ident,
- actual_field.ident)) {
+ actual_field.ident)) {
auto err =
terr_record_fields(expected_field.ident,
actual_field.ident);
@@ -1296,14 +1376,15 @@ 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)) {
- append[field]
+ auto mt = rec(ty=rty, mut=mut);
+ _vec.push[field]
(result_fields,
- rec(ty=rty with expected_field));
+ rec(mt=mt with expected_field));
}
case (_) {
ret result;
@@ -1440,6 +1521,12 @@ fn type_err_to_str(&ty.type_err err) -> str {
case (terr_mismatch) {
ret "types differ";
}
+ case (terr_box_mutability) {
+ ret "boxed values differ in mutability";
+ }
+ case (terr_vec_mutability) {
+ ret "vectors differ in mutability";
+ }
case (terr_tuple_size(?e_sz, ?a_sz)) {
ret "expected a tuple with " + _uint.to_str(e_sz, 10u) +
" elements but found one with " + _uint.to_str(a_sz, 10u) +
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 1818c4fd..14d4f714 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -4,7 +4,6 @@ import front.ast.mutability;
import middle.fold;
import driver.session;
import util.common;
-import util.common.append;
import util.common.span;
import middle.ty;
@@ -277,6 +276,10 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
ret rec(mode=arg.mode, ty=ast_ty_to_ty(getter, arg.ty));
}
+ fn ast_mt_to_mt(ty_getter getter, &ast.mt mt) -> ty.mt {
+ ret rec(ty=ast_ty_to_ty(getter, mt.ty), mut=mt.mut);
+ }
+
fn instantiate(ty_getter getter, ast.def_id id,
vec[@ast.ty] args) -> @ty.t {
// TODO: maybe record cname chains so we can do
@@ -306,8 +309,8 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
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_box(?mt)) { sty = ty.ty_box(ast_mt_to_mt(getter, mt)); }
+ case (ast.ty_vec(?mt)) { sty = ty.ty_vec(ast_mt_to_mt(getter, mt)); }
case (ast.ty_port(?t)) {
sty = ty.ty_port(ast_ty_to_ty(getter, t));
@@ -318,17 +321,17 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
}
case (ast.ty_tup(?fields)) {
- let vec[@ty.t] flds = vec();
- for (@ast.ty field in fields) {
- append[@ty.t](flds, ast_ty_to_ty(getter, field));
+ let vec[ty.mt] flds = vec();
+ for (ast.mt field in fields) {
+ _vec.push[ty.mt](flds, ast_mt_to_mt(getter, field));
}
sty = ty.ty_tup(flds);
}
case (ast.ty_rec(?fields)) {
let vec[field] flds = vec();
for (ast.ty_field f in fields) {
- append[field](flds, rec(ident=f.ident,
- ty=ast_ty_to_ty(getter, f.ty)));
+ _vec.push[field](flds, rec(ident=f.ident,
+ mt=ast_mt_to_mt(getter, f.mt)));
}
sty = ty.ty_rec(flds);
}
@@ -358,30 +361,24 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t {
cname = some(path_to_str(path));
}
- case (ast.ty_mutable(?t)) {
- mut = ast.mut;
- auto t0 = ast_ty_to_ty(getter, t);
- sty = t0.struct;
- cname = t0.cname;
- }
-
case (ast.ty_obj(?meths)) {
let vec[ty.method] tmeths = vec();
auto f = bind ast_arg_to_arg(getter, _);
for (ast.ty_method m in meths) {
auto ins = _vec.map[ast.ty_arg, arg](f, m.inputs);
auto out = ast_ty_to_ty(getter, m.output);
- append[ty.method](tmeths,
+ _vec.push[ty.method](tmeths,
rec(proto=m.proto,
ident=m.ident,
inputs=ins,
output=out));
}
- sty = ty.ty_obj(tmeths);
+
+ sty = ty.ty_obj(ty.sort_methods(tmeths));
}
}
- ret @rec(struct=sty, mut=mut, cname=cname);
+ ret @rec(struct=sty, cname=cname);
}
fn actual_type(@ty.t t, @ast.item item) -> @ty.t {
@@ -546,14 +543,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
auto methods =
_vec.map[@ast.method,method](f, obj_info.methods);
- fn method_lteq(&method a, &method b) -> bool {
- ret _str.lteq(a.ident, b.ident);
- }
-
- methods = std.sort.merge_sort[method](bind method_lteq(_,_),
- methods);
-
- auto t_obj = plain_ty(ty.ty_obj(methods));
+ auto t_obj = plain_ty(ty.ty_obj(ty.sort_methods(methods)));
ret t_obj;
}
@@ -565,7 +555,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
for (ast.obj_field f in obj_info.fields) {
auto g = bind getter(id_to_ty_item, item_to_ty, _);
auto t_field = ast_ty_to_ty(g, f.ty);
- append[arg](t_inputs, rec(mode=ast.alias, ty=t_field));
+ _vec.push[arg](t_inputs, rec(mode=ast.alias, ty=t_field));
}
auto t_fn = plain_ty(ty.ty_fn(ast.proto_fn, t_inputs, t_obj));
ret t_fn;
@@ -645,8 +635,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
// Avoid repeating work.
ret item_to_ty.get(def_id);
}
- auto x =
- @rec(struct=ty.ty_native, mut=ast.imm, cname=none[str]);
+ auto x = @rec(struct=ty.ty_native, cname=none[str]);
item_to_ty.insert(def_id, x);
ret x;
}
@@ -870,7 +859,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
with meth.node
);
m = @rec(node=m_ with *meth);
- append[@ast.method](methods, m);
+ _vec.push[@ast.method](methods, m);
}
auto g = bind getter(e.id_to_ty_item, e.item_to_ty, _);
for (ast.obj_field fld in ob.fields) {
@@ -879,7 +868,7 @@ fn collect_item_types(session.session sess, @ast.crate crate)
ann=ast.ann_type(fty, none[vec[@ty.t]])
with fld
);
- append[ast.obj_field](fields, f);
+ _vec.push[ast.obj_field](fields, f);
}
auto ob_ = rec(methods = methods,
@@ -980,7 +969,7 @@ fn strip_boxes(@ty.t t) -> @ty.t {
auto t1 = t;
while (true) {
alt (t1.struct) {
- case (ty.ty_box(?inner)) { t1 = inner; }
+ case (ty.ty_box(?inner)) { t1 = inner.ty; }
case (_) { ret t1; }
}
}
@@ -990,7 +979,7 @@ fn strip_boxes(@ty.t t) -> @ty.t {
fn add_boxes(uint n, @ty.t t) -> @ty.t {
auto t1 = t;
while (n != 0u) {
- t1 = plain_ty(ty.ty_box(t1));
+ t1 = ty.plain_box_ty(t1);
n -= 1u;
}
ret t1;
@@ -1002,7 +991,7 @@ fn count_boxes(@ty.t t) -> uint {
auto t1 = t;
while (true) {
alt (t1.struct) {
- case (ty.ty_box(?inner)) { n += 1u; t1 = inner; }
+ case (ty.ty_box(?inner)) { n += 1u; t1 = inner.ty; }
case (_) { ret n; }
}
}
@@ -1150,13 +1139,15 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
auto e_1;
alt (e.node) {
- case (ast.expr_vec(?es_0, ?ann)) {
+ case (ast.expr_vec(?es_0, ?mut, ?ann)) {
+ // TODO: enforce mutability
+
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
let vec[@ast.expr] es_1 = vec();
alt (t.struct) {
- case (ty.ty_vec(?subty)) {
+ case (ty.ty_vec(?mt)) {
for (@ast.expr e_0 in es_0) {
- es_1 += vec(demand_expr(fcx, subty, e_0));
+ es_1 += vec(demand_expr(fcx, mt.ty, e_0));
}
}
case (_) {
@@ -1164,16 +1155,16 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
fail;
}
}
- e_1 = ast.expr_vec(es_1, ast.ann_type(t, none[vec[@ty.t]]));
+ e_1 = ast.expr_vec(es_1, mut, ast.ann_type(t, none[vec[@ty.t]]));
}
case (ast.expr_tup(?es_0, ?ann)) {
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
let vec[ast.elt] elts_1 = vec();
alt (t.struct) {
- case (ty.ty_tup(?subtys)) {
+ case (ty.ty_tup(?mts)) {
auto i = 0u;
for (ast.elt elt_0 in es_0) {
- auto e_1 = demand_expr(fcx, subtys.(i), elt_0.expr);
+ auto e_1 = demand_expr(fcx, mts.(i).ty, elt_0.expr);
elts_1 += vec(rec(mut=elt_0.mut, expr=e_1));
i += 1u;
}
@@ -1192,15 +1183,15 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
auto t = demand(fcx, e.span, expected, ann_to_type(ann));
let vec[ast.field] fields_1 = vec();
alt (t.struct) {
- case (ty.ty_rec(?field_tys)) {
+ case (ty.ty_rec(?field_mts)) {
alt (base_0) {
case (none[@ast.expr]) {
auto i = 0u;
for (ast.field field_0 in fields_0) {
check (_str.eq(field_0.ident,
- field_tys.(i).ident));
+ field_mts.(i).ident));
auto e_1 = demand_expr(fcx,
- field_tys.(i).ty,
+ field_mts.(i).mt.ty,
field_0.expr);
fields_1 += vec(rec(mut=field_0.mut,
ident=field_0.ident,
@@ -1217,9 +1208,9 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
for (ast.field field_0 in fields_0) {
- for (ty.field ft in field_tys) {
+ for (ty.field ft in field_mts) {
if (_str.eq(field_0.ident, ft.ident)) {
- auto e_1 = demand_expr(fcx, ft.ty,
+ auto e_1 = demand_expr(fcx, ft.mt.ty,
field_0.expr);
fields_1 +=
vec(rec(mut=field_0.mut,
@@ -1411,7 +1402,8 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e,
}
case (_) {
- fcx.ccx.sess.unimpl("type unification for expression variant");
+ fcx.ccx.sess.span_unimpl(e.span,
+ "type unification for expression variant");
fail;
}
}
@@ -1438,8 +1430,10 @@ fn demand_block(&@fn_ctxt fcx, @ty.t expected, &ast.block bloc) -> ast.block {
// Writeback: the phase that writes inferred types back into the AST.
-fn writeback_local(&@fn_ctxt fcx, &span sp, @ast.local local)
+fn writeback_local(&option.t[@fn_ctxt] env, &span sp, @ast.local local)
-> @ast.decl {
+ auto fcx = option.get[@fn_ctxt](env);
+
if (!fcx.locals.contains_key(local.id)) {
fcx.ccx.sess.span_err(sp, "unable to determine type of local: "
+ local.ident);
@@ -1453,10 +1447,25 @@ fn writeback_local(&@fn_ctxt fcx, &span sp, @ast.local local)
}
fn writeback(&@fn_ctxt fcx, &ast.block block) -> ast.block {
- auto fld = fold.new_identity_fold[@fn_ctxt]();
- auto f = writeback_local;
- fld = @rec(fold_decl_local = f with *fld);
- ret fold.fold_block[@fn_ctxt](fcx, fld, block);
+ fn update_env_for_item(&option.t[@fn_ctxt] env, @ast.item i)
+ -> option.t[@fn_ctxt] {
+ ret none[@fn_ctxt];
+ }
+ fn keep_going(&option.t[@fn_ctxt] env) -> bool {
+ ret !option.is_none[@fn_ctxt](env);
+ }
+
+ auto fld = fold.new_identity_fold[option.t[@fn_ctxt]]();
+ auto wbl = writeback_local;
+ auto uefi = update_env_for_item;
+ auto kg = keep_going;
+ fld = @rec(
+ fold_decl_local = wbl,
+ update_env_for_item = uefi,
+ keep_going = kg
+ with *fld
+ );
+ ret fold.fold_block[option.t[@fn_ctxt]](some[@fn_ctxt](fcx), fld, block);
}
// AST fragment checking
@@ -1572,14 +1581,14 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
// FIXME: this breaks aliases. We need a ty_fn_arg.
auto arg_ty = rec(mode=ast.val, ty=expr_ty(a_0));
- append[arg](arg_tys_0, arg_ty);
+ _vec.push[arg](arg_tys_0, arg_ty);
}
case (none[@ast.expr]) {
args_0 += vec(none[@ast.expr]);
// FIXME: breaks aliases too?
auto typ = next_ty_var(fcx.ccx);
- append[arg](arg_tys_0, rec(mode=ast.val, ty=typ));
+ _vec.push[arg](arg_tys_0, rec(mode=ast.val, ty=typ));
}
}
}
@@ -1623,10 +1632,11 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
case (some[@ast.expr](?e_0)) {
auto arg_ty_1 = arg_tys_1.(i);
auto e_1 = demand_expr(fcx, arg_ty_1.ty, e_0);
- append[option.t[@ast.expr]](args_1, some[@ast.expr](e_1));
+ _vec.push[option.t[@ast.expr]](args_1,
+ some[@ast.expr](e_1));
}
case (none[@ast.expr]) {
- append[option.t[@ast.expr]](args_1, none[@ast.expr]);
+ _vec.push[option.t[@ast.expr]](args_1, none[@ast.expr]);
}
}
@@ -1693,11 +1703,14 @@ 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.ty_box(oper_t)); }
+ case (ast.box) {
+ // TODO: mutable
+ oper_t = ty.plain_box_ty(oper_t);
+ }
case (ast.deref) {
alt (oper_t.struct) {
- case (ty.ty_box(?inner_t)) {
- oper_t = inner_t;
+ case (ty.ty_box(?inner)) {
+ oper_t = inner.ty;
}
case (_) {
fcx.ccx.sess.span_err
@@ -1707,9 +1720,6 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
}
}
}
- case (ast._mutable) {
- oper_t = @rec(mut=ast.mut with *oper_t);
- }
case (_) { oper_t = strip_boxes(oper_t); }
}
@@ -2096,12 +2106,9 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
ast.expr_cast(e_1, t, ann));
}
- case (ast.expr_vec(?args, _)) {
+ case (ast.expr_vec(?args, ?mut, _)) {
let vec[@ast.expr] args_1 = vec();
- // FIXME: implement mutable vectors with leading 'mutable' flag
- // marking the elements as mutable.
-
let @ty.t t;
if (_vec.len[@ast.expr](args) == 0u) {
t = next_ty_var(fcx.ccx);
@@ -2114,28 +2121,27 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
auto expr_1 = check_expr(fcx, e);
auto expr_t = expr_ty(expr_1);
demand(fcx, expr.span, t, expr_t);
- append[@ast.expr](args_1,expr_1);
+ _vec.push[@ast.expr](args_1,expr_1);
}
- auto ann = ast.ann_type(plain_ty(ty.ty_vec(t)), none[vec[@ty.t]]);
+
+ auto vec_sty = ty.ty_vec(rec(ty=t, mut=mut));
+ auto ann = ast.ann_type(plain_ty(vec_sty), none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
- ast.expr_vec(args_1, ann));
+ ast.expr_vec(args_1, mut, ann));
}
case (ast.expr_tup(?elts, _)) {
let vec[ast.elt] elts_1 = vec();
- let vec[@ty.t] elts_t = vec();
+ let vec[ty.mt] elts_mt = vec();
for (ast.elt e in elts) {
auto expr_1 = check_expr(fcx, e.expr);
auto expr_t = expr_ty(expr_1);
- if (e.mut == ast.mut) {
- expr_t = @rec(mut=ast.mut with *expr_t);
- }
- append[ast.elt](elts_1, rec(expr=expr_1 with e));
- append[@ty.t](elts_t, expr_t);
+ _vec.push[ast.elt](elts_1, rec(expr=expr_1 with e));
+ elts_mt += vec(rec(ty=expr_t, mut=e.mut));
}
- auto ann = ast.ann_type(plain_ty(ty.ty_tup(elts_t)),
+ auto ann = ast.ann_type(plain_ty(ty.ty_tup(elts_mt)),
none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_tup(elts_1, ann));
@@ -2157,11 +2163,10 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
for (ast.field f in fields) {
auto expr_1 = check_expr(fcx, f.expr);
auto expr_t = expr_ty(expr_1);
- if (f.mut == ast.mut) {
- expr_t = @rec(mut=ast.mut with *expr_t);
- }
- append[ast.field](fields_1, rec(expr=expr_1 with f));
- append[field](fields_t, rec(ident=f.ident, ty=expr_t));
+ _vec.push[ast.field](fields_1, rec(expr=expr_1 with f));
+
+ auto expr_mt = rec(ty=expr_t, mut=f.mut);
+ _vec.push[field](fields_t, rec(ident=f.ident, mt=expr_mt));
}
auto ann = ast.ann_none;
@@ -2195,7 +2200,7 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
auto found = false;
for (ty.field bf in base_fields) {
if (_str.eq(f.ident, bf.ident)) {
- demand(fcx, expr.span, f.ty, bf.ty);
+ demand(fcx, expr.span, f.mt.ty, bf.mt.ty);
found = true;
}
}
@@ -2220,11 +2225,11 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
case (ty.ty_tup(?args)) {
let uint ix = ty.field_num(fcx.ccx.sess,
expr.span, field);
- if (ix >= _vec.len[@ty.t](args)) {
+ if (ix >= _vec.len[ty.mt](args)) {
fcx.ccx.sess.span_err(expr.span,
"bad index on tuple");
}
- auto ann = ast.ann_type(args.(ix), none[vec[@ty.t]]);
+ auto ann = ast.ann_type(args.(ix).ty, none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_field(base_1,
field,
@@ -2238,7 +2243,8 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
fcx.ccx.sess.span_err(expr.span,
"bad index on record");
}
- auto ann = ast.ann_type(fields.(ix).ty, none[vec[@ty.t]]);
+ auto ann = ast.ann_type(fields.(ix).mt.ty,
+ none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_field(base_1,
field,
@@ -2278,14 +2284,14 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
auto idx_t = expr_ty(idx_1);
alt (base_t.struct) {
- case (ty.ty_vec(?t)) {
+ case (ty.ty_vec(?mt)) {
if (! type_is_integral(idx_t)) {
fcx.ccx.sess.span_err
(idx.span,
"non-integral type of vec index: "
+ ty_to_str(idx_t));
}
- auto ann = ast.ann_type(t, none[vec[@ty.t]]);
+ auto ann = ast.ann_type(mt.ty, none[vec[@ty.t]]);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_index(base_1,
idx_1,
@@ -2418,7 +2424,7 @@ fn check_stmt(&@fn_ctxt fcx, &@ast.stmt stmt) -> @ast.stmt {
fn check_block(&@fn_ctxt fcx, &ast.block block) -> ast.block {
let vec[@ast.stmt] stmts = vec();
for (@ast.stmt s in block.node.stmts) {
- append[@ast.stmt](stmts, check_stmt(fcx, s));
+ _vec.push[@ast.stmt](stmts, check_stmt(fcx, s));
}
auto expr = none[@ast.expr];
diff --git a/src/comp/pretty/pp.rs b/src/comp/pretty/pp.rs
index d3145180..0c355001 100644
--- a/src/comp/pretty/pp.rs
+++ b/src/comp/pretty/pp.rs
@@ -39,12 +39,12 @@ fn mkstate(io.writer out, uint width) -> ps {
impure fn push_context(ps p, contexttype tp, uint indent) {
before_print(p, false);
- p.context = _vec.push[context](p.context, rec(tp=tp, indent=base_indent(p)
- + indent));
+ _vec.push[context](p.context, rec(tp=tp, indent=base_indent(p)
+ + indent));
}
-impure fn pop_context(ps p) {
- p.context = _vec.pop[context](p.context);
+fn pop_context(ps p) {
+ _vec.pop[context](p.context);
}
impure fn add_token(ps p, token tok) {
@@ -110,7 +110,8 @@ impure fn finish_block_scan(ps p, contexttype tp) {
}
p.scandepth = 0u;
push_context(p, tp, indent);
- for (token t in _vec.shift[token](p.buffered)) {add_token(p, t);}
+ _vec.shift[token](p.buffered);
+ for (token t in p.buffered) { add_token(p, t); }
}
impure fn finish_break_scan(ps p) {
@@ -125,7 +126,8 @@ impure fn finish_break_scan(ps p) {
p.col += width;
}
p.scandepth = 0u;
- for (token t in _vec.shift[token](p.buffered)) {add_token(p, t);}
+ _vec.shift[token](p.buffered);
+ for (token t in p.buffered) { add_token(p, t); }
}
impure fn start_scan(ps p, token tok) {
diff --git a/src/comp/pretty/pprust.rs b/src/comp/pretty/pprust.rs
index a25bc447..6f5ea096 100644
--- a/src/comp/pretty/pprust.rs
+++ b/src/comp/pretty/pprust.rs
@@ -48,7 +48,7 @@ impure fn bclose(ps s) {
end(s);
pp.cwrd(s, "}");
}
-impure fn commasep[IN](ps s, vec[IN] elts, impure fn (ps, IN) op) {
+impure fn commasep[IN](ps s, vec[IN] elts, impure fn (ps, &IN) op) {
auto first = true;
for (IN elt in elts) {
if (first) {first = false;}
@@ -57,7 +57,16 @@ impure fn commasep[IN](ps s, vec[IN] elts, impure fn (ps, IN) op) {
}
}
-impure fn print_type(ps s, @ast.ty ty) {
+impure fn print_mt(ps s, &ast.mt mt) {
+ alt (mt.mut) {
+ case (ast.mut) { wrd1(s, "mutable"); }
+ case (ast.maybe_mut) { wrd1(s, "mutable?"); }
+ case (ast.imm) { /* nothing */ }
+ }
+ print_type(s, mt.ty);
+}
+
+impure fn print_type(ps s, &@ast.ty ty) {
hbox(s);
alt (ty.node) {
case (ast.ty_nil) {wrd(s, "()");}
@@ -67,22 +76,22 @@ impure fn print_type(ps s, @ast.ty ty) {
case (ast.ty_machine(?tm)) {wrd(s, util.common.ty_mach_to_str(tm));}
case (ast.ty_char) {wrd(s, "char");}
case (ast.ty_str) {wrd(s, "str");}
- case (ast.ty_box(?t)) {wrd(s, "@"); print_type(s, t);}
- case (ast.ty_vec(?t)) {wrd(s, "vec["); print_type(s, t); wrd(s, "]");}
+ case (ast.ty_box(?mt)) {wrd(s, "@"); print_mt(s, mt);}
+ case (ast.ty_vec(?mt)) {wrd(s, "vec["); print_mt(s, mt); wrd(s, "]");}
case (ast.ty_type) {wrd(s, "type");}
case (ast.ty_tup(?elts)) {
wrd(s, "tup");
popen(s);
- auto f = print_type;
- commasep[@ast.ty](s, elts, f);
+ auto f = print_mt;
+ commasep[ast.mt](s, elts, f);
pclose(s);
}
case (ast.ty_rec(?fields)) {
wrd(s, "rec");
popen(s);
- impure fn print_field(ps s, ast.ty_field f) {
+ impure fn print_field(ps s, &ast.ty_field f) {
hbox(s);
- print_type(s, f.ty);
+ print_mt(s, f.mt);
space(s);
wrd(s, f.ident);
end(s);
@@ -110,10 +119,6 @@ impure fn print_type(ps s, @ast.ty ty) {
case (ast.ty_path(?path,_)) {
print_path(s, path);
}
- case (ast.ty_mutable(?t)) {
- wrd1(s, "mutable");
- print_type(s, t);
- }
}
end(s);
}
@@ -186,7 +191,7 @@ impure fn print_item(ps s, @ast.item item) {
wrd(s, v.name);
if (_vec.len[ast.variant_arg](v.args) > 0u) {
popen(s);
- impure fn print_variant_arg(ps s, ast.variant_arg arg) {
+ impure fn print_variant_arg(ps s, &ast.variant_arg arg) {
print_type(s, arg.ty);
}
auto f = print_variant_arg;
@@ -203,7 +208,7 @@ impure fn print_item(ps s, @ast.item item) {
wrd(s, id);
print_type_params(s, params);
popen(s);
- impure fn print_field(ps s, ast.obj_field field) {
+ impure fn print_field(ps s, &ast.obj_field field) {
hbox(s);
print_type(s, field.ty);
space(s);
@@ -285,18 +290,21 @@ impure fn print_literal(ps s, @ast.lit lit) {
}
}
-impure fn print_expr(ps s, @ast.expr expr) {
+impure fn print_expr(ps s, &@ast.expr expr) {
auto pe = print_expr;
hbox(s);
alt (expr.node) {
- case (ast.expr_vec(?exprs,_)) {
+ case (ast.expr_vec(?exprs,?mut,_)) {
+ if (mut == ast.mut) {
+ wrd1(s, "mutable");
+ }
wrd(s, "vec");
popen(s);
commasep[@ast.expr](s, exprs, pe);
pclose(s);
}
case (ast.expr_tup(?exprs,_)) {
- impure fn printElt(ps s, ast.elt elt) {
+ impure fn printElt(ps s, &ast.elt elt) {
hbox(s);
if (elt.mut == ast.mut) {wrd1(s, "mutable");}
print_expr(s, elt.expr);
@@ -309,7 +317,7 @@ impure fn print_expr(ps s, @ast.expr expr) {
pclose(s);
}
case (ast.expr_rec(?fields,?wth,_)) {
- impure fn print_field(ps s, ast.field field) {
+ impure fn print_field(ps s, &ast.field field) {
hbox(s);
if (field.mut == ast.mut) {wrd1(s, "mutable");}
wrd(s, field.ident);
@@ -340,7 +348,7 @@ impure fn print_expr(ps s, @ast.expr expr) {
pclose(s);
}
case (ast.expr_bind(?func,?args,_)) {
- impure fn print_opt(ps s, option.t[@ast.expr] expr) {
+ impure fn print_opt(ps s, &option.t[@ast.expr] expr) {
alt (expr) {
case (option.some[@ast.expr](?expr)) {
print_expr(s, expr);
@@ -364,7 +372,6 @@ impure fn print_expr(ps s, @ast.expr expr) {
}
case (ast.expr_unary(?op,?expr,_)) {
wrd(s, ast.unop_to_str(op));
- if (op == ast._mutable) {space(s);}
print_expr(s, expr);
}
case (ast.expr_lit(?lit,_)) {
@@ -577,7 +584,7 @@ impure fn print_path(ps s, ast.path path) {
}
}
-impure fn print_pat(ps s, @ast.pat pat) {
+impure fn print_pat(ps s, &@ast.pat pat) {
alt (pat.node) {
case (ast.pat_wild(_)) {wrd(s, "_");}
case (ast.pat_bind(?id,_,_)) {wrd(s, "?" + id);}
@@ -605,7 +612,7 @@ impure fn print_fn(ps s, ast.fn_decl decl, str name,
wrd(s, name);
print_type_params(s, typarams);
popen(s);
- impure fn print_arg(ps s, ast.arg x) {
+ impure fn print_arg(ps s, &ast.arg x) {
hbox(s);
print_type(s, x.ty);
space(s);
@@ -627,7 +634,7 @@ impure fn print_fn(ps s, ast.fn_decl decl, str name,
impure fn print_type_params(ps s, vec[ast.ty_param] params) {
if (_vec.len[ast.ty_param](params) > 0u) {
wrd(s, "[");
- impure fn printParam(ps s, ast.ty_param param) {wrd(s, param.ident);}
+ impure fn printParam(ps s, &ast.ty_param param) {wrd(s, param.ident);}
auto f = printParam;
commasep[ast.ty_param](s, params, f);
wrd(s, "]");
@@ -642,7 +649,7 @@ impure fn print_view_item(ps s, @ast.view_item item) {
wrd(s, id);
if (_vec.len[@ast.meta_item](mta) > 0u) {
popen(s);
- impure fn print_meta(ps s, @ast.meta_item item) {
+ impure fn print_meta(ps s, &@ast.meta_item item) {
hbox(s);
wrd1(s, item.node.name);
wrd1(s, "=");
@@ -717,7 +724,7 @@ fn escape_str(str st, char to_escape) -> str {
case ('\\') {out += "\\\\";}
case (?cur) {
if (cur == to_escape) {out += "\\";}
- out += cur as u8;
+ _str.push_byte(out, cur as u8);
}
}
i += 1u;
@@ -738,7 +745,7 @@ impure fn print_ty_fn(ps s, ast.proto proto, option.t[str] id,
case (_) {}
}
popen(s);
- impure fn print_arg(ps s, ast.ty_arg input) {
+ impure fn print_arg(ps s, &ast.ty_arg input) {
if (middle.ty.mode_is_alias(input.mode)) {wrd(s, "&");}
print_type(s, input.ty);
}
diff --git a/src/comp/util/common.rs b/src/comp/util/common.rs
index 63ec2c69..4b4f5481 100644
--- a/src/comp/util/common.rs
+++ b/src/comp/util/common.rs
@@ -68,15 +68,6 @@ fn istr(int i) -> str {
ret _int.to_str(i, 10u);
}
-
-// FIXME: Weird bug. Due to the way we auto-deref + in +=, we can't append a
-// boxed value to a vector-of-boxes using +=. Best to figure out a way to fix
-// this. Deref-on-demand or something? It's a hazard of the ambiguity between
-// single-element and vector append.
-fn append[T](&mutable vec[T] v, &T t) {
- v += t;
-}
-
//
// Local Variables:
// mode: rust