From 70bf54bcac587c0bc8a3a593bda75115e4c23aa8 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 1 Feb 2011 16:23:48 -0800 Subject: Implement 'else if' --- src/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 56a98b984f5..ac7dfcbbb71 100644 --- a/src/Makefile +++ b/src/Makefile @@ -447,6 +447,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ div-mod.rs \ drop-bind-thunk-args.rs \ drop-on-ret.rs \ + else-if.rs \ fact.rs \ fn-lval.rs \ fun-call-variants.rs \ -- cgit 1.4.1-3-g733a5 From 4b06dc574ba7d3ae50795cbe4f10d4be6e9c64a1 Mon Sep 17 00:00:00 2001 From: Rafael Ávila de Espíndola Date: Tue, 1 Feb 2011 13:40:04 -0500 Subject: Add very minimal support for native modules. For now they must be empty. --- src/Makefile | 1 + src/comp/front/ast.rs | 6 ++++++ src/comp/front/parser.rs | 19 +++++++++++++++++++ src/comp/middle/fold.rs | 31 +++++++++++++++++++++++++++++-- src/comp/middle/typeck.rs | 4 ++++ src/test/run-pass/native2.rs | 5 +++++ 6 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 src/test/run-pass/native2.rs (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index ac7dfcbbb71..221ec9ffcca 100644 --- a/src/Makefile +++ b/src/Makefile @@ -476,6 +476,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ linear-for-loop.rs \ multiline-comment.rs \ mutual-recursion-group.rs \ + native2.rs \ obj-drop.rs \ obj-recursion.rs \ obj-with-vec.rs \ diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index be47615a502..5f527f2d3b3 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -227,6 +227,8 @@ type _mod = rec(vec[@view_item] view_items, vec[@item] items, mod_index index); +type native_mod = rec(str native_name); + type variant_arg = rec(@ty ty, def_id id); type variant = rec(str name, vec[variant_arg] args, def_id id, ann ann); @@ -241,6 +243,7 @@ tag item_ { item_const(ident, @ty, @expr, def_id, ann); item_fn(ident, _fn, vec[ty_param], def_id, ann); item_mod(ident, _mod, def_id); + item_native_mod(ident, native_mod, def_id); item_ty(ident, @ty, vec[ty_param], def_id, ann); item_tag(ident, vec[variant], vec[ty_param], def_id); item_obj(ident, _obj, vec[ty_param], def_id, ann); @@ -268,6 +271,9 @@ fn index_item(mod_index index, @item it) { case (ast.item_mod(?id, _, _)) { index.insert(id, ast.mie_item(it)); } + case (ast.item_native_mod(?id, _, _)) { + index.insert(id, ast.mie_item(it)); + } case (ast.item_ty(?id, _, _, _, _)) { index.insert(id, ast.mie_item(it)); } diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 0c90df5c783..16adfedb0c1 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -1577,6 +1577,20 @@ impure fn parse_item_mod(parser p) -> @ast.item { ret @spanned(lo, hi, item); } +impure fn parse_item_native_mod(parser p) -> @ast.item { + auto lo = p.get_span(); + expect(p, token.NATIVE); + auto native_name = parse_str_lit(p); + expect(p, token.MOD); + auto id = parse_ident(p); + expect(p, token.LBRACE); + auto m = rec(native_name = native_name); + auto hi = p.get_span(); + expect(p, token.RBRACE); + auto item = ast.item_native_mod(id, m, p.next_def_id()); + ret @spanned(lo, hi, item); +} + impure fn parse_item_type(parser p) -> @ast.item { auto lo = p.get_span(); expect(p, token.TYPE); @@ -1717,6 +1731,11 @@ impure fn parse_item(parser p) -> @ast.item { check (lyr == ast.layer_value); ret parse_item_mod(p); } + case (token.NATIVE) { + check (eff == ast.eff_pure); + check (lyr == ast.layer_value); + ret parse_item_native_mod(p); + } case (token.TYPE) { check (eff == ast.eff_pure); ret parse_item_type(p); diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index 7e6839a831e..2426d8ae8cc 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -196,6 +196,9 @@ type ast_fold[ENV] = (fn(&ENV e, &span sp, ident ident, &ast._mod m, def_id id) -> @item) fold_item_mod, + (fn(&ENV e, &span sp, ident ident, + &ast.native_mod m, def_id id) -> @item) fold_item_native_mod, + (fn(&ENV e, &span sp, ident ident, @ty t, vec[ast.ty_param] ty_params, def_id id, ann a) -> @item) fold_item_ty, @@ -229,6 +232,8 @@ type ast_fold[ENV] = (fn(&ENV e, &ast._mod m) -> ast._mod) fold_mod, + (fn(&ENV e, &ast.native_mod m) -> ast.native_mod) fold_native_mod, + (fn(&ENV e, &span sp, &ast._mod m) -> @ast.crate) fold_crate, @@ -780,6 +785,11 @@ fn fold_item[ENV](&ENV env, ast_fold[ENV] fld, @item i) -> @item { ret fld.fold_item_mod(env_, i.span, ident, mm_, id); } + case (ast.item_native_mod(?ident, ?mm, ?id)) { + let ast.native_mod mm_ = fold_native_mod[ENV](env_, fld, mm); + ret fld.fold_item_native_mod(env_, i.span, ident, mm_, id); + } + case (ast.item_ty(?ident, ?ty, ?params, ?id, ?ann)) { let @ast.ty ty_ = fold_ty[ENV](env_, fld, ty); ret fld.fold_item_ty(env_, i.span, ident, ty_, params, id, ann); @@ -810,7 +820,6 @@ fn fold_item[ENV](&ENV env, ast_fold[ENV] fld, @item i) -> @item { fail; } - fn fold_mod[ENV](&ENV e, ast_fold[ENV] fld, &ast._mod m) -> ast._mod { let vec[@view_item] view_items = vec(); @@ -830,7 +839,12 @@ fn fold_mod[ENV](&ENV e, ast_fold[ENV] fld, &ast._mod m) -> ast._mod { } ret fld.fold_mod(e, rec(view_items=view_items, items=items, index=index)); - } +} + +fn fold_native_mod[ENV](&ENV e, ast_fold[ENV] fld, + &ast.native_mod m) -> ast.native_mod { + ret fld.fold_native_mod(e, rec(native_name = m.native_name)); +} fn fold_crate[ENV](&ENV env, ast_fold[ENV] fld, @ast.crate c) -> @ast.crate { let ENV env_ = fld.update_env_for_crate(env, c); @@ -1105,6 +1119,11 @@ fn identity_fold_item_mod[ENV](&ENV e, &span sp, ident i, ret @respan(sp, ast.item_mod(i, m, id)); } +fn identity_fold_item_native_mod[ENV](&ENV e, &span sp, ident i, + &ast.native_mod m, def_id id) -> @item { + ret @respan(sp, ast.item_native_mod(i, m, id)); +} + fn identity_fold_item_ty[ENV](&ENV e, &span sp, ident i, @ty t, vec[ast.ty_param] ty_params, def_id id, ann a) -> @item { @@ -1159,6 +1178,11 @@ fn identity_fold_mod[ENV](&ENV e, &ast._mod m) -> ast._mod { ret m; } +fn identity_fold_native_mod[ENV](&ENV e, + &ast.native_mod m) -> ast.native_mod { + ret m; +} + fn identity_fold_crate[ENV](&ENV e, &span sp, &ast._mod m) -> @ast.crate { ret @respan(sp, rec(module=m)); } @@ -1281,6 +1305,8 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] { fold_item_const= bind identity_fold_item_const[ENV](_,_,_,_,_,_,_), fold_item_fn = bind identity_fold_item_fn[ENV](_,_,_,_,_,_,_), fold_item_mod = bind identity_fold_item_mod[ENV](_,_,_,_,_), + fold_item_native_mod = + bind identity_fold_item_native_mod[ENV](_,_,_,_,_), fold_item_ty = bind identity_fold_item_ty[ENV](_,_,_,_,_,_,_), fold_item_tag = bind identity_fold_item_tag[ENV](_,_,_,_,_,_), fold_item_obj = bind identity_fold_item_obj[ENV](_,_,_,_,_,_,_), @@ -1293,6 +1319,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] { fold_block = bind identity_fold_block[ENV](_,_,_), fold_fn = bind identity_fold_fn[ENV](_,_,_,_,_,_), fold_mod = bind identity_fold_mod[ENV](_,_), + fold_native_mod = bind identity_fold_native_mod[ENV](_,_), fold_crate = bind identity_fold_crate[ENV](_,_,_), fold_obj = bind identity_fold_obj[ENV](_,_,_), diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 725c02fdde5..43d35b37041 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -376,6 +376,7 @@ fn collect_item_types(session.session sess, @ast.crate crate) } case (ast.item_mod(_, _, _)) { fail; } + case (ast.item_native_mod(_, _, _)) { fail; } } } @@ -455,6 +456,9 @@ fn collect_item_types(session.session sess, @ast.crate crate) case (ast.item_mod(_, _, _)) { // ignore item_mod, it has no type. } + case (ast.item_native_mod(_, _, _)) { + // ignore item_native_mod, it has no type. + } case (_) { // This call populates the ty_table with the converted type of // the item in passing; we don't need to do anything else. diff --git a/src/test/run-pass/native2.rs b/src/test/run-pass/native2.rs new file mode 100644 index 00000000000..abb6335249a --- /dev/null +++ b/src/test/run-pass/native2.rs @@ -0,0 +1,5 @@ +native "rust" mod rustrt { +} + +fn main(vec[str] args) { +} -- cgit 1.4.1-3-g733a5 From 8c0d35066bcc0ab0eb35818f4de63bccee097e5c Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Wed, 9 Feb 2011 09:54:58 -0800 Subject: Elide passed-typarams when tydescs are captured. Un-XFAIL generic-obj.rs. --- src/Makefile | 1 + src/comp/middle/trans.rs | 28 ++++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 221ec9ffcca..bd7b616fe16 100644 --- a/src/Makefile +++ b/src/Makefile @@ -455,6 +455,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ generic-fn.rs \ generic-fn-infer.rs \ generic-drop-glue.rs \ + generic-obj.rs \ generic-tup.rs \ generic-type.rs \ hello.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 4401f8852c7..2a9c32da5e4 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -399,13 +399,15 @@ fn type_of_fn_full(@crate_ctxt cx, } } - // Args >3: ty params ... - auto ty_param_count = - ty.count_ty_params(plain_ty(ty.ty_fn(inputs, output))); - auto i = 0u; - while (i < ty_param_count) { - atys += T_ptr(T_tydesc()); - i += 1u; + // Args >3: ty params, if not acquired via capture... + if (obj_self == none[TypeRef]) { + auto ty_param_count = + ty.count_ty_params(plain_ty(ty.ty_fn(inputs, output))); + auto i = 0u; + while (i < ty_param_count) { + atys += T_ptr(T_tydesc()); + i += 1u; + } } // ... then explicit args. @@ -3387,11 +3389,13 @@ fn create_llargs_for_fn_args(&@fn_ctxt cx, auto arg_n = 3u; - for (ast.ty_param tp in ty_params) { - auto llarg = llvm.LLVMGetParam(cx.llfn, arg_n); - check (llarg as int != 0); - cx.lltydescs.insert(tp.id, llarg); - arg_n += 1u; + if (ty_self == none[TypeRef]) { + for (ast.ty_param tp in ty_params) { + auto llarg = llvm.LLVMGetParam(cx.llfn, arg_n); + check (llarg as int != 0); + cx.lltydescs.insert(tp.id, llarg); + arg_n += 1u; + } } -- cgit 1.4.1-3-g733a5 From 6e39102299eb962ac3c381e73ed7fcca68192f45 Mon Sep 17 00:00:00 2001 From: Rob Arnold Date: Thu, 3 Feb 2011 22:59:04 -0800 Subject: Add FreeBSD support in the Makefile --- src/Makefile | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index bd7b616fe16..0c3bf6d3d9e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -32,6 +32,26 @@ CFG_RUSTC_FLAGS := -nowarn # embedded into the executable, so use a no-op command. DSYMUTIL := true +ifeq ($(CFG_OSTYPE), FreeBSD) + CFG_RUNTIME := librustrt.so + CFG_STDLIB := libstd.so + CFG_GCC_CFLAGS += -fPIC -march=i686 -I/usr/local/include + CFG_GCC_LINK_FLAGS += -shared -fPIC -lpthread -lrt + ifeq ($(CFG_CPUTYPE), x86_64) + CFG_GCC_CFLAGS += -m32 + CFG_GCC_LINK_FLAGS += -m32 + endif + CFG_NATIVE := 1 + CFG_UNIXY := 1 + CFG_VALGRIND := $(shell which valgrind) + ifdef CFG_VALGRIND + CFG_VALGRIND += --leak-check=full \ + --error-exitcode=1 \ + --quiet --vex-iropt-level=0 \ + --suppressions=etc/x86.supp + endif +endif + ifeq ($(CFG_OSTYPE), Linux) CFG_RUNTIME := librustrt.so CFG_STDLIB := libstd.so -- cgit 1.4.1-3-g733a5 From b7dfbc9db079a6c55d9e716d295f87597752b668 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Wed, 9 Feb 2011 13:19:20 -0800 Subject: Fix bug in test and un-XFAIL 4 tests now passing on rustc. --- src/Makefile | 4 ++++ src/test/run-pass/generic-type-synonym.rs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 0c3bf6d3d9e..02bd8708601 100644 --- a/src/Makefile +++ b/src/Makefile @@ -474,10 +474,12 @@ TEST_XFAILS_RUSTC := $(filter-out \ fun-indirect-call.rs \ generic-fn.rs \ generic-fn-infer.rs \ + generic-exterior-box.rs \ generic-drop-glue.rs \ generic-obj.rs \ generic-tup.rs \ generic-type.rs \ + generic-type-synonym.rs \ hello.rs \ int.rs \ i32-sub.rs \ @@ -489,6 +491,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ import6.rs \ import7.rs \ import8.rs \ + inner-module.rs \ item-name-overload.rs \ large-records.rs \ lazy-init.rs \ @@ -505,6 +508,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ opeq.rs \ output-slot-variants.rs \ over-constrained-vregs.rs \ + path.rs \ readalias.rs \ rec.rs \ rec-auto.rs \ diff --git a/src/test/run-pass/generic-type-synonym.rs b/src/test/run-pass/generic-type-synonym.rs index 4ddc8946ba4..c3d2a9d5903 100644 --- a/src/test/run-pass/generic-type-synonym.rs +++ b/src/test/run-pass/generic-type-synonym.rs @@ -1,4 +1,4 @@ type foo[T] = tup(T); type bar[T] = foo[T]; -fn takebar[T](bar[T] b) {} +fn takebar[T](&bar[T] b) {} fn main() {} \ No newline at end of file -- cgit 1.4.1-3-g733a5 From 378c0087ca7572cd17726c704fe04d57bf4687af Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 30 Jan 2011 17:18:19 -0500 Subject: Parse 'be' statement. Pass tailcall tests. No actual tailcalls yet. --- src/Makefile | 3 +++ src/comp/front/ast.rs | 1 + src/comp/front/parser.rs | 7 +++++++ src/comp/middle/fold.rs | 13 +++++++++++++ src/comp/middle/trans.rs | 9 +++++++++ src/comp/middle/typeck.rs | 15 +++++++++++++++ 6 files changed, 48 insertions(+) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 02bd8708601..5c3f297f788 100644 --- a/src/Makefile +++ b/src/Makefile @@ -517,6 +517,9 @@ TEST_XFAILS_RUSTC := $(filter-out \ simple-obj.rs \ stateful-obj.rs \ str-idx.rs \ + tail-call-arg-leak.rs \ + tail-cps.rs \ + tail-direct.rs \ type-in-nested-module.rs \ type-param.rs \ tup.rs \ diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 5f315e58262..756a7ad1e6b 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -116,6 +116,7 @@ type stmt = spanned[stmt_]; tag stmt_ { stmt_decl(@decl); stmt_ret(option.t[@expr]); + stmt_be(@expr); stmt_log(@expr); stmt_check_expr(@expr); stmt_fail; diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index 8d1309352bb..a1b519ba7f5 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -1200,6 +1200,12 @@ impure fn parse_stmt(parser p) -> @ast.stmt { } } + case (token.BE) { + p.bump(); + auto e = parse_expr(p); + ret @spanned(lo, e.span, ast.stmt_be(e)); + } + case (token.LET) { auto decl = parse_let(p); auto hi = p.get_span(); @@ -1340,6 +1346,7 @@ fn stmt_ends_with_semi(@ast.stmt stmt) -> bool { } } case (ast.stmt_ret(_)) { ret true; } + case (ast.stmt_be(_)) { ret true; } case (ast.stmt_log(_)) { ret true; } case (ast.stmt_check_expr(_)) { ret true; } case (ast.stmt_fail) { ret true; } diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index 7e5c2d26aef..9194f734bee 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -176,6 +176,9 @@ type ast_fold[ENV] = (fn(&ENV e, &span sp, &option.t[@expr] rv) -> @stmt) fold_stmt_ret, + (fn(&ENV e, &span sp, + @expr e) -> @stmt) fold_stmt_be, + (fn(&ENV e, &span sp, @expr e) -> @stmt) fold_stmt_log, @@ -636,6 +639,11 @@ fn fold_stmt[ENV](&ENV env, ast_fold[ENV] fld, &@stmt s) -> @stmt { ret fld.fold_stmt_ret(env_, s.span, oee); } + case (ast.stmt_be(?e)) { + auto ee = fold_expr(env_, fld, e); + ret fld.fold_stmt_be(env_, s.span, ee); + } + case (ast.stmt_log(?e)) { auto ee = fold_expr(env_, fld, e); ret fld.fold_stmt_log(env_, s.span, ee); @@ -1136,6 +1144,10 @@ fn identity_fold_stmt_ret[ENV](&ENV env, &span sp, ret @respan(sp, ast.stmt_ret(rv)); } +fn identity_fold_stmt_be[ENV](&ENV env, &span sp, @expr x) -> @stmt { + ret @respan(sp, ast.stmt_be(x)); +} + fn identity_fold_stmt_log[ENV](&ENV e, &span sp, @expr x) -> @stmt { ret @respan(sp, ast.stmt_log(x)); } @@ -1366,6 +1378,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] { fold_stmt_decl = bind identity_fold_stmt_decl[ENV](_,_,_), fold_stmt_ret = bind identity_fold_stmt_ret[ENV](_,_,_), + fold_stmt_be = bind identity_fold_stmt_be[ENV](_,_,_), fold_stmt_log = bind identity_fold_stmt_log[ENV](_,_,_), fold_stmt_check_expr = bind identity_fold_stmt_check_expr[ENV](_,_,_), diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 2a9c32da5e4..499ab027d50 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3128,6 +3128,11 @@ fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result { ret res(bcx, C_nil()); } +fn trans_be(@block_ctxt cx, @ast.expr e) -> result { + // FIXME: So this isn't actually a tail call + ret trans_ret(cx, some(e)); +} + fn init_local(@block_ctxt cx, @ast.local local) -> result { // Make a note to drop this slot on the way out. @@ -3178,6 +3183,10 @@ fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result { bcx = trans_ret(cx, e).bcx; } + case (ast.stmt_be(?e)) { + bcx = trans_be(cx, e).bcx; + } + case (ast.stmt_expr(?e)) { bcx = trans_expr(cx, e).bcx; } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 5b14eea4101..7a2b0616d2b 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1719,6 +1719,21 @@ fn check_stmt(&@fn_ctxt fcx, &@ast.stmt stmt) -> @ast.stmt { } } + case (ast.stmt_be(?expr)) { + alt (expr.node) { + case (ast.expr_call(_, _, _)) { + auto expr_0 = check_expr(fcx, expr); + auto expr_1 = demand_expr(fcx, fcx.ret_ty, expr_0); + ret @fold.respan[ast.stmt_](stmt.span, + ast.stmt_be(expr_1)); + } + case (_) { + fcx.ccx.sess.err("Non-call expression in tail call"); + fail; + } + } + } + case (ast.stmt_log(?expr)) { auto expr_t = check_expr(fcx, expr); ret @fold.respan[ast.stmt_](stmt.span, ast.stmt_log(expr_t)); -- cgit 1.4.1-3-g733a5 From 6461cf30de748fbe310640cd9c195965fc3da229 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 30 Jan 2011 17:38:46 -0500 Subject: Add compile-fail tests for tail calls --- src/Makefile | 3 +++ src/test/compile-fail/tail-non-call.rs | 10 ++++++++++ src/test/compile-fail/tail-typeck.rs | 13 +++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 src/test/compile-fail/tail-non-call.rs create mode 100644 src/test/compile-fail/tail-typeck.rs (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 5c3f297f788..7a31c24a041 100644 --- a/src/Makefile +++ b/src/Makefile @@ -434,6 +434,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ test/compile-fail/bad-recv.rs \ test/compile-fail/bad-send.rs \ test/compile-fail/infinite-vec-type-recursion.rs \ + test/compile-fail/tail-non-call.rs \ test/compile-fail/writing-through-read-alias.rs # Same strategy here for the time being: just list the ones that @@ -555,6 +556,8 @@ TEST_XFAILS_RUSTC := $(filter-out \ multiline-comment-line-tracking.rs \ output-type-mismatch.rs \ rec-missing-fields.rs \ + tail-non-call.rs \ + tail-typeck.rs \ type-shadow.rs \ while-type-error.rs \ wrong-ret-type.rs \ diff --git a/src/test/compile-fail/tail-non-call.rs b/src/test/compile-fail/tail-non-call.rs new file mode 100644 index 00000000000..2742d1fe89d --- /dev/null +++ b/src/test/compile-fail/tail-non-call.rs @@ -0,0 +1,10 @@ +// error-pattern: Non-call expression in tail call + +fn f() -> int { + auto x = 1; + be x; +} + +fn main() { + auto y = f(); +} \ No newline at end of file diff --git a/src/test/compile-fail/tail-typeck.rs b/src/test/compile-fail/tail-typeck.rs new file mode 100644 index 00000000000..10b95546f22 --- /dev/null +++ b/src/test/compile-fail/tail-typeck.rs @@ -0,0 +1,13 @@ +// error-pattern: mismatched types + +fn f() -> int { + be g(); +} + +fn g() -> uint { + ret 0u; +} + +fn main() { + auto y = f(); +} \ No newline at end of file -- cgit 1.4.1-3-g733a5 From 2b669008a8bcfcf0d1ed41cecd243e59cded4ded Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 10 Feb 2011 15:04:11 -0800 Subject: Un-XFAIL generic-derived-type.rs. --- src/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 7a31c24a041..a1c38bb9234 100644 --- a/src/Makefile +++ b/src/Makefile @@ -473,6 +473,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ fn-lval.rs \ fun-call-variants.rs \ fun-indirect-call.rs \ + generic-derived-type.rs \ generic-fn.rs \ generic-fn-infer.rs \ generic-exterior-box.rs \ -- cgit 1.4.1-3-g733a5 From 7c25fb5628c398b79b9293b6b31d62936dcba613 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 10 Feb 2011 17:33:08 -0800 Subject: Fix bug in trans_field, un-XFAIL two more tests. --- src/Makefile | 2 ++ src/comp/middle/trans.rs | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index a1c38bb9234..c1f33b91929 100644 --- a/src/Makefile +++ b/src/Makefile @@ -449,6 +449,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ arith-0.rs \ arith-1.rs \ arith-2.rs \ + auto-instantiate.rs \ autoderef-full-lval.rs \ bind-exterior.rs \ bind-interior.rs \ @@ -479,6 +480,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ generic-exterior-box.rs \ generic-drop-glue.rs \ generic-obj.rs \ + generic-obj-with-derived-type.rs \ generic-tup.rs \ generic-type.rs \ generic-type-synonym.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 6399b900f5e..4135a6e59de 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -2376,10 +2376,8 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt, fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base, &ast.ident field, &ast.ann ann) -> lval_result { - auto lv = trans_lval(cx, base); - auto r = lv.res; + auto r = trans_expr(cx, base); r = autoderef(r.bcx, r.val, ty.expr_ty(base)); - check (lv.is_mem); auto t = ty.expr_ty(base); alt (t.struct) { case (ty.ty_tup(?fields)) { -- cgit 1.4.1-3-g733a5 From 7446af747d83622c849ec9f29c0365aa7bf4e697 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 10 Feb 2011 19:40:02 -0800 Subject: Translate pat_lit, un-XFAIL alt-pattern-lit.rs for rustc. --- src/Makefile | 1 + src/comp/middle/trans.rs | 42 ++++++++++++++++++++++++++++++------------ 2 files changed, 31 insertions(+), 12 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index c1f33b91929..d55a63c2797 100644 --- a/src/Makefile +++ b/src/Makefile @@ -444,6 +444,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ TEST_XFAILS_RUSTC := $(filter-out \ $(addprefix test/run-pass/, \ alt-path.rs \ + alt-pattern-lit.rs \ alt-pattern-simple.rs \ alt-tag.rs \ arith-0.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 4135a6e59de..bedfad97980 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1838,6 +1838,24 @@ fn trans_unary(@block_ctxt cx, ast.unop op, fail; } +// FIXME: implement proper structural comparison. + +fn trans_compare(@block_ctxt cx, ast.binop op, + ValueRef lhs, ValueRef rhs) -> ValueRef { + auto cmp = lib.llvm.LLVMIntEQ; + alt (op) { + case (ast.eq) { cmp = lib.llvm.LLVMIntEQ; } + case (ast.ne) { cmp = lib.llvm.LLVMIntNE; } + + // FIXME (issue #57): switch by signedness. + case (ast.lt) { cmp = lib.llvm.LLVMIntSLT; } + case (ast.le) { cmp = lib.llvm.LLVMIntSLE; } + case (ast.ge) { cmp = lib.llvm.LLVMIntSGE; } + case (ast.gt) { cmp = lib.llvm.LLVMIntSGT; } + } + ret cx.build.ICmp(cmp, lhs, rhs); +} + fn trans_eager_binop(@block_ctxt cx, ast.binop op, ValueRef lhs, ValueRef rhs) -> ValueRef { @@ -1857,18 +1875,7 @@ fn trans_eager_binop(@block_ctxt cx, ast.binop op, case (ast.lsr) { ret cx.build.LShr(lhs, rhs); } case (ast.asr) { ret cx.build.AShr(lhs, rhs); } case (_) { - auto cmp = lib.llvm.LLVMIntEQ; - alt (op) { - case (ast.eq) { cmp = lib.llvm.LLVMIntEQ; } - case (ast.ne) { cmp = lib.llvm.LLVMIntNE; } - - // FIXME (issue #57): switch by signedness. - case (ast.lt) { cmp = lib.llvm.LLVMIntSLT; } - case (ast.le) { cmp = lib.llvm.LLVMIntSLE; } - case (ast.ge) { cmp = lib.llvm.LLVMIntSGE; } - case (ast.gt) { cmp = lib.llvm.LLVMIntSGT; } - } - ret cx.build.ICmp(cmp, lhs, rhs); + ret trans_compare(cx, op, lhs, rhs); } } fail; @@ -2132,6 +2139,16 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval, alt (pat.node) { case (ast.pat_wild(_)) { ret res(cx, llval); } case (ast.pat_bind(_, _, _)) { ret res(cx, llval); } + + case (ast.pat_lit(?lt, ?ann)) { + auto lllit = trans_lit(cx.fcx.ccx, *lt, ann); + auto lleq = trans_compare(cx, ast.eq, llval, lllit); + + auto matched_cx = new_sub_block_ctxt(cx, "matched_cx"); + cx.build.CondBr(lleq, matched_cx.llbb, next_cx.llbb); + ret res(matched_cx, llval); + } + case (ast.pat_tag(?id, ?subpats, ?vdef_opt, ?ann)) { auto lltagptr = cx.build.GEP(llval, vec(C_int(0), C_int(0))); auto lltag = cx.build.Load(lltagptr); @@ -2184,6 +2201,7 @@ fn trans_pat_binding(@block_ctxt cx, @ast.pat pat, ValueRef llval) -> result { alt (pat.node) { case (ast.pat_wild(_)) { ret res(cx, llval); } + case (ast.pat_lit(_, _)) { ret res(cx, llval); } case (ast.pat_bind(?id, ?def_id, ?ann)) { auto ty = node_ann_type(cx.fcx.ccx, ann); auto llty = type_of(cx.fcx.ccx, ty); -- cgit 1.4.1-3-g733a5 From 0ebfb8227c190609e80af3fb52b9813c4b282cc0 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Sun, 13 Feb 2011 00:49:04 -0500 Subject: Add support for unsigned binops. Closes #57 --- src/Makefile | 2 ++ src/comp/middle/trans.rs | 70 ++++++++++++++++++++++++++++--------- src/test/run-pass/arith-unsigned.rs | 24 +++++++++++++ 3 files changed, 80 insertions(+), 16 deletions(-) create mode 100644 src/test/run-pass/arith-unsigned.rs (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index d55a63c2797..3457864cca7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -408,6 +408,7 @@ TASK_XFAILS := test/run-pass/task-comm-8.rs \ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ $(NOMINAL_TAG_XFAILS) \ $(CONST_TAG_XFAILS) \ + test/run-pass/arith-unsigned.rs \ test/run-pass/child-outlives-parent.rs \ test/run-pass/clone-with-exterior.rs \ test/run-pass/constrained-type.rs \ @@ -450,6 +451,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ arith-0.rs \ arith-1.rs \ arith-2.rs \ + arith-unsigned.rs \ auto-instantiate.rs \ autoderef-full-lval.rs \ bind-exterior.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index bedfad97980..c1a4aa6f62a 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1840,33 +1840,67 @@ fn trans_unary(@block_ctxt cx, ast.unop op, // FIXME: implement proper structural comparison. -fn trans_compare(@block_ctxt cx, ast.binop op, +fn trans_compare(@block_ctxt cx, ast.binop op, @ty.t intype, ValueRef lhs, ValueRef rhs) -> ValueRef { auto cmp = lib.llvm.LLVMIntEQ; alt (op) { case (ast.eq) { cmp = lib.llvm.LLVMIntEQ; } case (ast.ne) { cmp = lib.llvm.LLVMIntNE; } - // FIXME (issue #57): switch by signedness. - case (ast.lt) { cmp = lib.llvm.LLVMIntSLT; } - case (ast.le) { cmp = lib.llvm.LLVMIntSLE; } - case (ast.ge) { cmp = lib.llvm.LLVMIntSGE; } - case (ast.gt) { cmp = lib.llvm.LLVMIntSGT; } + case (ast.lt) { + if (ty.type_is_signed(intype)) { + cmp = lib.llvm.LLVMIntSLT; + } else { + cmp = lib.llvm.LLVMIntULT; + } + } + case (ast.le) { + if (ty.type_is_signed(intype)) { + cmp = lib.llvm.LLVMIntSLE; + } else { + cmp = lib.llvm.LLVMIntULE; + } + } + case (ast.gt) { + if (ty.type_is_signed(intype)) { + cmp = lib.llvm.LLVMIntSGT; + } else { + cmp = lib.llvm.LLVMIntUGT; + } + } + case (ast.ge) { + if (ty.type_is_signed(intype)) { + cmp = lib.llvm.LLVMIntSGE; + } else { + cmp = lib.llvm.LLVMIntUGE; + } + } } ret cx.build.ICmp(cmp, lhs, rhs); } -fn trans_eager_binop(@block_ctxt cx, ast.binop op, +fn trans_eager_binop(@block_ctxt cx, ast.binop op, @ty.t intype, ValueRef lhs, ValueRef rhs) -> ValueRef { alt (op) { case (ast.add) { ret cx.build.Add(lhs, rhs); } case (ast.sub) { ret cx.build.Sub(lhs, rhs); } - // FIXME (issue #57): switch by signedness. case (ast.mul) { ret cx.build.Mul(lhs, rhs); } - case (ast.div) { ret cx.build.SDiv(lhs, rhs); } - case (ast.rem) { ret cx.build.SRem(lhs, rhs); } + case (ast.div) { + if (ty.type_is_signed(intype)) { + ret cx.build.SDiv(lhs, rhs); + } else { + ret cx.build.UDiv(lhs, rhs); + } + } + case (ast.rem) { + if (ty.type_is_signed(intype)) { + ret cx.build.SRem(lhs, rhs); + } else { + ret cx.build.URem(lhs, rhs); + } + } case (ast.bitor) { ret cx.build.Or(lhs, rhs); } case (ast.bitand) { ret cx.build.And(lhs, rhs); } @@ -1875,7 +1909,7 @@ fn trans_eager_binop(@block_ctxt cx, ast.binop op, case (ast.lsr) { ret cx.build.LShr(lhs, rhs); } case (ast.asr) { ret cx.build.AShr(lhs, rhs); } case (_) { - ret trans_compare(cx, op, lhs, rhs); + ret trans_compare(cx, op, intype, lhs, rhs); } } fail; @@ -1950,10 +1984,12 @@ fn trans_binary(@block_ctxt cx, ast.binop op, case (_) { // Remaining cases are eager: auto lhs = trans_expr(cx, a); - lhs = autoderef(lhs.bcx, lhs.val, ty.expr_ty(a)); + auto lhty = ty.expr_ty(a); + lhs = autoderef(lhs.bcx, lhs.val, lhty); auto rhs = trans_expr(lhs.bcx, b); - rhs = autoderef(rhs.bcx, rhs.val, ty.expr_ty(b)); - ret res(rhs.bcx, trans_eager_binop(rhs.bcx, op, + auto rhty = ty.expr_ty(b); + rhs = autoderef(rhs.bcx, rhs.val, rhty); + ret res(rhs.bcx, trans_eager_binop(rhs.bcx, op, lhty, lhs.val, rhs.val)); } } @@ -2142,7 +2178,8 @@ fn trans_pat_match(@block_ctxt cx, @ast.pat pat, ValueRef llval, case (ast.pat_lit(?lt, ?ann)) { auto lllit = trans_lit(cx.fcx.ccx, *lt, ann); - auto lleq = trans_compare(cx, ast.eq, llval, lllit); + auto lltype = ty.ann_to_type(ann); + auto lleq = trans_compare(cx, ast.eq, lltype, llval, lllit); auto matched_cx = new_sub_block_ctxt(cx, "matched_cx"); cx.build.CondBr(lleq, matched_cx.llbb, next_cx.llbb); @@ -3035,7 +3072,8 @@ fn trans_expr(@block_ctxt cx, @ast.expr e) -> result { auto lhs_val = load_scalar_or_boxed(lhs_res.res.bcx, lhs_res.res.val, t); auto rhs_res = trans_expr(lhs_res.res.bcx, src); - auto v = trans_eager_binop(rhs_res.bcx, op, lhs_val, rhs_res.val); + auto v = trans_eager_binop(rhs_res.bcx, op, t, + lhs_val, rhs_res.val); // FIXME: calculate copy init-ness in typestate. ret copy_ty(rhs_res.bcx, DROP_EXISTING, lhs_res.res.val, v, t); diff --git a/src/test/run-pass/arith-unsigned.rs b/src/test/run-pass/arith-unsigned.rs new file mode 100644 index 00000000000..3fac37142f8 --- /dev/null +++ b/src/test/run-pass/arith-unsigned.rs @@ -0,0 +1,24 @@ +// Unsigned integer operations + +fn main() { + check (0u8 < 255u8); + check (0u8 <= 255u8); + check (255u8 > 0u8); + check (255u8 >= 0u8); + check (250u8 / 10u8 == 25u8); + check (255u8 % 10u8 == 5u8); + check (0u16 < 60000u16); + check (0u16 <= 60000u16); + check (60000u16 > 0u16); + check (60000u16 >= 0u16); + check (60000u16 / 10u16 == 6000u16); + check (60005u16 % 10u16 == 5u16); + check (0u32 < 4000000000u32); + check (0u32 <= 4000000000u32); + check (4000000000u32 > 0u32); + check (4000000000u32 >= 0u32); + check (4000000000u32 / 10u32 == 400000000u32); + check (4000000005u32 % 10u32 == 5u32); + + // 64-bit numbers have some flakiness yet. Not tested +} -- cgit 1.4.1-3-g733a5 From 370c1ad00eaa0ff95c4e09a6e0545bf833d6668a Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 15 Feb 2011 15:07:55 -0800 Subject: Handle record update in typeck. --- src/Makefile | 1 + src/comp/middle/typeck.rs | 94 ++++++++++++++++++++++++++++++++++++++++------- 2 files changed, 81 insertions(+), 14 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 3457864cca7..11c7bee89d2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -553,6 +553,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ bad-expr-path.rs \ bad-expr-path2.rs \ bogus-tag.rs \ + fru-extra-field.rs \ import.rs \ import2.rs \ import3.rs \ diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 83caf891a03..9b7c9439625 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -912,23 +912,48 @@ fn demand_expr_full(&@fn_ctxt fcx, @ty.t expected, @ast.expr e, } case (ast.expr_rec(?fields_0, ?base_0, ?ann)) { - // FIXME: handle presence of a nonempty base. - check (base_0 == none[@ast.expr]); auto base_1 = base_0; 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)) { - auto i = 0u; - for (ast.field field_0 in fields_0) { - check (_str.eq(field_0.ident, field_tys.(i).ident)); - auto e_1 = demand_expr(fcx, field_tys.(i).ty, - field_0.expr); - fields_1 += vec(rec(mut=field_0.mut, - ident=field_0.ident, - expr=e_1)); - i += 1u; + 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)); + auto e_1 = demand_expr(fcx, + field_tys.(i).ty, + field_0.expr); + fields_1 += vec(rec(mut=field_0.mut, + ident=field_0.ident, + expr=e_1)); + i += 1u; + } + } + case (some[@ast.expr](?bx)) { + + base_1 = + some[@ast.expr](demand_expr(fcx, t, bx)); + + let vec[field] base_fields = vec(); + + for (ast.field field_0 in fields_0) { + + for (ty.field ft in field_tys) { + if (_str.eq(field_0.ident, ft.ident)) { + auto e_1 = demand_expr(fcx, ft.ty, + field_0.expr); + fields_1 += + vec(rec(mut=field_0.mut, + ident=field_0.ident, + expr=e_1)); + } + } + } + } } } case (_) { @@ -1708,8 +1733,6 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr { case (ast.expr_rec(?fields, ?base, _)) { - // FIXME: handle presence of a nonempty base. - check (base == none[@ast.expr]); auto base_1 = base; let vec[ast.field] fields_1 = vec(); @@ -1725,7 +1748,50 @@ fn check_expr(&@fn_ctxt fcx, @ast.expr expr) -> @ast.expr { append[field](fields_t, rec(ident=f.ident, ty=expr_t)); } - auto ann = ast.ann_type(plain_ty(ty.ty_rec(fields_t))); + auto ann = ast.ann_none; + + alt (base) { + case (none[@ast.expr]) { + ann = ast.ann_type(plain_ty(ty.ty_rec(fields_t))); + } + + case (some[@ast.expr](?bexpr)) { + auto bexpr_1 = check_expr(fcx, bexpr); + auto bexpr_t = expr_ty(bexpr_1); + + let vec[field] base_fields = vec(); + + alt (bexpr_t.struct) { + case (ty.ty_rec(?flds)) { + base_fields = flds; + } + case (_) { + fcx.ccx.sess.span_err + (expr.span, + "record update non-record base"); + } + } + + ann = ast.ann_type(bexpr_t); + + for (ty.field f in fields_t) { + 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); + found = true; + } + } + if (!found) { + fcx.ccx.sess.span_err + (expr.span, + "unknown field in record update: " + + f.ident); + } + } + } + } + ret @fold.respan[ast.expr_](expr.span, ast.expr_rec(fields_1, base_1, ann)); } -- cgit 1.4.1-3-g733a5 From d4bf67dde638fdeea4361daf16bee421d479628e Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 15 Feb 2011 18:16:13 -0800 Subject: Translate record extension. --- src/Makefile | 1 + src/comp/middle/trans.rs | 44 ++++++++++++++++++++++++++++++++++++-------- 2 files changed, 37 insertions(+), 8 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 11c7bee89d2..544075faf15 100644 --- a/src/Makefile +++ b/src/Makefile @@ -519,6 +519,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ readalias.rs \ rec.rs \ rec-auto.rs \ + rec-extend.rs \ rec-tup.rs \ return-nil.rs \ simple-obj.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 72a4fe5ca98..7d3f9997437 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -2998,9 +2998,6 @@ fn trans_vec(@block_ctxt cx, vec[@ast.expr] args, fn trans_rec(@block_ctxt cx, vec[ast.field] fields, option.t[@ast.expr] base, &ast.ann ann) -> result { - // FIXME: handle presence of a nonempty base. - check (base == none[@ast.expr]); - auto bcx = cx; auto t = node_ann_type(bcx.fcx.ccx, ann); auto llty = type_of(bcx.fcx.ccx, t); @@ -3011,13 +3008,44 @@ fn trans_rec(@block_ctxt cx, vec[ast.field] fields, find_scope_cx(cx).cleanups += clean(bind drop_ty(_, rec_val, t)); let int i = 0; - for (ast.field f in fields) { - auto e_ty = ty.expr_ty(f.expr); - auto src_res = trans_expr(bcx, f.expr); - bcx = src_res.bcx; + auto base_val = C_nil(); + + alt (base) { + case (none[@ast.expr]) { } + case (some[@ast.expr](?bexp)) { + auto base_res = trans_expr(bcx, bexp); + bcx = base_res.bcx; + base_val = base_res.val; + } + } + + let vec[ty.field] ty_fields = vec(); + alt (t.struct) { + case (ty.ty_rec(?flds)) { ty_fields = flds; } + } + + for (ty.field tf in ty_fields) { + auto e_ty = tf.ty; auto dst_res = GEP_tup_like(bcx, t, rec_val, vec(0, i)); bcx = dst_res.bcx; - bcx = copy_ty(src_res.bcx, INIT, dst_res.val, src_res.val, e_ty).bcx; + + auto expr_provided = false; + auto src_res = res(bcx, C_nil()); + + for (ast.field f in fields) { + if (_str.eq(f.ident, tf.ident)) { + expr_provided = true; + src_res = trans_expr(bcx, f.expr); + } + } + if (!expr_provided) { + src_res = GEP_tup_like(bcx, t, base_val, vec(0, i)); + src_res = res(src_res.bcx, + load_scalar_or_boxed(bcx, src_res.val, e_ty)); + } + + bcx = src_res.bcx; + bcx = copy_ty(bcx, INIT, dst_res.val, src_res.val, e_ty).bcx; i += 1; } ret res(bcx, rec_val); -- cgit 1.4.1-3-g733a5 From 293637139fe55990397849badfb60c96d4211b31 Mon Sep 17 00:00:00 2001 From: Rafael Avila de Espindola Date: Wed, 16 Feb 2011 15:00:40 -0500 Subject: Add missing case to ty_to_str. Disable test that now fails because we produce undefined references to the native functions. --- src/Makefile | 1 - src/comp/middle/ty.rs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 544075faf15..85867532302 100644 --- a/src/Makefile +++ b/src/Makefile @@ -507,7 +507,6 @@ TEST_XFAILS_RUSTC := $(filter-out \ linear-for-loop.rs \ multiline-comment.rs \ mutual-recursion-group.rs \ - native2.rs \ obj-drop.rs \ obj-recursion.rs \ obj-with-vec.rs \ diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 21b68fb51e8..a9be0c3649a 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -210,6 +210,7 @@ fn ty_to_str(&@t typ) -> str { } alt (typ.struct) { + case (ty_native) { s = "native"; } case (ty_nil) { s = "()"; } case (ty_bool) { s = "bool"; } case (ty_int) { s = "int"; } -- cgit 1.4.1-3-g733a5 From a63696dfe2bd47d34925a3ad44db9d2ede949e36 Mon Sep 17 00:00:00 2001 From: Rafael Avila de Espindola Date: Wed, 16 Feb 2011 15:34:59 -0500 Subject: Add a more specialized decl_native_fn_and_pair. Native functions now have the right name. --- src/Makefile | 1 + src/comp/middle/trans.rs | 14 +++++++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 85867532302..544075faf15 100644 --- a/src/Makefile +++ b/src/Makefile @@ -507,6 +507,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ linear-for-loop.rs \ multiline-comment.rs \ mutual-recursion-group.rs \ + native2.rs \ obj-drop.rs \ obj-recursion.rs \ obj-with-vec.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 282a62d6c84..94fa9f9105e 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -4062,12 +4062,24 @@ fn decl_fn_and_pair(@crate_ctxt cx, cx.fn_pairs.insert(id, gvar); } +fn decl_native_fn_and_pair(@crate_ctxt cx, + str name, + &ast.ann ann, + ast.def_id id) { + + auto llpairty = node_type(cx, ann); + auto llfty = get_pair_fn_ty(llpairty); + + let ValueRef llfn = decl_fastcall_fn(cx.llmod, name, llfty); + cx.item_ids.insert(id, llfn); +} + fn collect_native_item(&@crate_ctxt cx, @ast.native_item i) -> @crate_ctxt { alt (i.node) { case (ast.native_item_fn(?name, _, _, ?fid, ?ann)) { cx.native_items.insert(fid, i); if (! cx.obj_methods.contains_key(fid)) { - decl_fn_and_pair(cx, "fn", name, ann, fid); + decl_native_fn_and_pair(cx, name, ann, fid); } } case (_) { /* fall through */ } -- cgit 1.4.1-3-g733a5 From e867d8ea993945803d96396bcba9c07d61d7c95d Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Wed, 16 Feb 2011 14:34:10 -0800 Subject: Un-XFAIL mutable-vec-drop.rs. --- src/Makefile | 1 + 1 file changed, 1 insertion(+) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 544075faf15..c468ded0fcc 100644 --- a/src/Makefile +++ b/src/Makefile @@ -506,6 +506,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ leak-box-as-tydesc.rs \ linear-for-loop.rs \ multiline-comment.rs \ + mutable-vec-drop.rs \ mutual-recursion-group.rs \ native2.rs \ obj-drop.rs \ -- cgit 1.4.1-3-g733a5 From b0c7439d777bbb967be7a67fa11096aaf540fe9f Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Fri, 18 Feb 2011 18:52:16 -0800 Subject: Implement expr_put. Un-XFAIL foreach-simple.rs; iters w/o env access work. --- src/Makefile | 1 + src/comp/middle/trans.rs | 31 +++++++++++++++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index c468ded0fcc..71c9807bc79 100644 --- a/src/Makefile +++ b/src/Makefile @@ -475,6 +475,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ else-if.rs \ fact.rs \ fn-lval.rs \ + foreach-simple.rs \ fun-call-variants.rs \ fun-indirect-call.rs \ generic-derived-type.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 59d6ad7f764..efa3a41dc6a 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3454,8 +3454,35 @@ fn trans_fail(@block_ctxt cx, common.span sp, str fail_str) -> result { } fn trans_put(@block_ctxt cx, &option.t[@ast.expr] e) -> result { - cx.fcx.ccx.sess.unimpl("put expr"); - fail; + auto llcallee = C_nil(); + auto llenv = C_nil(); + + alt (cx.fcx.lliterbody) { + case (some[ValueRef](?lli)) { + auto slot = cx.build.Alloca(val_ty(lli)); + cx.build.Store(lli, slot); + + llcallee = cx.build.GEP(slot, vec(C_int(0), + C_int(abi.fn_field_code))); + llcallee = cx.build.Load(llcallee); + + llenv = cx.build.GEP(slot, vec(C_int(0), + C_int(abi.fn_field_box))); + llenv = cx.build.Load(llenv); + } + } + auto bcx = cx; + auto dummy_retslot = bcx.build.Alloca(T_nil()); + let vec[ValueRef] llargs = vec(dummy_retslot, cx.fcx.lltaskptr, llenv); + alt (e) { + case (none[@ast.expr]) { } + case (some[@ast.expr](?x)) { + auto r = trans_expr(bcx, x); + llargs += r.val; + bcx = r.bcx; + } + } + ret res(bcx, bcx.build.FastCall(llcallee, llargs)); } fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result { -- cgit 1.4.1-3-g733a5 From 60f97aa9cc73ee4e0b57abc07dc543c8fa823ee2 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 21 Feb 2011 17:42:23 -0800 Subject: Find main functions buried within modules. Un-XFAIL import.rs. --- src/Makefile | 1 + src/comp/middle/trans.rs | 27 +++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 71c9807bc79..872ced9896d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -492,6 +492,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ int.rs \ i32-sub.rs \ i8-incr.rs \ + import.rs \ import2.rs \ import3.rs \ import4.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index efa3a41dc6a..35fefc104be 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -4602,6 +4602,30 @@ fn create_crate_constant(@crate_ctxt cx) { llvm.LLVMSetInitializer(cx.crate_ptr, crate_val); } +fn find_main_fn(@crate_ctxt cx) -> ValueRef { + auto e = sep() + "main"; + let ValueRef v = C_nil(); + let uint n = 0u; + for each (tup(str,ValueRef) i in cx.item_names.items()) { + if (_str.ends_with(i._0, e)) { + n += 1u; + v = i._1; + } + } + alt (n) { + case (0u) { + cx.sess.err("main fn not found"); + } + case (1u) { + ret v; + } + case (_) { + cx.sess.err("multiple main fns found"); + } + } + fail; +} + fn trans_main_fn(@crate_ctxt cx, ValueRef llcrate) { auto T_main_args = vec(T_int(), T_int()); auto T_rust_start_args = vec(T_int(), T_int(), T_int(), T_int()); @@ -4621,8 +4645,7 @@ fn trans_main_fn(@crate_ctxt cx, ValueRef llcrate) { auto llargc = llvm.LLVMGetParam(llmain, 0u); auto llargv = llvm.LLVMGetParam(llmain, 1u); - check (cx.item_names.contains_key("_rust" + sep() + "main")); - auto llrust_main = cx.item_names.get("_rust" + sep() + "main"); + auto llrust_main = find_main_fn(cx); // // Emit the moral equivalent of: -- cgit 1.4.1-3-g733a5 From 3a7271a026248c88ebefff6c5b585245a5151eb1 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 22 Feb 2011 18:20:40 -0800 Subject: Un-XFAIL argv.rs and command-line-args.rs. --- src/Makefile | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 872ced9896d..2616ae4769e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -448,6 +448,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ alt-pattern-lit.rs \ alt-pattern-simple.rs \ alt-tag.rs \ + argv.rs \ arith-0.rs \ arith-1.rs \ arith-2.rs \ @@ -464,6 +465,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ box-in-tup.rs \ cast.rs \ char.rs \ + command-line-args.rs \ complex.rs \ const.rs \ dead-code-one-arm-if.rs \ -- cgit 1.4.1-3-g733a5 From eac75b76486ec54f677b2460f09635380437b125 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Tue, 22 Feb 2011 20:23:38 -0500 Subject: Teach rustc about reserved keywords --- src/Makefile | 7 +++++++ src/comp/front/lexer.rs | 17 ++++++++++++++++- src/test/compile-fail/reserved-dec.rs | 5 +++++ src/test/compile-fail/reserved-f128.rs | 5 +++++ src/test/compile-fail/reserved-f16.rs | 5 +++++ src/test/compile-fail/reserved-f80.rs | 5 +++++ src/test/compile-fail/reserved-m128.rs | 5 +++++ src/test/compile-fail/reserved-m32.rs | 5 +++++ src/test/compile-fail/reserved-m64.rs | 5 +++++ 9 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 src/test/compile-fail/reserved-dec.rs create mode 100644 src/test/compile-fail/reserved-f128.rs create mode 100644 src/test/compile-fail/reserved-f16.rs create mode 100644 src/test/compile-fail/reserved-f80.rs create mode 100644 src/test/compile-fail/reserved-m128.rs create mode 100644 src/test/compile-fail/reserved-m32.rs create mode 100644 src/test/compile-fail/reserved-m64.rs (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 2616ae4769e..551a70010b4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -569,6 +569,13 @@ TEST_XFAILS_RUSTC := $(filter-out \ multiline-comment-line-tracking.rs \ output-type-mismatch.rs \ rec-missing-fields.rs \ + reserved-dec.rs \ + reserved-f128.rs \ + reserved-f16.rs \ + reserved-f80.rs \ + reserved-m128.rs \ + reserved-m32.rs \ + reserved-m64.rs \ tail-non-call.rs \ tail-typeck.rs \ type-shadow.rs \ diff --git a/src/comp/front/lexer.rs b/src/comp/front/lexer.rs index 481fc5dd639..99e9217f507 100644 --- a/src/comp/front/lexer.rs +++ b/src/comp/front/lexer.rs @@ -90,7 +90,6 @@ fn new_reader(stdio_reader rdr, str filename) -> reader } auto keywords = new_str_hash[token.token](); - auto reserved = new_str_hash[()](); keywords.insert("mod", token.MOD); keywords.insert("use", token.USE); @@ -191,6 +190,16 @@ fn new_reader(stdio_reader rdr, str filename) -> reader keywords.insert("f32", token.MACH(common.ty_f32)); keywords.insert("f64", token.MACH(common.ty_f64)); + auto reserved = new_str_hash[()](); + + reserved.insert("f16", ()); // IEEE 754-2008 'binary16' interchange fmt + reserved.insert("f80", ()); // IEEE 754-1985 'extended' + reserved.insert("f128", ()); // IEEE 754-2008 'binary128' + reserved.insert("m32", ()); // IEEE 754-2008 'decimal32' + reserved.insert("m64", ()); // IEEE 754-2008 'decimal64' + reserved.insert("m128", ()); // IEEE 754-2008 'decimal128' + reserved.insert("dec", ()); // One of m32, m64, m128 + ret reader(rdr, filename, rdr.getc() as char, rdr.getc() as char, 1u, 0u, 1u, 0u, keywords, reserved); } @@ -425,6 +434,12 @@ impure fn next_token(reader rdr) -> token.token { ret kwds.get(accum_str); } + auto rsvd = rdr.get_reserved(); + if (rsvd.contains_key(accum_str)) { + log "reserved keyword"; + fail; + } + ret token.IDENT(accum_str); } diff --git a/src/test/compile-fail/reserved-dec.rs b/src/test/compile-fail/reserved-dec.rs new file mode 100644 index 00000000000..d8c204d9fb3 --- /dev/null +++ b/src/test/compile-fail/reserved-dec.rs @@ -0,0 +1,5 @@ +// error-pattern:reserved keyword + +fn main() { + let int dec = 0; +} diff --git a/src/test/compile-fail/reserved-f128.rs b/src/test/compile-fail/reserved-f128.rs new file mode 100644 index 00000000000..63d00f705bf --- /dev/null +++ b/src/test/compile-fail/reserved-f128.rs @@ -0,0 +1,5 @@ +// error-pattern:reserved keyword + +fn main() { + let int f128 = 0; +} diff --git a/src/test/compile-fail/reserved-f16.rs b/src/test/compile-fail/reserved-f16.rs new file mode 100644 index 00000000000..bfb14cd8fee --- /dev/null +++ b/src/test/compile-fail/reserved-f16.rs @@ -0,0 +1,5 @@ +// error-pattern:reserved keyword + +fn main() { + let int f16 = 0; +} diff --git a/src/test/compile-fail/reserved-f80.rs b/src/test/compile-fail/reserved-f80.rs new file mode 100644 index 00000000000..33e8bd5e5b3 --- /dev/null +++ b/src/test/compile-fail/reserved-f80.rs @@ -0,0 +1,5 @@ +// error-pattern:reserved keyword + +fn main() { + let int f80 = 0; +} diff --git a/src/test/compile-fail/reserved-m128.rs b/src/test/compile-fail/reserved-m128.rs new file mode 100644 index 00000000000..c4d36bf76e0 --- /dev/null +++ b/src/test/compile-fail/reserved-m128.rs @@ -0,0 +1,5 @@ +// error-pattern:reserved keyword + +fn main() { + let int m128 = 0; +} diff --git a/src/test/compile-fail/reserved-m32.rs b/src/test/compile-fail/reserved-m32.rs new file mode 100644 index 00000000000..bdb3a427c7e --- /dev/null +++ b/src/test/compile-fail/reserved-m32.rs @@ -0,0 +1,5 @@ +// error-pattern:reserved keyword + +fn main() { + let int m32 = 0; +} diff --git a/src/test/compile-fail/reserved-m64.rs b/src/test/compile-fail/reserved-m64.rs new file mode 100644 index 00000000000..034884a6fdd --- /dev/null +++ b/src/test/compile-fail/reserved-m64.rs @@ -0,0 +1,5 @@ +// error-pattern:reserved keyword + +fn main() { + let int m64 = 0; +} -- cgit 1.4.1-3-g733a5 From b4d6589e7387a7c7df0841f51f0fa5ef831883d9 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 23 Feb 2011 10:58:43 -0800 Subject: Implement type descriptor binding. Un-XFAIL test/run-pass/generic-bind.rs. --- src/Makefile | 1 + src/comp/middle/trans.rs | 115 +++++++++++++++++++++++++++++++++++++++-------- src/comp/middle/ty.rs | 3 ++ 3 files changed, 100 insertions(+), 19 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 551a70010b4..edbe9e29ab7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -480,6 +480,7 @@ TEST_XFAILS_RUSTC := $(filter-out \ foreach-simple.rs \ fun-call-variants.rs \ fun-indirect-call.rs \ + generic-bind.rs \ generic-derived-type.rs \ generic-fn.rs \ generic-fn-infer.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 6a19a6e57f9..30f3cdc4495 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -373,11 +373,12 @@ fn T_typaram_ptr(type_names tn) -> TypeRef { fn T_closure_ptr(type_names tn, TypeRef lltarget_ty, - TypeRef llbindings_ty) -> TypeRef { + TypeRef llbindings_ty, + uint n_ty_params) -> TypeRef { ret T_ptr(T_box(T_struct(vec(T_ptr(T_tydesc(tn)), lltarget_ty, - llbindings_ty) - // FIXME: add captured typarams. + llbindings_ty, + T_captured_tydescs(tn, n_ty_params)) ))); } @@ -388,7 +389,8 @@ fn T_opaque_closure_ptr(type_names tn) -> TypeRef { } auto t = T_closure_ptr(tn, T_struct(vec(T_ptr(T_nil()), T_ptr(T_nil()))), - T_nil()); + T_nil(), + 0u); tn.associate(s, t); ret t; } @@ -2747,7 +2749,8 @@ fn trans_bind_thunk(@crate_ctxt cx, @ty.t outgoing_fty, vec[option.t[@ast.expr]] args, TypeRef llclosure_ty, - vec[@ty.t] bound_tys) -> ValueRef { + vec[@ty.t] bound_tys, + uint ty_param_count) -> ValueRef { // Construct a thunk-call with signature incoming_fty, and that copies // args forward into a call to outgoing_fty. @@ -2755,9 +2758,6 @@ fn trans_bind_thunk(@crate_ctxt cx, let TypeRef llthunk_ty = get_pair_fn_ty(type_of(cx, incoming_fty)); let ValueRef llthunk = decl_fastcall_fn(cx.llmod, s, llthunk_ty); - // FIXME: handle ty params properly. - let vec[ast.ty_param] ty_params = vec(); - auto fcx = new_fn_ctxt(cx, s, llthunk); auto bcx = new_top_block_ctxt(fcx); @@ -2779,11 +2779,33 @@ fn trans_bind_thunk(@crate_ctxt cx, vec(C_int(0), C_int(abi.fn_field_box))); lltargetclosure = bcx.build.Load(lltargetclosure); - let vec[ValueRef] llargs = vec(fcx.llretptr, + + auto outgoing_ret_ty = ty.ty_fn_ret(outgoing_fty); + auto outgoing_arg_tys = ty.ty_fn_args(outgoing_fty); + + auto llretptr = fcx.llretptr; + if (ty.type_has_dynamic_size(outgoing_ret_ty)) { + llretptr = bcx.build.PointerCast(llretptr, T_typaram_ptr(cx.tn)); + } + + let vec[ValueRef] llargs = vec(llretptr, fcx.lltaskptr, lltargetclosure); - let uint a = 0u; + + // Copy in the type parameters. + let uint i = 0u; + while (i < ty_param_count) { + auto lltyparam_ptr = + bcx.build.GEP(llbody, vec(C_int(0), + C_int(abi.closure_elt_ty_params), + C_int(i as int))); + llargs += vec(bcx.build.Load(lltyparam_ptr)); + i += 1u; + } + + let uint a = 2u + i; // retptr, task ptr, env come first let int b = 0; + let uint outgoing_arg_index = 0u; for (option.t[@ast.expr] arg in args) { alt (arg) { @@ -2800,10 +2822,19 @@ fn trans_bind_thunk(@crate_ctxt cx, // Arg will be provided when the thunk is invoked. case (none[@ast.expr]) { let ValueRef passed_arg = llvm.LLVMGetParam(llthunk, a); + if (ty.type_has_dynamic_size(outgoing_arg_tys. + (outgoing_arg_index).ty)) { + // Cast to a generic typaram pointer in order to make a + // type-compatible call. + passed_arg = bcx.build.PointerCast(passed_arg, + T_typaram_ptr(cx.tn)); + } llargs += passed_arg; a += 1u; } } + + outgoing_arg_index += 0u; } // FIXME: turn this call + ret into a tail call. @@ -2811,6 +2842,7 @@ fn trans_bind_thunk(@crate_ctxt cx, vec(C_int(0), C_int(abi.fn_field_code))); lltargetfn = bcx.build.Load(lltargetfn); + auto r = bcx.build.FastCall(lltargetfn, llargs); bcx.build.RetVoid(); @@ -2835,7 +2867,23 @@ fn trans_bind(@block_ctxt cx, @ast.expr f, } } } - if (_vec.len[@ast.expr](bound) == 0u) { + + // Figure out which tydescs we need to pass, if any. + // FIXME: typestate botch + let @ty.t outgoing_fty = ty.plain_ty(ty.ty_nil); + let vec[ValueRef] lltydescs = vec(); + alt (f_res.generic) { + case (none[generic_info]) { + outgoing_fty = ty.expr_ty(f); + } + case (some[generic_info](?ginfo)) { + outgoing_fty = ginfo.item_type; + lltydescs = ginfo.tydescs; + } + } + auto ty_param_count = _vec.len[ValueRef](lltydescs); + + if (_vec.len[@ast.expr](bound) == 0u && ty_param_count == 0u) { // Trivial 'binding': just return the static pair-ptr. ret f_res.res; } else { @@ -2846,20 +2894,27 @@ fn trans_bind(@block_ctxt cx, @ast.expr f, // Translate the bound expressions. let vec[@ty.t] bound_tys = vec(); let vec[ValueRef] bound_vals = vec(); + auto i = 0u; for (@ast.expr e in bound) { auto arg = trans_expr(bcx, e); bcx = arg.bcx; + append[ValueRef](bound_vals, arg.val); append[@ty.t](bound_tys, ty.expr_ty(e)); + + i += 1u; } + // Get the type of the bound function. + let TypeRef lltarget_ty = type_of(bcx.fcx.ccx, outgoing_fty); + // Synthesize a closure type. let @ty.t bindings_ty = plain_ty(ty.ty_tup(bound_tys)); - let TypeRef lltarget_ty = type_of(bcx.fcx.ccx, ty.expr_ty(f)); let TypeRef llbindings_ty = type_of(bcx.fcx.ccx, bindings_ty); let TypeRef llclosure_ty = T_closure_ptr(cx.fcx.ccx.tn, lltarget_ty, - llbindings_ty); + llbindings_ty, + ty_param_count); // Malloc a box for the body. auto r = trans_malloc_inner(bcx, llclosure_ty); @@ -2888,19 +2943,40 @@ fn trans_bind(@block_ctxt cx, @ast.expr f, bcx.build.GEP(closure, vec(C_int(0), C_int(abi.closure_elt_target))); - bcx.build.Store(bcx.build.Load(f_res.res.val), bound_target); + auto src = bcx.build.Load(f_res.res.val); + bcx.build.Store(src, bound_target); // Copy expr values into boxed bindings. - let int i = 0; + i = 0u; auto bindings = bcx.build.GEP(closure, vec(C_int(0), C_int(abi.closure_elt_bindings))); for (ValueRef v in bound_vals) { auto bound = bcx.build.GEP(bindings, - vec(C_int(0),C_int(i))); + vec(C_int(0), C_int(i as int))); bcx = copy_ty(r.bcx, INIT, bound, v, bound_tys.(i)).bcx; - i += 1; + i += 1u; + } + + // If necessary, copy tydescs describing type parameters into the + // appropriate slot in the closure. + alt (f_res.generic) { + case (none[generic_info]) { /* nothing to do */ } + case (some[generic_info](?ginfo)) { + auto ty_params_slot = + bcx.build.GEP(closure, + vec(C_int(0), + C_int(abi.closure_elt_ty_params))); + auto i = 0; + for (ValueRef td in ginfo.tydescs) { + auto ty_param_slot = bcx.build.GEP(ty_params_slot, + vec(C_int(0), + C_int(i))); + bcx.build.Store(td, ty_param_slot); + i += 1; + } + } } // Make thunk and store thunk-ptr in outer pair's code slot. @@ -2910,8 +2986,9 @@ fn trans_bind(@block_ctxt cx, @ast.expr f, let @ty.t pair_ty = node_ann_type(cx.fcx.ccx, ann); let ValueRef llthunk = - trans_bind_thunk(cx.fcx.ccx, pair_ty, ty.expr_ty(f), - args, llclosure_ty, bound_tys); + trans_bind_thunk(cx.fcx.ccx, pair_ty, outgoing_fty, + args, llclosure_ty, bound_tys, + ty_param_count); bcx.build.Store(llthunk, pair_code); diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 0f277329d1b..5535879e6e1 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -598,12 +598,14 @@ fn ty_fn_args(@t fty) -> vec[arg] { case (ty.ty_fn(_, ?a, _)) { ret a; } case (ty.ty_native_fn(?a, _)) { ret a; } } + fail; } fn ty_fn_proto(@t fty) -> ast.proto { alt (fty.struct) { case (ty.ty_fn(?p, _, _)) { ret p; } } + fail; } fn ty_fn_ret(@t fty) -> @t { @@ -611,6 +613,7 @@ fn ty_fn_ret(@t fty) -> @t { case (ty.ty_fn(_, _, ?r)) { ret r; } case (ty.ty_native_fn(_, ?r)) { ret r; } } + fail; } fn is_fn_ty(@t fty) -> bool { -- cgit 1.4.1-3-g733a5 From 144a2a1d339299bc3dff7bc9eebcf1f9bba8656b Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 23 Feb 2011 17:36:33 -0800 Subject: Invert test/run-pass/ for rustc --- src/Makefile | 217 ++++++++++++++++++++++++++++------------------------------- 1 file changed, 104 insertions(+), 113 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index edbe9e29ab7..390f91733c4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -438,120 +438,111 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ test/compile-fail/tail-non-call.rs \ test/compile-fail/writing-through-read-alias.rs -# Same strategy here for the time being: just list the ones that -# work and assume the others don't. Invert this when we're closer -# to actually bootstrapping. - -TEST_XFAILS_RUSTC := $(filter-out \ - $(addprefix test/run-pass/, \ - alt-path.rs \ - alt-pattern-lit.rs \ - alt-pattern-simple.rs \ - alt-tag.rs \ - argv.rs \ - arith-0.rs \ - arith-1.rs \ - arith-2.rs \ - arith-unsigned.rs \ - auto-instantiate.rs \ - autoderef-full-lval.rs \ - bind-exterior.rs \ - bind-interior.rs \ - bind-thunk.rs \ - bind-trivial.rs \ - bitwise.rs \ - bool-not.rs \ - box.rs \ - box-in-tup.rs \ - cast.rs \ - char.rs \ - command-line-args.rs \ - complex.rs \ - const.rs \ - dead-code-one-arm-if.rs \ - deep.rs \ - deref.rs \ - div-mod.rs \ - drop-bind-thunk-args.rs \ - drop-on-ret.rs \ - else-if.rs \ - fact.rs \ - fn-lval.rs \ - foreach-simple.rs \ - fun-call-variants.rs \ - fun-indirect-call.rs \ - generic-bind.rs \ - generic-derived-type.rs \ - generic-fn.rs \ - generic-fn-infer.rs \ - generic-exterior-box.rs \ - generic-drop-glue.rs \ - generic-obj.rs \ - generic-obj-with-derived-type.rs \ - generic-tup.rs \ - generic-type.rs \ - generic-type-synonym.rs \ - hello.rs \ - int.rs \ - i32-sub.rs \ - i8-incr.rs \ - import.rs \ - import2.rs \ - import3.rs \ - import4.rs \ - import5.rs \ - import6.rs \ - import7.rs \ - import8.rs \ - inner-module.rs \ - item-name-overload.rs \ - large-records.rs \ - lazy-init.rs \ - lazy-and-or.rs \ - leak-box-as-tydesc.rs \ - linear-for-loop.rs \ - multiline-comment.rs \ - mutable-vec-drop.rs \ - mutual-recursion-group.rs \ - native2.rs \ - obj-drop.rs \ - obj-recursion.rs \ - obj-with-vec.rs \ - operator-associativity.rs \ - opeq.rs \ - output-slot-variants.rs \ - over-constrained-vregs.rs \ - path.rs \ - readalias.rs \ - rec.rs \ - rec-auto.rs \ - rec-extend.rs \ - rec-tup.rs \ - return-nil.rs \ - simple-obj.rs \ - stateful-obj.rs \ - str-idx.rs \ - tail-call-arg-leak.rs \ - tail-cps.rs \ - tail-direct.rs \ - type-in-nested-module.rs \ - type-param.rs \ - tup.rs \ - u32-decr.rs \ - u8-incr.rs \ - u8-incr-decr.rs \ - uint.rs \ - unit.rs \ - use.rs \ - tag.rs \ - vec.rs \ - vec-drop.rs \ - vec-in-tup.rs \ - vec-late-init.rs \ - while-and-do-while.rs \ - while-flow-graph.rs \ - writealias.rs \ +TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ + acyclic-unwind.rs \ + alt-pattern-drop.rs \ + alt-type-simple.rs \ + append-units.rs \ + autoderef-objfn.rs \ + basic-1.rs \ + basic-2.rs \ + basic.rs \ + bind-obj-ctor.rs \ + box-unbox.rs \ + child-outlives-parent.rs \ + clone-with-exterior.rs \ + comm.rs \ + constrained-type.rs \ + destructor-ordering.rs \ + drop-on-empty-block-exit.rs \ + drop-parametric-closure-with-bound-box.rs \ + export-non-interference.rs \ + exterior.rs \ + foreach-nested-2.rs \ + foreach-nested.rs \ + foreach-put-structured.rs \ + foreach-simple-outer-slot.rs \ + generic-fn-twice.rs \ + generic-iter-frame.rs \ + generic-recursive-tag.rs \ + generic-tag-alt.rs \ + generic-tag-values.rs \ + generic-tag.rs \ + integral-indexing.rs \ + iter-range.rs \ + iter-ret.rs \ + lazychan.rs \ + lib-bitv.rs \ + lib-deque.rs \ + lib-int.rs \ + lib-io.rs \ + lib-map.rs \ + lib-rand.rs \ + lib-sha1.rs \ + lib-sort.rs \ + lib-str.rs \ + lib-task.rs \ + lib-uint.rs \ + lib-vec-str-conversions.rs \ + lib-vec.rs \ + list.rs \ + many.rs \ + mlist-cycle.rs \ + mlist.rs \ + mutable-alias-vec.rs \ + native-opaque-type.rs \ + obj-as.rs \ + obj-dtor.rs \ + obj-return-polytypes.rs \ + pred.rs \ + preempt.rs \ + rt-circular-buffer.rs \ + size-and-align.rs \ + spawn-fn.rs \ + spawn-module-qualified.rs \ + spawn.rs \ + str-append.rs \ + str-concat.rs \ + structured-compare.rs \ + syntax-extension-fmt.rs \ + syntax-extension-shell.rs \ + task-comm-0.rs \ + task-comm-1.rs \ + task-comm-10.rs \ + task-comm-11.rs \ + task-comm-12.rs \ + task-comm-13-thread.rs \ + task-comm-13.rs \ + task-comm-15.rs \ + task-comm-2.rs \ + task-comm-3.rs \ + task-comm-4.rs \ + task-comm-5.rs \ + task-comm-6.rs \ + task-comm-7.rs \ + task-comm-8.rs \ + task-comm-9.rs \ + task-comm.rs \ + task-killjoin.rs \ + task-life-0.rs \ + threads.rs \ + type-sizes.rs \ + use-import-export.rs \ + user.rs \ + utf8.rs \ + vec-alloc-append.rs \ + vec-append.rs \ + vec-concat.rs \ + vec-slice.rs \ + while-prelude-drop.rs \ + while-with-break.rs \ + yield.rs \ + yield2.rs \ + multi.rc \ + native-mod.rc \ + native.rc \ ) \ + $(filter-out \ $(addprefix test/compile-fail/, \ alt-tag-nullary.rs \ alt-tag-unary.rs \ -- cgit 1.4.1-3-g733a5 From 4ebd75a54757b06718fc87a72c20389a9e7f29d0 Mon Sep 17 00:00:00 2001 From: Brian Anderson Date: Thu, 24 Feb 2011 00:07:38 -0500 Subject: Restore working rustc run-pass tests --- src/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 390f91733c4..70b3ca0f53d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -574,7 +574,7 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ while-type-error.rs \ wrong-ret-type.rs \ ), \ - $(wildcard test/*/*.rs test/*/*.rc)) + $(wildcard test/*fail/*.rs test/*fail/*.rc)) ifdef MINGW_CROSS -- cgit 1.4.1-3-g733a5 From 0a65283c5eeae0b98fff7d213dbaad59889e677e Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Wed, 23 Feb 2011 18:39:27 -0800 Subject: Cast more aggressively to the callee type when calling generic functions. Add a test-case for this, and XFAIL it in rustboot. --- src/Makefile | 1 + src/comp/middle/trans.rs | 6 +++--- src/test/run-pass/generic-fn-box.rs | 9 +++++++++ 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass/generic-fn-box.rs (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 70b3ca0f53d..12b65246754 100644 --- a/src/Makefile +++ b/src/Makefile @@ -416,6 +416,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ test/run-pass/obj-as.rs \ test/run-pass/vec-slice.rs \ test/run-pass/fn-lval.rs \ + test/run-pass/generic-fn-box.rs \ test/run-pass/generic-recursive-tag.rs \ test/run-pass/generic-tup.rs \ test/run-pass/iter-ret.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 30f3cdc4495..72f1106b217 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3132,9 +3132,9 @@ fn trans_args(@block_ctxt cx, bcx = re.bcx; } - if (ty.type_has_dynamic_size(args.(i).ty)) { - val = bcx.build.PointerCast(val, - T_typaram_ptr(cx.fcx.ccx.tn)); + if (ty.count_ty_params(args.(i).ty) > 0u) { + auto lldestty = type_of(cx.fcx.ccx, args.(i).ty); + val = bcx.build.PointerCast(val, lldestty); } llargs += val; diff --git a/src/test/run-pass/generic-fn-box.rs b/src/test/run-pass/generic-fn-box.rs new file mode 100644 index 00000000000..e821a784598 --- /dev/null +++ b/src/test/run-pass/generic-fn-box.rs @@ -0,0 +1,9 @@ +fn f[T](@T x) -> @T { + ret x; +} + +fn main() { + auto x = f(@3); + log *x; +} + -- cgit 1.4.1-3-g733a5 From 5332250d3bddf509994832965f3c5d7b68662ce4 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 24 Feb 2011 13:51:18 -0800 Subject: Revert "Cast more aggressively to the callee type when calling generic functions. Add a test-case for this, and XFAIL it in rustboot." due to test failures This reverts commit 0a65283c5eeae0b98fff7d213dbaad59889e677e. --- src/Makefile | 1 - src/comp/middle/trans.rs | 6 +++--- src/test/run-pass/generic-fn-box.rs | 9 --------- 3 files changed, 3 insertions(+), 13 deletions(-) delete mode 100644 src/test/run-pass/generic-fn-box.rs (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 12b65246754..70b3ca0f53d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -416,7 +416,6 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ test/run-pass/obj-as.rs \ test/run-pass/vec-slice.rs \ test/run-pass/fn-lval.rs \ - test/run-pass/generic-fn-box.rs \ test/run-pass/generic-recursive-tag.rs \ test/run-pass/generic-tup.rs \ test/run-pass/iter-ret.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 72f1106b217..30f3cdc4495 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3132,9 +3132,9 @@ fn trans_args(@block_ctxt cx, bcx = re.bcx; } - if (ty.count_ty_params(args.(i).ty) > 0u) { - auto lldestty = type_of(cx.fcx.ccx, args.(i).ty); - val = bcx.build.PointerCast(val, lldestty); + if (ty.type_has_dynamic_size(args.(i).ty)) { + val = bcx.build.PointerCast(val, + T_typaram_ptr(cx.fcx.ccx.tn)); } llargs += val; diff --git a/src/test/run-pass/generic-fn-box.rs b/src/test/run-pass/generic-fn-box.rs deleted file mode 100644 index e821a784598..00000000000 --- a/src/test/run-pass/generic-fn-box.rs +++ /dev/null @@ -1,9 +0,0 @@ -fn f[T](@T x) -> @T { - ret x; -} - -fn main() { - auto x = f(@3); - log *x; -} - -- cgit 1.4.1-3-g733a5 From dcd65fac199d3caac4b1019304ef5e1b480f31ff Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 24 Feb 2011 13:51:53 -0800 Subject: Cast more aggressively to the callee type when calling generic functions. Add a test-case for this, and XFAIL it in rustboot. --- src/Makefile | 1 + src/comp/middle/trans.rs | 12 +++++++++--- src/test/run-pass/generic-fn-box.rs | 9 +++++++++ 3 files changed, 19 insertions(+), 3 deletions(-) create mode 100644 src/test/run-pass/generic-fn-box.rs (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 70b3ca0f53d..12b65246754 100644 --- a/src/Makefile +++ b/src/Makefile @@ -416,6 +416,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ test/run-pass/obj-as.rs \ test/run-pass/vec-slice.rs \ test/run-pass/fn-lval.rs \ + test/run-pass/generic-fn-box.rs \ test/run-pass/generic-recursive-tag.rs \ test/run-pass/generic-tup.rs \ test/run-pass/iter-ret.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 30f3cdc4495..a3a1d83fc3e 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3091,6 +3091,12 @@ fn trans_args(@block_ctxt cx, } // ... then explicit args. + + // First we figure out the caller's view of the types of the arguments. + // This will be needed if this is a generic call, because the callee has + // to cast her view of the arguments to the caller's view. + auto arg_tys = type_of_explicit_args(cx.fcx.ccx, args); + auto i = 0u; for (@ast.expr e in es) { auto mode = args.(i).mode; @@ -3132,9 +3138,9 @@ fn trans_args(@block_ctxt cx, bcx = re.bcx; } - if (ty.type_has_dynamic_size(args.(i).ty)) { - val = bcx.build.PointerCast(val, - T_typaram_ptr(cx.fcx.ccx.tn)); + if (ty.count_ty_params(args.(i).ty) > 0u) { + auto lldestty = arg_tys.(i); + val = bcx.build.PointerCast(val, lldestty); } llargs += val; diff --git a/src/test/run-pass/generic-fn-box.rs b/src/test/run-pass/generic-fn-box.rs new file mode 100644 index 00000000000..e821a784598 --- /dev/null +++ b/src/test/run-pass/generic-fn-box.rs @@ -0,0 +1,9 @@ +fn f[T](@T x) -> @T { + ret x; +} + +fn main() { + auto x = f(@3); + log *x; +} + -- cgit 1.4.1-3-g733a5 From 19b2850388f634b500e612d8f24bbcb8c0fa2f3c Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 24 Feb 2011 19:24:12 -0800 Subject: rustc: Perform type parameter substitutions when emitting glue for generic tags. Un-XFAIL generic-tag.rs. --- src/Makefile | 1 - src/comp/middle/trans.rs | 21 +++++++++++++-------- src/comp/middle/ty.rs | 43 ++++++++++++++++++++++++++++++++++++++++++- src/comp/middle/typeck.rs | 23 +---------------------- 4 files changed, 56 insertions(+), 32 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 12b65246754..1f5901ba405 100644 --- a/src/Makefile +++ b/src/Makefile @@ -468,7 +468,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ generic-recursive-tag.rs \ generic-tag-alt.rs \ generic-tag-values.rs \ - generic-tag.rs \ integral-indexing.rs \ iter-range.rs \ iter-ret.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index a3a1d83fc3e..467aaa0df0e 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1,3 +1,4 @@ +import std._int; import std._str; import std._uint; import std._vec; @@ -61,7 +62,8 @@ type glue_fns = rec(ValueRef activate_glue, tag arity { nullary; n_ary; } type tag_info = rec(type_handle th, mutable vec[tup(ast.def_id,arity)] variants, - mutable uint size); + mutable uint size, + vec[ast.ty_param] ty_params); state type crate_ctxt = rec(session.session sess, ModuleRef llmod, @@ -1498,9 +1500,7 @@ fn iter_structural_ty(@block_ctxt cx, i += 1; } } - case (ty.ty_tag(?tid, _)) { - // TODO: type params! - + case (ty.ty_tag(?tid, ?tps)) { check (cx.fcx.ccx.tags.contains_key(tid)); auto info = cx.fcx.ccx.tags.get(tid); auto n_variants = _vec.len[tup(ast.def_id,arity)](info.variants); @@ -1559,11 +1559,15 @@ fn iter_structural_ty(@block_ctxt cx, auto llfldp = variant_cx.build.GEP(llvarp, v); + auto ty_subst = ty.substitute_ty_params( + info.ty_params, tps, a.ty); + auto llfld = load_scalar_or_boxed(variant_cx, - llfldp, a.ty); + llfldp, + ty_subst); - auto res = f(variant_cx, llfld, a.ty); + auto res = f(variant_cx, llfld, ty_subst); variant_cx = res.bcx; j += 1u; } @@ -4433,13 +4437,14 @@ fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt { cx.items.insert(mid, i); } - case (ast.item_tag(_, ?variants, _, ?tag_id)) { + case (ast.item_tag(_, ?variants, ?tps, ?tag_id)) { auto vi = new_def_hash[uint](); auto navi = new_def_hash[uint](); let vec[tup(ast.def_id,arity)] variant_info = vec(); cx.tags.insert(tag_id, @rec(th=mk_type_handle(), mutable variants=variant_info, - mutable size=0u)); + mutable size=0u, + ty_params=tps)); cx.items.insert(tag_id, i); } diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index 5535879e6e1..02a7ffc241b 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1450,7 +1450,7 @@ fn type_err_to_str(&ty.type_err err) -> str { } } -// Type parameter resolution, used in translation +// Type parameter resolution, used in translation and typechecking fn resolve_ty_params(ty_params_and_ty ty_params_and_polyty, @t monoty) -> vec[@t] { @@ -1492,6 +1492,47 @@ fn resolve_ty_params(ty_params_and_ty ty_params_and_polyty, ret result_tys; } +// Performs type parameter replacement using the supplied mapping from +// parameter IDs to types. +fn replace_type_params(@t typ, hashmap[ast.def_id,@t] param_map) -> @t { + state obj param_replacer(hashmap[ast.def_id,@t] param_map) { + fn fold_simple_ty(@t typ) -> @t { + alt (typ.struct) { + case (ty_param(?param_def)) { + if (param_map.contains_key(param_def)) { + ret param_map.get(param_def); + } else { + ret typ; + } + } + case (_) { + ret typ; + } + } + } + } + auto replacer = param_replacer(param_map); + ret fold_ty(replacer, typ); +} + +// Substitutes the type parameters specified by @ty_params with the +// corresponding types in @bound in the given type. The two vectors must have +// the same length. +fn substitute_ty_params(vec[ast.ty_param] ty_params, vec[@t] bound, @t ty) + -> @t { + auto ty_param_len = _vec.len[ast.ty_param](ty_params); + check (ty_param_len == _vec.len[@t](bound)); + + auto bindings = common.new_def_hash[@t](); + auto i = 0u; + while (i < ty_param_len) { + bindings.insert(ty_params.(i).id, bound.(i)); + i += 1u; + } + + ret replace_type_params(ty, bindings); +} + // Local Variables: // mode: rust // fill-column: 78; diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 0d583c5e418..40fd0f15202 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -147,27 +147,6 @@ 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 replace_type_params(@ty.t t, ty_table param_map) -> @ty.t { - state obj param_replacer(ty_table param_map) { - fn fold_simple_ty(@ty.t t) -> @ty.t { - alt (t.struct) { - case (ty.ty_param(?param_def)) { - if (param_map.contains_key(param_def)) { - ret param_map.get(param_def); - } else { - ret t; - } - } - case (_) { - ret t; - } - } - } - } - auto replacer = param_replacer(param_map); - ret ty.fold_ty(replacer, t); - } - fn instantiate(ty_getter getter, ast.def_id id, vec[@ast.ty] args) -> @ty.t { // TODO: maybe record cname chains so we can do @@ -183,7 +162,7 @@ fn ast_ty_to_ty(ty_getter getter, &@ast.ty ast_ty) -> @ty.t { auto param = params.(i); param_map.insert(param.id, ast_ty_to_ty(getter, arg)); } - ret replace_type_params(ty_and_params.ty, param_map); + ret ty.replace_type_params(ty_and_params.ty, param_map); } auto mut = ast.imm; -- cgit 1.4.1-3-g733a5 From 3d04fa029e7773bca591502c2890944fae1cefdc Mon Sep 17 00:00:00 2001 From: Rafael Ávila de Espíndola Date: Fri, 25 Feb 2011 11:59:00 -0500 Subject: Disable test that is failing on valgrind. --- src/Makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 1f5901ba405..e189c8d0692 100644 --- a/src/Makefile +++ b/src/Makefile @@ -439,7 +439,8 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ test/compile-fail/tail-non-call.rs \ test/compile-fail/writing-through-read-alias.rs -TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ +TEST_XFAILS_RUSTC := $(CONST_TAG_XFAILS) \ + $(addprefix test/run-pass/, \ acyclic-unwind.rs \ alt-pattern-drop.rs \ alt-type-simple.rs \ -- cgit 1.4.1-3-g733a5 From a172f5aef5f7d26fba9dbf94a1ade60d6d62ba74 Mon Sep 17 00:00:00 2001 From: Rafael Ávila de Espíndola Date: Mon, 28 Feb 2011 17:33:46 -0500 Subject: Declare wrappers to the native functions and use those to create the fn/closure pairs. Disable native2.rs for now as we are not yet defining the wrappers and it fails to link. --- src/Makefile | 1 + src/comp/middle/trans.rs | 32 ++++++++++++++++++++++++++++---- 2 files changed, 29 insertions(+), 4 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index e189c8d0692..6659297e8df 100644 --- a/src/Makefile +++ b/src/Makefile @@ -491,6 +491,7 @@ TEST_XFAILS_RUSTC := $(CONST_TAG_XFAILS) \ mlist-cycle.rs \ mlist.rs \ mutable-alias-vec.rs \ + native2.rs \ native-opaque-type.rs \ obj-as.rs \ obj-dtor.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 3564b1b36d0..189c742cee6 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -4395,6 +4395,12 @@ fn decl_fn_and_pair(@crate_ctxt cx, // Declare the global constant pair that points to it. let str ps = cx.names.next("_rust_" + kind + "_pair") + sep() + name; + + register_fn_pair(cx, ps, llpairty, llfn, id); +} + +fn register_fn_pair(@crate_ctxt cx, str ps, TypeRef llpairty, ValueRef llfn, + ast.def_id id) { let ValueRef gvar = llvm.LLVMAddGlobal(cx.llmod, llpairty, _str.buf(ps)); auto pair = C_struct(vec(llfn, @@ -4410,16 +4416,34 @@ fn decl_fn_and_pair(@crate_ctxt cx, cx.fn_pairs.insert(id, gvar); } +fn native_fn_wrapper_type(@crate_ctxt cx, &ast.ann ann) -> TypeRef { + auto x = node_ann_type(cx, ann); + alt (x.struct) { + case (ty.ty_native_fn(?abi, ?args, ?out)) { + ret type_of_fn(cx, ast.proto_fn, args, out); + } + } + fail; +} + fn decl_native_fn_and_pair(@crate_ctxt cx, str name, &ast.ann ann, ast.def_id id) { + // Declare the wrapper. + auto wrapper_type = native_fn_wrapper_type(cx, ann); + let str s = cx.names.next("_rust_wrapper") + sep() + name; + let ValueRef wrapper_fn = decl_fastcall_fn(cx.llmod, s, wrapper_type); - auto llpairty = node_type(cx, ann); - auto llfty = get_pair_fn_ty(llpairty); + // Declare the global constant pair that points to it. + auto wrapper_pair_type = T_fn_pair(cx.tn, wrapper_type); + let str ps = cx.names.next("_rust_wrapper_pair") + sep() + name; - let ValueRef llfn = decl_cdecl_fn(cx.llmod, name, llfty); - cx.item_ids.insert(id, llfn); + register_fn_pair(cx, ps, wrapper_pair_type, wrapper_fn, id); + + // Declare the function itself. + auto llfty = get_pair_fn_ty(node_type(cx, ann)); + decl_cdecl_fn(cx.llmod, name, llfty); } fn collect_native_item(&@crate_ctxt cx, @ast.native_item i) -> @crate_ctxt { -- cgit 1.4.1-3-g733a5 From 7f2398e557d4b75cbf83dc88b6740e83a8d20910 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Tue, 1 Mar 2011 13:00:50 -0800 Subject: Implement structured compare for rec, tup, tag. Un-XFAIL structured-compare.rs. --- src/Makefile | 1 - src/comp/middle/trans.rs | 76 +++++++++++++++++++++++++++++++++++------------- 2 files changed, 55 insertions(+), 22 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 6659297e8df..2be8be48338 100644 --- a/src/Makefile +++ b/src/Makefile @@ -505,7 +505,6 @@ TEST_XFAILS_RUSTC := $(CONST_TAG_XFAILS) \ spawn.rs \ str-append.rs \ str-concat.rs \ - structured-compare.rs \ syntax-extension-fmt.rs \ syntax-extension-shell.rs \ task-comm-0.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 61da7f53d5c..9a650da5876 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -1583,24 +1583,30 @@ fn iter_structural_ty_full(@block_ctxt cx, auto llunion_b_ptr = cx.build.GEP(bv, vec(C_int(0), C_int(1))); auto lldiscrim_b = cx.build.Load(lldiscrim_b_ptr); - auto unr_cx = new_sub_block_ctxt(cx, "tag-iter-unr"); + // NB: we must hit the discriminant first so that structural + // comparison know not to proceed when the discriminants differ. + auto bcx = cx; + bcx = f(bcx, lldiscrim_a, lldiscrim_b, + plain_ty(ty.ty_int)).bcx; + + auto unr_cx = new_sub_block_ctxt(bcx, "tag-iter-unr"); unr_cx.build.Unreachable(); - auto llswitch = cx.build.Switch(lldiscrim_a, unr_cx.llbb, + auto llswitch = bcx.build.Switch(lldiscrim_a, unr_cx.llbb, n_variants); - auto next_cx = new_sub_block_ctxt(cx, "tag-iter-next"); + auto next_cx = new_sub_block_ctxt(bcx, "tag-iter-next"); auto i = 0u; for (ast.variant variant in variants) { - auto variant_cx = new_sub_block_ctxt(cx, + auto variant_cx = new_sub_block_ctxt(bcx, "tag-iter-variant-" + _uint.to_str(i, 10u)); llvm.LLVMAddCase(llswitch, C_int(i as int), variant_cx.llbb); if (_vec.len[ast.variant_arg](variant.args) > 0u) { // N-ary variant. - auto llvarty = type_of_variant(cx.fcx.ccx, variants.(i)); + auto llvarty = type_of_variant(bcx.fcx.ccx, variants.(i)); auto fn_ty = ty.ann_to_type(variants.(i).ann); alt (fn_ty.struct) { @@ -1611,7 +1617,7 @@ fn iter_structural_ty_full(@block_ctxt cx, auto llvarp_b = variant_cx.build. TruncOrBitCast(llunion_b_ptr, T_ptr(llvarty)); - auto ty_params = tag_ty_params(cx.fcx.ccx, tid); + auto ty_params = tag_ty_params(bcx.fcx.ccx, tid); auto j = 0u; for (ty.arg a in args) { @@ -2023,37 +2029,65 @@ fn trans_compare(@block_ctxt cx, ast.binop op, @ty.t t, auto next = new_sub_block_ctxt(cx, "structural compare end"); cx.build.Br(scx.llbb); - // Start with the assumptioin that our predicate holds. + /* + * We're doing lexicographic comparison here. We start with the + * assumption that the two input elements are equal. Depending on + * operator, this means that the result is either true or false; + * equality produces 'true' for ==, <= and >=. It produces 'false' for + * !=, < and >. + * + * We then move one element at a time through the structure checking + * for pairwise element equality. If we have equality, our assumption + * about overall sequence equality is not modified, so we have to move + * to the next element. + * + * If we do not have pairwise element equality, we have reached an + * element that 'decides' the lexicographic comparison. So we exit the + * loop with a flag that indicates the true/false sense of that + * decision, by testing the element again with the operator we're + * interested in. + * + * When we're lucky, LLVM should be able to fold some of these two + * tests together (as they're applied to the same operands and in some + * cases are sometimes redundant). But we don't bother trying to + * optimize combinations like that, at this level. + */ + auto flag = scx.build.Alloca(T_i1()); - scx.build.Store(C_integral(1, T_i1()), flag); - // Attempt to prove otherwise by assuming true, comparing each element - // and writing 0 + early-exiting if any comparisons fail. + alt (op) { + // ==, <= and >= default to true if they find == all the way. + case (ast.eq) { scx.build.Store(C_integral(1, T_i1()), flag); } + case (ast.le) { scx.build.Store(C_integral(1, T_i1()), flag); } + case (ast.ge) { scx.build.Store(C_integral(1, T_i1()), flag); } + case (_) { + // ==, <= and >= default to false if they find == all the way. + scx.build.Store(C_integral(0, T_i1()), flag); + } + } - fn inner(@block_ctxt next_cx, + fn inner(@block_ctxt last_cx, ValueRef flag, ast.binop op, @block_ctxt cx, ValueRef av, ValueRef bv, @ty.t t) -> result { - // Compare av op bv + auto cnt_cx = new_sub_block_ctxt(cx, "continue comparison"); auto stop_cx = new_sub_block_ctxt(cx, "stop comparison"); - auto r = trans_compare(cx, op, t, av, bv); - - // if true, then carry on, else write 0 to flag, branch to 'next'. - r.bcx.build.CondBr(r.val, cnt_cx.llbb, stop_cx.llbb); - stop_cx.build.Store(C_integral(0, T_i1()), flag); - stop_cx.build.Br(next_cx.llbb); + // First 'eq' comparison: if so, continue to next elts. + auto eq_r = trans_compare(cx, ast.eq, t, av, bv); + eq_r.bcx.build.CondBr(eq_r.val, cnt_cx.llbb, stop_cx.llbb); + // Second 'op' comparison: find out how this elt-pair decides. + auto stop_r = trans_compare(stop_cx, op, t, av, bv); + stop_r.bcx.build.Store(stop_r.val, flag); + stop_r.bcx.build.Br(last_cx.llbb); ret res(cnt_cx, C_nil()); } - // FIXME: this is wrong for tag types; need to confirm discriminants - // are equal before blindly walking over elements. - auto r = iter_structural_ty_full(scx, lhs, rhs, t, bind inner(next, flag, op, _, _, _, _)); -- cgit 1.4.1-3-g733a5 From 7f74d4d4f2e0635d644be6e2259973b5cf559a2e Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Thu, 3 Mar 2011 14:31:25 -0800 Subject: Turn on Valgrind for Mac --- src/Makefile | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 2be8be48338..37726b6eea1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -43,13 +43,6 @@ ifeq ($(CFG_OSTYPE), FreeBSD) endif CFG_NATIVE := 1 CFG_UNIXY := 1 - CFG_VALGRIND := $(shell which valgrind) - ifdef CFG_VALGRIND - CFG_VALGRIND += --leak-check=full \ - --error-exitcode=1 \ - --quiet --vex-iropt-level=0 \ - --suppressions=etc/x86.supp - endif endif ifeq ($(CFG_OSTYPE), Linux) @@ -63,13 +56,6 @@ ifeq ($(CFG_OSTYPE), Linux) endif CFG_NATIVE := 1 CFG_UNIXY := 1 - CFG_VALGRIND := $(shell which valgrind) - ifdef CFG_VALGRIND - CFG_VALGRIND += --leak-check=full \ - --error-exitcode=1 \ - --quiet --vex-iropt-level=0 \ - --suppressions=etc/x86.supp - endif endif ifeq ($(CFG_OSTYPE), Darwin) @@ -137,6 +123,13 @@ ifdef CFG_UNIXY CFG_GCC_LINK_FLAGS += -m32 endif endif + CFG_VALGRIND := $(shell which valgrind) + ifdef CFG_VALGRIND + CFG_VALGRIND += --leak-check=full \ + --error-exitcode=1 \ + --quiet --vex-iropt-level=0 \ + --suppressions=etc/x86.supp + endif endif ifdef CFG_GCC -- cgit 1.4.1-3-g733a5 From 5c7db0cde15adfda5b43112ee86d4bfe3bd9ee82 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Thu, 3 Mar 2011 15:19:26 -0800 Subject: Rewrite rustboot's flow-graph wiring passes to be less awful. Add test for nested control-flow constructs. --- src/Makefile | 1 + src/boot/me/typestate.ml | 352 +++++++++-------------------- src/test/run-pass/typestate-cfg-nesting.rs | 26 +++ 3 files changed, 131 insertions(+), 248 deletions(-) create mode 100644 src/test/run-pass/typestate-cfg-nesting.rs (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 37726b6eea1..49cc04567c1 100644 --- a/src/Makefile +++ b/src/Makefile @@ -521,6 +521,7 @@ TEST_XFAILS_RUSTC := $(CONST_TAG_XFAILS) \ task-life-0.rs \ threads.rs \ type-sizes.rs \ + typestate-cfg-nesting.rs \ use-import-export.rs \ user.rs \ utf8.rs \ diff --git a/src/boot/me/typestate.ml b/src/boot/me/typestate.ml index ea0204f37cc..1c9c90eaa4a 100644 --- a/src/boot/me/typestate.ml +++ b/src/boot/me/typestate.ml @@ -24,7 +24,6 @@ type typestate_tables = ts_prestates: (node_id,Bits.t) Hashtbl.t; ts_poststates: (node_id,Bits.t) Hashtbl.t; ts_graph: node_graph; - ts_siblings: sibling_map; ts_stmts: Ast.stmt Stack.t; ts_maxid: int ref; } @@ -38,7 +37,6 @@ let new_tables _ = ts_poststates = Hashtbl.create 0; ts_prestates = Hashtbl.create 0; ts_graph = Hashtbl.create 0; - ts_siblings = Hashtbl.create 0; ts_stmts = Stack.create (); ts_maxid = ref 0 } ;; @@ -790,279 +788,143 @@ let show_node cx graph s i = s (int_of_node i) (lset_fmt (Hashtbl.find graph i))) ;; -let graph_sequence_building_visitor - (cx:ctxt) - (tables_stack:typestate_tables Stack.t) - (inner:Walk.visitor) - : Walk.visitor = +let add_flow_edges (graph:node_graph) (n:node_id) (dsts:node_id list) : unit = + if Hashtbl.mem graph n + then + let existing = Hashtbl.find graph n in + Hashtbl.replace graph n (lset_union existing dsts) + else + Hashtbl.add graph n dsts +;; - let tables _ = Stack.top tables_stack in +let rec build_flow_graph_for_stmt + (graph:node_graph) + (predecessors:node_id list) + (s:Ast.stmt) + : node_id list = - (* Flow each stmt to its sequence-successor. *) - let visit_stmts stmts = - let ts = tables () in - let graph = ts.ts_graph in - let sibs = ts.ts_siblings in - let len = Array.length stmts in - for i = 0 to len - 2 - do - let stmt = stmts.(i) in - let next = stmts.(i+1) in - log cx "sequential stmt edge %d -> %d" - (int_of_node stmt.id) (int_of_node next.id); - htab_put graph stmt.id [next.id]; - htab_put sibs stmt.id next.id; - done; - (* Flow last node to nowhere. *) - if len > 0 - then htab_put graph stmts.(len-1).id [] + let connect ps qs = + List.iter + (fun pred -> add_flow_edges graph pred qs) + ps in - let visit_stmt_pre s = - (* Sequence the prelude nodes on special stmts. *) - begin - match s.node with - Ast.STMT_while sw -> - let (stmts, _) = sw.Ast.while_lval in - visit_stmts stmts - | _ -> () - end; - inner.Walk.visit_stmt_pre s + let seq ps (ss:Ast.stmt array) = + build_flow_graph_for_stmts graph ps ss in - let visit_block_pre b = - visit_stmts b.node; - inner.Walk.visit_block_pre b + let blk ps b = + connect ps [b.id]; + seq [b.id] b.node in - { inner with - Walk.visit_stmt_pre = visit_stmt_pre; - Walk.visit_block_pre = visit_block_pre } -;; - -let add_flow_edges (graph:node_graph) (n:node_id) (dsts:node_id list) : unit = - let existing = Hashtbl.find graph n in - Hashtbl.replace graph n (lset_union existing dsts) -;; + let first ss = + if Array.length ss = 0 + then [] + else [ss.(0).id] + in -let remove_flow_edges - (graph:node_graph) - (n:node_id) - (dsts:node_id list) - : unit = - let existing = Hashtbl.find graph n in - Hashtbl.replace graph n (lset_diff existing dsts) -;; + connect [s.id] []; + let outs = + match s.node with + | Ast.STMT_while sw -> + let (pre_loop_stmts, _) = sw.Ast.while_lval in + let body = sw.Ast.while_body in + let preloop_end = seq [s.id] pre_loop_stmts in + connect predecessors [s.id]; + connect (blk preloop_end body) (first pre_loop_stmts); + preloop_end + + | Ast.STMT_for sf -> + let body_end = blk [s.id] sf.Ast.for_body in + connect predecessors [s.id]; + connect body_end (first sf.Ast.for_body.node); + body_end + + | Ast.STMT_for_each sfe -> + let head_end = blk [s.id] sfe.Ast.for_each_head in + let body_end = blk head_end sfe.Ast.for_each_body in + connect predecessors [s.id]; + connect body_end (first sfe.Ast.for_each_head.node); + body_end + + | Ast.STMT_if sif -> + connect predecessors [s.id]; + (blk [s.id] sif.Ast.if_then) @ + (match sif.Ast.if_else with + None -> [s.id] + | Some els -> blk [s.id] els) + + | Ast.STMT_alt_tag sat -> + connect predecessors [s.id]; + Array.fold_left + (fun ends {node=(_, b); id=_} -> (blk [s.id] b) @ ends) + [] sat.Ast.alt_tag_arms + + | Ast.STMT_block b -> + blk predecessors b + + | _ -> + connect predecessors [s.id]; + [s.id] + in + connect outs []; + outs -let last_id (nodes:('a identified) array) : node_id = - let len = Array.length nodes in - nodes.(len-1).id +and build_flow_graph_for_stmts + (graph:node_graph) + (predecessors:node_id list) + (ss:Ast.stmt array) + : node_id list = + Array.fold_left (build_flow_graph_for_stmt graph) predecessors ss ;; -let last_id_or_block_id (block:Ast.block) : node_id = - let len = Array.length block.node in - if len = 0 - then block.id - else last_id block.node -;; -let graph_general_block_structure_building_visitor +let graph_building_visitor (cx:ctxt) (tables_stack:typestate_tables Stack.t) (inner:Walk.visitor) : Walk.visitor = let tables _ = Stack.top tables_stack in + let graph _ = (tables()).ts_graph in + let blk b = + add_flow_edges (graph()) b.id []; + ignore (build_flow_graph_for_stmts (graph()) [b.id] b.node) + in - let visit_stmt_pre s = - let ts = tables () in - let stmts = ts.ts_stmts in - Stack.push s stmts; - inner.Walk.visit_stmt_pre s + let visit_mod_item_pre n p i = + begin + match i.node.Ast.decl_item with + Ast.MOD_ITEM_fn fn -> blk fn.Ast.fn_body + | _ -> () + end; + inner.Walk.visit_mod_item_pre n p i in - let visit_stmt_post s = - let ts = tables () in - let stmts = ts.ts_stmts in - inner.Walk.visit_stmt_post s; - ignore (Stack.pop stmts) + let visit_obj_fn_pre obj ident fn = + blk fn.node.Ast.fn_body; + inner.Walk.visit_obj_fn_pre obj ident fn in - let show_node = - fun n id -> show_node cx (tables()).ts_graph n id + let visit_obj_drop_pre obj b = + blk b; + inner.Walk.visit_obj_drop_pre obj b in let visit_block_pre b = - begin - let ts = tables () in - let graph = ts.ts_graph in - let sibs = ts.ts_siblings in - let stmts = ts.ts_stmts in - let len = Array.length b.node in - let _ = htab_put graph b.id - (if len > 0 then [b.node.(0).id] else []) - in - - (* - * If block has len, - * then flow block to block.node.(0) and block.node.(len-1) to dsts - * else flow block to dsts - * - * so AST: - * - * block#n{ stmt#0 ... stmt#k }; - * stmt#j; - * - * turns into graph: - * - * block#n -> stmt#0 -> ... -> stmt#k -> stmt#j - * - *) - if Stack.is_empty stmts - then () - else - let s = Stack.top stmts in - add_flow_edges graph s.id [b.id]; - match htab_search sibs s.id with - None -> () - | Some sib_id -> - if len > 0 - then - add_flow_edges graph (last_id b.node) [sib_id] - else - add_flow_edges graph b.id [sib_id] - end; - show_node "block" b.id; + if Hashtbl.mem cx.ctxt_block_is_loop_body b.id + then blk b; inner.Walk.visit_block_pre b in { inner with - Walk.visit_stmt_pre = visit_stmt_pre; - Walk.visit_stmt_post = visit_stmt_post; + Walk.visit_mod_item_pre = visit_mod_item_pre; + Walk.visit_obj_fn_pre = visit_obj_fn_pre; + Walk.visit_obj_drop_pre = visit_obj_drop_pre; Walk.visit_block_pre = visit_block_pre } -;; - - -let graph_special_block_structure_building_visitor - (cx:ctxt) - (tables_stack:typestate_tables Stack.t) - (inner:Walk.visitor) - : Walk.visitor = - let tables _ = Stack.top tables_stack in - - let visit_stmt_pre s = - begin - match s.node with - - Ast.STMT_if sif -> - let ts = tables () in - let graph = ts.ts_graph in - let cond_id = s.id in - let succ = Hashtbl.find graph cond_id in - let then_id = sif.Ast.if_then.id in - let then_end_id = last_id_or_block_id sif.Ast.if_then in - let show_node = show_node cx graph in - let succ = List.filter (fun x -> not (x = then_id)) succ in - show_node "initial cond" cond_id; - show_node "initial then" then_id; - show_node "initial then_end" then_end_id; - begin - match sif.Ast.if_else with - None -> - Hashtbl.replace graph cond_id (then_id :: succ); - (* Kill residual messed-up block wiring.*) - remove_flow_edges graph then_end_id [then_id]; - show_node "cond" cond_id; - show_node "then" then_id; - show_node "then_end" then_end_id; - - | Some e -> - let else_id = e.id in - let succ = - List.filter (fun x -> not (x = else_id)) succ - in - let else_end_id = last_id_or_block_id e in - show_node "initial else" else_id; - show_node "initial else_end" else_end_id; - Hashtbl.replace graph cond_id [then_id; else_id]; - Hashtbl.replace graph then_end_id succ; - Hashtbl.replace graph else_end_id succ; - - (* Kill residual messed-up block wiring.*) - remove_flow_edges graph then_end_id [then_id]; - remove_flow_edges graph else_id [then_id]; - remove_flow_edges graph else_end_id [then_id]; - show_node "cond" cond_id; - show_node "then" then_id; - show_node "then_end" then_end_id; - show_node "else" else_id; - show_node "else_end" else_end_id; - end; - - | Ast.STMT_while sw -> - (* There are a bunch of rewirings to do on 'while' nodes. *) - - begin - let ts = tables () in - let graph = ts.ts_graph in - let dsts = Hashtbl.find graph s.id in - let body = sw.Ast.while_body in - let succ_stmts = - List.filter (fun x -> not (x = body.id)) dsts - in - - let (pre_loop_stmts, _) = sw.Ast.while_lval in - let loop_head_id = - (* Splice loop prelude into flow graph, save loop-head - * node. - *) - let slen = Array.length pre_loop_stmts in - if slen > 0 - then - begin - let pre_loop_begin = pre_loop_stmts.(0).id in - let pre_loop_end = last_id pre_loop_stmts in - remove_flow_edges graph s.id [body.id]; - add_flow_edges graph s.id [pre_loop_begin]; - add_flow_edges graph pre_loop_end [body.id]; - pre_loop_end - end - else - body.id - in - - (* Always flow s into the loop prelude; prelude may end - * loop. - *) - remove_flow_edges graph s.id succ_stmts; - add_flow_edges graph loop_head_id succ_stmts; - - (* Flow loop-end to loop-head. *) - let loop_end = last_id_or_block_id body in - add_flow_edges graph loop_end [loop_head_id] - end - - | Ast.STMT_alt_tag at -> - let ts = tables () in - let graph = ts.ts_graph in - let dsts = Hashtbl.find graph s.id in - let arm_blocks = - let arm_block_id { node = (_, block); id = _ } = block.id in - Array.to_list (Array.map arm_block_id at.Ast.alt_tag_arms) - in - let succ_stmts = - List.filter (fun x -> not (List.mem x arm_blocks)) dsts - in - remove_flow_edges graph s.id succ_stmts - - | _ -> () - end; - inner.Walk.visit_stmt_post s - in - { inner with - Walk.visit_stmt_pre = visit_stmt_pre } ;; let find_roots @@ -1631,13 +1493,7 @@ let process_crate (condition_assigning_visitor cx tables_stack scopes Walk.empty_visitor))); (table_managed - (graph_sequence_building_visitor cx tables_stack - Walk.empty_visitor)); - (table_managed - (graph_general_block_structure_building_visitor cx tables_stack - Walk.empty_visitor)); - (table_managed - (graph_special_block_structure_building_visitor cx tables_stack + (graph_building_visitor cx tables_stack Walk.empty_visitor)); |] in diff --git a/src/test/run-pass/typestate-cfg-nesting.rs b/src/test/run-pass/typestate-cfg-nesting.rs new file mode 100644 index 00000000000..8f0506469b1 --- /dev/null +++ b/src/test/run-pass/typestate-cfg-nesting.rs @@ -0,0 +1,26 @@ + +fn f() { + + auto x = 10; + auto y = 11; + if (true) { + alt (x) { + case (_) { + y = x; + } + } + } else { + } +} + +fn main() { + + auto x = 10; + auto y = 11; + if (true) { + while (false) { + y = x; + } + } else { + } +} -- cgit 1.4.1-3-g733a5 From 95c0cefd32bc1af5e91857511187760010aaffc7 Mon Sep 17 00:00:00 2001 From: Rafael Ávila de Espíndola Date: Fri, 4 Mar 2011 15:29:33 -0500 Subject: Build empty wrappers. This lets us compile hello world, but so far it just returns 0. --- src/Makefile | 1 - src/comp/middle/trans.rs | 5 +++++ 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 49cc04567c1..2ec0f9d168e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -484,7 +484,6 @@ TEST_XFAILS_RUSTC := $(CONST_TAG_XFAILS) \ mlist-cycle.rs \ mlist.rs \ mutable-alias-vec.rs \ - native2.rs \ native-opaque-type.rs \ obj-as.rs \ obj-dtor.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index d2fa0acc327..2f45691adf2 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -4829,6 +4829,11 @@ fn decl_native_fn_and_pair(@crate_ctxt cx, let str s = cx.names.next("_rust_wrapper") + sep() + name; let ValueRef wrapper_fn = decl_fastcall_fn(cx.llmod, s, wrapper_type); + // Build the wrapper. + auto fcx = new_fn_ctxt(cx, wrapper_fn); + auto bcx = new_top_block_ctxt(fcx); + bcx.build.RetVoid(); + // Declare the global constant pair that points to it. auto wrapper_pair_type = T_fn_pair(cx.tn, wrapper_type); let str ps = cx.names.next("_rust_wrapper_pair") + sep() + name; -- cgit 1.4.1-3-g733a5 From 94b681afe4f8fb09141d459963b268c76fbd0072 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Fri, 4 Mar 2011 18:05:48 -0800 Subject: rustc: Use copy_ty() when initializing N-ary tag variants. Un-XFAIL generic-tag.rs. --- src/Makefile | 3 +-- src/comp/middle/trans.rs | 23 ++++++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 2ec0f9d168e..484740b5df2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -432,8 +432,7 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ test/compile-fail/tail-non-call.rs \ test/compile-fail/writing-through-read-alias.rs -TEST_XFAILS_RUSTC := $(CONST_TAG_XFAILS) \ - $(addprefix test/run-pass/, \ +TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ acyclic-unwind.rs \ alt-pattern-drop.rs \ alt-type-simple.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 9b7a501c52e..b5ff42248dc 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -363,17 +363,22 @@ fn T_taskptr(type_names tn) -> TypeRef { ret T_ptr(T_task(tn)); } -fn T_typaram_ptr(type_names tn) -> TypeRef { +// This type must never be used directly; it must always be cast away. +fn T_typaram(type_names tn) -> TypeRef { auto s = "typaram"; if (tn.name_has_type(s)) { ret tn.get_type(s); } - auto t = T_ptr(T_i8()); + auto t = T_i8(); tn.associate(s, t); ret t; } +fn T_typaram_ptr(type_names tn) -> TypeRef { + ret T_ptr(T_typaram(tn)); +} + fn T_closure_ptr(type_names tn, TypeRef lltarget_ty, TypeRef llbindings_ty, @@ -2068,7 +2073,6 @@ fn call_tydesc_glue(@block_ctxt cx, ValueRef v, @ty.t t, int field) { fn incr_all_refcnts(@block_ctxt cx, ValueRef v, @ty.t t) -> result { - if (!ty.type_is_scalar(t)) { call_tydesc_glue(cx, v, t, abi.tydesc_field_take_glue_off); } @@ -4820,9 +4824,18 @@ fn trans_tag_variant(@crate_ctxt cx, ast.def_id tag_id, // works. So we have to cast to the destination's view of the type. auto llargptr = bcx.build.PointerCast(fcx.llargs.get(va.id), val_ty(lldestptr)); - auto llargval = bcx.build.Load(llargptr); - bcx.build.Store(llargval, lldestptr); + auto arg_ty = arg_tys.(i).ty; + auto llargval; + if (ty.type_is_structural(arg_ty)) { + llargval = llargptr; + } else { + llargval = bcx.build.Load(llargptr); + } + + rslt = copy_ty(bcx, INIT, lldestptr, llargval, arg_ty); + bcx = rslt.bcx; + i += 1u; } -- cgit 1.4.1-3-g733a5 From f017a9e71fde98dbfdb2edb9fbc2af8781611664 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 7 Mar 2011 00:18:10 -0800 Subject: Un-XFAIL str-concat.rs. --- src/Makefile | 1 - 1 file changed, 1 deletion(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 484740b5df2..81ca965db16 100644 --- a/src/Makefile +++ b/src/Makefile @@ -495,7 +495,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ spawn-module-qualified.rs \ spawn.rs \ str-append.rs \ - str-concat.rs \ syntax-extension-fmt.rs \ syntax-extension-shell.rs \ task-comm-0.rs \ -- cgit 1.4.1-3-g733a5 From eeb2d6d32cbdc975fcc0a0c82adca37913ed6dff Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 7 Mar 2011 14:28:52 -0800 Subject: rustc: Un-XFAIL box-unbox.rs --- src/Makefile | 1 - 1 file changed, 1 deletion(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 81ca965db16..17fb737ef13 100644 --- a/src/Makefile +++ b/src/Makefile @@ -442,7 +442,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ basic-2.rs \ basic.rs \ bind-obj-ctor.rs \ - box-unbox.rs \ child-outlives-parent.rs \ clone-with-exterior.rs \ comm.rs \ -- cgit 1.4.1-3-g733a5 From 7fa8936ece50c5d58edcf3c3166e9570ba6e6197 Mon Sep 17 00:00:00 2001 From: Graydon Hoare Date: Mon, 7 Mar 2011 14:48:24 -0800 Subject: Un-XFAIL 5 more tests that pass lately. --- src/Makefile | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 17fb737ef13..ac82293216d 100644 --- a/src/Makefile +++ b/src/Makefile @@ -437,7 +437,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ alt-pattern-drop.rs \ alt-type-simple.rs \ append-units.rs \ - autoderef-objfn.rs \ basic-1.rs \ basic-2.rs \ basic.rs \ @@ -447,10 +446,8 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ comm.rs \ constrained-type.rs \ destructor-ordering.rs \ - drop-on-empty-block-exit.rs \ drop-parametric-closure-with-bound-box.rs \ export-non-interference.rs \ - exterior.rs \ foreach-nested-2.rs \ foreach-nested.rs \ foreach-put-structured.rs \ @@ -482,7 +479,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ mlist-cycle.rs \ mlist.rs \ mutable-alias-vec.rs \ - native-opaque-type.rs \ obj-as.rs \ obj-dtor.rs \ obj-return-polytypes.rs \ @@ -523,7 +519,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ utf8.rs \ vec-alloc-append.rs \ vec-append.rs \ - vec-concat.rs \ vec-slice.rs \ while-prelude-drop.rs \ while-with-break.rs \ -- cgit 1.4.1-3-g733a5 From 3869b3bfe489fc8db37b4436a9a38e732cc3d219 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 7 Mar 2011 15:12:41 -0800 Subject: Modernize test/run-pass/generic-recursive-tag.rs. Un-XFAIL it in rustboot. --- src/Makefile | 1 - src/test/run-pass/generic-recursive-tag.rs | 7 ++++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index ac82293216d..a1c13918e3a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -410,7 +410,6 @@ TEST_XFAILS_BOOT := $(TASK_XFAILS) \ test/run-pass/vec-slice.rs \ test/run-pass/fn-lval.rs \ test/run-pass/generic-fn-box.rs \ - test/run-pass/generic-recursive-tag.rs \ test/run-pass/generic-tup.rs \ test/run-pass/iter-ret.rs \ test/run-pass/lib-io.rs \ diff --git a/src/test/run-pass/generic-recursive-tag.rs b/src/test/run-pass/generic-recursive-tag.rs index ad06345bf28..b9596b0da9c 100644 --- a/src/test/run-pass/generic-recursive-tag.rs +++ b/src/test/run-pass/generic-recursive-tag.rs @@ -1,8 +1,9 @@ tag list[T] { cons(@T, @list[T]); - nil(); + nil; } fn main() { - let list[int] a = cons[int](10, cons[int](12, cons[int](13, nil[int]()))); -} \ No newline at end of file + let list[int] a = cons[int](@10, @cons[int](@12, @cons[int](@13, + @nil[int]))); +} -- cgit 1.4.1-3-g733a5 From 6f7e21ddac7bd956db55ea6885fbcfd3fb9f29a7 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 7 Mar 2011 15:43:55 -0800 Subject: rustc: Truncate or zero-extend indexes appropriately. Un-XFAIL integral-indexing.rs. --- src/Makefile | 1 - src/comp/middle/trans.rs | 17 +++++++++++++++-- 2 files changed, 15 insertions(+), 3 deletions(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index a1c13918e3a..2a6e7b154a4 100644 --- a/src/Makefile +++ b/src/Makefile @@ -456,7 +456,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ generic-recursive-tag.rs \ generic-tag-alt.rs \ generic-tag-values.rs \ - integral-indexing.rs \ iter-range.rs \ iter-ret.rs \ lazychan.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index aa904674925..7ad96ba247d 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3209,10 +3209,23 @@ fn trans_index(@block_ctxt cx, &ast.span sp, @ast.expr base, auto v = lv.val; auto bcx = ix.bcx; + // Cast to an LLVM integer. Rust is less strict than LLVM in this regard. + auto ix_val; + auto ix_size = llsize_of_real(cx.fcx.ccx, val_ty(ix.val)); + auto int_size = llsize_of_real(cx.fcx.ccx, T_int()); + if (ix_size < int_size) { + ix_val = bcx.build.ZExt(ix.val, T_int()); + } else if (ix_size > int_size) { + ix_val = bcx.build.Trunc(ix.val, T_int()); + } else { + ix_val = ix.val; + } + auto llunit_ty = node_type(cx.fcx.ccx, ann); auto unit_sz = size_of(bcx, node_ann_type(cx.fcx.ccx, ann)); bcx = unit_sz.bcx; - auto scaled_ix = bcx.build.Mul(ix.val, unit_sz.val); + + auto scaled_ix = bcx.build.Mul(ix_val, unit_sz.val); auto lim = bcx.build.GEP(v, vec(C_int(0), C_int(abi.vec_elt_fill))); lim = bcx.build.Load(lim); @@ -3229,7 +3242,7 @@ fn trans_index(@block_ctxt cx, &ast.span sp, @ast.expr base, fail_res.bcx.build.Br(next_cx.llbb); auto body = next_cx.build.GEP(v, vec(C_int(0), C_int(abi.vec_elt_data))); - auto elt = next_cx.build.GEP(body, vec(C_int(0), ix.val)); + auto elt = next_cx.build.GEP(body, vec(C_int(0), ix_val)); ret lval_mem(next_cx, elt); } -- cgit 1.4.1-3-g733a5 From 6ed226c6b3a28f3c10d2176d7dba7e339bf0ab99 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Mon, 7 Mar 2011 16:35:00 -0800 Subject: rustc: Cast the LLVM representations of tag types when constructing boxes. Un-XFAIL list.rs. --- src/Makefile | 1 - src/comp/middle/trans.rs | 9 +++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/Makefile') diff --git a/src/Makefile b/src/Makefile index 2a6e7b154a4..8855a2d10ba 100644 --- a/src/Makefile +++ b/src/Makefile @@ -472,7 +472,6 @@ TEST_XFAILS_RUSTC := $(addprefix test/run-pass/, \ lib-uint.rs \ lib-vec-str-conversions.rs \ lib-vec.rs \ - list.rs \ many.rs \ mlist-cycle.rs \ mlist.rs \ diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 7ad96ba247d..723a845d8ff 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -2266,6 +2266,15 @@ fn trans_unary(@block_ctxt cx, ast.unop op, vec(C_int(0), C_int(abi.box_rc_field_body))); sub.bcx.build.Store(C_int(1), rc); + + // Cast the body type to the type of the value. This is needed to + // make tags work, since tags have a different LLVM type depending + // on whether they're boxed or not. + if (!ty.type_has_dynamic_size(e_ty)) { + auto llety = T_ptr(type_of(sub.bcx.fcx.ccx, e_ty)); + body = sub.bcx.build.PointerCast(body, llety); + } + sub = copy_ty(sub.bcx, INIT, body, e_val, e_ty); ret res(sub.bcx, box); } -- cgit 1.4.1-3-g733a5