diff --git a/src/comp/front/test.rs b/src/comp/front/test.rs index 3e87cc1f78b9..a01f17c14dfc 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 bdb723ebaf85..60ea72ea9a2a 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) { + 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) { - 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 0b3a03c6b1ac..608796696d6f 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], - moves: [spanned] +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; /* // 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 f1db62e24e20..1b3bb87cddcd 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] { + 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 000000000000..b4aa10b22b87 --- /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 000000000000..95d06f4588e2 --- /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