diff --git a/src/imports.rs b/src/imports.rs index 4ae40b7fc0b..bc343307272 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -178,19 +178,26 @@ impl<'a> FmtVisitor<'a> { // Order the imports by view-path & other import path properties ordered_use_items.sort_by(|a, b| compare_use_items(a.0, b.0).unwrap()); // First, output the span before the first import + let prev_span_str = self.snippet(codemap::mk_sp(self.last_pos, pos_before_first_use_item)); + // Look for purely trailing space at the start of the prefix snippet before a linefeed, or + // a prefix that's entirely horizontal whitespace. + let prefix_span_start = match prev_span_str.find('\n') { + Some(offset) if prev_span_str[..offset].trim().is_empty() => { + self.last_pos + BytePos(offset as u32) + } + None if prev_span_str.trim().is_empty() => pos_before_first_use_item, + _ => self.last_pos, + }; // Look for indent (the line part preceding the use is all whitespace) and excise that // from the prefix - let prev_span_str = self.snippet(codemap::mk_sp(self.last_pos, pos_before_first_use_item)); let span_end = match prev_span_str.rfind('\n') { - Some(offset) => { - if prev_span_str[offset..].trim().is_empty() { - self.last_pos + BytePos(offset as u32) - } else { - pos_before_first_use_item - } + Some(offset) if prev_span_str[offset..].trim().is_empty() => { + self.last_pos + BytePos(offset as u32) } - None => pos_before_first_use_item, + _ => pos_before_first_use_item, }; + + self.last_pos = prefix_span_start; self.format_missing(span_end); for ordered in ordered_use_items { // Fake out the formatter by setting `self.last_pos` to the appropriate location before diff --git a/src/missed_spans.rs b/src/missed_spans.rs index 7e6d1516636..0e7d1402fc5 100644 --- a/src/missed_spans.rs +++ b/src/missed_spans.rs @@ -14,6 +14,10 @@ use syntax::codemap::{self, BytePos, Span, Pos}; use comment::{CodeCharKind, CommentCodeSlices, rewrite_comment}; impl<'a> FmtVisitor<'a> { + fn output_at_start(&self) -> bool { + self.buffer.len == 0 + } + // TODO these format_missing methods are ugly. Refactor and add unit tests // for the central whitespace stripping loop. pub fn format_missing(&mut self, end: BytePos) { @@ -25,7 +29,7 @@ impl<'a> FmtVisitor<'a> { let config = self.config; self.format_missing_inner(end, |this, last_snippet, snippet| { this.buffer.push_str(last_snippet.trim_right()); - if last_snippet == snippet { + if last_snippet == snippet && !this.output_at_start() { // No new lines in the snippet. this.buffer.push_str("\n"); } @@ -41,7 +45,7 @@ impl<'a> FmtVisitor<'a> { if start == end { // Do nothing if this is the beginning of the file. - if start != self.codemap.lookup_char_pos(start).file.start_pos { + if !self.output_at_start() { process_last_snippet(self, "", ""); } return; diff --git a/src/visitor.rs b/src/visitor.rs index b60c5156680..b89b97487a5 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -559,7 +559,7 @@ impl<'a> FmtVisitor<'a> { self.last_pos = filemap.start_pos; self.block_indent = Indent::empty(); self.walk_mod_items(m); - self.format_missing(filemap.end_pos); + self.format_missing_with_indent(filemap.end_pos); } pub fn get_context(&self) -> RewriteContext { diff --git a/tests/config/issue-1124.toml b/tests/config/issue-1124.toml new file mode 100644 index 00000000000..44148a2d3c3 --- /dev/null +++ b/tests/config/issue-1124.toml @@ -0,0 +1 @@ +reorder_imports = true diff --git a/tests/source/issue-1124.rs b/tests/source/issue-1124.rs new file mode 100644 index 00000000000..0b9d68f49b8 --- /dev/null +++ b/tests/source/issue-1124.rs @@ -0,0 +1,13 @@ +use d; use c; use b; use a; +// The previous line has a space after the `use a;` + +mod a { use d; use c; use b; use a; } + +use z; + +use y; + + + +use x; +use a; \ No newline at end of file diff --git a/tests/target/issue-1124.rs b/tests/target/issue-1124.rs new file mode 100644 index 00000000000..d30f29461d8 --- /dev/null +++ b/tests/target/issue-1124.rs @@ -0,0 +1,21 @@ +use a; +use b; +use c; +use d; +// The previous line has a space after the `use a;` + +mod a { + use a; + use b; + use c; + use d; +} + +use a; + + + +use x; + +use y; +use z;