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.
This commit is contained in:
parent
559f00ba99
commit
840012b5e0
6 changed files with 134 additions and 57 deletions
15
src/items.rs
15
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
|
||||
|
|
130
src/types.rs
130
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)
|
||||
}
|
||||
|
|
15
src/utils.rs
15
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;
|
||||
|
@ -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 {
|
||||
|
|
|
@ -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!() ;
|
||||
}
|
||||
|
|
|
@ -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 @@ extern {
|
|||
pub fn bar();
|
||||
}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn DMR_GetDevice(pHDev: *mut HDEV,
|
||||
searchMode: DeviceSearchMode,
|
||||
pSearchString: *const c_char,
|
||||
|
@ -28,7 +28,7 @@ extern "Rust" {
|
|||
pub static mut var: SomeType;
|
||||
}
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
fn syscall(number: libc::c_long, // comment 1
|
||||
// comm 2
|
||||
... /* sup? */)
|
||||
|
@ -37,7 +37,7 @@ extern {
|
|||
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,
|
||||
|
|
|
@ -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!();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue