about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMarcus Klaas <mail@marcusklaas.nl>2015-11-22 16:07:38 +0100
committerMarcus Klaas <mail@marcusklaas.nl>2015-11-22 16:07:38 +0100
commit840012b5e02db35a121bc69b91c77cde05f63ae7 (patch)
tree563e1b039e5c25902b90646fc209a841399094b6 /src
parent559f00ba9951b29c73339d94bcaeb5efa94b332a (diff)
Format bare function types
Fix https://github.com/rust-lang-nursery/rustfmt/issues/616.
Fix https://github.com/rust-lang-nursery/rustfmt/issues/276.
Close https://github.com/rust-lang-nursery/rustfmt/issues/350.
Diffstat (limited to 'src')
-rw-r--r--src/items.rs15
-rw-r--r--src/types.rs130
-rw-r--r--src/utils.rs15
3 files changed, 107 insertions, 53 deletions
diff --git a/src/items.rs b/src/items.rs
index d1502d173da..bbe51c73c40 100644
--- a/src/items.rs
+++ b/src/items.rs
@@ -80,11 +80,7 @@ impl Rewrite for ast::Local {
 
 impl<'a> FmtVisitor<'a> {
     pub fn format_foreign_mod(&mut self, fm: &ast::ForeignMod, span: Span) {
-        self.buffer.push_str("extern ");
-
-        if fm.abi != abi::Abi::C {
-            self.buffer.push_str(&format!("{} ", fm.abi));
-        }
+        self.buffer.push_str(&::utils::format_abi(fm.abi));
 
         let snippet = self.snippet(span);
         let brace_pos = snippet.find_uncommented("{").unwrap() as u32;
@@ -856,17 +852,14 @@ fn rewrite_fn_base(context: &RewriteContext,
     let mut result = String::with_capacity(1024);
     // Vis unsafety abi.
     result.push_str(format_visibility(vis));
+    result.push_str(::utils::format_unsafety(unsafety));
 
-    if let ast::Unsafety::Unsafe = unsafety {
-        result.push_str("unsafe ");
-    }
     if let ast::Constness::Const = constness {
         result.push_str("const ");
     }
+
     if abi != abi::Rust {
-        result.push_str("extern ");
-        result.push_str(&abi.to_string());
-        result.push(' ');
+        result.push_str(&::utils::format_abi(abi));
     }
 
     // fn foo
diff --git a/src/types.rs b/src/types.rs
index 6d8ee483b14..807f0f17a43 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -8,9 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use syntax::ast::{self, Mutability};
+use syntax::ast::{self, Mutability, FunctionRetTy};
 use syntax::print::pprust;
 use syntax::codemap::{self, Span, BytePos};
+use syntax::abi;
 
 use Indent;
 use lists::{format_item_list, itemize_list, format_fn_args};
@@ -214,43 +215,12 @@ fn rewrite_segment(expr_context: bool,
             format!("{}<{}>", separator, list_str)
         }
         ast::PathParameters::ParenthesizedParameters(ref data) => {
-            // 2 for ()
-            let budget = try_opt!(width.checked_sub(2));
-            // 1 for (
-            let offset = offset + 1;
-            let list_lo = span_after(data.span, "(", context.codemap);
-            let items = itemize_list(context.codemap,
-                                     data.inputs.iter(),
-                                     ")",
-                                     |ty| ty.span.lo,
-                                     |ty| ty.span.hi,
-                                     |ty| ty.rewrite(context, budget, offset),
-                                     list_lo,
-                                     span_hi);
-            println!("got here");
-
-            let list_str = try_opt!(format_fn_args(items, budget, offset, context.config));
-
-            println!("got here 2");
-            let output = match data.output {
-                Some(ref ty) => {
-                    let budget = try_opt!(width.checked_sub(4));
-                    let type_str = try_opt!(ty.rewrite(context, budget, offset + 4));
-                    format!(" -> {}", type_str)
-                }
-                None => String::new(),
-            };
-
-            println!("got here 3");
-
-            let infix = if output.len() + list_str.len() > width {
-                format!("\n{}", (offset - 1).to_string(context.config))
-            } else {
-                String::new()
-            };
-            println!("({}){}{}", &list_str, &infix, &output);
-
-            format!("({}){}{}", list_str, infix, output)
+            try_opt!(format_function_type(data.inputs.iter().map(|x| &**x),
+                                          data.output.as_ref().map(|x| &**x),
+                                          data.span,
+                                          context,
+                                          width,
+                                          offset))
         }
         _ => String::new(),
     };
@@ -258,6 +228,49 @@ fn rewrite_segment(expr_context: bool,
     Some(format!("{}{}", segment.identifier, params))
 }
 
+fn format_function_type<'a, I>(inputs: I,
+                               output: Option<&ast::Ty>,
+                               span: Span,
+                               context: &RewriteContext,
+                               width: usize,
+                               offset: Indent)
+                               -> Option<String>
+    where I: Iterator<Item = &'a ast::Ty>
+{
+    // 2 for ()
+    let budget = try_opt!(width.checked_sub(2));
+    // 1 for (
+    let offset = offset + 1;
+    let list_lo = span_after(span, "(", context.codemap);
+    let items = itemize_list(context.codemap,
+                             inputs,
+                             ")",
+                             |ty| ty.span.lo,
+                             |ty| ty.span.hi,
+                             |ty| ty.rewrite(context, budget, offset),
+                             list_lo,
+                             span.hi);
+
+    let list_str = try_opt!(format_fn_args(items, budget, offset, context.config));
+
+    let output = match output {
+        Some(ref ty) => {
+            let budget = try_opt!(width.checked_sub(4));
+            let type_str = try_opt!(ty.rewrite(context, budget, offset + 4));
+            format!(" -> {}", type_str)
+        }
+        None => String::new(),
+    };
+
+    let infix = if output.len() + list_str.len() > width {
+        format!("\n{}", (offset - 1).to_string(context.config))
+    } else {
+        String::new()
+    };
+
+    Some(format!("({}){}{}", list_str, infix, output))
+}
+
 impl Rewrite for ast::WherePredicate {
     fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> {
         // TODO: dead spans?
@@ -501,14 +514,47 @@ impl Rewrite for ast::Ty {
                     None
                 }
             }
-            ast::TyBareFn(ref bare_fn) => bare_fn.rewrite(context, width, offset),
+            ast::TyBareFn(ref bare_fn) => {
+                rewrite_bare_fn(bare_fn, self.span, context, width, offset)
+            }
             ast::TyMac(..) | ast::TyTypeof(..) => unreachable!(),
         }
     }
 }
 
-impl Rewrite for ast::BareFnTy {
-    fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Option<String> {
-        None
+fn rewrite_bare_fn(bare_fn: &ast::BareFnTy,
+                   span: Span,
+                   context: &RewriteContext,
+                   width: usize,
+                   offset: Indent)
+                   -> Option<String> {
+    let mut result = String::with_capacity(128);
+
+    result.push_str(&::utils::format_unsafety(bare_fn.unsafety));
+
+    if bare_fn.abi != abi::Rust {
+        result.push_str(&::utils::format_abi(bare_fn.abi));
     }
+
+    result.push_str("fn");
+
+    let output = match bare_fn.decl.output {
+        FunctionRetTy::Return(ref ty) => Some(&**ty),
+        FunctionRetTy::NoReturn(..) => None,
+        FunctionRetTy::DefaultReturn(..) => unreachable!(),
+    };
+
+    let budget = try_opt!(width.checked_sub(result.len()));
+    let indent = offset + result.len();
+
+    let rewrite = try_opt!(format_function_type(bare_fn.decl.inputs.iter().map(|x| &*(x.ty)),
+                                                output,
+                                                span,
+                                                context,
+                                                budget,
+                                                indent));
+
+    result.push_str(&rewrite);
+
+    Some(result)
 }
diff --git a/src/utils.rs b/src/utils.rs
index 37dfb756972..6170b0c5ee0 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -12,6 +12,7 @@ use std::cmp::Ordering;
 
 use syntax::ast::{self, Visibility, Attribute, MetaItem, MetaItem_};
 use syntax::codemap::{CodeMap, Span, BytePos};
+use syntax::abi;
 
 use Indent;
 use comment::FindUncommented;
@@ -46,6 +47,14 @@ pub fn format_visibility(vis: Visibility) -> &'static str {
 }
 
 #[inline]
+pub fn format_unsafety(unsafety: ast::Unsafety) -> &'static str {
+    match unsafety {
+        ast::Unsafety::Unsafe => "unsafe ",
+        ast::Unsafety::Normal => "",
+    }
+}
+
+#[inline]
 pub fn format_mutability(mutability: ast::Mutability) -> &'static str {
     match mutability {
         ast::Mutability::MutMutable => "mut ",
@@ -53,6 +62,12 @@ pub fn format_mutability(mutability: ast::Mutability) -> &'static str {
     }
 }
 
+#[inline]
+// FIXME(#451): include "C"?
+pub fn format_abi(abi: abi::Abi) -> String {
+    format!("extern {} ", abi)
+}
+
 // The width of the first line in s.
 #[inline]
 pub fn first_line_width(s: &str) -> usize {