]> git.lizzy.rs Git - rust.git/commitdiff
Format bare function types
authorMarcus Klaas <mail@marcusklaas.nl>
Sun, 22 Nov 2015 15:07:38 +0000 (16:07 +0100)
committerMarcus Klaas <mail@marcusklaas.nl>
Sun, 22 Nov 2015 15:07:38 +0000 (16:07 +0100)
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.

src/items.rs
src/types.rs
src/utils.rs
tests/source/fn-simple.rs
tests/target/extern.rs
tests/target/fn-simple.rs

index d1502d173dabfef9900d443f07d242b92b64af67..bbe51c73c400ad4e48e8ff2cec249913c3e3242b 100644 (file)
@@ -80,11 +80,7 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Opt
 
 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
index 6d8ee483b14cd9e7ed7209191f540f9ef7692cf9..807f0f17a43bbe1fcdf0b2cd93ad87bcfa2f7c22 100644 (file)
@@ -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 @@ fn rewrite(&self, context: &RewriteContext, width: usize, offset: Indent) -> Opt
                     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)
 }
index 37dfb756972548c54e596f648697e03ebbbfa5e6..6170b0c5ee0fcd389c774167dbb6f603d191d2b3 100644 (file)
@@ -12,6 +12,7 @@
 
 use syntax::ast::{self, Visibility, Attribute, MetaItem, MetaItem_};
 use syntax::codemap::{CodeMap, Span, BytePos};
+use syntax::abi;
 
 use Indent;
 use comment::FindUncommented;
@@ -45,6 +46,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 {
@@ -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 {
index 4c216ec26b8740ae028fa616f3f060a5edb216d0..93c4322441706ab83c13a187d9604554add1cdef 100644 (file)
@@ -32,3 +32,12 @@ fn zzzzzzzzzzzzzzzzzzzz<Type, NodeType>
                        (selff: Type, mut handle: node::Handle<IdRef<'id, Node<K, V>>, Type, NodeType>)
                         -> SearchStack<'a, K, V, Type, NodeType>{
 }
+
+unsafe fn generic_call(cx: *mut JSContext, argc: libc::c_uint, vp: *mut JSVal,
+    is_lenient: bool,
+                       call: unsafe extern fn(*const JSJitInfo, *mut JSContext,
+                                              HandleObject, *mut libc::c_void, u32,
+                                              *mut JSVal)
+                                              -> u8) {
+    let f:  fn  ( _ , _  ) ->  _   =  panic!()  ;
+}
index 35475660bae7a162ea295079810d5c1fda267166..ca8c43d8b2c69de3811f5c25a7c60b05a23cf89e 100644 (file)
@@ -1,5 +1,5 @@
 
-extern {
+extern "C" {
     fn c_func(x: *mut *mut libc::c_void);
 
     fn c_func(x: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
@@ -11,7 +11,7 @@ fn c_func(x: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX,
     pub fn bar();
 }
 
-extern {
+extern "C" {
     fn DMR_GetDevice(pHDev: *mut HDEV,
                      searchMode: DeviceSearchMode,
                      pSearchString: *const c_char,
@@ -28,7 +28,7 @@ fn DMR_GetDevice(pHDev: *mut HDEV,
     pub static mut var: SomeType;
 }
 
-extern {
+extern "C" {
     fn syscall(number: libc::c_long, // comment 1
                // comm 2
                ... /* sup? */)
@@ -37,7 +37,7 @@ fn syscall(number: libc::c_long, // comment 1
     fn foo(x: *const c_char, ...) -> libc::c_long;
 }
 
-extern {
+extern "C" {
     pub fn freopen(filename: *const c_char,
                    mode: *const c_char,
                    mode2: *const c_char,
index 6acb1a3e582fc3eb016872c8cc372b918c7659e4..e5de6b0f00d1f582cdc8714caf4158caf179aab0 100644 (file)
@@ -50,3 +50,17 @@ fn zzzzzzzzzzzzzzzzzzzz<Type, NodeType>(selff: Type,
                                                                  NodeType>)
                                         -> SearchStack<'a, K, V, Type, NodeType> {
 }
+
+unsafe fn generic_call(cx: *mut JSContext,
+                       argc: libc::c_uint,
+                       vp: *mut JSVal,
+                       is_lenient: bool,
+                       call: unsafe extern "C" fn(*const JSJitInfo,
+                                                  *mut JSContext,
+                                                  HandleObject,
+                                                  *mut libc::c_void,
+                                                  u32,
+                                                  *mut JSVal)
+                                                  -> u8) {
+    let f: fn(_, _) -> _ = panic!();
+}