about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2011-12-17 21:12:30 -0800
committerNiko Matsakis <niko@alum.mit.edu>2011-12-19 14:07:46 -0800
commitb2b2a430df33a234be62d97d7efc1f0a3d419b50 (patch)
tree392e4e0d7eb11ed978920a38e89de84b86b80a10
parentb0f1a5f051f1e2a5eb164e0d2abb35edea4a4c75 (diff)
downloadrust-b2b2a430df33a234be62d97d7efc1f0a3d419b50.tar.gz
rust-b2b2a430df33a234be62d97d7efc1f0a3d419b50.zip
resolve capture clauses
-rw-r--r--src/comp/front/test.rs9
-rw-r--r--src/comp/middle/resolve.rs19
-rw-r--r--src/comp/syntax/ast.rs16
-rw-r--r--src/comp/syntax/parse/parser.rs23
-rw-r--r--src/test/compile-fail/cap-clause-unresolved-copy.rs6
-rw-r--r--src/test/compile-fail/cap-clause-unresolved-move.rs6
6 files changed, 49 insertions, 30 deletions
diff --git a/src/comp/front/test.rs b/src/comp/front/test.rs
index 3e87cc1f78b..a01f17c14df 100644
--- a/src/comp/front/test.rs
+++ b/src/comp/front/test.rs
@@ -347,12 +347,9 @@ fn mk_test_wrapper(cx: test_ctxt,
         body: wrapper_body
     };
 
-    let wrapper_capture: @ast::capture = @{
-        node: {
-            copies: [],
-            moves: []
-        },
-        span: span
+    let wrapper_capture: @ast::capture_clause = @{
+        copies: [],
+        moves: []
     };
 
     let wrapper_expr: ast::expr = {
diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs
index bdb723ebaf8..60ea72ea9a2 100644
--- a/src/comp/middle/resolve.rs
+++ b/src/comp/middle/resolve.rs
@@ -299,6 +299,16 @@ fn check_unused_imports(e: @env) {
     };
 }
 
+fn resolve_capture_item(e: @env, sc: scopes, &&cap_item: @ast::capture_item) {
+    let dcur = lookup_in_scope_strict(
+        *e, sc, cap_item.span, cap_item.name, ns_value);
+    maybe_insert(e, cap_item.id, dcur);
+}
+
+fn maybe_insert(e: @env, id: node_id, def: option::t<def>) {
+    if option::is_some(def) { e.def_map.insert(id, option::get(def)); }
+}
+
 fn resolve_names(e: @env, c: @ast::crate) {
     e.used_imports.track = true;
     let v =
@@ -325,6 +335,11 @@ fn resolve_names(e: @env, c: @ast::crate) {
                          lookup_path_strict(*e, sc, exp.span, p.node,
                                             ns_value));
           }
+          ast::expr_fn(_, cap_clause) {
+            let rci = bind resolve_capture_item(e, sc, _);
+            vec::iter(cap_clause.copies, rci);
+            vec::iter(cap_clause.moves, rci);
+          }
           _ { }
         }
     }
@@ -361,10 +376,6 @@ fn resolve_names(e: @env, c: @ast::crate) {
           _ { }
         }
     }
-
-    fn maybe_insert(e: @env, id: node_id, def: option::t<def>) {
-        if option::is_some(def) { e.def_map.insert(id, option::get(def)); }
-    }
 }
 
 
diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs
index 0b3a03c6b1a..608796696d6 100644
--- a/src/comp/syntax/ast.rs
+++ b/src/comp/syntax/ast.rs
@@ -226,7 +226,7 @@ tag expr_ {
     expr_for(@local, @expr, blk);
     expr_do_while(blk, @expr);
     expr_alt(@expr, [arm]);
-    expr_fn(_fn, @capture);
+    expr_fn(_fn, @capture_clause);
     expr_block(blk);
 
     /*
@@ -261,13 +261,15 @@ tag expr_ {
     expr_mac(mac);
 }
 
-// At the moment, one can only capture local variables.
-type capture_ = {
-    copies: [spanned<ident>],
-    moves: [spanned<ident>]
+type capture_item = {
+    id: int,
+    name: ident, // Currently, can only capture a local var.
+    span: span
+};
+type capture_clause = {
+    copies: [@capture_item],
+    moves: [@capture_item]
 };
-
-type capture = spanned<capture_>;
 
 /*
 // Says whether this is a block the user marked as
diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs
index f1db62e24e2..1b3bb87cddc 100644
--- a/src/comp/syntax/parse/parser.rs
+++ b/src/comp/syntax/parse/parser.rs
@@ -1244,7 +1244,7 @@ fn parse_if_expr(p: parser) -> @ast::expr {
 //   CC := [copy ID*; move ID*]
 //
 // where any part is optional and trailing ; is permitted.
-fn parse_capture_clause(p: parser) -> @ast::capture {
+fn parse_capture_clause(p: parser) -> @ast::capture_clause {
     fn expect_opt_trailing_semi(p: parser) {
         if !eat(p, token::SEMI) {
             if p.peek() != token::RBRACKET {
@@ -1253,15 +1253,15 @@ fn parse_capture_clause(p: parser) -> @ast::capture {
         }
     }
 
-    fn eat_ident_list(p: parser) -> [ast::spanned<ast::ident>] {
+    fn eat_ident_list(p: parser) -> [@ast::capture_item] {
         let res = [];
         while true {
             alt p.peek() {
               token::IDENT(_, _) {
-                let i = spanned(p.get_lo_pos(),
-                                p.get_hi_pos(),
-                                parse_ident(p));
-                res += [i];
+                let id = p.get_id();
+                let sp = ast_util::mk_sp(p.get_lo_pos(), p.get_hi_pos());
+                let ident = parse_ident(p);
+                res += [@{id:id, name:ident, span:sp}];
                 if !eat(p, token::COMMA) {
                     ret res;
                 }
@@ -1276,7 +1276,6 @@ fn parse_capture_clause(p: parser) -> @ast::capture {
     let copies = [];
     let moves = [];
 
-    let lo = p.get_lo_pos();
     if eat(p, token::LBRACKET) {
         while !eat(p, token::RBRACKET) {
             if eat_word(p, "copy") {
@@ -1291,27 +1290,25 @@ fn parse_capture_clause(p: parser) -> @ast::capture {
             }
         }
     }
-    let hi = p.get_last_hi_pos();
 
-    ret @spanned(lo, hi, {copies: copies, moves: moves});
+    ret @{copies: copies, moves: moves};
 }
 
 fn parse_fn_expr(p: parser, proto: ast::proto) -> @ast::expr {
     let lo = p.get_last_lo_pos();
-    let captures = parse_capture_clause(p);
+    let capture_clause = parse_capture_clause(p);
     let decl = parse_fn_decl(p, ast::impure_fn, ast::il_normal);
     let body = parse_block(p);
     let _fn = {decl: decl, proto: proto, body: body};
-    ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn, captures));
+    ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn, capture_clause));
 }
 
 fn parse_fn_block_expr(p: parser) -> @ast::expr {
     let lo = p.get_last_lo_pos();
     let decl = parse_fn_block_decl(p);
-    let mid = p.get_last_hi_pos();
     let body = parse_block_tail(p, lo, ast::default_blk);
     let _fn = {decl: decl, proto: ast::proto_block, body: body};
-    let captures = @spanned(lo, mid, {copies: [], moves: []});
+    let captures = @{copies: [], moves: []};
     ret mk_expr(p, lo, body.span.hi, ast::expr_fn(_fn, captures));
 }
 
diff --git a/src/test/compile-fail/cap-clause-unresolved-copy.rs b/src/test/compile-fail/cap-clause-unresolved-copy.rs
new file mode 100644
index 00000000000..b4aa10b22b8
--- /dev/null
+++ b/src/test/compile-fail/cap-clause-unresolved-copy.rs
@@ -0,0 +1,6 @@
+// error-pattern:unresolved name: z
+fn main() {
+    let x = 5;
+    let y = sendfn[copy z, x]() {
+    };
+}
\ No newline at end of file
diff --git a/src/test/compile-fail/cap-clause-unresolved-move.rs b/src/test/compile-fail/cap-clause-unresolved-move.rs
new file mode 100644
index 00000000000..95d06f4588e
--- /dev/null
+++ b/src/test/compile-fail/cap-clause-unresolved-move.rs
@@ -0,0 +1,6 @@
+// error-pattern:unresolved name: z
+fn main() {
+    let x = 5;
+    let y = sendfn[move z, x]() {
+    };
+}
\ No newline at end of file