push changes through to get things compiling, if not running.
This commit is contained in:
parent
c28ada0368
commit
aa1cd61c84
|
@ -347,9 +347,18 @@ fn mk_test_wrapper(cx: test_ctxt,
|
|||
body: wrapper_body
|
||||
};
|
||||
|
||||
let wrapper_capture: @ast::capture = @{
|
||||
node: {
|
||||
is_send: false,
|
||||
copies: [],
|
||||
moves: []
|
||||
},
|
||||
span: span
|
||||
};
|
||||
|
||||
let wrapper_expr: ast::expr = {
|
||||
id: cx.sess.next_node_id(),
|
||||
node: ast::expr_fn(wrapper_fn),
|
||||
node: ast::expr_fn(wrapper_fn, wrapper_capture),
|
||||
span: span
|
||||
};
|
||||
|
||||
|
|
|
@ -164,6 +164,13 @@ fn parse_constr<copy T>(st: @pstate, sd: str_def, pser: arg_parser<T>) ->
|
|||
ret @respan(sp, {path: pth, args: args, id: def});
|
||||
}
|
||||
|
||||
fn parse_ty_rust_fn(st: @pstate, sd: str_def, p: ast::proto) -> ty::t {
|
||||
let func = parse_ty_fn(st, sd);
|
||||
ret ty::mk_fn(st.tcx, p,
|
||||
func.args, func.ty, func.cf,
|
||||
func.cs);
|
||||
}
|
||||
|
||||
fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
|
||||
alt next(st) as char {
|
||||
'n' { ret ty::mk_nil(st.tcx); }
|
||||
|
@ -235,21 +242,17 @@ fn parse_ty(st: @pstate, sd: str_def) -> ty::t {
|
|||
st.pos = st.pos + 1u;
|
||||
ret ty::mk_tup(st.tcx, params);
|
||||
}
|
||||
's' {
|
||||
ret parse_ty_rust_fn(st, sd, ast::proto_send);
|
||||
}
|
||||
'F' {
|
||||
let func = parse_ty_fn(st, sd);
|
||||
ret ty::mk_fn(st.tcx, ast::proto_shared(ast::sugar_normal),
|
||||
func.args, func.ty, func.cf,
|
||||
func.cs);
|
||||
ret parse_ty_rust_fn(st, sd, ast::proto_shared(ast::sugar_normal));
|
||||
}
|
||||
'f' {
|
||||
let func = parse_ty_fn(st, sd);
|
||||
ret ty::mk_fn(st.tcx, ast::proto_bare, func.args, func.ty, func.cf,
|
||||
func.cs);
|
||||
ret parse_ty_rust_fn(st, sd, ast::proto_bare);
|
||||
}
|
||||
'B' {
|
||||
let func = parse_ty_fn(st, sd);
|
||||
ret ty::mk_fn(st.tcx, ast::proto_block, func.args, func.ty, func.cf,
|
||||
func.cs);
|
||||
ret parse_ty_rust_fn(st, sd, ast::proto_block);
|
||||
}
|
||||
'N' {
|
||||
let func = parse_ty_fn(st, sd);
|
||||
|
|
|
@ -193,6 +193,7 @@ fn enc_sty(w: io::writer, cx: @ctxt, st: ty::sty) {
|
|||
}
|
||||
fn enc_proto(w: io::writer, proto: proto) {
|
||||
alt proto {
|
||||
proto_send. { w.write_char('s'); }
|
||||
proto_shared(_) { w.write_char('F'); }
|
||||
proto_block. { w.write_char('B'); }
|
||||
proto_bare. { w.write_char('f'); }
|
||||
|
|
|
@ -34,9 +34,7 @@ fn collect_freevars(def_map: resolve::def_map, walker: fn@(visit::vt<int>)) ->
|
|||
lambda (expr: @ast::expr, &&depth: int, v: visit::vt<int>) {
|
||||
alt expr.node {
|
||||
ast::expr_fn(f, captures) {
|
||||
if f.proto == ast::proto_block ||
|
||||
f.proto == ast::proto_shared(ast::sugar_normal) ||
|
||||
f.proto == ast::proto_shared(ast::sugar_sexy) {
|
||||
if f.proto != ast::proto_bare {
|
||||
visit::visit_expr(expr, depth + 1, v);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,6 +48,17 @@ fn check_crate(tcx: ty::ctxt, last_uses: last_use::last_uses,
|
|||
}
|
||||
|
||||
fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
|
||||
|
||||
fn check_free_vars(e: @expr,
|
||||
cx: ctx,
|
||||
check_fn: fn(ctx, ty::t, sp: span)) {
|
||||
for free in *freevars::get_freevars(cx.tcx, e.id) {
|
||||
let id = ast_util::def_id_of_def(free).node;
|
||||
let ty = ty::node_id_to_type(cx.tcx, id);
|
||||
check_fn(cx, ty, e.span);
|
||||
}
|
||||
}
|
||||
|
||||
alt e.node {
|
||||
expr_assign(_, ex) | expr_assign_op(_, _, ex) |
|
||||
expr_block({node: {expr: some(ex), _}, _}) |
|
||||
|
@ -65,7 +76,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
|
|||
let ty_fields = alt ty::struct(cx.tcx, t) { ty::ty_rec(f) { f } };
|
||||
for tf in ty_fields {
|
||||
if !vec::any({|f| f.node.ident == tf.ident}, fields) &&
|
||||
ty::type_kind(cx.tcx, tf.mt.ty) == kind_noncopyable {
|
||||
!kind_can_be_copied(ty::type_kind(cx.tcx, tf.mt.ty)) {
|
||||
cx.tcx.sess.span_err(ex.span,
|
||||
"copying a noncopyable value");
|
||||
}
|
||||
|
@ -107,19 +118,11 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
|
|||
none. {}
|
||||
}
|
||||
}
|
||||
expr_fn({proto: proto_send, _}, captures) {
|
||||
for free in *freevars::get_freevars(cx.tcx, e.id) {
|
||||
let id = ast_util::def_id_of_def(free).node;
|
||||
let ty = ty::node_id_to_type(cx.tcx, id);
|
||||
check_copy(cx, ty, e.span);
|
||||
}
|
||||
expr_fn({proto: proto_send., _}, captures) { // NDM captures
|
||||
check_free_vars(e, cx, check_send);
|
||||
}
|
||||
expr_fn({proto: proto_shared(_), _}, captures) {
|
||||
for free in *freevars::get_freevars(cx.tcx, e.id) {
|
||||
let id = ast_util::def_id_of_def(free).node;
|
||||
let ty = ty::node_id_to_type(cx.tcx, id);
|
||||
check_copy(cx, ty, e.span);
|
||||
}
|
||||
expr_fn({proto: proto_shared(_), _}, captures) { // NDM captures
|
||||
check_free_vars(e, cx, check_copy);
|
||||
}
|
||||
expr_ternary(_, a, b) { maybe_copy(cx, a); maybe_copy(cx, b); }
|
||||
_ { }
|
||||
|
@ -159,11 +162,17 @@ fn check_copy_ex(cx: ctx, ex: @expr, _warn: bool) {
|
|||
}
|
||||
|
||||
fn check_copy(cx: ctx, ty: ty::t, sp: span) {
|
||||
if ty::type_kind(cx.tcx, ty) == kind_noncopyable {
|
||||
if !kind_can_be_copied(ty::type_kind(cx.tcx, ty)) {
|
||||
cx.tcx.sess.span_err(sp, "copying a noncopyable value");
|
||||
}
|
||||
}
|
||||
|
||||
fn check_send(cx: ctx, ty: ty::t, sp: span) {
|
||||
if !kind_can_be_sent(ty::type_kind(cx.tcx, ty)) {
|
||||
cx.tcx.sess.span_err(sp, "not a sendable value");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Local Variables:
|
||||
// mode: rust
|
||||
|
|
|
@ -49,8 +49,9 @@ fn comma_str(args: [@constr_arg_use]) -> str {
|
|||
|
||||
fn constraint_to_str(tcx: ty::ctxt, c: sp_constr) -> str {
|
||||
alt c.node {
|
||||
ninit(_, i) {
|
||||
ret "init(" + i + " [" + tcx.sess.span_str(c.span) + "])";
|
||||
ninit(id, i) {
|
||||
ret #fmt("init(%s id=%d [%s])",
|
||||
i, id, tcx.sess.span_str(c.span));
|
||||
}
|
||||
npred(p, _, args) {
|
||||
ret path_to_str(p) + "(" + comma_str(args) + ")" + "[" +
|
||||
|
|
|
@ -278,6 +278,7 @@ fn handle_var(fcx: fn_ctxt, rslt: pre_and_post, id: node_id, name: ident) {
|
|||
}
|
||||
|
||||
fn handle_var_def(fcx: fn_ctxt, rslt: pre_and_post, def: def, name: ident) {
|
||||
log ("handle_var_def: ", def, name);
|
||||
alt def {
|
||||
def_local(d_id, _) | def_arg(d_id, _) {
|
||||
use_var(fcx, d_id.node);
|
||||
|
@ -345,6 +346,7 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
|
|||
let rslt = expr_pp(fcx.ccx, e);
|
||||
clear_pp(rslt);
|
||||
for def in *freevars::get_freevars(fcx.ccx.tcx, e.id) {
|
||||
log ("handle_var_def: def=", def);
|
||||
handle_var_def(fcx, rslt, def, "upvar");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1971,29 +1971,23 @@ mod unify {
|
|||
}
|
||||
fn unify_fn_proto(e_proto: ast::proto, a_proto: ast::proto,
|
||||
variance: variance) -> option::t<result> {
|
||||
fn rank(proto: ast::proto) -> int {
|
||||
ret alt proto {
|
||||
ast::proto_block. { 0 }
|
||||
ast::proto_shared(_) { 1 }
|
||||
ast::proto_send. { 2 }
|
||||
ast::proto_bare. { 3 }
|
||||
};
|
||||
}
|
||||
|
||||
fn gt(e_proto: ast::proto, a_proto: ast::proto) -> bool {
|
||||
alt e_proto {
|
||||
ast::proto_block. {
|
||||
// Every function type is a subtype of block
|
||||
false
|
||||
}
|
||||
ast::proto_shared(_) {
|
||||
a_proto == ast::proto_block
|
||||
}
|
||||
ast::proto_bare. {
|
||||
a_proto != ast::proto_bare
|
||||
}
|
||||
}
|
||||
ret rank(e_proto) > rank(a_proto);
|
||||
}
|
||||
|
||||
ret if e_proto == a_proto {
|
||||
none
|
||||
} else if variance == invariant {
|
||||
if e_proto != a_proto {
|
||||
some(ures_err(terr_mismatch))
|
||||
} else {
|
||||
fail
|
||||
}
|
||||
some(ures_err(terr_mismatch))
|
||||
} else if variance == covariant {
|
||||
if gt(e_proto, a_proto) {
|
||||
some(ures_err(terr_mismatch))
|
||||
|
|
|
@ -106,6 +106,25 @@ tag mutability { mut; imm; maybe_mut; }
|
|||
|
||||
tag kind { kind_sendable; kind_copyable; kind_noncopyable; }
|
||||
|
||||
// Using these query functons is preferable to direct comparison or matching
|
||||
// against the kind constants, as we may modify the kind hierarchy in the
|
||||
// future.
|
||||
pure fn kind_can_be_copied(k: kind) -> bool {
|
||||
ret alt k {
|
||||
kind_sendable. { true }
|
||||
kind_copyable. { true }
|
||||
kind_noncopyable. { false }
|
||||
};
|
||||
}
|
||||
|
||||
pure fn kind_can_be_sent(k: kind) -> bool {
|
||||
ret alt k {
|
||||
kind_sendable. { true }
|
||||
kind_copyable. { false }
|
||||
kind_noncopyable. { false }
|
||||
};
|
||||
}
|
||||
|
||||
tag proto_sugar {
|
||||
sugar_normal;
|
||||
sugar_sexy;
|
||||
|
|
|
@ -16,6 +16,7 @@ tag file_type { CRATE_FILE; SOURCE_FILE; }
|
|||
|
||||
tag fn_kw {
|
||||
fn_kw_fn;
|
||||
fn_kw_fn_at;
|
||||
fn_kw_lambda;
|
||||
fn_kw_block;
|
||||
}
|
||||
|
@ -542,10 +543,9 @@ fn parse_ty(p: parser, colons_before_params: bool) -> @ast::ty {
|
|||
} else if eat_word(p, "block") {
|
||||
t = parse_ty_fn(ast::proto_block, p);
|
||||
} else if eat_word(p, "lambda") {
|
||||
if p.peek() == token::LBRACE { // lambda[send](...)
|
||||
expect(p, token::LBRACE);
|
||||
if eat(p, token::LBRACKET) { // lambda[send](...)
|
||||
expect_word(p, "send");
|
||||
expect(p, token::RBRACE);
|
||||
expect(p, token::RBRACKET);
|
||||
t = parse_ty_fn(ast::proto_send, p);
|
||||
} else { // lambda(...)
|
||||
t = parse_ty_fn(ast::proto_shared(ast::sugar_sexy), p);
|
||||
|
@ -843,8 +843,8 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
|
|||
ret parse_spawn_expr(p);
|
||||
*/
|
||||
} else if eat_word(p, "fn") {
|
||||
let proto = parse_fn_anon_proto(p);
|
||||
ret parse_fn_expr(p, fn_kw_fn);
|
||||
let kw = parse_fn_anon_kw(p);
|
||||
ret parse_fn_expr(p, kw);
|
||||
} else if eat_word(p, "block") {
|
||||
ret parse_fn_expr(p, fn_kw_block);
|
||||
} else if eat_word(p, "lambda") {
|
||||
|
@ -1295,7 +1295,7 @@ fn parse_if_expr(p: parser) -> @ast::expr {
|
|||
fn parse_capture_clause(p: parser) -> @ast::capture {
|
||||
fn expect_opt_trailing_semi(p: parser) {
|
||||
if !eat(p, token::SEMI) {
|
||||
if p.peek() != token::RBRACE {
|
||||
if p.peek() != token::RBRACKET {
|
||||
p.fatal("expecting ; or ]");
|
||||
}
|
||||
}
|
||||
|
@ -1306,7 +1306,9 @@ fn parse_capture_clause(p: parser) -> @ast::capture {
|
|||
while true {
|
||||
alt p.peek() {
|
||||
token::IDENT(_, _) {
|
||||
let i = spanned(p.get_lo_pos(), p.get_hi_pos(), parse_ident(p));
|
||||
let i = spanned(p.get_lo_pos(),
|
||||
p.get_hi_pos(),
|
||||
parse_ident(p));
|
||||
res += [i];
|
||||
if !eat(p, token::COMMA) {
|
||||
ret res;
|
||||
|
@ -1316,6 +1318,7 @@ fn parse_capture_clause(p: parser) -> @ast::capture {
|
|||
_ { ret res; }
|
||||
}
|
||||
}
|
||||
std::util::unreachable();
|
||||
}
|
||||
|
||||
let is_send = false;
|
||||
|
@ -1323,8 +1326,8 @@ fn parse_capture_clause(p: parser) -> @ast::capture {
|
|||
let moves = [];
|
||||
|
||||
let lo = p.get_lo_pos();
|
||||
if eat(p, token::LBRACE) {
|
||||
while !eat(p, token::RBRACE) {
|
||||
if eat(p, token::LBRACKET) {
|
||||
while !eat(p, token::RBRACKET) {
|
||||
if eat_word(p, "send") {
|
||||
is_send = true;
|
||||
expect_opt_trailing_semi(p);
|
||||
|
@ -1352,10 +1355,13 @@ fn parse_fn_expr(p: parser, kw: fn_kw) -> @ast::expr {
|
|||
let body = parse_block(p);
|
||||
let proto = alt (kw, captures.node.is_send) {
|
||||
(fn_kw_fn., true) { ast::proto_bare }
|
||||
(fn_kw_fn_at., true) { ast::proto_send }
|
||||
(fn_kw_lambda., true) { ast::proto_send }
|
||||
(fn_kw_block., true) { p.fatal("block cannot be declared sendable"); }
|
||||
(fn_kw_fn., false) { ast::proto_bare }
|
||||
(fn_kw_fn_at., false) { ast::proto_shared(ast::sugar_normal) }
|
||||
(fn_kw_lambda., false) { ast::proto_shared(ast::sugar_sexy) }
|
||||
(fn_kw_block., false) { ast::proto_block }
|
||||
(_, true) { p.fatal("only lambda can be declared sendable"); }
|
||||
};
|
||||
let _fn = {decl: decl, proto: proto, body: body};
|
||||
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 {
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_fn_anon_proto(p: parser) -> ast::proto {
|
||||
fn parse_fn_anon_kw(p: parser) -> fn_kw {
|
||||
if p.peek() == token::AT {
|
||||
p.bump();
|
||||
ast::proto_shared(ast::sugar_normal)
|
||||
fn_kw_fn_at
|
||||
} else {
|
||||
ast::proto_bare
|
||||
fn_kw_fn
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1600,6 +1600,7 @@ fn proto_to_str(p: ast::proto) -> str {
|
|||
ret alt p {
|
||||
ast::proto_bare. { "fn" }
|
||||
ast::proto_block. { "block" }
|
||||
ast::proto_send. { "lambda[send]" }
|
||||
ast::proto_shared(ast::sugar_normal.) { "fn@" }
|
||||
ast::proto_shared(ast::sugar_sexy.) { "lambda" }
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue