From 89d8eabba52db201d2e6d7ca53882c8bb9af3231 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 28 Apr 2018 13:23:50 +0900 Subject: [PATCH 1/6] Add tests for #2594 --- tests/source/enum.rs | 4 ++++ tests/target/enum.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/tests/source/enum.rs b/tests/source/enum.rs index f3dbae4b84d..64e15110609 100644 --- a/tests/source/enum.rs +++ b/tests/source/enum.rs @@ -192,3 +192,7 @@ pub enum QlError { // (kind, input, expected) #[fail(display = "Could not find {}: Found: {}, expected: {:?}", 0, 1, 2)] ResolveError(&'static str, String, Option), } + +// #2594 +enum Foo {} +enum Bar { } diff --git a/tests/target/enum.rs b/tests/target/enum.rs index 4b79d0d8c7b..e429e45287e 100644 --- a/tests/target/enum.rs +++ b/tests/target/enum.rs @@ -258,3 +258,7 @@ pub enum QlError { #[fail(display = "Could not find {}: Found: {}, expected: {:?}", 0, 1, 2)] ResolveError(&'static str, String, Option), } + +// #2594 +enum Foo {} +enum Bar {} From a9553654592fa9508c4a42b9c47a04fc3b4357d8 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 28 Apr 2018 13:24:05 +0900 Subject: [PATCH 2/6] Use a glob import for import utils --- src/items.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/items.rs b/src/items.rs index 80e837ed904..1924d881127 100644 --- a/src/items.rs +++ b/src/items.rs @@ -32,11 +32,7 @@ use rewrite::{Rewrite, RewriteContext}; use shape::{Indent, Shape}; use spanned::Spanned; use types::TraitTyParamBounds; -use utils::{colon_spaces, contains_skip, first_line_width, format_abi, format_auto, - format_constness, format_defaultness, format_mutability, format_unsafety, - format_visibility, is_attributes_extendable, last_line_contains_single_line_comment, - last_line_used_width, last_line_width, mk_sp, semicolon_for_expr, starts_with_newline, - stmt_expr, trimmed_last_line_width}; +use utils::*; use vertical::rewrite_with_alignment; use visitor::FmtVisitor; From 82d8dd2f4bdcd61b08c6952e4e6ebdf4db70b299 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 28 Apr 2018 13:59:03 +0900 Subject: [PATCH 3/6] Factor out a formatting routine for empty struct and tuple --- src/items.rs | 35 +++++++++++++++++++++++++++++++++++ src/utils.rs | 10 ++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/items.rs b/src/items.rs index 1924d881127..e6351a3aa15 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1242,6 +1242,41 @@ fn get_bytepos_after_visibility(vis: &ast::Visibility, default_span: Span) -> By } } +// Format tuple or struct without any fields. We need to make sure that the comments +// inside the delimiters are preserved. +fn format_empty_struct_or_tuple( + context: &RewriteContext, + span: Span, + offset: Indent, + result: &mut String, + opener: &str, + closer: &str, +) { + // 3 = " {}" or "();" + let used_width = last_line_used_width(&result, offset.width()) + 3; + if used_width > context.config.max_width() { + result.push_str(&offset.to_string_with_newline(context.config)) + } + result.push_str(opener); + match rewrite_missing_comment(span, Shape::indented(offset, context.config), context) { + Some(ref s) if s.is_empty() => (), + Some(ref s) => { + if !is_single_line(s) || first_line_contains_single_line_comment(s) { + let nested_indent_str = offset + .block_indent(context.config) + .to_string_with_newline(context.config); + result.push_str(&nested_indent_str); + } + result.push_str(s); + if last_line_contains_single_line_comment(s) { + result.push_str(&offset.to_string_with_newline(context.config)); + } + } + None => result.push_str(context.snippet(span)), + } + result.push_str(closer); +} + fn format_tuple_struct( context: &RewriteContext, struct_parts: &StructParts, diff --git a/src/utils.rs b/src/utils.rs index 2493c9a5c74..9ed1df35a42 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -133,6 +133,16 @@ pub fn outer_attributes(attrs: &[ast::Attribute]) -> Vec { filter_attributes(attrs, ast::AttrStyle::Outer) } +#[inline] +pub fn is_single_line(s: &str) -> bool { + s.chars().find(|&c| c == '\n').is_none() +} + +#[inline] +pub fn first_line_contains_single_line_comment(s: &str) -> bool { + s.lines().next().map_or(false, |l| l.contains("//")) +} + #[inline] pub fn last_line_contains_single_line_comment(s: &str) -> bool { s.lines().last().map_or(false, |l| l.contains("//")) From fb0c6affa5b76001af2ea04c41c2204f6724fc63 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 28 Apr 2018 13:59:54 +0900 Subject: [PATCH 4/6] Use format_empty_struct_or_tuple --- src/items.rs | 44 +++++++------------------------------------- 1 file changed, 7 insertions(+), 37 deletions(-) diff --git a/src/items.rs b/src/items.rs index e6351a3aa15..341cce8a71f 100644 --- a/src/items.rs +++ b/src/items.rs @@ -1190,18 +1190,8 @@ pub fn format_struct_struct( } if fields.is_empty() { - let snippet = context.snippet(mk_sp(body_lo, span.hi() - BytePos(1))); - if snippet.trim().is_empty() { - // `struct S {}` - } else if snippet.trim_right_matches(&[' ', '\t'][..]).ends_with('\n') { - // fix indent - result.push_str(snippet.trim_right()); - result.push('\n'); - result.push_str(&offset.to_string(context.config)); - } else { - result.push_str(snippet); - } - result.push('}'); + let inner_span = mk_sp(body_lo, span.hi() - BytePos(1)); + format_empty_struct_or_tuple(context, inner_span, offset, &mut result, "", "}"); return Some(result); } @@ -1340,31 +1330,11 @@ fn format_tuple_struct( }; if fields.is_empty() { - // 3 = `();` - let used_width = last_line_used_width(&result, offset.width()) + 3; - if used_width > context.config.max_width() { - result.push('\n'); - result.push_str(&offset - .block_indent(context.config) - .to_string(context.config)) - } - result.push('('); - let snippet = context.snippet(mk_sp( - body_lo, - context - .snippet_provider - .span_before(mk_sp(body_lo, span.hi()), ")"), - )); - if snippet.is_empty() { - // `struct S ()` - } else if snippet.trim_right_matches(&[' ', '\t'][..]).ends_with('\n') { - result.push_str(snippet.trim_right()); - result.push('\n'); - result.push_str(&offset.to_string(context.config)); - } else { - result.push_str(snippet); - } - result.push(')'); + let body_hi = context + .snippet_provider + .span_before(mk_sp(body_lo, span.hi()), ")"); + let inner_span = mk_sp(body_lo, body_hi); + format_empty_struct_or_tuple(context, inner_span, offset, &mut result, "(", ")"); } else { let shape = Shape::indented(offset, context.config).sub_width(1)?; let fields = &fields.iter().collect::>(); From e512c19ed5451a4f0e9f17eac488b1414c1c6aed Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 28 Apr 2018 14:03:14 +0900 Subject: [PATCH 5/6] Use format_empty_struct_or_tuple over format_missing_no_indent Closes #2594. --- src/items.rs | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/src/items.rs b/src/items.rs index 341cce8a71f..c2a2d0d2180 100644 --- a/src/items.rs +++ b/src/items.rs @@ -453,35 +453,39 @@ impl<'a> FmtVisitor<'a> { self.last_pos = body_start; - self.block_indent = self.block_indent.block_indent(self.config); - let variant_list = self.format_variant_list(enum_def, body_start, span.hi() - BytePos(1)); - match variant_list { - Some(ref body_str) => self.push_str(body_str), - None => self.format_missing_no_indent(span.hi() - BytePos(1)), - } - self.block_indent = self.block_indent.block_unindent(self.config); - - if variant_list.is_some() || contains_comment(&enum_snippet[brace_pos..]) { - let indent_str = self.block_indent.to_string(self.config); - self.push_str(&indent_str); + match self.format_variant_list(enum_def, body_start, span.hi()) { + Some(ref s) if enum_def.variants.is_empty() => self.push_str(s), + rw => { + self.push_rewrite(mk_sp(body_start, span.hi()), rw); + self.block_indent = self.block_indent.block_unindent(self.config); + } } - self.push_str("}"); - self.last_pos = span.hi(); } // Format the body of an enum definition fn format_variant_list( - &self, + &mut self, enum_def: &ast::EnumDef, body_lo: BytePos, body_hi: BytePos, ) -> Option { if enum_def.variants.is_empty() { - return None; + let mut buffer = String::with_capacity(128); + // 1 = "}" + let span = mk_sp(body_lo, body_hi - BytePos(1)); + format_empty_struct_or_tuple( + &self.get_context(), + span, + self.block_indent, + &mut buffer, + "", + "}", + ); + return Some(buffer); } let mut result = String::with_capacity(1024); - let indentation = self.block_indent.to_string_with_newline(self.config); - result.push_str(&indentation); + let original_offset = self.block_indent; + self.block_indent = self.block_indent.block_indent(self.config); let itemize_list_with = |one_line_width: usize| { itemize_list( @@ -526,7 +530,8 @@ impl<'a> FmtVisitor<'a> { let list = write_list(&items, &fmt)?; result.push_str(&list); - result.push('\n'); + result.push_str(&original_offset.to_string_with_newline(self.config)); + result.push('}'); Some(result) } From 3432807ac2c9118058e61961f1d14bdb709004f5 Mon Sep 17 00:00:00 2001 From: topecongiro Date: Sat, 28 Apr 2018 14:07:10 +0900 Subject: [PATCH 6/6] Temporarily fix tests cc #2655. --- tests/target/configs/struct_field_align_threshold/20.rs | 8 ++++++-- tests/target/issue-977.rs | 4 +++- tests/target/structs.rs | 8 ++++++-- tests/target/unions.rs | 4 +++- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/tests/target/configs/struct_field_align_threshold/20.rs b/tests/target/configs/struct_field_align_threshold/20.rs index b84afc56835..f6ee4ed1f0a 100644 --- a/tests/target/configs/struct_field_align_threshold/20.rs +++ b/tests/target/configs/struct_field_align_threshold/20.rs @@ -255,8 +255,12 @@ struct Foo { struct Foo { // trailing space -> } -struct Foo { /* comment */ } -struct Foo( /* comment */ ); +struct Foo { + // comment +} +struct Foo( + // comment +); struct LongStruct { a: A, diff --git a/tests/target/issue-977.rs b/tests/target/issue-977.rs index 9420054449d..c4bc82d85d4 100644 --- a/tests/target/issue-977.rs +++ b/tests/target/issue-977.rs @@ -4,7 +4,9 @@ trait NameC { // comment } -struct FooC { /* comment */ } +struct FooC { + // comment +} enum MooC { // comment } diff --git a/tests/target/structs.rs b/tests/target/structs.rs index 59a57a9b5b4..7f9ef1e6164 100644 --- a/tests/target/structs.rs +++ b/tests/target/structs.rs @@ -228,8 +228,12 @@ struct Foo { struct Foo { // trailing space -> } -struct Foo { /* comment */ } -struct Foo( /* comment */ ); +struct Foo { + // comment +} +struct Foo( + // comment +); struct LongStruct { a: A, diff --git a/tests/target/unions.rs b/tests/target/unions.rs index eb6c3ae7e15..6de682297af 100644 --- a/tests/target/unions.rs +++ b/tests/target/unions.rs @@ -136,7 +136,9 @@ union Foo { union Foo { // trailing space -> } -union Foo { /* comment */ } +union Foo { + // comment +} union LongUnion { a: A,