distinguish "any closure" and "stack closure" (block)
This commit is contained in:
parent
47a534c197
commit
8685a1f7c4
|
@ -161,6 +161,17 @@ fn parse_ty_rust_fn(st: @pstate, conv: conv_did, p: ast::proto) -> ty::t {
|
|||
ret ty::mk_fn(st.tcx, {proto: p with parse_ty_fn(st, conv)});
|
||||
}
|
||||
|
||||
fn parse_proto(c: char) -> ast::proto {
|
||||
alt c {
|
||||
'~' { ast::proto_uniq }
|
||||
'@' { ast::proto_box }
|
||||
'*' { ast::proto_any }
|
||||
'&' { ast::proto_block }
|
||||
'n' { ast::proto_bare }
|
||||
_ { fail "illegal fn type kind " + str::from_char(c); }
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
|
||||
alt next(st) as char {
|
||||
'n' { ret ty::mk_nil(st.tcx); }
|
||||
|
@ -230,17 +241,9 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
|
|||
st.pos = st.pos + 1u;
|
||||
ret ty::mk_tup(st.tcx, params);
|
||||
}
|
||||
's' {
|
||||
ret parse_ty_rust_fn(st, conv, ast::proto_uniq);
|
||||
}
|
||||
'F' {
|
||||
ret parse_ty_rust_fn(st, conv, ast::proto_box);
|
||||
}
|
||||
'f' {
|
||||
ret parse_ty_rust_fn(st, conv, ast::proto_bare);
|
||||
}
|
||||
'B' {
|
||||
ret parse_ty_rust_fn(st, conv, ast::proto_block);
|
||||
let proto = parse_proto(next(st) as char);
|
||||
parse_ty_rust_fn(st, conv, proto)
|
||||
}
|
||||
'N' {
|
||||
let func = parse_ty_fn(st, conv);
|
||||
|
|
|
@ -192,10 +192,11 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
|
|||
}
|
||||
fn enc_proto(w: io::writer, proto: proto) {
|
||||
alt proto {
|
||||
proto_uniq. { w.write_char('s'); }
|
||||
proto_box. { w.write_char('F'); }
|
||||
proto_block. { w.write_char('B'); }
|
||||
proto_bare. { w.write_char('f'); }
|
||||
proto_uniq. { w.write_str("f~"); }
|
||||
proto_box. { w.write_str("f@"); }
|
||||
proto_block. { w.write_str("f&"); }
|
||||
proto_any. { w.write_str("f*"); }
|
||||
proto_bare. { w.write_str("fn"); }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,11 +88,14 @@ fn visit_fn(cx: @ctx, _fk: visit::fn_kind, decl: ast::fn_decl,
|
|||
// Blocks need to obey any restrictions from the enclosing scope, and may
|
||||
// be called multiple times.
|
||||
let proto = ty::ty_fn_proto(cx.tcx, fty);
|
||||
if proto == ast::proto_block {
|
||||
alt proto {
|
||||
ast::proto_block. | ast::proto_any. {
|
||||
check_loop(*cx, sc) {|| v.visit_block(body, sc, v);}
|
||||
} else {
|
||||
}
|
||||
ast::proto_box. | ast::proto_uniq. | ast::proto_bare. {
|
||||
let sc = {bs: [], invalid: @mutable list::nil};
|
||||
v.visit_block(body, sc, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
|
|||
fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
|
||||
if !cx.allow_block {
|
||||
alt ty::struct(cx.tcx, ty::expr_ty(cx.tcx, ex)) {
|
||||
ty::ty_fn({proto: proto_block., _}) {
|
||||
ty::ty_fn({proto: p, _}) if is_blockish(p) {
|
||||
cx.tcx.sess.span_err(ex.span, "expressions with block type \
|
||||
can only appear in callee or (by-ref) argument position");
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ fn check_capture_clause(tcx: ty::ctxt,
|
|||
};
|
||||
|
||||
alt fn_proto {
|
||||
ast::proto_block. {
|
||||
ast::proto_any. | ast::proto_block. {
|
||||
check_block_captures(cap_clause.copies);
|
||||
check_block_captures(cap_clause.moves);
|
||||
}
|
||||
|
@ -113,7 +113,7 @@ fn compute_capture_vars(tcx: ty::ctxt,
|
|||
}
|
||||
|
||||
let implicit_mode = alt fn_proto {
|
||||
ast::proto_block. { cap_ref }
|
||||
ast::proto_any. | ast::proto_block. { cap_ref }
|
||||
ast::proto_bare. | ast::proto_box. | ast::proto_uniq. { cap_copy }
|
||||
};
|
||||
|
||||
|
|
|
@ -63,8 +63,8 @@ fn with_appropriate_checker(cx: ctx, id: node_id,
|
|||
alt ty::ty_fn_proto(cx.tcx, fty) {
|
||||
proto_uniq. { b(check_send); }
|
||||
proto_box. { b(check_copy); }
|
||||
proto_block. { /* no check needed */ }
|
||||
proto_bare. { b(check_none); }
|
||||
proto_any. | proto_block. { /* no check needed */ }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -63,9 +63,9 @@ fn find_last_uses(c: @crate, def_map: resolve::def_map,
|
|||
ret mini_table;
|
||||
}
|
||||
|
||||
fn is_block(cx: ctx, id: node_id) -> bool {
|
||||
fn ex_is_blockish(cx: ctx, id: node_id) -> bool {
|
||||
alt ty::struct(cx.tcx, ty::node_id_to_monotype(cx.tcx, id)) {
|
||||
ty::ty_fn({proto: proto_block., _}) { true }
|
||||
ty::ty_fn({proto: p, _}) if is_blockish(p) { true }
|
||||
_ { false }
|
||||
}
|
||||
}
|
||||
|
@ -152,8 +152,12 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
|
|||
let arg_ts = ty::ty_fn_args(cx.tcx, ty::expr_ty(cx.tcx, f));
|
||||
for arg in args {
|
||||
alt arg.node {
|
||||
expr_fn(proto_block., _, _, _) { fns += [arg]; }
|
||||
expr_fn_block(_, _) if is_block(cx, arg.id) { fns += [arg]; }
|
||||
expr_fn(p, _, _, _) if is_blockish(p) {
|
||||
fns += [arg];
|
||||
}
|
||||
expr_fn_block(_, _) if ex_is_blockish(cx, arg.id) {
|
||||
fns += [arg];
|
||||
}
|
||||
_ {
|
||||
alt arg_ts[i].mode {
|
||||
by_mut_ref. { clear_if_path(cx, arg, v, false); }
|
||||
|
@ -174,11 +178,13 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
|
|||
cx: ctx, v: visit::vt<ctx>) {
|
||||
let fty = ty::node_id_to_type(cx.tcx, id);
|
||||
let proto = ty::ty_fn_proto(cx.tcx, fty);
|
||||
if proto == proto_block {
|
||||
alt proto {
|
||||
proto_any. | proto_block. {
|
||||
visit_block(func, cx, {||
|
||||
visit::visit_fn(fk, decl, body, sp, id, cx, v);
|
||||
});
|
||||
} else {
|
||||
}
|
||||
proto_box. | proto_uniq. | proto_bare. {
|
||||
alt cx.tcx.freevars.find(id) {
|
||||
some(vars) {
|
||||
for v in *vars {
|
||||
|
@ -193,6 +199,7 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
|
|||
visit::visit_fn(fk, decl, body, sp, id, cx, v);
|
||||
cx.blocks <-> old;
|
||||
leave_fn(cx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -269,7 +269,7 @@ fn is_immutable_def(cx: @ctx, def: def) -> option::t<str> {
|
|||
let ty = ty::node_id_to_monotype(cx.tcx, node_id);
|
||||
let proto = ty::ty_fn_proto(cx.tcx, ty);
|
||||
ret alt proto {
|
||||
proto_block. { is_immutable_def(cx, *inner) }
|
||||
proto_any. | proto_block. { is_immutable_def(cx, *inner) }
|
||||
_ { some("upvar") }
|
||||
};
|
||||
}
|
||||
|
|
|
@ -523,6 +523,7 @@ fn trans_expr_fn(bcx: @block_ctxt,
|
|||
};
|
||||
|
||||
let closure = alt proto {
|
||||
ast::proto_any. { fail "proto_any cannot appear in an expr"; }
|
||||
ast::proto_block. { trans_closure_env(ty::ck_block) }
|
||||
ast::proto_box. { trans_closure_env(ty::ck_box) }
|
||||
ast::proto_uniq. { trans_closure_env(ty::ck_uniq) }
|
||||
|
@ -664,6 +665,7 @@ fn make_fn_glue(
|
|||
ret alt ty::struct(tcx, t) {
|
||||
ty::ty_native_fn(_, _) | ty::ty_fn({proto: ast::proto_bare., _}) { bcx }
|
||||
ty::ty_fn({proto: ast::proto_block., _}) { bcx }
|
||||
ty::ty_fn({proto: ast::proto_any., _}) { bcx }
|
||||
ty::ty_fn({proto: ast::proto_uniq., _}) { fn_env(ty::ck_uniq) }
|
||||
ty::ty_fn({proto: ast::proto_box., _}) { fn_env(ty::ck_box) }
|
||||
_ { fail "make_fn_glue invoked on non-function type" }
|
||||
|
|
|
@ -993,6 +993,7 @@ pure fn kind_can_be_sent(k: kind) -> bool {
|
|||
|
||||
fn proto_kind(p: proto) -> kind {
|
||||
alt p {
|
||||
ast::proto_any. { kind_noncopyable }
|
||||
ast::proto_block. { kind_noncopyable }
|
||||
ast::proto_box. { kind_copyable }
|
||||
ast::proto_uniq. { kind_sendable }
|
||||
|
@ -1925,7 +1926,8 @@ mod unify {
|
|||
// subtype).
|
||||
fn sub_proto(p_sub: ast::proto, p_sup: ast::proto) -> bool {
|
||||
ret alt (p_sub, p_sup) {
|
||||
(_, ast::proto_block.) { true }
|
||||
(_, ast::proto_any.) { true }
|
||||
(_, ast::proto_block.) { true } /* NDM temporary */
|
||||
(ast::proto_bare., _) { true }
|
||||
|
||||
// Equal prototypes are always subprotos:
|
||||
|
|
|
@ -2874,7 +2874,7 @@ mod dict {
|
|||
_ {}
|
||||
}
|
||||
}
|
||||
ast::expr_fn(ast::proto_block., _, _, _) {}
|
||||
ast::expr_fn(p, _, _, _) if ast::is_blockish(p) {}
|
||||
ast::expr_fn(_, _, _, _) { ret; }
|
||||
_ {}
|
||||
}
|
||||
|
|
|
@ -117,6 +117,13 @@ tag proto {
|
|||
proto_block; // fn&
|
||||
}
|
||||
|
||||
pure fn is_blockish(p: ast::proto) -> bool {
|
||||
alt p {
|
||||
proto_any. | proto_block. { true }
|
||||
proto_bare. | proto_uniq. | proto_box. { false }
|
||||
}
|
||||
}
|
||||
|
||||
tag binop {
|
||||
add;
|
||||
sub;
|
||||
|
|
|
@ -481,11 +481,12 @@ fn parse_ty(p: parser, colons_before_params: bool) -> @ast::ty {
|
|||
} else if eat_word(p, "fn") {
|
||||
let proto = parse_fn_ty_proto(p);
|
||||
alt proto {
|
||||
ast::proto_bare. { p.fatal("fn is deprecated, use native fn"); }
|
||||
ast::proto_bare. { p.warn("fn is deprecated, use native fn"); }
|
||||
_ { /* fallthrough */ }
|
||||
}
|
||||
t = parse_ty_fn(proto, p);
|
||||
} else if eat_word(p, "block") {
|
||||
//p.warn("block is deprecated, use fn& or fn");
|
||||
t = parse_ty_fn(ast::proto_block, p);
|
||||
} else if eat_word(p, "native") {
|
||||
expect_word(p, "fn");
|
||||
|
@ -788,11 +789,13 @@ fn parse_bottom_expr(p: parser) -> pexpr {
|
|||
} else if eat_word(p, "fn") {
|
||||
let proto = parse_fn_ty_proto(p);
|
||||
alt proto {
|
||||
ast::proto_bare. { p.warn("fn expr are deprecated, use fn@"); }
|
||||
ast::proto_bare. { p.fatal("fn expr are deprecated, use fn@"); }
|
||||
ast::proto_any. { p.fatal("fn* cannot be used in an expression"); }
|
||||
_ { /* fallthrough */ }
|
||||
}
|
||||
ret pexpr(parse_fn_expr(p, proto));
|
||||
} else if eat_word(p, "block") {
|
||||
p.warn("block is deprecated, use fn& or fn");
|
||||
ret pexpr(parse_fn_expr(p, ast::proto_block));
|
||||
} else if eat_word(p, "unchecked") {
|
||||
ret pexpr(parse_block_expr(p, lo, ast::unchecked_blk));
|
||||
|
@ -2055,19 +2058,12 @@ fn parse_item_tag(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
|||
}
|
||||
|
||||
fn parse_fn_ty_proto(p: parser) -> ast::proto {
|
||||
<<<<<<< HEAD
|
||||
if p.token == token::AT {
|
||||
p.bump();
|
||||
ast::proto_box
|
||||
} else if p.token == token::TILDE {
|
||||
=======
|
||||
alt p.peek() {
|
||||
alt p.token {
|
||||
token::AT. {
|
||||
p.bump();
|
||||
ast::proto_box
|
||||
}
|
||||
token::TILDE. {
|
||||
>>>>>>> make blocks fn& and fn stand for "any closure"
|
||||
p.bump();
|
||||
ast::proto_uniq
|
||||
}
|
||||
|
@ -2075,6 +2071,10 @@ fn parse_fn_ty_proto(p: parser) -> ast::proto {
|
|||
p.bump();
|
||||
ast::proto_block
|
||||
}
|
||||
token::BINOP(token::STAR.) {
|
||||
p.bump(); // temporary: fn* for any closure
|
||||
ast::proto_any
|
||||
}
|
||||
_ {
|
||||
ast::proto_bare
|
||||
}
|
||||
|
|
|
@ -1611,11 +1611,12 @@ fn opt_proto_to_str(opt_p: option<ast::proto>) -> str {
|
|||
|
||||
fn proto_to_str(p: ast::proto) -> str {
|
||||
ret alt p {
|
||||
ast::proto_bare. { "native fn" }
|
||||
ast::proto_block. { "block" }
|
||||
ast::proto_uniq. { "fn~" }
|
||||
ast::proto_box. { "fn@" }
|
||||
};
|
||||
ast::proto_bare. { "native fn" }
|
||||
ast::proto_any. { "fn*" }
|
||||
ast::proto_block. { "fn&" }
|
||||
ast::proto_uniq. { "fn~" }
|
||||
ast::proto_box. { "fn@" }
|
||||
};
|
||||
}
|
||||
|
||||
fn ty_constr_to_str(c: @ast::ty_constr) -> str {
|
||||
|
|
|
@ -116,13 +116,19 @@ fn safe_to_steal_ty(t: @ast::ty, tm: test_mode) -> bool {
|
|||
}
|
||||
|
||||
// Not type-parameterized: https://github.com/graydon/rust/issues/898
|
||||
fn stash_expr_if(c: fn(@ast::expr, test_mode)->bool, es: @mutable [ast::expr], e: @ast::expr, tm: test_mode) {
|
||||
fn stash_expr_if(c: fn@(@ast::expr, test_mode)->bool,
|
||||
es: @mutable [ast::expr],
|
||||
e: @ast::expr,
|
||||
tm: test_mode) {
|
||||
if c(e, tm) {
|
||||
*es += [*e];
|
||||
} else {/* now my indices are wrong :( */ }
|
||||
}
|
||||
|
||||
fn stash_ty_if(c: fn(@ast::ty, test_mode)->bool, es: @mutable [ast::ty], e: @ast::ty, tm: test_mode) {
|
||||
fn stash_ty_if(c: fn@(@ast::ty, test_mode)->bool,
|
||||
es: @mutable [ast::ty],
|
||||
e: @ast::ty,
|
||||
tm: test_mode) {
|
||||
if c(e, tm) {
|
||||
*es += [*e];
|
||||
} else {/* now my indices are wrong :( */ }
|
||||
|
@ -236,8 +242,8 @@ fn check_variants_T<T: copy>(
|
|||
filename: str,
|
||||
thing_label: str,
|
||||
things: [T],
|
||||
stringifier: fn(@T) -> str,
|
||||
replacer: fn(ast::crate, uint, T, test_mode) -> ast::crate,
|
||||
stringifier: fn@(@T) -> str,
|
||||
replacer: fn@(ast::crate, uint, T, test_mode) -> ast::crate,
|
||||
cx: context
|
||||
) {
|
||||
#error("%s contains %u %s objects", filename, vec::len(things), thing_label);
|
||||
|
|
|
@ -49,7 +49,7 @@ type test_name = str;
|
|||
// to support isolation of tests into tasks.
|
||||
type test_fn<T> = T;
|
||||
|
||||
type default_test_fn = test_fn<sendfn()>;
|
||||
type default_test_fn = test_fn<fn~()>;
|
||||
|
||||
// The definition of a single test. A test runner will run a list of
|
||||
// these.
|
||||
|
@ -336,7 +336,7 @@ fn run_test<T: copy>(test: test_desc<T>,
|
|||
// We need to run our tests in another task in order to trap test failures.
|
||||
// This function only works with functions that don't contain closures.
|
||||
fn default_test_to_task(&&f: default_test_fn) -> joinable {
|
||||
ret task::spawn_joinable(sendfn[copy f]() {
|
||||
ret task::spawn_joinable(fn~[copy f]() {
|
||||
configure_test_task();
|
||||
f();
|
||||
});
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// error-pattern:Variable 'x' captured more than once
|
||||
fn main() {
|
||||
let x = 5;
|
||||
let y = sendfn[move x; copy x]() -> int { x };
|
||||
let y = fn~[move x; copy x]() -> int { x };
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// error-pattern:Variable 'x' captured more than once
|
||||
fn main() {
|
||||
let x = 5;
|
||||
let y = sendfn[copy x, x]() -> int { x };
|
||||
let y = fn~[copy x, x]() -> int { x };
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// error-pattern:Variable 'x' captured more than once
|
||||
fn main() {
|
||||
let x = 5;
|
||||
let y = sendfn[move x, x]() -> int { x };
|
||||
let y = fn~[move x, x]() -> int { x };
|
||||
}
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
// error-pattern:Upvars (like 'x') cannot be moved into a closure
|
||||
fn main() {
|
||||
let x = 5;
|
||||
let _y = sendfn[move x]() -> int {
|
||||
let _z = sendfn[move x]() -> int { x };
|
||||
let _y = fn~[move x]() -> int {
|
||||
let _z = fn~[move x]() -> int { x };
|
||||
22
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// error-pattern:unresolved name: z
|
||||
fn main() {
|
||||
let x = 5;
|
||||
let y = sendfn[copy z, x]() {
|
||||
let y = fn~[copy z, x]() {
|
||||
};
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
// error-pattern:unresolved name: z
|
||||
fn main() {
|
||||
let x = 5;
|
||||
let y = sendfn[move z, x]() {
|
||||
let y = fn~[move z, x]() {
|
||||
};
|
||||
}
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
fn main() {
|
||||
let x = 5;
|
||||
let _y = sendfn[move x]() { };
|
||||
let _y = fn~[move x]() { };
|
||||
let _z = x; //< error: Unsatisfied precondition constraint
|
||||
}
|
||||
|
|
|
@ -2,6 +2,6 @@
|
|||
|
||||
fn main() {
|
||||
// Typestate should work even in a fn@. we should reject this program.
|
||||
let f = fn () -> int { let i: int; ret i; };
|
||||
let f = fn@() -> int { let i: int; ret i; };
|
||||
log(error, f());
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
// error-pattern:Unsatisfied precondition
|
||||
|
||||
fn main() {
|
||||
let j = fn () -> int { let i: int; ret i; }();
|
||||
let j = fn@() -> int { let i: int; ret i; }();
|
||||
log(error, j);
|
||||
}
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
fn main() {
|
||||
let x = @3u;
|
||||
let _f = sendfn(y: uint) -> uint { ret *x+y; };
|
||||
let _f = fn~(y: uint) -> uint { ret *x+y; };
|
||||
}
|
|
@ -3,4 +3,4 @@
|
|||
use std;
|
||||
import task;
|
||||
|
||||
fn main() { task::spawn(sendfn() -> int { 10 }); }
|
||||
fn main() { task::spawn(fn~() -> int { 10 }); }
|
||||
|
|
|
@ -9,8 +9,8 @@ fn main() {
|
|||
|
||||
let x = ~2;
|
||||
let y = ptr::addr_of(*x) as uint;
|
||||
let snd_copy = sendfn[copy x]() -> uint { ptr::addr_of(*x) as uint };
|
||||
let snd_move = sendfn[move x]() -> uint { ptr::addr_of(*x) as uint };
|
||||
let snd_copy = fn~[copy x]() -> uint { ptr::addr_of(*x) as uint };
|
||||
let snd_move = fn~[move x]() -> uint { ptr::addr_of(*x) as uint };
|
||||
assert snd_copy() != y;
|
||||
assert snd_move() == y;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// error-pattern: warning: Captured variable 'y' not used in closure
|
||||
fn main() {
|
||||
let x = 5;
|
||||
let _y = sendfn[copy x]() { };
|
||||
let _y = fn~[copy x]() { };
|
||||
}
|
||||
|
|
|
@ -3,6 +3,6 @@ fn test(f: block(uint) -> uint) -> uint {
|
|||
}
|
||||
|
||||
fn main() {
|
||||
let y = test(sendfn(x: uint) -> uint { ret 4u * x; });
|
||||
let y = test(fn~(x: uint) -> uint { ret 4u * x; });
|
||||
assert y == 88u;
|
||||
}
|
|
@ -8,7 +8,7 @@ fn main() {
|
|||
let y = ~2;
|
||||
let y_in_parent = ptr::addr_of(*y) as uint;
|
||||
|
||||
task::spawn(sendfn[copy ch, y; move x]() {
|
||||
task::spawn(fn~[copy ch, y; move x]() {
|
||||
let x_in_child = ptr::addr_of(*x) as uint;
|
||||
comm::send(ch, x_in_child);
|
||||
|
||||
|
|
|
@ -63,8 +63,8 @@ fn filter_for_ignored_option() {
|
|||
|
||||
let opts = {filter: option::none, run_ignored: true};
|
||||
let tests =
|
||||
[{name: "1", fn: fn () { }, ignore: true, should_fail: false},
|
||||
{name: "2", fn: fn () { }, ignore: false, should_fail: false}];
|
||||
[{name: "1", fn: fn@() { }, ignore: true, should_fail: false},
|
||||
{name: "2", fn: fn@() { }, ignore: false, should_fail: false}];
|
||||
let filtered = test::filter_tests(opts, tests);
|
||||
|
||||
assert (vec::len(filtered) == 1u);
|
||||
|
@ -85,7 +85,7 @@ fn sort_tests() {
|
|||
"test::sort_tests"];
|
||||
let tests =
|
||||
{
|
||||
let testfn = fn () { };
|
||||
let testfn = fn@() { };
|
||||
let tests = [];
|
||||
for name: str in names {
|
||||
let test = {name: name, fn: testfn, ignore: false,
|
||||
|
|
Loading…
Reference in New Issue