]> git.lizzy.rs Git - rust.git/commitdiff
push changes through to get things compiling, if not running.
authorNiko Matsakis <niko@alum.mit.edu>
Sat, 10 Dec 2011 00:56:48 +0000 (16:56 -0800)
committerNiko Matsakis <niko@alum.mit.edu>
Wed, 14 Dec 2011 22:32:18 +0000 (14:32 -0800)
src/comp/front/test.rs
src/comp/metadata/tydecode.rs
src/comp/metadata/tyencode.rs
src/comp/middle/freevars.rs
src/comp/middle/kind.rs
src/comp/middle/tstate/auxiliary.rs
src/comp/middle/tstate/pre_post_conditions.rs
src/comp/middle/ty.rs
src/comp/syntax/ast.rs
src/comp/syntax/parse/parser.rs
src/comp/syntax/print/pprust.rs

index 4756ee0b83ef4ba58feec121dc5146f4debdf6be..c2ca656192e8e611b4e83d6049fa171c471fccea 100644 (file)
@@ -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
     };
 
index 0bf44376b63239134f7d6c82567ad3fc66a29c16..434564f9c0d1d667ebe19830a2ad2dc969480cd3 100644 (file)
@@ -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);
index 9fb37e4f4bfe8b798840340cb8c1c116642dafb6..18ab46d7ef310d3f2dc66aef4450383c40cfc0fd 100644 (file)
@@ -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'); }
index bf1530e523fdef6306971ce836b18698504c26ac..8055f49f5d873c0d4c1b95a95d05bcf37d7decd2 100644 (file)
@@ -34,9 +34,7 @@ fn ignore_item(_i: @ast::item, &&_depth: int, _v: 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);
                 }
               }
index 974c6ca5f7f35f8a0fc47844ea0f4dc0b70aa2c3..8e577484303b6c13a3e8eb7bd7f80d3e621e458a 100644 (file)
@@ -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
index ec1c268e77541b91826f6c0aebbc9ff9e893abd6..c9f27e3681043f51aa3eaf159a521b86f3576ff7 100644 (file)
@@ -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) + ")" + "[" +
index 929dbce308a10efa4f33dcb9bf83e346b7065f25..ce759abf74d7c15cc07eecf38278741f9e0f4e01 100644 (file)
@@ -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");
         }
       }
index d369e818d479f714f0d9bf5df898a04438fc7192..d35d2038190fdac968243ea3e32df361c576b8dc 100644 (file)
@@ -1971,29 +1971,23 @@ fn unify_fn_common(cx: @ctxt, _expected: t, _actual: t,
     }
     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))
index 62b24e220d869cc340abd77d9232e1d4135f4491..0034eede2f2acc6bf57d78b00fc6c7a4044770a1 100644 (file)
 
 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;
index 063042e3bad8169a9d4644e4c08a1392674e01b6..c8b94616ab9e3b669cea3aca4b1be3637926f2d0 100644 (file)
@@ -16,6 +16,7 @@
 
 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 eat_ident_list(p: parser) -> [ast::spanned<ast::ident>] {
         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 eat_ident_list(p: parser) -> [ast::spanned<ast::ident>] {
               _ { ret res; }
             }
         }
+        std::util::unreachable();
     }
 
     let is_send = false;
@@ -1323,8 +1326,8 @@ fn eat_ident_list(p: parser) -> [ast::spanned<ast::ident>] {
     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
     }
 }
 
index 16b9f89bf637da5e1ec42f4ed80895839b8117f6..5899cf95d7ea7e52fcaf6bf573e56a002fda8abf 100644 (file)
@@ -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" }
         };