about summary refs log tree commit diff
path: root/src/libsyntax/parse
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-08-14 03:46:22 +0000
committerbors <bors@rust-lang.org>2014-08-14 03:46:22 +0000
commit9d45d63d0d18f21f74c8a2a4e5367a785932f64e (patch)
treeb87ab6a2dd1256c5068314d0773dcf485c58a624 /src/libsyntax/parse
parentaa98b25c4f0c10729dff37c699904ad57b8fbda8 (diff)
parenta63003fe1aac487d3c0c527c4c984375c998de99 (diff)
downloadrust-9d45d63d0d18f21f74c8a2a4e5367a785932f64e.tar.gz
rust-9d45d63d0d18f21f74c8a2a4e5367a785932f64e.zip
auto merge of #15929 : pcwalton/rust/by-ref-closures, r=alexcrichton
by-reference upvars.

This partially implements RFC 38. A snapshot will be needed to turn this
on, because stage0 cannot yet parse the keyword.

Part of #12831.

r? @alexcrichton
Diffstat (limited to 'src/libsyntax/parse')
-rw-r--r--src/libsyntax/parse/parser.rs17
1 files changed, 13 insertions, 4 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 08d96f5b008..f0920603ad1 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -17,6 +17,7 @@ use ast::{Provided, Public, FnStyle};
 use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
 use ast::{BiBitAnd, BiBitOr, BiBitXor, Block};
 use ast::{BlockCheckMode, UnBox};
+use ast::{CaptureByRef, CaptureByValue, CaptureClause};
 use ast::{Crate, CrateConfig, Decl, DeclItem};
 use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf};
 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
@@ -1985,7 +1986,7 @@ impl<'a> Parser<'a> {
                                     ExprBlock(blk));
             },
             token::BINOP(token::OR) |  token::OROR => {
-                return self.parse_lambda_expr();
+                return self.parse_lambda_expr(CaptureByValue);
             },
             // FIXME #13626: Should be able to stick in
             // token::SELF_KEYWORD_NAME
@@ -2036,6 +2037,9 @@ impl<'a> Parser<'a> {
                 hi = self.last_span.hi;
             },
             _ => {
+                if self.eat_keyword(keywords::Ref) {
+                    return self.parse_lambda_expr(CaptureByRef);
+                }
                 if self.eat_keyword(keywords::Proc) {
                     let decl = self.parse_proc_decl();
                     let body = self.parse_expr();
@@ -2696,7 +2700,8 @@ impl<'a> Parser<'a> {
     }
 
     // `|args| expr`
-    pub fn parse_lambda_expr(&mut self) -> Gc<Expr> {
+    pub fn parse_lambda_expr(&mut self, capture_clause: CaptureClause)
+                             -> Gc<Expr> {
         let lo = self.span.lo;
         let (decl, is_unboxed) = self.parse_fn_block_decl();
         let body = self.parse_expr();
@@ -2710,9 +2715,13 @@ impl<'a> Parser<'a> {
         });
 
         if is_unboxed {
-            self.mk_expr(lo, body.span.hi, ExprUnboxedFn(decl, fakeblock))
+            self.mk_expr(lo,
+                         body.span.hi,
+                         ExprUnboxedFn(capture_clause, decl, fakeblock))
         } else {
-            self.mk_expr(lo, body.span.hi, ExprFnBlock(decl, fakeblock))
+            self.mk_expr(lo,
+                         body.span.hi,
+                         ExprFnBlock(capture_clause, decl, fakeblock))
         }
     }