about summary refs log tree commit diff
path: root/src/libsyntax/print
diff options
context:
space:
mode:
authorPatrick Walton <pcwalton@mimiga.net>2014-05-28 22:26:56 -0700
committerPatrick Walton <pcwalton@mimiga.net>2014-07-18 09:01:37 -0700
commit02adaca4dc7eb4594d8bda9a7e04bc0247fc2a74 (patch)
tree2edb47de67e3c8a0d006f61217d7dffaab824b27 /src/libsyntax/print
parent5ddc7b4a252fbebee5f2ac87ed755139816d6823 (diff)
downloadrust-02adaca4dc7eb4594d8bda9a7e04bc0247fc2a74.tar.gz
rust-02adaca4dc7eb4594d8bda9a7e04bc0247fc2a74.zip
librustc: Implement unboxed closures with mutable receivers
Diffstat (limited to 'src/libsyntax/print')
-rw-r--r--src/libsyntax/print/pprust.rs61
1 files changed, 54 insertions, 7 deletions
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 10caaea86cf..dd96118ea49 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -188,7 +188,7 @@ pub fn method_to_string(p: &ast::Method) -> String {
 }
 
 pub fn fn_block_to_string(p: &ast::FnDecl) -> String {
-    to_string(|s| s.print_fn_block_args(p))
+    to_string(|s| s.print_fn_block_args(p, false))
 }
 
 pub fn path_to_string(p: &ast::Path) -> String {
@@ -259,7 +259,8 @@ fn needs_parentheses(expr: &ast::Expr) -> bool {
     match expr.node {
         ast::ExprAssign(..) | ast::ExprBinary(..) |
         ast::ExprFnBlock(..) | ast::ExprProc(..) |
-        ast::ExprAssignOp(..) | ast::ExprCast(..) => true,
+        ast::ExprUnboxedFn(..) | ast::ExprAssignOp(..) |
+        ast::ExprCast(..) => true,
         _ => false,
     }
 }
@@ -1004,9 +1005,20 @@ impl<'a> State<'a> {
         try!(self.maybe_print_comment(meth.span.lo));
         try!(self.print_outer_attributes(meth.attrs.as_slice()));
         match meth.node {
-            ast::MethDecl(ident, ref generics, ref explicit_self, fn_style, decl, body, vis) => {
-                try!(self.print_fn(&*decl, Some(fn_style), abi::Rust,
-                                   ident, generics, Some(explicit_self.node),
+            ast::MethDecl(ident,
+                          ref generics,
+                          abi,
+                          ref explicit_self,
+                          fn_style,
+                          decl,
+                          body,
+                          vis) => {
+                try!(self.print_fn(&*decl,
+                                   Some(fn_style),
+                                   abi,
+                                   ident,
+                                   generics,
+                                   Some(explicit_self.node),
                                    vis));
                 try!(word(&mut self.s, " "));
                 self.print_block_with_attrs(&*body, meth.attrs.as_slice())
@@ -1446,7 +1458,37 @@ impl<'a> State<'a> {
                 // we are inside.
                 //
                 // if !decl.inputs.is_empty() {
-                try!(self.print_fn_block_args(&**decl));
+                try!(self.print_fn_block_args(&**decl, false));
+                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.unwrap().node {
+                        ast::ExprBlock(blk) => {
+                            try!(self.print_block_unclosed(&*blk));
+                        }
+                        _ => {
+                            // this is a bare expression
+                            try!(self.print_expr(&*body.expr.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(ref decl, ref body) => {
+                // 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, true));
                 try!(space(&mut self.s));
                 // }
 
@@ -1939,8 +1981,13 @@ impl<'a> State<'a> {
     }
 
     pub fn print_fn_block_args(&mut self,
-                               decl: &ast::FnDecl) -> IoResult<()> {
+                               decl: &ast::FnDecl,
+                               is_unboxed: bool)
+                               -> IoResult<()> {
         try!(word(&mut self.s, "|"));
+        if is_unboxed {
+            try!(self.word_space("&mut:"));
+        }
         try!(self.print_fn_args(decl, None));
         try!(word(&mut self.s, "|"));