diff --git a/src/config.rs b/src/config.rs index 7e1172e1b9a..3e251ad1e39 100644 --- a/src/config.rs +++ b/src/config.rs @@ -270,6 +270,7 @@ create_config! { newline_style: NewlineStyle, NewlineStyle::Unix, "Unix or Windows line endings"; fn_brace_style: BraceStyle, BraceStyle::SameLineWhere, "Brace style for functions"; item_brace_style: BraceStyle, BraceStyle::SameLineWhere, "Brace style for structs and enums"; + impl_empty_single_line: bool, true, "Put empty-body implementations on a single line"; fn_empty_single_line: bool, true, "Put empty-body functions on a single line"; fn_single_line: bool, false, "Put single-expression functions on a single line"; fn_return_indent: ReturnIndent, ReturnIndent::WithArgs, diff --git a/src/items.rs b/src/items.rs index d81ff776126..85fcb2bf7b1 100644 --- a/src/items.rs +++ b/src/items.rs @@ -26,6 +26,8 @@ use syntax::codemap; use syntax::{ast, abi}; use syntax::codemap::{Span, BytePos, mk_sp}; use syntax::parse::token; +use syntax::ast::ImplItem; +use syntax::ptr::P; // Statements of the form // let pat: ty = init; @@ -490,8 +492,18 @@ pub fn format_impl(context: &RewriteContext, item: &ast::Item, offset: Indent) - context.config.where_density, "{", None)); - if !where_clause_str.contains('\n') && - result.len() + where_clause_str.len() + offset.width() > context.config.max_width { + + if try_opt!(is_impl_single_line(context, &items, &result, &where_clause_str, &item)) { + result.push_str(&where_clause_str); + if where_clause_str.contains('\n') { + result.push_str("\n{\n}"); + } else { + result.push_str(" {}"); + } + return Some(result); + } + + if !where_clause_str.is_empty() && !where_clause_str.contains('\n') { result.push('\n'); let width = context.block_indent.width() + context.config.tab_spaces - 1; let where_indent = Indent::new(0, width); @@ -510,6 +522,7 @@ pub fn format_impl(context: &RewriteContext, item: &ast::Item, offset: Indent) - } } } + result.push('{'); let snippet = context.snippet(item.span); @@ -536,13 +549,31 @@ pub fn format_impl(context: &RewriteContext, item: &ast::Item, offset: Indent) - result.push_str(&outer_indent_str); } + if result.chars().last().unwrap() == '{' { + result.push('\n'); + } result.push('}'); + Some(result) } else { unreachable!(); } } +fn is_impl_single_line(context: &RewriteContext, + items: &Vec>, + result: &str, + where_clause_str: &str, + item: &ast::Item) + -> Option { + let snippet = context.snippet(item.span); + let open_pos = try_opt!(snippet.find_uncommented("{")) + 1; + + Some(context.config.impl_empty_single_line && items.is_empty() && + result.len() + where_clause_str.len() <= context.config.max_width && + !contains_comment(&snippet[open_pos..])) +} + pub fn format_struct(context: &RewriteContext, item_name: &str, ident: ast::Ident, diff --git a/tests/source/impls.rs b/tests/source/impls.rs index c3c3ab8ad3a..d04b5ce1eeb 100644 --- a/tests/source/impls.rs +++ b/tests/source/impls.rs @@ -22,6 +22,12 @@ impl<'a, 'b, X, Y: Foo> Foo<'a, X> for Bar<'b, Y> where X: Fooooooooooooooo fn foo() { "hi" } } +impl Foo for Bar where T: Baz +{ +} + +impl Foo for Bar where T: Baz { /* Comment */ } + impl Foo { fn foo() {} } @@ -64,3 +70,10 @@ impl X { fn do_parse( mut self : X ) {} } impl Y5000 { fn bar(self: X< 'a , 'b >, y: Y) {} } + +pub impl Foo for Bar where T: Foo +{ + fn foo() { "hi" } +} + +pub impl Foo for Bar where T: Foo, Z: Baz {} diff --git a/tests/target/impls.rs b/tests/target/impls.rs index b6c1193a77d..33bc7481905 100644 --- a/tests/target/impls.rs +++ b/tests/target/impls.rs @@ -16,7 +16,8 @@ pub impl Foo for Bar { // Comment 3 } -pub unsafe impl<'a, 'b, X, Y: Foo> !Foo<'a, X> for Bar<'b, Y> where X: Foo<'a, Z> +pub unsafe impl<'a, 'b, X, Y: Foo> !Foo<'a, X> for Bar<'b, Y> + where X: Foo<'a, Z> { fn foo() { "hi" @@ -31,13 +32,22 @@ impl<'a, 'b, X, Y: Foo> Foo<'a, X> for Bar<'b, Y> } } -impl<'a, 'b, X, Y: Foo> Foo<'a, X> for Bar<'b, Y> where X: Foooooooooooooooooooooooooooo<'a, Z> +impl<'a, 'b, X, Y: Foo> Foo<'a, X> for Bar<'b, Y> + where X: Foooooooooooooooooooooooooooo<'a, Z> { fn foo() { "hi" } } +impl Foo for Bar where T: Baz {} + +impl Foo for Bar + where T: Baz +{ + // Comment +} + impl Foo { fn foo() {} } @@ -80,3 +90,17 @@ impl X { impl Y5000 { fn bar(self: X<'a, 'b>, y: Y) {} } + +pub impl Foo for Bar + where T: Foo +{ + fn foo() { + "hi" + } +} + +pub impl Foo for Bar + where T: Foo, + Z: Baz +{ +}