about summary refs log tree commit diff
path: root/src/libsyntax
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-11-20 12:01:44 +0000
committerbors <bors@rust-lang.org>2014-11-20 12:01:44 +0000
commit1d81776209cfa2b5cb1825bdbf3965a7a7f0440a (patch)
tree43c3aa55ebfb5fd8b24173e1315a4212346bbd8f /src/libsyntax
parentb825b3496aff1ed784f7a7ca935245208b95aabb (diff)
parentb9c5cd4dc420b90874784b253bcb8fd4ac72441a (diff)
downloadrust-1d81776209cfa2b5cb1825bdbf3965a7a7f0440a.tar.gz
rust-1d81776209cfa2b5cb1825bdbf3965a7a7f0440a.zip
auto merge of #19113 : nikomatsakis/rust/unboxed-boxed-closure-unification, r=acrichto
Use the expected type to infer the argument/return types of unboxed closures. Also, in `||` expressions, use the expected type to decide if the result should be a boxed or unboxed closure (and if an unboxed closure, what kind).

This supercedes PR #19089, which was already reviewed by @pcwalton.
Diffstat (limited to 'src/libsyntax')
-rw-r--r--src/libsyntax/ast.rs3
-rw-r--r--src/libsyntax/ast_map/blocks.rs6
-rw-r--r--src/libsyntax/ext/build.rs4
-rw-r--r--src/libsyntax/ext/expand.rs7
-rw-r--r--src/libsyntax/feature_gate.rs2
-rw-r--r--src/libsyntax/fold.rs11
-rw-r--r--src/libsyntax/parse/parser.rs26
-rw-r--r--src/libsyntax/print/pprust.rs47
-rw-r--r--src/libsyntax/visit.rs9
9 files changed, 27 insertions, 88 deletions
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index e3058c0a248..5d4fd2704a2 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -667,9 +667,8 @@ pub enum Expr_ {
     // FIXME #6993: change to Option<Name> ... or not, if these are hygienic.
     ExprLoop(P<Block>, Option<Ident>),
     ExprMatch(P<Expr>, Vec<Arm>, MatchSource),
-    ExprFnBlock(CaptureClause, P<FnDecl>, P<Block>),
+    ExprClosure(CaptureClause, Option<UnboxedClosureKind>, P<FnDecl>, P<Block>),
     ExprProc(P<FnDecl>, P<Block>),
-    ExprUnboxedFn(CaptureClause, UnboxedClosureKind, P<FnDecl>, P<Block>),
     ExprBlock(P<Block>),
 
     ExprAssign(P<Expr>, P<Expr>),
diff --git a/src/libsyntax/ast_map/blocks.rs b/src/libsyntax/ast_map/blocks.rs
index a35ee3ab1d0..8db12fbd835 100644
--- a/src/libsyntax/ast_map/blocks.rs
+++ b/src/libsyntax/ast_map/blocks.rs
@@ -37,7 +37,7 @@ use visit;
 ///
 /// More specifically, it is one of either:
 ///   - A function item,
-///   - A closure expr (i.e. an ExprFnBlock or ExprProc), or
+///   - A closure expr (i.e. an ExprClosure or ExprProc), or
 ///   - The default implementation for a trait method.
 ///
 /// To construct one, use the `Code::from_node` function.
@@ -71,7 +71,7 @@ impl MaybeFnLike for ast::TraitItem {
 impl MaybeFnLike for ast::Expr {
     fn is_fn_like(&self) -> bool {
         match self.node {
-            ast::ExprFnBlock(..) | ast::ExprProc(..) => true,
+            ast::ExprClosure(..) | ast::ExprProc(..) => true,
             _ => false,
         }
     }
@@ -215,7 +215,7 @@ impl<'a> FnLikeNode<'a> {
                 }
             }
             ast_map::NodeExpr(e) => match e.node {
-                ast::ExprFnBlock(_, ref decl, ref block) =>
+                ast::ExprClosure(_, _, ref decl, ref block) =>
                     closure(ClosureParts::new(&**decl, &**block, e.id, e.span)),
                 ast::ExprProc(ref decl, ref block) =>
                     closure(ClosureParts::new(&**decl, &**block, e.id, e.span)),
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index ffc42b67033..b18a0c8411c 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -864,14 +864,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
     fn lambda_fn_decl(&self, span: Span,
                       fn_decl: P<ast::FnDecl>, blk: P<ast::Block>) -> P<ast::Expr> {
-        self.expr(span, ast::ExprFnBlock(ast::CaptureByRef, fn_decl, blk))
+        self.expr(span, ast::ExprClosure(ast::CaptureByRef, None, fn_decl, blk))
     }
     fn lambda(&self, span: Span, ids: Vec<ast::Ident>, blk: P<ast::Block>) -> P<ast::Expr> {
         let fn_decl = self.fn_decl(
             ids.iter().map(|id| self.arg(span, *id, self.ty_infer(span))).collect(),
             self.ty_infer(span));
 
-        self.expr(span, ast::ExprFnBlock(ast::CaptureByRef, fn_decl, blk))
+        self.expr(span, ast::ExprClosure(ast::CaptureByRef, None, fn_decl, blk))
     }
     fn lambda0(&self, span: Span, blk: P<ast::Block>) -> P<ast::Expr> {
         self.lambda(span, Vec::new(), blk)
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 081456bebe1..04132679a03 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -207,10 +207,11 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             fld.cx.expr(span, ast::ExprForLoop(pat, head, body, opt_ident))
         }
 
-        ast::ExprFnBlock(capture_clause, fn_decl, block) => {
+        ast::ExprClosure(capture_clause, opt_kind, fn_decl, block) => {
             let (rewritten_fn_decl, rewritten_block)
                 = expand_and_rename_fn_decl_and_block(fn_decl, block, fld);
-            let new_node = ast::ExprFnBlock(capture_clause,
+            let new_node = ast::ExprClosure(capture_clause,
+                                            opt_kind,
                                             rewritten_fn_decl,
                                             rewritten_block);
             P(ast::Expr{id:id, node: new_node, span: fld.new_span(span)})
@@ -1555,7 +1556,7 @@ mod test {
             0)
     }
 
-    // closure arg hygiene (ExprFnBlock)
+    // closure arg hygiene (ExprClosure)
     // expands to fn f(){(|x_1 : int| {(x_2 + x_1)})(3);}
     #[test] fn closure_arg_hygiene(){
         run_renaming_test(
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 460a94a8d5a..9635f0175f0 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -309,7 +309,7 @@ impl<'a, 'v> Visitor<'v> for Context<'a> {
 
     fn visit_expr(&mut self, e: &ast::Expr) {
         match e.node {
-            ast::ExprUnboxedFn(..) => {
+            ast::ExprClosure(_, Some(_), _, _) => {
                 self.gate_feature("unboxed_closures",
                                   e.span,
                                   "unboxed closures are a work-in-progress \
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 2e6ee49f0ff..1bdf9ea73df 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -1326,18 +1326,13 @@ pub fn noop_fold_expr<T: Folder>(Expr {id, node, span}: Expr, folder: &mut T) ->
                         arms.move_map(|x| folder.fold_arm(x)),
                         source)
             }
-            ExprFnBlock(capture_clause, decl, body) => {
-                ExprFnBlock(capture_clause,
-                            folder.fold_fn_decl(decl),
-                            folder.fold_block(body))
-            }
             ExprProc(decl, body) => {
                 ExprProc(folder.fold_fn_decl(decl),
                          folder.fold_block(body))
             }
-            ExprUnboxedFn(capture_clause, kind, decl, body) => {
-                ExprUnboxedFn(capture_clause,
-                            kind,
+            ExprClosure(capture_clause, opt_kind, decl, body) => {
+                ExprClosure(capture_clause,
+                            opt_kind,
                             folder.fold_fn_decl(decl),
                             folder.fold_block(body))
             }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index a6fe3902395..ab0543d64b7 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -25,10 +25,10 @@ use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, Explicit
 use ast::{Expr, Expr_, ExprAddrOf, ExprMatch, ExprAgain};
 use ast::{ExprAssign, ExprAssignOp, ExprBinary, ExprBlock, ExprBox};
 use ast::{ExprBreak, ExprCall, ExprCast};
-use ast::{ExprField, ExprTupField, ExprFnBlock, ExprIf, ExprIfLet, ExprIndex, ExprSlice};
+use ast::{ExprField, ExprTupField, ExprClosure, ExprIf, ExprIfLet, ExprIndex, ExprSlice};
 use ast::{ExprLit, ExprLoop, ExprMac};
 use ast::{ExprMethodCall, ExprParen, ExprPath, ExprProc};
-use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary, ExprUnboxedFn};
+use ast::{ExprRepeat, ExprRet, ExprStruct, ExprTup, ExprUnary};
 use ast::{ExprVec, ExprWhile, ExprWhileLet, ExprForLoop, Field, FnDecl};
 use ast::{Once, Many};
 use ast::{FnUnboxedClosureKind, FnMutUnboxedClosureKind};
@@ -2999,7 +2999,8 @@ impl<'a> Parser<'a> {
 
     // `|args| expr`
     pub fn parse_lambda_expr(&mut self, capture_clause: CaptureClause)
-                             -> P<Expr> {
+                             -> P<Expr>
+    {
         let lo = self.span.lo;
         let (decl, optional_unboxed_closure_kind) =
             self.parse_fn_block_decl();
@@ -3013,21 +3014,10 @@ impl<'a> Parser<'a> {
             rules: DefaultBlock,
         });
 
-        match optional_unboxed_closure_kind {
-            Some(unboxed_closure_kind) => {
-                self.mk_expr(lo,
-                             fakeblock.span.hi,
-                             ExprUnboxedFn(capture_clause,
-                                           unboxed_closure_kind,
-                                           decl,
-                                           fakeblock))
-            }
-            None => {
-                self.mk_expr(lo,
-                             fakeblock.span.hi,
-                             ExprFnBlock(capture_clause, decl, fakeblock))
-            }
-        }
+        self.mk_expr(
+            lo,
+            fakeblock.span.hi,
+            ExprClosure(capture_clause, optional_unboxed_closure_kind, decl, fakeblock))
     }
 
     pub fn parse_else_expr(&mut self) -> P<Expr> {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 8e7804aaa71..5652a9a9d3a 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -444,9 +444,8 @@ pub fn visibility_qualified(vis: ast::Visibility, s: &str) -> String {
 fn needs_parentheses(expr: &ast::Expr) -> bool {
     match expr.node {
         ast::ExprAssign(..) | ast::ExprBinary(..) |
-        ast::ExprFnBlock(..) | ast::ExprProc(..) |
-        ast::ExprUnboxedFn(..) | ast::ExprAssignOp(..) |
-        ast::ExprCast(..) => true,
+        ast::ExprClosure(..) | ast::ExprProc(..) |
+        ast::ExprAssignOp(..) | ast::ExprCast(..) => true,
         _ => false,
     }
 }
@@ -1662,49 +1661,11 @@ impl<'a> State<'a> {
                 }
                 try!(self.bclose_(expr.span, indent_unit));
             }
-            ast::ExprFnBlock(capture_clause, ref decl, ref body) => {
+            ast::ExprClosure(capture_clause, opt_kind, ref decl, ref body) => {
                 try!(self.print_capture_clause(capture_clause));
 
-                // in do/for blocks we don't want to show an empty
-                // argument list, but at this point we don't know which
-                // we are inside.
-                //
-                // if !decl.inputs.is_empty() {
-                try!(self.print_fn_block_args(&**decl, None));
+                try!(self.print_fn_block_args(&**decl, opt_kind));
                 try!(space(&mut self.s));
-                // }
-
-                if !body.stmts.is_empty() || !body.expr.is_some() {
-                    try!(self.print_block_unclosed(&**body));
-                } else {
-                    // we extract the block, so as not to create another set of boxes
-                    match body.expr.as_ref().unwrap().node {
-                        ast::ExprBlock(ref blk) => {
-                            try!(self.print_block_unclosed(&**blk));
-                        }
-                        _ => {
-                            // this is a bare expression
-                            try!(self.print_expr(&**body.expr.as_ref().unwrap()));
-                            try!(self.end()); // need to close a box
-                        }
-                    }
-                }
-                // a box will be closed by print_expr, but we didn't want an overall
-                // wrapper so we closed the corresponding opening. so create an
-                // empty box to satisfy the close.
-                try!(self.ibox(0));
-            }
-            ast::ExprUnboxedFn(capture_clause, kind, ref decl, ref body) => {
-                try!(self.print_capture_clause(capture_clause));
-
-                // in do/for blocks we don't want to show an empty
-                // argument list, but at this point we don't know which
-                // we are inside.
-                //
-                // if !decl.inputs.is_empty() {
-                try!(self.print_fn_block_args(&**decl, Some(kind)));
-                try!(space(&mut self.s));
-                // }
 
                 if !body.stmts.is_empty() || !body.expr.is_some() {
                     try!(self.print_block_unclosed(&**body));
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index 41a7ce7d78e..a0bdd739113 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -815,14 +815,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr) {
                 visitor.visit_arm(arm)
             }
         }
-        ExprFnBlock(_, ref function_declaration, ref body) => {
-            visitor.visit_fn(FkFnBlock,
-                             &**function_declaration,
-                             &**body,
-                             expression.span,
-                             expression.id)
-        }
-        ExprUnboxedFn(_, _, ref function_declaration, ref body) => {
+        ExprClosure(_, _, ref function_declaration, ref body) => {
             visitor.visit_fn(FkFnBlock,
                              &**function_declaration,
                              &**body,