Skip to content

Commit 8685a1f

Browse files
committed
distinguish "any closure" and "stack closure" (block)
1 parent 47a534c commit 8685a1f

32 files changed

+102
-70
lines changed

src/comp/metadata/tydecode.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,17 @@ fn parse_ty_rust_fn(st: @pstate, conv: conv_did, p: ast::proto) -> ty::t {
161161
ret ty::mk_fn(st.tcx, {proto: p with parse_ty_fn(st, conv)});
162162
}
163163

164+
fn parse_proto(c: char) -> ast::proto {
165+
alt c {
166+
'~' { ast::proto_uniq }
167+
'@' { ast::proto_box }
168+
'*' { ast::proto_any }
169+
'&' { ast::proto_block }
170+
'n' { ast::proto_bare }
171+
_ { fail "illegal fn type kind " + str::from_char(c); }
172+
}
173+
}
174+
164175
fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
165176
alt next(st) as char {
166177
'n' { ret ty::mk_nil(st.tcx); }
@@ -230,17 +241,9 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t {
230241
st.pos = st.pos + 1u;
231242
ret ty::mk_tup(st.tcx, params);
232243
}
233-
's' {
234-
ret parse_ty_rust_fn(st, conv, ast::proto_uniq);
235-
}
236-
'F' {
237-
ret parse_ty_rust_fn(st, conv, ast::proto_box);
238-
}
239244
'f' {
240-
ret parse_ty_rust_fn(st, conv, ast::proto_bare);
241-
}
242-
'B' {
243-
ret parse_ty_rust_fn(st, conv, ast::proto_block);
245+
let proto = parse_proto(next(st) as char);
246+
parse_ty_rust_fn(st, conv, proto)
244247
}
245248
'N' {
246249
let func = parse_ty_fn(st, conv);

src/comp/metadata/tyencode.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,11 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
192192
}
193193
fn enc_proto(w: io::writer, proto: proto) {
194194
alt proto {
195-
proto_uniq. { w.write_char('s'); }
196-
proto_box. { w.write_char('F'); }
197-
proto_block. { w.write_char('B'); }
198-
proto_bare. { w.write_char('f'); }
195+
proto_uniq. { w.write_str("f~"); }
196+
proto_box. { w.write_str("f@"); }
197+
proto_block. { w.write_str("f&"); }
198+
proto_any. { w.write_str("f*"); }
199+
proto_bare. { w.write_str("fn"); }
199200
}
200201
}
201202

src/comp/middle/alias.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,11 +88,14 @@ fn visit_fn(cx: @ctx, _fk: visit::fn_kind, decl: ast::fn_decl,
8888
// Blocks need to obey any restrictions from the enclosing scope, and may
8989
// be called multiple times.
9090
let proto = ty::ty_fn_proto(cx.tcx, fty);
91-
if proto == ast::proto_block {
91+
alt proto {
92+
ast::proto_block. | ast::proto_any. {
9293
check_loop(*cx, sc) {|| v.visit_block(body, sc, v);}
93-
} else {
94+
}
95+
ast::proto_box. | ast::proto_uniq. | ast::proto_bare. {
9496
let sc = {bs: [], invalid: @mutable list::nil};
9597
v.visit_block(body, sc, v);
98+
}
9699
}
97100
}
98101

src/comp/middle/block_use.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
1414
fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
1515
if !cx.allow_block {
1616
alt ty::struct(cx.tcx, ty::expr_ty(cx.tcx, ex)) {
17-
ty::ty_fn({proto: proto_block., _}) {
17+
ty::ty_fn({proto: p, _}) if is_blockish(p) {
1818
cx.tcx.sess.span_err(ex.span, "expressions with block type \
1919
can only appear in callee or (by-ref) argument position");
2020
}

src/comp/middle/capture.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ fn check_capture_clause(tcx: ty::ctxt,
7575
};
7676

7777
alt fn_proto {
78-
ast::proto_block. {
78+
ast::proto_any. | ast::proto_block. {
7979
check_block_captures(cap_clause.copies);
8080
check_block_captures(cap_clause.moves);
8181
}
@@ -113,7 +113,7 @@ fn compute_capture_vars(tcx: ty::ctxt,
113113
}
114114

115115
let implicit_mode = alt fn_proto {
116-
ast::proto_block. { cap_ref }
116+
ast::proto_any. | ast::proto_block. { cap_ref }
117117
ast::proto_bare. | ast::proto_box. | ast::proto_uniq. { cap_copy }
118118
};
119119

src/comp/middle/kind.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ fn with_appropriate_checker(cx: ctx, id: node_id,
6363
alt ty::ty_fn_proto(cx.tcx, fty) {
6464
proto_uniq. { b(check_send); }
6565
proto_box. { b(check_copy); }
66-
proto_block. { /* no check needed */ }
6766
proto_bare. { b(check_none); }
67+
proto_any. | proto_block. { /* no check needed */ }
6868
}
6969
}
7070

src/comp/middle/last_use.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ fn find_last_uses(c: @crate, def_map: resolve::def_map,
6363
ret mini_table;
6464
}
6565

66-
fn is_block(cx: ctx, id: node_id) -> bool {
66+
fn ex_is_blockish(cx: ctx, id: node_id) -> bool {
6767
alt ty::struct(cx.tcx, ty::node_id_to_monotype(cx.tcx, id)) {
68-
ty::ty_fn({proto: proto_block., _}) { true }
68+
ty::ty_fn({proto: p, _}) if is_blockish(p) { true }
6969
_ { false }
7070
}
7171
}
@@ -152,8 +152,12 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
152152
let arg_ts = ty::ty_fn_args(cx.tcx, ty::expr_ty(cx.tcx, f));
153153
for arg in args {
154154
alt arg.node {
155-
expr_fn(proto_block., _, _, _) { fns += [arg]; }
156-
expr_fn_block(_, _) if is_block(cx, arg.id) { fns += [arg]; }
155+
expr_fn(p, _, _, _) if is_blockish(p) {
156+
fns += [arg];
157+
}
158+
expr_fn_block(_, _) if ex_is_blockish(cx, arg.id) {
159+
fns += [arg];
160+
}
157161
_ {
158162
alt arg_ts[i].mode {
159163
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,
174178
cx: ctx, v: visit::vt<ctx>) {
175179
let fty = ty::node_id_to_type(cx.tcx, id);
176180
let proto = ty::ty_fn_proto(cx.tcx, fty);
177-
if proto == proto_block {
181+
alt proto {
182+
proto_any. | proto_block. {
178183
visit_block(func, cx, {||
179184
visit::visit_fn(fk, decl, body, sp, id, cx, v);
180185
});
181-
} else {
186+
}
187+
proto_box. | proto_uniq. | proto_bare. {
182188
alt cx.tcx.freevars.find(id) {
183189
some(vars) {
184190
for v in *vars {
@@ -193,6 +199,7 @@ fn visit_fn(fk: visit::fn_kind, decl: fn_decl, body: blk,
193199
visit::visit_fn(fk, decl, body, sp, id, cx, v);
194200
cx.blocks <-> old;
195201
leave_fn(cx);
202+
}
196203
}
197204
}
198205

src/comp/middle/mut.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ fn is_immutable_def(cx: @ctx, def: def) -> option::t<str> {
269269
let ty = ty::node_id_to_monotype(cx.tcx, node_id);
270270
let proto = ty::ty_fn_proto(cx.tcx, ty);
271271
ret alt proto {
272-
proto_block. { is_immutable_def(cx, *inner) }
272+
proto_any. | proto_block. { is_immutable_def(cx, *inner) }
273273
_ { some("upvar") }
274274
};
275275
}

src/comp/middle/trans_closure.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ fn trans_expr_fn(bcx: @block_ctxt,
523523
};
524524

525525
let closure = alt proto {
526+
ast::proto_any. { fail "proto_any cannot appear in an expr"; }
526527
ast::proto_block. { trans_closure_env(ty::ck_block) }
527528
ast::proto_box. { trans_closure_env(ty::ck_box) }
528529
ast::proto_uniq. { trans_closure_env(ty::ck_uniq) }
@@ -664,6 +665,7 @@ fn make_fn_glue(
664665
ret alt ty::struct(tcx, t) {
665666
ty::ty_native_fn(_, _) | ty::ty_fn({proto: ast::proto_bare., _}) { bcx }
666667
ty::ty_fn({proto: ast::proto_block., _}) { bcx }
668+
ty::ty_fn({proto: ast::proto_any., _}) { bcx }
667669
ty::ty_fn({proto: ast::proto_uniq., _}) { fn_env(ty::ck_uniq) }
668670
ty::ty_fn({proto: ast::proto_box., _}) { fn_env(ty::ck_box) }
669671
_ { fail "make_fn_glue invoked on non-function type" }

src/comp/middle/ty.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -993,6 +993,7 @@ pure fn kind_can_be_sent(k: kind) -> bool {
993993

994994
fn proto_kind(p: proto) -> kind {
995995
alt p {
996+
ast::proto_any. { kind_noncopyable }
996997
ast::proto_block. { kind_noncopyable }
997998
ast::proto_box. { kind_copyable }
998999
ast::proto_uniq. { kind_sendable }
@@ -1925,7 +1926,8 @@ mod unify {
19251926
// subtype).
19261927
fn sub_proto(p_sub: ast::proto, p_sup: ast::proto) -> bool {
19271928
ret alt (p_sub, p_sup) {
1928-
(_, ast::proto_block.) { true }
1929+
(_, ast::proto_any.) { true }
1930+
(_, ast::proto_block.) { true } /* NDM temporary */
19291931
(ast::proto_bare., _) { true }
19301932

19311933
// Equal prototypes are always subprotos:

src/comp/middle/typeck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2874,7 +2874,7 @@ mod dict {
28742874
_ {}
28752875
}
28762876
}
2877-
ast::expr_fn(ast::proto_block., _, _, _) {}
2877+
ast::expr_fn(p, _, _, _) if ast::is_blockish(p) {}
28782878
ast::expr_fn(_, _, _, _) { ret; }
28792879
_ {}
28802880
}

src/comp/syntax/ast.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,13 @@ tag proto {
117117
proto_block; // fn&
118118
}
119119

120+
pure fn is_blockish(p: ast::proto) -> bool {
121+
alt p {
122+
proto_any. | proto_block. { true }
123+
proto_bare. | proto_uniq. | proto_box. { false }
124+
}
125+
}
126+
120127
tag binop {
121128
add;
122129
sub;

src/comp/syntax/parse/parser.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -481,11 +481,12 @@ fn parse_ty(p: parser, colons_before_params: bool) -> @ast::ty {
481481
} else if eat_word(p, "fn") {
482482
let proto = parse_fn_ty_proto(p);
483483
alt proto {
484-
ast::proto_bare. { p.fatal("fn is deprecated, use native fn"); }
484+
ast::proto_bare. { p.warn("fn is deprecated, use native fn"); }
485485
_ { /* fallthrough */ }
486486
}
487487
t = parse_ty_fn(proto, p);
488488
} else if eat_word(p, "block") {
489+
//p.warn("block is deprecated, use fn& or fn");
489490
t = parse_ty_fn(ast::proto_block, p);
490491
} else if eat_word(p, "native") {
491492
expect_word(p, "fn");
@@ -788,11 +789,13 @@ fn parse_bottom_expr(p: parser) -> pexpr {
788789
} else if eat_word(p, "fn") {
789790
let proto = parse_fn_ty_proto(p);
790791
alt proto {
791-
ast::proto_bare. { p.warn("fn expr are deprecated, use fn@"); }
792+
ast::proto_bare. { p.fatal("fn expr are deprecated, use fn@"); }
793+
ast::proto_any. { p.fatal("fn* cannot be used in an expression"); }
792794
_ { /* fallthrough */ }
793795
}
794796
ret pexpr(parse_fn_expr(p, proto));
795797
} else if eat_word(p, "block") {
798+
p.warn("block is deprecated, use fn& or fn");
796799
ret pexpr(parse_fn_expr(p, ast::proto_block));
797800
} else if eat_word(p, "unchecked") {
798801
ret pexpr(parse_block_expr(p, lo, ast::unchecked_blk));
@@ -2055,26 +2058,23 @@ fn parse_item_tag(p: parser, attrs: [ast::attribute]) -> @ast::item {
20552058
}
20562059

20572060
fn parse_fn_ty_proto(p: parser) -> ast::proto {
2058-
<<<<<<< HEAD
2059-
if p.token == token::AT {
2060-
p.bump();
2061-
ast::proto_box
2062-
} else if p.token == token::TILDE {
2063-
=======
2064-
alt p.peek() {
2061+
alt p.token {
20652062
token::AT. {
20662063
p.bump();
20672064
ast::proto_box
20682065
}
20692066
token::TILDE. {
2070-
>>>>>>> make blocks fn& and fn stand for "any closure"
20712067
p.bump();
20722068
ast::proto_uniq
20732069
}
20742070
token::BINOP(token::AND.) {
20752071
p.bump();
20762072
ast::proto_block
20772073
}
2074+
token::BINOP(token::STAR.) {
2075+
p.bump(); // temporary: fn* for any closure
2076+
ast::proto_any
2077+
}
20782078
_ {
20792079
ast::proto_bare
20802080
}

src/comp/syntax/print/pprust.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1611,11 +1611,12 @@ fn opt_proto_to_str(opt_p: option<ast::proto>) -> str {
16111611

16121612
fn proto_to_str(p: ast::proto) -> str {
16131613
ret alt p {
1614-
ast::proto_bare. { "native fn" }
1615-
ast::proto_block. { "block" }
1616-
ast::proto_uniq. { "fn~" }
1617-
ast::proto_box. { "fn@" }
1618-
};
1614+
ast::proto_bare. { "native fn" }
1615+
ast::proto_any. { "fn*" }
1616+
ast::proto_block. { "fn&" }
1617+
ast::proto_uniq. { "fn~" }
1618+
ast::proto_box. { "fn@" }
1619+
};
16191620
}
16201621

16211622
fn ty_constr_to_str(c: @ast::ty_constr) -> str {

src/fuzzer/fuzzer.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,13 +116,19 @@ fn safe_to_steal_ty(t: @ast::ty, tm: test_mode) -> bool {
116116
}
117117

118118
// Not type-parameterized: https://github.com/graydon/rust/issues/898
119-
fn stash_expr_if(c: fn(@ast::expr, test_mode)->bool, es: @mutable [ast::expr], e: @ast::expr, tm: test_mode) {
119+
fn stash_expr_if(c: fn@(@ast::expr, test_mode)->bool,
120+
es: @mutable [ast::expr],
121+
e: @ast::expr,
122+
tm: test_mode) {
120123
if c(e, tm) {
121124
*es += [*e];
122125
} else {/* now my indices are wrong :( */ }
123126
}
124127

125-
fn stash_ty_if(c: fn(@ast::ty, test_mode)->bool, es: @mutable [ast::ty], e: @ast::ty, tm: test_mode) {
128+
fn stash_ty_if(c: fn@(@ast::ty, test_mode)->bool,
129+
es: @mutable [ast::ty],
130+
e: @ast::ty,
131+
tm: test_mode) {
126132
if c(e, tm) {
127133
*es += [*e];
128134
} else {/* now my indices are wrong :( */ }
@@ -236,8 +242,8 @@ fn check_variants_T<T: copy>(
236242
filename: str,
237243
thing_label: str,
238244
things: [T],
239-
stringifier: fn(@T) -> str,
240-
replacer: fn(ast::crate, uint, T, test_mode) -> ast::crate,
245+
stringifier: fn@(@T) -> str,
246+
replacer: fn@(ast::crate, uint, T, test_mode) -> ast::crate,
241247
cx: context
242248
) {
243249
#error("%s contains %u %s objects", filename, vec::len(things), thing_label);

src/libstd/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ type test_name = str;
4949
// to support isolation of tests into tasks.
5050
type test_fn<T> = T;
5151

52-
type default_test_fn = test_fn<sendfn()>;
52+
type default_test_fn = test_fn<fn~()>;
5353

5454
// The definition of a single test. A test runner will run a list of
5555
// these.
@@ -336,7 +336,7 @@ fn run_test<T: copy>(test: test_desc<T>,
336336
// We need to run our tests in another task in order to trap test failures.
337337
// This function only works with functions that don't contain closures.
338338
fn default_test_to_task(&&f: default_test_fn) -> joinable {
339-
ret task::spawn_joinable(sendfn[copy f]() {
339+
ret task::spawn_joinable(fn~[copy f]() {
340340
configure_test_task();
341341
f();
342342
});
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// error-pattern:Variable 'x' captured more than once
22
fn main() {
33
let x = 5;
4-
let y = sendfn[move x; copy x]() -> int { x };
4+
let y = fn~[move x; copy x]() -> int { x };
55
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// error-pattern:Variable 'x' captured more than once
22
fn main() {
33
let x = 5;
4-
let y = sendfn[copy x, x]() -> int { x };
4+
let y = fn~[copy x, x]() -> int { x };
55
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// error-pattern:Variable 'x' captured more than once
22
fn main() {
33
let x = 5;
4-
let y = sendfn[move x, x]() -> int { x };
4+
let y = fn~[move x, x]() -> int { x };
55
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// error-pattern:Upvars (like 'x') cannot be moved into a closure
22
fn main() {
33
let x = 5;
4-
let _y = sendfn[move x]() -> int {
5-
let _z = sendfn[move x]() -> int { x };
4+
let _y = fn~[move x]() -> int {
5+
let _z = fn~[move x]() -> int { x };
66
22
77
};
88
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// error-pattern:unresolved name: z
22
fn main() {
33
let x = 5;
4-
let y = sendfn[copy z, x]() {
4+
let y = fn~[copy z, x]() {
55
};
66
}

0 commit comments

Comments
 (0)