Skip to content

Commit b037463

Browse files
committed
---
yaml --- r: 6689 b: refs/heads/master c: aa1cd61 h: refs/heads/master i: 6687: aa69266 v: v3
1 parent 7763fcf commit b037463

File tree

12 files changed

+104
-61
lines changed

12 files changed

+104
-61
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: c28ada0368de78034e0930e01406f5e03a70d610
2+
refs/heads/master: aa1cd61c84199c8a1e44645e4af3f8c15c6dd018

trunk/src/comp/front/test.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -347,9 +347,18 @@ fn mk_test_wrapper(cx: test_ctxt,
347347
body: wrapper_body
348348
};
349349

350+
let wrapper_capture: @ast::capture = @{
351+
node: {
352+
is_send: false,
353+
copies: [],
354+
moves: []
355+
},
356+
span: span
357+
};
358+
350359
let wrapper_expr: ast::expr = {
351360
id: cx.sess.next_node_id(),
352-
node: ast::expr_fn(wrapper_fn),
361+
node: ast::expr_fn(wrapper_fn, wrapper_capture),
353362
span: span
354363
};
355364

trunk/src/comp/metadata/tydecode.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,13 @@ fn parse_constr<copy T>(st: @pstate, sd: str_def, pser: arg_parser<T>) ->
164164
ret @respan(sp, {path: pth, args: args, id: def});
165165
}
166166

167+
fn parse_ty_rust_fn(st: @pstate, sd: str_def, p: ast::proto) -> ty::t {
168+
let func = parse_ty_fn(st, sd);
169+
ret ty::mk_fn(st.tcx, p,
170+
func.args, func.ty, func.cf,
171+
func.cs);
172+
}
173+
167174
fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
168175
alt next(st) as char {
169176
'n' { ret ty::mk_nil(st.tcx); }
@@ -235,21 +242,17 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
235242
st.pos = st.pos + 1u;
236243
ret ty::mk_tup(st.tcx, params);
237244
}
245+
's' {
246+
ret parse_ty_rust_fn(st, sd, ast::proto_send);
247+
}
238248
'F' {
239-
let func = parse_ty_fn(st, sd);
240-
ret ty::mk_fn(st.tcx, ast::proto_shared(ast::sugar_normal),
241-
func.args, func.ty, func.cf,
242-
func.cs);
249+
ret parse_ty_rust_fn(st, sd, ast::proto_shared(ast::sugar_normal));
243250
}
244251
'f' {
245-
let func = parse_ty_fn(st, sd);
246-
ret ty::mk_fn(st.tcx, ast::proto_bare, func.args, func.ty, func.cf,
247-
func.cs);
252+
ret parse_ty_rust_fn(st, sd, ast::proto_bare);
248253
}
249254
'B' {
250-
let func = parse_ty_fn(st, sd);
251-
ret ty::mk_fn(st.tcx, ast::proto_block, func.args, func.ty, func.cf,
252-
func.cs);
255+
ret parse_ty_rust_fn(st, sd, ast::proto_block);
253256
}
254257
'N' {
255258
let func = parse_ty_fn(st, sd);

trunk/src/comp/metadata/tyencode.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
193193
}
194194
fn enc_proto(w: io::writer, proto: proto) {
195195
alt proto {
196+
proto_send. { w.write_char('s'); }
196197
proto_shared(_) { w.write_char('F'); }
197198
proto_block. { w.write_char('B'); }
198199
proto_bare. { w.write_char('f'); }

trunk/src/comp/middle/freevars.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,7 @@ fn collect_freevars(def_map: resolve::def_map, walker: fn@(visit::vt<int>)) ->
3434
lambda (expr: @ast::expr, &&depth: int, v: visit::vt<int>) {
3535
alt expr.node {
3636
ast::expr_fn(f, captures) {
37-
if f.proto == ast::proto_block ||
38-
f.proto == ast::proto_shared(ast::sugar_normal) ||
39-
f.proto == ast::proto_shared(ast::sugar_sexy) {
37+
if f.proto != ast::proto_bare {
4038
visit::visit_expr(expr, depth + 1, v);
4139
}
4240
}

trunk/src/comp/middle/kind.rs

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ fn check_crate(tcx: ty::ctxt, last_uses: last_use::last_uses,
4848
}
4949

5050
fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
51+
52+
fn check_free_vars(e: @expr,
53+
cx: ctx,
54+
check_fn: fn(ctx, ty::t, sp: span)) {
55+
for free in *freevars::get_freevars(cx.tcx, e.id) {
56+
let id = ast_util::def_id_of_def(free).node;
57+
let ty = ty::node_id_to_type(cx.tcx, id);
58+
check_fn(cx, ty, e.span);
59+
}
60+
}
61+
5162
alt e.node {
5263
expr_assign(_, ex) | expr_assign_op(_, _, ex) |
5364
expr_block({node: {expr: some(ex), _}, _}) |
@@ -65,7 +76,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
6576
let ty_fields = alt ty::struct(cx.tcx, t) { ty::ty_rec(f) { f } };
6677
for tf in ty_fields {
6778
if !vec::any({|f| f.node.ident == tf.ident}, fields) &&
68-
ty::type_kind(cx.tcx, tf.mt.ty) == kind_noncopyable {
79+
!kind_can_be_copied(ty::type_kind(cx.tcx, tf.mt.ty)) {
6980
cx.tcx.sess.span_err(ex.span,
7081
"copying a noncopyable value");
7182
}
@@ -107,19 +118,11 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
107118
none. {}
108119
}
109120
}
110-
expr_fn({proto: proto_send, _}, captures) {
111-
for free in *freevars::get_freevars(cx.tcx, e.id) {
112-
let id = ast_util::def_id_of_def(free).node;
113-
let ty = ty::node_id_to_type(cx.tcx, id);
114-
check_copy(cx, ty, e.span);
115-
}
121+
expr_fn({proto: proto_send., _}, captures) { // NDM captures
122+
check_free_vars(e, cx, check_send);
116123
}
117-
expr_fn({proto: proto_shared(_), _}, captures) {
118-
for free in *freevars::get_freevars(cx.tcx, e.id) {
119-
let id = ast_util::def_id_of_def(free).node;
120-
let ty = ty::node_id_to_type(cx.tcx, id);
121-
check_copy(cx, ty, e.span);
122-
}
124+
expr_fn({proto: proto_shared(_), _}, captures) { // NDM captures
125+
check_free_vars(e, cx, check_copy);
123126
}
124127
expr_ternary(_, a, b) { maybe_copy(cx, a); maybe_copy(cx, b); }
125128
_ { }
@@ -159,11 +162,17 @@ fn check_copy_ex(cx: ctx, ex: @expr, _warn: bool) {
159162
}
160163

161164
fn check_copy(cx: ctx, ty: ty::t, sp: span) {
162-
if ty::type_kind(cx.tcx, ty) == kind_noncopyable {
165+
if !kind_can_be_copied(ty::type_kind(cx.tcx, ty)) {
163166
cx.tcx.sess.span_err(sp, "copying a noncopyable value");
164167
}
165168
}
166169

170+
fn check_send(cx: ctx, ty: ty::t, sp: span) {
171+
if !kind_can_be_sent(ty::type_kind(cx.tcx, ty)) {
172+
cx.tcx.sess.span_err(sp, "not a sendable value");
173+
}
174+
}
175+
167176
//
168177
// Local Variables:
169178
// mode: rust

trunk/src/comp/middle/tstate/auxiliary.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,9 @@ fn comma_str(args: [@constr_arg_use]) -> str {
4949

5050
fn constraint_to_str(tcx: ty::ctxt, c: sp_constr) -> str {
5151
alt c.node {
52-
ninit(_, i) {
53-
ret "init(" + i + " [" + tcx.sess.span_str(c.span) + "])";
52+
ninit(id, i) {
53+
ret #fmt("init(%s id=%d [%s])",
54+
i, id, tcx.sess.span_str(c.span));
5455
}
5556
npred(p, _, args) {
5657
ret path_to_str(p) + "(" + comma_str(args) + ")" + "[" +

trunk/src/comp/middle/tstate/pre_post_conditions.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,7 @@ fn handle_var(fcx: fn_ctxt, rslt: pre_and_post, id: node_id, name: ident) {
278278
}
279279

280280
fn handle_var_def(fcx: fn_ctxt, rslt: pre_and_post, def: def, name: ident) {
281+
log ("handle_var_def: ", def, name);
281282
alt def {
282283
def_local(d_id, _) | def_arg(d_id, _) {
283284
use_var(fcx, d_id.node);
@@ -345,6 +346,7 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
345346
let rslt = expr_pp(fcx.ccx, e);
346347
clear_pp(rslt);
347348
for def in *freevars::get_freevars(fcx.ccx.tcx, e.id) {
349+
log ("handle_var_def: def=", def);
348350
handle_var_def(fcx, rslt, def, "upvar");
349351
}
350352
}

trunk/src/comp/middle/ty.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1971,29 +1971,23 @@ mod unify {
19711971
}
19721972
fn unify_fn_proto(e_proto: ast::proto, a_proto: ast::proto,
19731973
variance: variance) -> option::t<result> {
1974+
fn rank(proto: ast::proto) -> int {
1975+
ret alt proto {
1976+
ast::proto_block. { 0 }
1977+
ast::proto_shared(_) { 1 }
1978+
ast::proto_send. { 2 }
1979+
ast::proto_bare. { 3 }
1980+
};
1981+
}
1982+
19741983
fn gt(e_proto: ast::proto, a_proto: ast::proto) -> bool {
1975-
alt e_proto {
1976-
ast::proto_block. {
1977-
// Every function type is a subtype of block
1978-
false
1979-
}
1980-
ast::proto_shared(_) {
1981-
a_proto == ast::proto_block
1982-
}
1983-
ast::proto_bare. {
1984-
a_proto != ast::proto_bare
1985-
}
1986-
}
1984+
ret rank(e_proto) > rank(a_proto);
19871985
}
19881986

19891987
ret if e_proto == a_proto {
19901988
none
19911989
} else if variance == invariant {
1992-
if e_proto != a_proto {
1993-
some(ures_err(terr_mismatch))
1994-
} else {
1995-
fail
1996-
}
1990+
some(ures_err(terr_mismatch))
19971991
} else if variance == covariant {
19981992
if gt(e_proto, a_proto) {
19991993
some(ures_err(terr_mismatch))

trunk/src/comp/syntax/ast.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,25 @@ tag mutability { mut; imm; maybe_mut; }
106106

107107
tag kind { kind_sendable; kind_copyable; kind_noncopyable; }
108108

109+
// Using these query functons is preferable to direct comparison or matching
110+
// against the kind constants, as we may modify the kind hierarchy in the
111+
// future.
112+
pure fn kind_can_be_copied(k: kind) -> bool {
113+
ret alt k {
114+
kind_sendable. { true }
115+
kind_copyable. { true }
116+
kind_noncopyable. { false }
117+
};
118+
}
119+
120+
pure fn kind_can_be_sent(k: kind) -> bool {
121+
ret alt k {
122+
kind_sendable. { true }
123+
kind_copyable. { false }
124+
kind_noncopyable. { false }
125+
};
126+
}
127+
109128
tag proto_sugar {
110129
sugar_normal;
111130
sugar_sexy;

trunk/src/comp/syntax/parse/parser.rs

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ tag file_type { CRATE_FILE; SOURCE_FILE; }
1616

1717
tag fn_kw {
1818
fn_kw_fn;
19+
fn_kw_fn_at;
1920
fn_kw_lambda;
2021
fn_kw_block;
2122
}
@@ -542,10 +543,9 @@ fn parse_ty(p: parser, colons_before_params: bool) -> @ast::ty {
542543
} else if eat_word(p, "block") {
543544
t = parse_ty_fn(ast::proto_block, p);
544545
} else if eat_word(p, "lambda") {
545-
if p.peek() == token::LBRACE { // lambda[send](...)
546-
expect(p, token::LBRACE);
546+
if eat(p, token::LBRACKET) { // lambda[send](...)
547547
expect_word(p, "send");
548-
expect(p, token::RBRACE);
548+
expect(p, token::RBRACKET);
549549
t = parse_ty_fn(ast::proto_send, p);
550550
} else { // lambda(...)
551551
t = parse_ty_fn(ast::proto_shared(ast::sugar_sexy), p);
@@ -843,8 +843,8 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
843843
ret parse_spawn_expr(p);
844844
*/
845845
} else if eat_word(p, "fn") {
846-
let proto = parse_fn_anon_proto(p);
847-
ret parse_fn_expr(p, fn_kw_fn);
846+
let kw = parse_fn_anon_kw(p);
847+
ret parse_fn_expr(p, kw);
848848
} else if eat_word(p, "block") {
849849
ret parse_fn_expr(p, fn_kw_block);
850850
} else if eat_word(p, "lambda") {
@@ -1295,7 +1295,7 @@ fn parse_if_expr(p: parser) -> @ast::expr {
12951295
fn parse_capture_clause(p: parser) -> @ast::capture {
12961296
fn expect_opt_trailing_semi(p: parser) {
12971297
if !eat(p, token::SEMI) {
1298-
if p.peek() != token::RBRACE {
1298+
if p.peek() != token::RBRACKET {
12991299
p.fatal("expecting ; or ]");
13001300
}
13011301
}
@@ -1306,7 +1306,9 @@ fn parse_capture_clause(p: parser) -> @ast::capture {
13061306
while true {
13071307
alt p.peek() {
13081308
token::IDENT(_, _) {
1309-
let i = spanned(p.get_lo_pos(), p.get_hi_pos(), parse_ident(p));
1309+
let i = spanned(p.get_lo_pos(),
1310+
p.get_hi_pos(),
1311+
parse_ident(p));
13101312
res += [i];
13111313
if !eat(p, token::COMMA) {
13121314
ret res;
@@ -1316,15 +1318,16 @@ fn parse_capture_clause(p: parser) -> @ast::capture {
13161318
_ { ret res; }
13171319
}
13181320
}
1321+
std::util::unreachable();
13191322
}
13201323

13211324
let is_send = false;
13221325
let copies = [];
13231326
let moves = [];
13241327

13251328
let lo = p.get_lo_pos();
1326-
if eat(p, token::LBRACE) {
1327-
while !eat(p, token::RBRACE) {
1329+
if eat(p, token::LBRACKET) {
1330+
while !eat(p, token::RBRACKET) {
13281331
if eat_word(p, "send") {
13291332
is_send = true;
13301333
expect_opt_trailing_semi(p);
@@ -1352,10 +1355,13 @@ fn parse_fn_expr(p: parser, kw: fn_kw) -> @ast::expr {
13521355
let body = parse_block(p);
13531356
let proto = alt (kw, captures.node.is_send) {
13541357
(fn_kw_fn., true) { ast::proto_bare }
1358+
(fn_kw_fn_at., true) { ast::proto_send }
13551359
(fn_kw_lambda., true) { ast::proto_send }
1360+
(fn_kw_block., true) { p.fatal("block cannot be declared sendable"); }
1361+
(fn_kw_fn., false) { ast::proto_bare }
1362+
(fn_kw_fn_at., false) { ast::proto_shared(ast::sugar_normal) }
13561363
(fn_kw_lambda., false) { ast::proto_shared(ast::sugar_sexy) }
13571364
(fn_kw_block., false) { ast::proto_block }
1358-
(_, true) { p.fatal("only lambda can be declared sendable"); }
13591365
};
13601366
let _fn = {decl: decl, proto: proto, body: body};
13611367
ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn, captures));
@@ -2151,12 +2157,12 @@ fn parse_fn_ty_proto(p: parser) -> ast::proto {
21512157
}
21522158
}
21532159

2154-
fn parse_fn_anon_proto(p: parser) -> ast::proto {
2160+
fn parse_fn_anon_kw(p: parser) -> fn_kw {
21552161
if p.peek() == token::AT {
21562162
p.bump();
2157-
ast::proto_shared(ast::sugar_normal)
2163+
fn_kw_fn_at
21582164
} else {
2159-
ast::proto_bare
2165+
fn_kw_fn
21602166
}
21612167
}
21622168

trunk/src/comp/syntax/print/pprust.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1600,6 +1600,7 @@ fn proto_to_str(p: ast::proto) -> str {
16001600
ret alt p {
16011601
ast::proto_bare. { "fn" }
16021602
ast::proto_block. { "block" }
1603+
ast::proto_send. { "lambda[send]" }
16031604
ast::proto_shared(ast::sugar_normal.) { "fn@" }
16041605
ast::proto_shared(ast::sugar_sexy.) { "lambda" }
16051606
};

0 commit comments

Comments
 (0)