diff options
Diffstat (limited to 'src')
41 files changed, 1300 insertions, 723 deletions
diff --git a/src/Makefile b/src/Makefile index 67a8743e..630babf3 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,3 +1,13 @@ +# Delete the built-in rules. +# This speeds builds up substantially on win32, maybe elsewhere. + +.SUFFIXES: +%:: %,v +%:: RCS/%,v +%:: RCS/% +%:: s.% +%:: SCCS/s.% + ###################################################################### # Auto-configuration ###################################################################### @@ -446,6 +456,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ test/run-pass/iter-ret.rs \ test/run-pass/leak-tag-copy.rs \ test/run-pass/lib-io.rs \ + test/run-pass/maybe-mutable.rs \ test/run-pass/mlist-cycle.rs \ test/run-pass/obj-as.rs \ test/run-pass/seq-compare.rs \ @@ -469,7 +480,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ acyclic-unwind.rs \ alt-pattern-drop.rs \ alt-type-simple.rs \ - append-units.rs \ basic-1.rs \ basic-2.rs \ basic.rs \ @@ -489,6 +499,7 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ lib-sha1.rs \ lib-sort.rs \ lib-str.rs \ + lib-str-buf.rs \ lib-task.rs \ lib-uint.rs \ lib-vec-str-conversions.rs \ diff --git a/src/Makefile.in b/src/Makefile.in deleted file mode 100644 index fd4bd317..00000000 --- a/src/Makefile.in +++ /dev/null @@ -1,129 +0,0 @@ -###################################################################### -# Residual auto-configuration -###################################################################### - -include config.mk -MKFILES := Makefile config.mk - -ifneq ($(MAKE_RESTARTS),) -CFG_INFO := $(info cfg: make restarts: $(MAKE_RESTARTS)) -endif - -CFG_INFO := $(info cfg: building on $(CFG_OSTYPE) $(CFG_CPUTYPE)) - -ifdef CFG_OCAMLC_OPT - $(info cfg: using ocaml native compiler) - OPT=.opt -else - $(info cfg: using ocaml bytecode compiler) -endif - -ifdef PROFILE_BOOT - $(info cfg: building bootstrap compiler with profiling (forcing native)) - CFG_NATIVE_BOOT := 1 - CFG_OCAMLOPT_PROFILE_FLAGS := -p -endif - -ifdef DEBUG - $(info cfg: forcing bytecode bootstrap compiler) - CFG_NATIVE_BOOT := -endif - -ifdef CFG_NATIVE_BOOT - $(info cfg: building native bootstrap compiler) -else - $(info cfg: building bytecode bootstrap compiler) -endif - -ifdef NO_VALGRIND - CFG_VALGRIND := -endif - - -###################################################################### -# Bootstrap compiler variables -###################################################################### - -# We must list them in link order. -# Nobody calculates the link-order DAG automatically, sadly. - -BOOT_MLS := \ - $(addsuffix .ml, \ - $(addprefix boot/util/, version fmt common bits) \ - $(addprefix boot/driver/, session) \ - $(addprefix boot/fe/, ast token lexer parser \ - extfmt pexp item cexp fuzz) \ - $(addprefix boot/be/, asm il abi) \ - $(addprefix boot/me/, walk semant resolve alias \ - simplify type dead layer effect typestate \ - loop layout transutil trans dwarf) \ - $(addprefix boot/be/, x86 ra pe elf macho) \ - $(addprefix boot/driver/, lib glue main)) \ - -BOOT_CMOS := $(BOOT_MLS:.ml=.cmo) -BOOT_CMXS := $(BOOT_MLS:.ml=.cmx) -BOOT_OBJS := $(BOOT_MLS:.ml=.o) -BOOT_CMIS := $(BOOT_MLS:.ml=.cmi) - -ML_DEP_INCS := -I $(S)boot/fe -I $(S)boot/me -I $(S)boot/be \ - -I $(S)boot/driver -I $(S)boot/util - -ML_INCS := $(ML_DEP_INCS) -ML_LIBS := unix.cma nums.cma bigarray.cma -ML_NATIVE_LIBS := unix.cmxa nums.cmxa bigarray.cmxa -OCAMLC_FLAGS := -g $(ML_INCS) -w Ael -warn-error Ael - - -###################################################################### -# Target-and-rule "utility variables" -###################################################################### - -ifdef VERBOSE - Q := - E = -else - Q := @ - E = echo $(1) -endif - -S := $(CFG_SRC_DIR) -X := $(CFG_EXE_SUFFIX) - -# Look in src dir. -VPATH := $(CFG_SRC_DIR) - -# Delete the built-in rules. -.SUFFIXES: -%:: %,v -%:: RCS/%,v -%:: RCS/% -%:: s.% -%:: SCCS/s.% - -###################################################################### -# Targets and rules -###################################################################### - -all: rustboot$(X) - -ifdef CFG_NATIVE_BOOT -rustboot$(X): $(BOOT_CMXS) $(MKFILES) - @$(call E, compile: $@) - $(Q)ocamlopt$(OPT) -o $@ $(OCAMLOPT_FLAGS) $(ML_NATIVE_LIBS) \ - $(BOOT_CMXS) -else -rustboot$(X): $(BOOT_CMOS) $(MKFILES) - @$(call E, compile: $@) - $(Q)ocamlc$(OPT) -o $@ $(OCAMLC_FLAGS) $(ML_LIBS) $(BOOT_CMOS) -endif - - -boot/util/version.ml: $(MKFILES) - $(Q)git log -1 \ - --pretty=format:'let version = "prerelease (%h %ci)";;' >$@ || exit 1 - -%.cmo: %.ml $(MKFILES) - @$(call E, compile: $@) - $(Q)ocamlc$(OPT) -c -o $@ $(OCAMLC_FLAGS) $< - -%.cmo: %.cmi $(MKFILES) diff --git a/src/boot/fe/pexp.ml b/src/boot/fe/pexp.ml index a5f3759a..c4dcfe1d 100644 --- a/src/boot/fe/pexp.ml +++ b/src/boot/fe/pexp.ml @@ -159,7 +159,14 @@ and parse_effect (ps:pstate) : Ast.effect = and parse_mutability (ps:pstate) : Ast.mutability = match peek ps with - MUTABLE -> bump ps; Ast.MUT_mutable + MUTABLE -> + begin + (* HACK: ignore "mutable?" *) + bump ps; + match peek ps with + QUES -> bump ps; Ast.MUT_immutable + | _ -> Ast.MUT_mutable + end | _ -> Ast.MUT_immutable and parse_ty_fn @@ -310,7 +317,12 @@ and parse_atomic_ty (ps:pstate) : Ast.ty = | MUTABLE -> bump ps; - Ast.TY_mutable (parse_ty ps) + begin + (* HACK: ignore "mutable?" *) + match peek ps with + QUES -> bump ps; parse_ty ps + | _ -> Ast.TY_mutable (parse_ty ps) + end | LPAREN -> begin diff --git a/src/boot/me/type.ml b/src/boot/me/type.ml index 87e8e4c1..72bdd404 100644 --- a/src/boot/me/type.ml +++ b/src/boot/me/type.ml @@ -993,8 +993,7 @@ let check_block (cx:Semant.ctxt) : (fn_ctx -> Ast.block -> unit) = let src_ty = check_atom ~deref:true src in let dst_ty = check_lval dst in match fundamental_ty dst_ty, fundamental_ty src_ty with - Ast.TY_vec elt1, Ast.TY_vec elt2 - | Ast.TY_vec elt1, elt2 -> + Ast.TY_vec elt1, Ast.TY_vec elt2 -> if elt1 = elt2 then () else @@ -1002,7 +1001,6 @@ let check_block (cx:Semant.ctxt) : (fn_ctx -> Ast.block -> unit) = "mismatched types in vec-append: %s += %s" (pretty_ty_str dst_ty) (pretty_ty_str src_ty) - | Ast.TY_str, (Ast.TY_mach Common.TY_u8) | Ast.TY_str, Ast.TY_str -> () | _ -> infer_lval src_ty dst; 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 diff --git a/src/configure.sh b/src/configure.sh deleted file mode 100644 index eb741680..00000000 --- a/src/configure.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/sh - -CFG_SRC_DIR=${0%${0##*/}} -CFG_BUILD_DIR=$PWD - -CFG_OSTYPE=$(uname -s) -CFG_CPUTYPE=$(uname -m) - -echo "configuring on $CFG_CPUTYPE $CFG_OSTYPE" - -echo "setting up build directories" -for i in boot/{fe,me,be,driver,util} \ - rt/{isaac,bigint,sync,test} \ - stage{0,1,2} \ - test/{run-pass,compile-{pass,fail}} -do - mkdir -p -v $i -done - -CFG_VALGRIND=$(sh which valgrind) -CFG_OCAMLC_OPT=$(sh which ocamlc.opt) - -echo "copying Makefile" -cp -v ${CFG_SRC_DIR}Makefile.in ./Makefile - -echo "writing config.mk" -cat >config.mk <<EOF - -CFG_OSTYPE := $CFG_OSTYPE -CFG_CPUTYPE := $CFG_CPUTYPE -CFG_SRC_DIR := $CFG_SRC_DIR -CFG_BUILD_DIR := $CFG_BUILD_DIR - -CFG_VALGRIND := $CFG_VALGRIND -CFG_OCAMLC_OPT := $CFG_OCAMLC_OPT - -EOF - -echo "configured ok" diff --git a/src/lib/_str.rs b/src/lib/_str.rs index 526dac8f..93d0a9f2 100644 --- a/src/lib/_str.rs +++ b/src/lib/_str.rs @@ -8,6 +8,8 @@ native "rust" mod rustrt { fn str_byte_len(str s) -> uint; fn str_alloc(uint n_bytes) -> str; fn str_from_vec(vec[u8] b) -> str; + fn str_from_cstr(sbuf cstr) -> str; + fn str_from_buf(sbuf buf, uint len) -> str; fn refcount[T](str s) -> uint; } @@ -111,6 +113,19 @@ fn unsafe_from_bytes(vec[u8] v) -> str { ret rustrt.str_from_vec(v); } +fn unsafe_from_byte(u8 u) -> str { + ret rustrt.str_from_vec(vec(u)); +} + +unsafe fn str_from_cstr(sbuf cstr) -> str { + ret rustrt.str_from_cstr(cstr); +} + +unsafe fn str_from_buf(sbuf buf, uint len) -> str { + ret rustrt.str_from_buf(buf, len); +} + + fn refcount(str s) -> uint { auto r = rustrt.refcount[u8](s); if (r == dbg.const_refcount) { @@ -190,7 +205,6 @@ fn starts_with(str haystack, str needle) -> bool { ret eq(substr(haystack, 0u, needle_len), needle); } - fn ends_with(str haystack, str needle) -> bool { let uint haystack_len = byte_len(haystack); let uint needle_len = byte_len(needle); @@ -206,34 +220,60 @@ fn ends_with(str haystack, str needle) -> bool { needle); } - fn substr(str s, uint begin, uint len) -> str { let str accum = ""; let uint i = begin; while (i < begin+len) { - accum += s.(i); + accum += unsafe_from_byte(s.(i)); i += 1u; } ret accum; } +fn shift_byte(&mutable str s) -> u8 { + auto len = byte_len(s); + check(len > 0u); + auto b = s.(0); + s = substr(s, 1u, len - 1u); + ret b; +} + +fn pop_byte(&mutable str s) -> u8 { + auto len = byte_len(s); + check(len > 0u); + auto b = s.(len - 1u); + s = substr(s, 0u, len - 1u); + ret b; +} + +fn push_byte(&mutable str s, u8 b) { + s += unsafe_from_byte(b); +} + +fn unshift_byte(&mutable str s, u8 b) { + auto res = alloc(byte_len(s) + 1u); + res += unsafe_from_byte(b); + res += s; + s = res; +} + fn split(str s, u8 sep) -> vec[str] { let vec[str] v = vec(); let str accum = ""; let bool ends_with_sep = false; for (u8 c in s) { if (c == sep) { - v += accum; + v += vec(accum); accum = ""; ends_with_sep = true; } else { - accum += c; + accum += unsafe_from_byte(c); ends_with_sep = false; } } if (_str.byte_len(accum) != 0u || ends_with_sep) { - v += accum; + v += vec(accum); } ret v; } diff --git a/src/lib/_uint.rs b/src/lib/_uint.rs index ceee9c77..5e8d4b97 100644 --- a/src/lib/_uint.rs +++ b/src/lib/_uint.rs @@ -61,7 +61,7 @@ fn to_str(mutable uint n, uint radix) -> str let str s = ""; while (n != 0u) { - s += digit(n % radix) as u8; + s += _str.unsafe_from_byte(digit(n % radix) as u8); n /= radix; } @@ -69,7 +69,7 @@ fn to_str(mutable uint n, uint radix) -> str let uint len = _str.byte_len(s); while (len != 0u) { len -= 1u; - s1 += s.(len); + s1 += _str.unsafe_from_byte(s.(len)); } ret s1; diff --git a/src/lib/_vec.rs b/src/lib/_vec.rs index 680c8884..80cd242d 100644 --- a/src/lib/_vec.rs +++ b/src/lib/_vec.rs @@ -103,28 +103,32 @@ fn slice[T](vec[T] v, uint start, uint end) -> vec[T] { ret result; } -fn shift[T](vec[T] v) -> vec[T] { - check(len[T](v) > 0u); - ret slice[T](v, 1u, len[T](v)); +fn shift[T](&mutable vec[T] v) -> T { + auto ln = len[T](v); + check(ln > 0u); + auto e = v.(0); + v = slice[T](v, 1u, ln); + ret e; } -fn pop[T](vec[T] v) -> vec[T] { - check(len[T](v) > 0u); - ret slice[T](v, 0u, len[T](v) - 1u); +fn pop[T](&mutable vec[T] v) -> T { + auto ln = len[T](v); + check(ln > 0u); + ln -= 1u; + auto e = v.(ln); + v = slice[T](v, 0u, ln); + ret e; } -fn push[T](vec[T] v, &T t) -> vec[T] { - v += t; - ret v; +fn push[T](&mutable vec[T] v, &T t) { + v += vec(t); } -fn unshift[T](vec[T] v, &T t) -> vec[T] { +fn unshift[T](&mutable vec[T] v, &T t) { auto res = alloc[T](len[T](v) + 1u); - res += t; - for (T t_ in v) { - res += t_; - } - ret res; + res += vec(t); + res += v; + v = res; } fn grow[T](&mutable vec[T] v, int n, &T initval) { @@ -152,7 +156,7 @@ fn map2[T,U,V](&operator2[T,U,V] f, &vec[T] v0, &vec[U] v1) -> vec[V] { let vec[V] u = alloc[V](v0_len); auto i = 0u; while (i < v0_len) { - u += f(v0.(i), v1.(i)); + u += vec(f(v0.(i), v1.(i))); i += 1u; } diff --git a/src/lib/fs.rs b/src/lib/fs.rs index 1b9ed4b0..677bbcc4 100644 --- a/src/lib/fs.rs +++ b/src/lib/fs.rs @@ -38,8 +38,18 @@ impure fn list_dir(path p) -> vec[str] { let vec[str] full_paths = vec(); for (str filename in os_fs.list_dir(p)) { if (!_str.eq(filename, ".")) {if (!_str.eq(filename, "..")) { - full_paths = _vec.push[str](full_paths, p + filename); + _vec.push[str](full_paths, p + filename); }} } ret full_paths; } + + +// Local Variables: +// mode: rust; +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: diff --git a/src/lib/io.rs b/src/lib/io.rs index 7135c2bc..a84fbbe9 100644 --- a/src/lib/io.rs +++ b/src/lib/io.rs @@ -52,7 +52,8 @@ state obj FILE_reader(os.libc.FILE f, bool must_close) { auto buf = ""; while (true) { auto ch = os.libc.fgetc(f); - if (ch == -1) {break;} if (ch == 10) {break;} + if (ch == -1) { ret buf; } + if (ch == 10) { ret buf; } buf += _str.unsafe_from_bytes(vec(ch as u8)); } ret buf; @@ -61,7 +62,7 @@ state obj FILE_reader(os.libc.FILE f, bool must_close) { auto buf = ""; while (true) { auto ch = os.libc.fgetc(f); - if (ch < 1) {break;} + if (ch < 1) { ret buf; } buf += _str.unsafe_from_bytes(vec(ch as u8)); } ret buf; diff --git a/src/lib/option.rs b/src/lib/option.rs index 25f82b52..29a6f6eb 100644 --- a/src/lib/option.rs +++ b/src/lib/option.rs @@ -31,6 +31,13 @@ fn map[T, U](&operator[T, U] f, &t[T] opt) -> t[U] { fail; // FIXME: remove me when exhaustiveness checking works } +fn is_none[T](&t[T] opt) -> bool { + alt (opt) { + case (none[T]) { ret true; } + case (some[T](_)) { ret false; } + } +} + // Local Variables: // mode: rust; // fill-column: 78; diff --git a/src/lib/posix_fs.rs b/src/lib/posix_fs.rs index 05366a15..0a37f85d 100644 --- a/src/lib/posix_fs.rs +++ b/src/lib/posix_fs.rs @@ -9,11 +9,23 @@ impure fn list_dir(str path) -> vec[str] { let vec[str] result = vec(); while (true) { auto ent = os.libc.readdir(dir); - if (ent as int == 0) {break;} - result = _vec.push[str](result, rustrt.rust_dirent_filename(ent)); + if (ent as int == 0) { + os.libc.closedir(dir); + ret result; + } + _vec.push[str](result, rustrt.rust_dirent_filename(ent)); } os.libc.closedir(dir); ret result; } const char path_sep = '/'; + +// Local Variables: +// mode: rust; +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: diff --git a/src/lib/run_program.rs b/src/lib/run_program.rs index bd9edbc8..f3ea95a1 100644 --- a/src/lib/run_program.rs +++ b/src/lib/run_program.rs @@ -8,9 +8,9 @@ native "rust" mod rustrt { fn argvec(str prog, vec[str] args) -> vec[sbuf] { auto argptrs = vec(_str.buf(prog)); for (str arg in args) { - argptrs = _vec.push[sbuf](argptrs, _str.buf(arg)); + _vec.push[sbuf](argptrs, _str.buf(arg)); } - argptrs = _vec.push[sbuf](argptrs, 0 as sbuf); + _vec.push[sbuf](argptrs, 0 as sbuf); ret argptrs; } diff --git a/src/lib/sha1.rs b/src/lib/sha1.rs index a57ea894..6b4e623b 100644 --- a/src/lib/sha1.rs +++ b/src/lib/sha1.rs @@ -169,10 +169,11 @@ fn mk_sha1() -> sha1 { let vec[u8] res = vec(); for (u32 hpart in st.h) { - res += (hpart >> 24u32) & 0xFFu32 as u8; - res += (hpart >> 16u32) & 0xFFu32 as u8; - res += (hpart >> 8u32) & 0xFFu32 as u8; - res += hpart & 0xFFu32 as u8; + auto a = (hpart >> 24u32) & 0xFFu32 as u8; + auto b = (hpart >> 16u32) & 0xFFu32 as u8; + auto c = (hpart >> 8u32) & 0xFFu32 as u8; + auto d = (hpart & 0xFFu32 as u8); + res += vec(a,b,c,d); } ret res; } diff --git a/src/lib/sort.rs b/src/lib/sort.rs index cff7efce..52839b1f 100644 --- a/src/lib/sort.rs +++ b/src/lib/sort.rs @@ -5,38 +5,38 @@ type lteq[T] = fn(&T a, &T b) -> bool; fn merge_sort[T](lteq[T] le, vec[T] v) -> vec[T] { - fn merge[T](lteq[T] le, vec[T] a, vec[T] b) -> vec[T] { - let vec[T] res = vec(); - let uint a_len = len[T](a); - let uint a_ix = 0u; - let uint b_len = len[T](b); - let uint b_ix = 0u; - while (a_ix < a_len && b_ix < b_len) { - if (le(a.(a_ix), b.(b_ix))) { - res += a.(a_ix); - a_ix += 1u; - } else { - res += b.(b_ix); - b_ix += 1u; - } + fn merge[T](lteq[T] le, vec[T] a, vec[T] b) -> vec[T] { + let vec[T] res = vec(); + let uint a_len = len[T](a); + let uint a_ix = 0u; + let uint b_len = len[T](b); + let uint b_ix = 0u; + while (a_ix < a_len && b_ix < b_len) { + if (le(a.(a_ix), b.(b_ix))) { + res += vec(a.(a_ix)); + a_ix += 1u; + } else { + res += vec(b.(b_ix)); + b_ix += 1u; + } + } + res += slice[T](a, a_ix, a_len); + res += slice[T](b, b_ix, b_len); + ret res; } - res += slice[T](a, a_ix, a_len); - res += slice[T](b, b_ix, b_len); - ret res; - } - let uint v_len = len[T](v); + let uint v_len = len[T](v); - if (v_len <= 1u) { - ret v; - } + if (v_len <= 1u) { + ret v; + } - let uint mid = v_len / 2u; - let vec[T] a = slice[T](v, 0u, mid); - let vec[T] b = slice[T](v, mid, v_len); - ret merge[T](le, - merge_sort[T](le, a), - merge_sort[T](le, b)); + let uint mid = v_len / 2u; + let vec[T] a = slice[T](v, 0u, mid); + let vec[T] b = slice[T](v, mid, v_len); + ret merge[T](le, + merge_sort[T](le, a), + merge_sort[T](le, b)); } // Local Variables: diff --git a/src/lib/std.rc b/src/lib/std.rc index a339fd85..7a3cdbb2 100644 --- a/src/lib/std.rc +++ b/src/lib/std.rc @@ -34,6 +34,17 @@ auth _str = unsafe; auth _vec = unsafe; auth _task = unsafe; + +// FIXME: impure on these will infect caller in a way that is totally +// beyond reason, if the caller's mutated-argument doesn't escape; +// 'impure' needs work. +auth _str.unshift_byte = impure; +auth _str.shift_byte = impure; +auth _str.pop_byte = impure; +auth _vec.shift = impure; +auth _vec.unshift = impure; +auth _vec.pop = impure; + auth dbg = unsafe; auth _uint.next_power_of_two = unsafe; diff --git a/src/lib/win32_fs.rs b/src/lib/win32_fs.rs index 641ef33e..f88d7798 100644 --- a/src/lib/win32_fs.rs +++ b/src/lib/win32_fs.rs @@ -8,3 +8,12 @@ impure fn list_dir(str path) -> vec[str] { } const char path_sep = '\\'; + +// Local Variables: +// mode: rust; +// fill-column: 78; +// indent-tabs-mode: nil +// c-basic-offset: 4 +// buffer-file-coding-system: utf-8-unix +// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'"; +// End: diff --git a/src/llvmext/rustllvm.def b/src/llvmext/rustllvm.def new file mode 100644 index 00000000..c1b521b5 --- /dev/null +++ b/src/llvmext/rustllvm.def @@ -0,0 +1,473 @@ +LIBRARY RUSTLLVM +EXPORTS + LLVMRustCreateMemoryBufferWithContentsOfFile + LLVMRustGetLastError + LLVMCreateObjectFile + LLVMDisposeObjectFile + LLVMGetSections + LLVMDisposeSectionIterator + LLVMIsSectionIteratorAtEnd + LLVMMoveToNextSection + LLVMGetSectionName + LLVMGetSectionSize + LLVMGetSectionContents + LLVMABIAlignmentOfType + LLVMABISizeOfType + LLVMAddAlias + LLVMAddAttribute + LLVMAddCase + LLVMAddDestination + LLVMAddFunction + LLVMAddFunctionAttr + LLVMAddGlobal + LLVMAddGlobalInAddressSpace + LLVMAddGlobalMapping + LLVMAddIncoming + LLVMAddInstrAttribute + LLVMAddModule + LLVMAddModuleProvider + LLVMAddTargetData + LLVMAddTypeName + LLVMAlignOf + LLVMAppendBasicBlock + LLVMAppendBasicBlockInContext + LLVMArrayType + LLVMBasicBlockAsValue + LLVMBlockAddress + LLVMBuildAShr + LLVMBuildAdd + LLVMBuildAggregateRet + LLVMBuildAlloca + LLVMBuildAnd + LLVMBuildArrayAlloca + LLVMBuildArrayMalloc + LLVMBuildBinOp + LLVMBuildBitCast + LLVMBuildBr + LLVMBuildCall + LLVMBuildCast + LLVMBuildCondBr + LLVMBuildExactSDiv + LLVMBuildExtractElement + LLVMBuildExtractValue + LLVMBuildFAdd + LLVMBuildFCmp + LLVMBuildFDiv + LLVMBuildFMul + LLVMBuildFNeg + LLVMBuildFPCast + LLVMBuildFPExt + LLVMBuildFPToSI + LLVMBuildFPToUI + LLVMBuildFPTrunc + LLVMBuildFRem + LLVMBuildFSub + LLVMBuildFree + LLVMBuildGEP + LLVMBuildGlobalString + LLVMBuildGlobalStringPtr + LLVMBuildICmp + LLVMBuildInBoundsGEP + LLVMBuildIndirectBr + LLVMBuildInsertElement + LLVMBuildInsertValue + LLVMBuildIntCast + LLVMBuildIntToPtr + LLVMBuildInvoke + LLVMBuildIsNotNull + LLVMBuildIsNull + LLVMBuildLShr + LLVMBuildLoad + LLVMBuildMalloc + LLVMBuildMul + LLVMBuildNSWAdd + LLVMBuildNSWMul + LLVMBuildNSWNeg + LLVMBuildNSWSub + LLVMBuildNUWAdd + LLVMBuildNUWMul + LLVMBuildNUWNeg + LLVMBuildNUWSub + LLVMBuildNeg + LLVMBuildNot + LLVMBuildOr + LLVMBuildPhi + LLVMBuildPointerCast + LLVMBuildPtrDiff + LLVMBuildPtrToInt + LLVMBuildRet + LLVMBuildRetVoid + LLVMBuildSDiv + LLVMBuildSExt + LLVMBuildSExtOrBitCast + LLVMBuildSIToFP + LLVMBuildSRem + LLVMBuildSelect + LLVMBuildShl + LLVMBuildShuffleVector + LLVMBuildStore + LLVMBuildStructGEP + LLVMBuildSub + LLVMBuildSwitch + LLVMBuildTrunc + LLVMBuildTruncOrBitCast + LLVMBuildUDiv + LLVMBuildUIToFP + LLVMBuildURem + LLVMBuildUnreachable + LLVMBuildUnwind + LLVMBuildVAArg + LLVMBuildXor + LLVMBuildZExt + LLVMBuildZExtOrBitCast + LLVMByteOrder + LLVMCallFrameAlignmentOfType + LLVMClearInsertionPosition + LLVMConstAShr + LLVMConstAdd + LLVMConstAllOnes + LLVMConstAnd + LLVMConstArray + LLVMConstBitCast + LLVMConstExactSDiv + LLVMConstExtractElement + LLVMConstExtractValue + LLVMConstFAdd + LLVMConstFCmp + LLVMConstFDiv + LLVMConstFMul + LLVMConstFNeg + LLVMConstFPCast + LLVMConstFPExt + LLVMConstFPToSI + LLVMConstFPToUI + LLVMConstFPTrunc + LLVMConstFRem + LLVMConstFSub + LLVMConstGEP + LLVMConstICmp + LLVMConstInBoundsGEP + LLVMConstInlineAsm + LLVMConstInsertElement + LLVMConstInsertValue + LLVMConstInt + LLVMConstIntCast + LLVMConstIntGetSExtValue + LLVMConstIntGetZExtValue + LLVMConstIntOfArbitraryPrecision + LLVMConstIntOfString + LLVMConstIntOfStringAndSize + LLVMConstIntToPtr + LLVMConstLShr + LLVMConstMul + LLVMConstNSWAdd + LLVMConstNSWMul + LLVMConstNSWNeg + LLVMConstNSWSub + LLVMConstNUWAdd + LLVMConstNUWMul + LLVMConstNUWNeg + LLVMConstNUWSub + LLVMConstNeg + LLVMConstNot + LLVMConstNull + LLVMConstOr + LLVMConstPointerCast + LLVMConstPointerNull + LLVMConstPtrToInt + LLVMConstReal + LLVMConstRealOfString + LLVMConstRealOfStringAndSize + LLVMConstSDiv + LLVMConstSExt + LLVMConstSExtOrBitCast + LLVMConstSIToFP + LLVMConstSRem + LLVMConstSelect + LLVMConstShl + LLVMConstShuffleVector + LLVMConstString + LLVMConstStringInContext + LLVMConstStruct + LLVMConstStructInContext + LLVMConstSub + LLVMConstTrunc + LLVMConstTruncOrBitCast + LLVMConstUDiv + LLVMConstUIToFP + LLVMConstURem + LLVMConstVector + LLVMConstXor + LLVMConstZExt + LLVMConstZExtOrBitCast + LLVMContextCreate + LLVMContextDispose + LLVMCopyStringRepOfTargetData + LLVMCountBasicBlocks + LLVMCountIncoming + LLVMCountParamTypes + LLVMCountParams + LLVMCountStructElementTypes + LLVMCreateBuilder + LLVMCreateBuilderInContext + LLVMCreateExecutionEngine + LLVMCreateExecutionEngineForModule + LLVMCreateFunctionPassManager + LLVMCreateFunctionPassManagerForModule + LLVMCreateGenericValueOfFloat + LLVMCreateGenericValueOfInt + LLVMCreateGenericValueOfPointer + LLVMCreateInterpreter + LLVMCreateInterpreterForModule + LLVMCreateJITCompiler + LLVMCreateJITCompilerForModule + LLVMCreateMemoryBufferWithContentsOfFile + LLVMCreateMemoryBufferWithSTDIN + LLVMCreateModuleProviderForExistingModule + LLVMCreateObjectFile + LLVMCreatePassManager + LLVMCreateTargetData + LLVMCreateTypeHandle + LLVMDeleteBasicBlock + LLVMDeleteFunction + LLVMDeleteGlobal + LLVMDeleteTypeName + LLVMDisposeBuilder + LLVMDisposeExecutionEngine + LLVMDisposeGenericValue + LLVMDisposeMemoryBuffer + LLVMDisposeMessage + LLVMDisposeModule + LLVMDisposeModuleProvider + LLVMDisposeObjectFile + LLVMDisposePassManager + LLVMDisposeSectionIterator + LLVMDisposeTargetData + LLVMDisposeTypeHandle + LLVMDoubleType + LLVMDoubleTypeInContext + LLVMDumpModule + LLVMDumpValue + LLVMElementAtOffset + LLVMFP128Type + LLVMFP128TypeInContext + LLVMFinalizeFunctionPassManager + LLVMFindFunction + LLVMFloatType + LLVMFloatTypeInContext + LLVMFreeMachineCodeForFunction + LLVMFunctionType + LLVMGenericValueIntWidth + LLVMGenericValueToFloat + LLVMGenericValueToInt + LLVMGenericValueToPointer + LLVMGetAlignment + LLVMGetArrayLength + LLVMGetAttribute + LLVMGetBasicBlockParent + LLVMGetBasicBlocks + LLVMGetBitcodeModule + LLVMGetBitcodeModuleInContext + LLVMGetBitcodeModuleProvider + LLVMGetBitcodeModuleProviderInContext + LLVMGetConstOpcode + LLVMGetCurrentDebugLocation + LLVMGetDataLayout + LLVMGetElementType + LLVMGetEntryBasicBlock + LLVMGetExecutionEngineTargetData + LLVMGetFirstBasicBlock + LLVMGetFirstFunction + LLVMGetFirstGlobal + LLVMGetFirstInstruction + LLVMGetFirstParam + LLVMGetFirstUse + LLVMGetFunctionAttr + LLVMGetFunctionCallConv + LLVMGetGC + LLVMGetGlobalContext + LLVMGetGlobalParent + LLVMGetGlobalPassRegistry + LLVMGetIncomingBlock + LLVMGetIncomingValue + LLVMGetInitializer + LLVMGetInsertBlock + LLVMGetInstructionCallConv + LLVMGetInstructionParent + LLVMGetIntTypeWidth + LLVMGetIntrinsicID + LLVMGetLastBasicBlock + LLVMGetLastFunction + LLVMGetLastGlobal + LLVMGetLastInstruction + LLVMGetLastParam + LLVMGetLinkage + LLVMGetMDKindID + LLVMGetMDKindIDInContext + LLVMGetMetadata + LLVMGetModuleContext + LLVMGetNamedFunction + LLVMGetNamedGlobal + LLVMGetNextBasicBlock + LLVMGetNextFunction + LLVMGetNextGlobal + LLVMGetNextInstruction + LLVMGetNextParam + LLVMGetNextUse + LLVMGetNumOperands + LLVMGetOperand + LLVMGetParam + LLVMGetParamParent + LLVMGetParamTypes + LLVMGetParams + LLVMGetPointerAddressSpace + LLVMGetPointerToGlobal + LLVMGetPreviousBasicBlock + LLVMGetPreviousFunction + LLVMGetPreviousGlobal + LLVMGetPreviousInstruction + LLVMGetPreviousParam + LLVMGetReturnType + LLVMGetSection + LLVMGetSectionContents + LLVMGetSectionName + LLVMGetSectionSize + LLVMGetSections + LLVMGetStructElementTypes + LLVMGetTarget + LLVMGetTypeByName + LLVMGetTypeContext + LLVMGetTypeKind + LLVMGetTypeName + LLVMGetUndef + LLVMGetUsedValue + LLVMGetUser + LLVMGetValueName + LLVMGetVectorSize + LLVMGetVisibility + LLVMHasMetadata + LLVMInitializeAnalysis + LLVMInitializeCodeGen + LLVMInitializeCore + LLVMInitializeFunctionPassManager + LLVMInitializeIPA + LLVMInitializeIPO + LLVMInitializeInstCombine + LLVMInitializeInstrumentation + LLVMInitializeScalarOpts + LLVMInitializeTarget + LLVMInitializeTransformUtils + LLVMInsertBasicBlock + LLVMInsertBasicBlockInContext + LLVMInsertIntoBuilder + LLVMInsertIntoBuilderWithName + LLVMInt16Type + LLVMInt16TypeInContext + LLVMInt1Type + LLVMInt1TypeInContext + LLVMInt32Type + LLVMInt32TypeInContext + LLVMInt64Type + LLVMInt64TypeInContext + LLVMInt8Type + LLVMInt8TypeInContext + LLVMIntPtrType + LLVMIntType + LLVMIntTypeInContext + LLVMInvalidateStructLayout + LLVMIsConstant + LLVMIsDeclaration + LLVMIsFunctionVarArg + LLVMIsGlobalConstant + LLVMIsNull + LLVMIsPackedStruct + LLVMIsSectionIteratorAtEnd + LLVMIsTailCall + LLVMIsThreadLocal + LLVMIsUndef + LLVMLabelType + LLVMLabelTypeInContext + LLVMLinkInInterpreter + LLVMLinkInJIT + LLVMMDNode + LLVMMDNodeInContext + LLVMMDString + LLVMMDStringInContext + LLVMModuleCreateWithName + LLVMModuleCreateWithNameInContext + LLVMMoveBasicBlockAfter + LLVMMoveBasicBlockBefore + LLVMMoveToNextSection + LLVMOffsetOfElement + LLVMOpaqueType + LLVMOpaqueTypeInContext + LLVMPPCFP128Type + LLVMPPCFP128TypeInContext + LLVMParseBitcode + LLVMParseBitcodeInContext + LLVMPointerSize + LLVMPointerType + LLVMPositionBuilder + LLVMPositionBuilderAtEnd + LLVMPositionBuilderBefore + LLVMPreferredAlignmentOfGlobal + LLVMPreferredAlignmentOfType + LLVMRecompileAndRelinkFunction + LLVMRefineType + LLVMRemoveAttribute + LLVMRemoveFunctionAttr + LLVMRemoveInstrAttribute + LLVMRemoveModule + LLVMRemoveModuleProvider + LLVMReplaceAllUsesWith + LLVMResolveTypeHandle + LLVMRunFunction + LLVMRunFunctionAsMain + LLVMRunFunctionPassManager + LLVMRunPassManager + LLVMRunStaticConstructors + LLVMRunStaticDestructors + LLVMSetAlignment + LLVMSetCurrentDebugLocation + LLVMSetDataLayout + LLVMSetFunctionCallConv + LLVMSetGC + LLVMSetGlobalConstant + LLVMSetInitializer + LLVMSetInstDebugLocation + LLVMSetInstrParamAlignment + LLVMSetInstructionCallConv + LLVMSetLinkage + LLVMSetMetadata + LLVMSetModuleInlineAsm + LLVMSetOperand + LLVMSetParamAlignment + LLVMSetSection + LLVMSetTailCall + LLVMSetTarget + LLVMSetThreadLocal + LLVMSetValueName + LLVMSetVisibility + LLVMSizeOf + LLVMSizeOfTypeInBits + LLVMStoreSizeOfType + LLVMStructType + LLVMStructTypeInContext + LLVMTypeOf + LLVMValueAsBasicBlock + LLVMValueIsBasicBlock + LLVMVectorType + LLVMVerifyFunction + LLVMVerifyModule + LLVMViewFunctionCFG + LLVMViewFunctionCFGOnly + LLVMVoidType + LLVMVoidTypeInContext + LLVMWriteBitcodeToFD + LLVMWriteBitcodeToFile + LLVMWriteBitcodeToFileHandle + LLVMX86FP80Type + LLVMX86FP80TypeInContext + LLVMX86MMXType + LLVMX86MMXTypeInContext + diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp index fcea449d..1f17fc8c 100644 --- a/src/rt/rust_builtin.cpp +++ b/src/rt/rust_builtin.cpp @@ -207,6 +207,29 @@ str_from_vec(rust_task *task, rust_vec *v) return st; } +extern "C" CDECL rust_str * +str_from_cstr(rust_task *task, char *sbuf) +{ + size_t len = strlen(sbuf) + 1; + rust_str *st = vec_alloc_with_data(task, len, len, 1, sbuf); + if (!st) { + task->fail(2); + return NULL; + } + return st; +} + +extern "C" CDECL rust_str * +str_from_buf(rust_task *task, char *buf, unsigned int len) { + rust_str *st = vec_alloc_with_data(task, len + 1, len, 1, buf); + if (!st) { + task->fail(2); + return NULL; + } + st->data[st->fill++] = '\0'; + return st; +} + extern "C" CDECL void * rand_new(rust_task *task) { diff --git a/src/test/bench/99-bottles/99bob-iter.rs b/src/test/bench/99-bottles/99bob-iter.rs index 336939c8..09638941 100644 --- a/src/test/bench/99-bottles/99bob-iter.rs +++ b/src/test/bench/99-bottles/99bob-iter.rs @@ -40,7 +40,7 @@ case (1) { b += ns; } else { - b += t.(i); + _str.push_byte(b, t.(i)); } i += 1u; } diff --git a/src/test/bench/99-bottles/99bob-simple.rs b/src/test/bench/99-bottles/99bob-simple.rs index 10fec27a..3c426f51 100644 --- a/src/test/bench/99-bottles/99bob-simple.rs +++ b/src/test/bench/99-bottles/99bob-simple.rs @@ -39,7 +39,7 @@ case (1) { b += ns; } else { - b += t.(i); + _str.push_byte(b, t.(i)); } i += 1u; } diff --git a/src/test/bench/shootout/fasta.rs b/src/test/bench/shootout/fasta.rs index ffec6db9..f88f4330 100644 --- a/src/test/bench/shootout/fasta.rs +++ b/src/test/bench/shootout/fasta.rs @@ -28,7 +28,7 @@ fn make_cumulative(vec[aminoacids] aa) -> vec[aminoacids] { let vec[aminoacids] ans = vec(); for (aminoacids a in aa) { cp += a._1; - ans += tup(a._0, cp); + ans += vec(tup(a._0, cp)); } ret ans; } @@ -59,7 +59,7 @@ fn make_random_fasta(str id, str desc, vec[aminoacids] genelist, int n) { auto rng = myrandom(std.rand.mk_rng().next()); let str op = ""; for each (uint i in _uint.range(0u, n as uint)) { - op += select_random(rng.next(100u32), genelist) as u8; + _str.push_byte(op, select_random(rng.next(100u32), genelist) as u8); if (_str.byte_len(op) >= LINE_LENGTH()) { log(op); op = ""; @@ -76,7 +76,7 @@ fn make_repeat_fasta(str id, str desc, str s, int n) { let uint sl = _str.byte_len(s); for each (uint i in _uint.range(0u, n as uint)) { - op += s.(i % sl); + _str.push_byte(op, s.(i % sl)); if (_str.byte_len(op) >= LINE_LENGTH()) { log(op); op = ""; diff --git a/src/test/run-pass/append-units.rs b/src/test/run-pass/append-units.rs deleted file mode 100644 index 05b3478b..00000000 --- a/src/test/run-pass/append-units.rs +++ /dev/null @@ -1,15 +0,0 @@ -fn main() { - auto v = vec(1,2,3); - v += 4; - v += 5; - check (v.(3) == 4); - check (v.(4) == 5); - - auto s = "hello"; - log s; - s += 'z' as u8; - s += 'y' as u8; - log s; - check (s.(5) == 'z' as u8); - check (s.(6) == 'y' as u8); -} diff --git a/src/test/run-pass/lib-str-buf.rs b/src/test/run-pass/lib-str-buf.rs new file mode 100644 index 00000000..7ba19e92 --- /dev/null +++ b/src/test/run-pass/lib-str-buf.rs @@ -0,0 +1,14 @@ +// -*- rust -*- + +use std; +import std._str; + +fn main() { + auto s = "hello"; + auto sb = _str.rustrt.str_buf(s); + auto s_cstr = _str.rustrt.str_from_cstr(sb); + check (_str.eq(s_cstr, s)); + auto s_buf = _str.rustrt.str_from_buf(sb, 5u); + check (_str.eq(s_buf, s)); +} + diff --git a/src/test/run-pass/maybe-mutable.rs b/src/test/run-pass/maybe-mutable.rs new file mode 100644 index 00000000..c0af0867 --- /dev/null +++ b/src/test/run-pass/maybe-mutable.rs @@ -0,0 +1,17 @@ +// -*- rust -*- + +fn len(vec[mutable? int] v) -> uint { + auto i = 0u; + for (int x in v) { + i += 1u; + } + ret i; +} + +fn main() { + auto v0 = vec(1, 2, 3, 4, 5); + log len(v0); + auto v1 = vec(mutable 1, 2, 3, 4, 5); + log len(v1); +} + |