]> git.lizzy.rs Git - rust.git/blobdiff - src/libsyntax/print/pprust.rs
auto merge of #15999 : Kimundi/rust/fix_folder, r=nikomatsakis
[rust.git] / src / libsyntax / print / pprust.rs
index 615a4489a73de46041e29694a90db51b2776e962..675588a4460fffd3ba82f3cfbaefed12040bd5c1 100644 (file)
@@ -18,7 +18,6 @@
 use codemap::{CodeMap, BytePos};
 use codemap;
 use diagnostic;
-use parse::classify::expr_is_simple_block;
 use parse::token;
 use parse::lexer::comments;
 use parse;
@@ -30,7 +29,6 @@
 use std::io::{IoResult, MemWriter};
 use std::io;
 use std::mem;
-use std::str;
 
 pub enum AnnNode<'a> {
     NodeBlock(&'a ast::Block),
@@ -138,7 +136,7 @@ pub fn to_string(f: |&mut State| -> IoResult<()>) -> String {
         // downcasts.
         let (_, wr): (uint, Box<MemWriter>) = mem::transmute_copy(&s.s.out);
         let result =
-            str::from_utf8_owned(Vec::from_slice(wr.get_ref())).unwrap();
+            String::from_utf8(Vec::from_slice(wr.get_ref().as_slice())).unwrap();
         mem::forget(wr);
         result.to_string()
     }
@@ -152,6 +150,10 @@ pub fn pat_to_string(pat: &ast::Pat) -> String {
     to_string(|s| s.print_pat(pat))
 }
 
+pub fn arm_to_string(arm: &ast::Arm) -> String {
+    to_string(|s| s.print_arm(arm))
+}
+
 pub fn expr_to_string(e: &ast::Expr) -> String {
     to_string(|s| s.print_expr(e))
 }
@@ -189,7 +191,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 {
@@ -260,7 +262,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,
     }
 }
@@ -1005,9 +1008,20 @@ pub fn print_method(&mut self, meth: &ast::Method) -> IoResult<()> {
         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())
@@ -1391,63 +1405,48 @@ pub fn print_expr(&mut self, expr: &ast::Expr) -> IoResult<()> {
                 try!(self.print_expr(&**expr));
                 try!(space(&mut self.s));
                 try!(self.bopen());
-                let len = arms.len();
-                for (i, arm) in arms.iter().enumerate() {
-                    // I have no idea why this check is necessary, but here it
-                    // is :(
-                    if arm.attrs.is_empty() {
-                        try!(space(&mut self.s));
-                    }
-                    try!(self.cbox(indent_unit));
-                    try!(self.ibox(0u));
-                    try!(self.print_outer_attributes(arm.attrs.as_slice()));
-                    let mut first = true;
-                    for p in arm.pats.iter() {
-                        if first {
-                            first = false;
-                        } else {
-                            try!(space(&mut self.s));
-                            try!(self.word_space("|"));
-                        }
-                        try!(self.print_pat(&**p));
-                    }
-                    try!(space(&mut self.s));
-                    match arm.guard {
-                        Some(ref e) => {
-                            try!(self.word_space("if"));
-                            try!(self.print_expr(&**e));
-                            try!(space(&mut self.s));
-                        }
-                        None => ()
-                    }
-                    try!(self.word_space("=>"));
+                for arm in arms.iter() {
+                    try!(self.print_arm(arm));
+                }
+                try!(self.bclose_(expr.span, indent_unit));
+            }
+            ast::ExprFnBlock(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, false));
+                try!(space(&mut self.s));
+                // }
 
-                    match arm.body.node {
-                        ast::ExprBlock(ref blk) => {
-                            // the block will close the pattern's ibox
-                            try!(self.print_block_unclosed_indent(&**blk,
-                                                                  indent_unit));
+                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));
                         }
                         _ => {
-                            try!(self.end()); // close the ibox for the pattern
-                            try!(self.print_expr(&*arm.body));
+                            // this is a bare expression
+                            try!(self.print_expr(&*body.expr.unwrap()));
+                            try!(self.end()); // need to close a box
                         }
                     }
-                    if !expr_is_simple_block(expr.clone())
-                        && i < len - 1 {
-                        try!(word(&mut self.s, ","));
-                    }
-                    try!(self.end()); // close enclosing cbox
                 }
-                try!(self.bclose_(expr.span, indent_unit));
+                // 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::ExprFnBlock(ref decl, ref body) => {
+            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));
+                try!(self.print_fn_block_args(&**decl, true));
                 try!(space(&mut self.s));
                 // }
 
@@ -1841,6 +1840,51 @@ pub fn print_pat(&mut self, pat: &ast::Pat) -> IoResult<()> {
         self.ann.post(self, NodePat(pat))
     }
 
+    fn print_arm(&mut self, arm: &ast::Arm) -> IoResult<()> {
+        // I have no idea why this check is necessary, but here it
+        // is :(
+        if arm.attrs.is_empty() {
+            try!(space(&mut self.s));
+        }
+        try!(self.cbox(indent_unit));
+        try!(self.ibox(0u));
+        try!(self.print_outer_attributes(arm.attrs.as_slice()));
+        let mut first = true;
+        for p in arm.pats.iter() {
+            if first {
+                first = false;
+            } else {
+                try!(space(&mut self.s));
+                try!(self.word_space("|"));
+            }
+            try!(self.print_pat(&**p));
+        }
+        try!(space(&mut self.s));
+        match arm.guard {
+            Some(ref e) => {
+                try!(self.word_space("if"));
+                try!(self.print_expr(&**e));
+                try!(space(&mut self.s));
+            }
+            None => ()
+        }
+        try!(self.word_space("=>"));
+
+        match arm.body.node {
+            ast::ExprBlock(ref blk) => {
+                // the block will close the pattern's ibox
+                try!(self.print_block_unclosed_indent(&**blk,
+                                                      indent_unit));
+            }
+            _ => {
+                try!(self.end()); // close the ibox for the pattern
+                try!(self.print_expr(&*arm.body));
+                try!(word(&mut self.s, ","));
+            }
+        }
+        self.end() // close enclosing cbox
+    }
+
     // Returns whether it printed anything
     fn print_explicit_self(&mut self,
                            explicit_self: ast::ExplicitSelf_,
@@ -1851,15 +1895,17 @@ fn print_explicit_self(&mut self,
             ast::SelfValue(_) => {
                 try!(word(&mut self.s, "self"));
             }
-            ast::SelfUniq(_) => {
-                try!(word(&mut self.s, "~self"));
-            }
             ast::SelfRegion(ref lt, m, _) => {
                 try!(word(&mut self.s, "&"));
                 try!(self.print_opt_lifetime(lt));
                 try!(self.print_mutability(m));
                 try!(word(&mut self.s, "self"));
             }
+            ast::SelfExplicit(ref typ, _) => {
+                try!(word(&mut self.s, "self"));
+                try!(self.word_space(":"));
+                try!(self.print_type(&**typ));
+            }
         }
         return Ok(true);
     }
@@ -1935,8 +1981,13 @@ pub fn print_fn_args_and_ret(&mut self, decl: &ast::FnDecl,
     }
 
     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, "|"));
 
@@ -2131,7 +2182,14 @@ pub fn print_view_path(&mut self, vp: &ast::ViewPath) -> IoResult<()> {
                     try!(word(&mut self.s, "::{"));
                 }
                 try!(self.commasep(Inconsistent, idents.as_slice(), |s, w| {
-                    s.print_ident(w.node.name)
+                    match w.node {
+                        ast::PathListIdent { name, .. } => {
+                            s.print_ident(name)
+                        },
+                        ast::PathListMod { .. } => {
+                            word(&mut s.s, "mod")
+                        }
+                    }
                 }));
                 word(&mut self.s, "}")
             }