diff --git a/src/formatting.rs b/src/formatting.rs index a9fe8381429..62876841813 100644 --- a/src/formatting.rs +++ b/src/formatting.rs @@ -230,7 +230,14 @@ impl<'a, T: FormatHandler + 'a> FormatContext<'a, T> { // For some reason, the source_map does not include terminating // newlines so we must add one on for each file. This is sad. - source_file::append_newline(&mut visitor.buffer, self.config.style_edition()); + let num_newlines = count_newlines(&visitor.buffer); + if self + .config + .file_lines() + .contains_line(&path, num_newlines + 1) + { + source_file::append_newline(&mut visitor.buffer, self.config.style_edition()); + } format_lines( &mut visitor.buffer, diff --git a/src/missed_spans.rs b/src/missed_spans.rs index d394bb40b6d..2654d2464ee 100644 --- a/src/missed_spans.rs +++ b/src/missed_spans.rs @@ -63,7 +63,10 @@ impl<'a> FmtVisitor<'a> { let config = self.config; self.format_missing_inner(end, |this, last_snippet, snippet| { this.push_str(last_snippet.trim_end()); - if last_snippet == snippet && !this.output_at_start() { + if last_snippet == snippet + && !this.output_at_start() + && !out_of_file_lines_range!(this, mk_sp(this.last_pos, end)) + { // No new lines in the snippet. this.push_str("\n"); } @@ -100,7 +103,11 @@ impl<'a> FmtVisitor<'a> { let snippet = self.snippet(span); // Do nothing for spaces in the beginning of the file - if start == BytePos(0) && end.0 as usize == snippet.len() && snippet.trim().is_empty() { + if start == BytePos(0) + && end.0 as usize == snippet.len() + && snippet.trim().is_empty() + && !out_of_file_lines_range!(self, span) + { return; } @@ -357,11 +364,20 @@ impl<'a> FmtVisitor<'a> { } } - let remaining = snippet[status.line_start..subslice.len() + offset].trim(); - if !remaining.is_empty() { - self.push_str(&self.block_indent.to_string(self.config)); - self.push_str(remaining); - status.line_start = subslice.len() + offset; + let mut remaining = &snippet[status.line_start..subslice.len() + offset]; + status.line_start = subslice.len() + offset; + + let skip_this_line = !self + .config + .file_lines() + .contains_line(file_name, status.cur_line); + if !skip_this_line { + remaining = remaining.trim(); + if !remaining.is_empty() { + self.push_str(&self.block_indent.to_string(self.config)); + } } + + self.push_str(remaining); } } diff --git a/src/visitor.rs b/src/visitor.rs index 6048084c8da..1b869ae43c2 100644 --- a/src/visitor.rs +++ b/src/visitor.rs @@ -895,8 +895,12 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { return false; } - let rewrite = attrs.rewrite(&self.get_context(), self.shape()); let span = mk_sp(attrs[0].span.lo(), attrs[attrs.len() - 1].span.hi()); + if out_of_file_lines_range!(self, span) { + return false; + } + + let rewrite = attrs.rewrite(&self.get_context(), self.shape()); self.push_rewrite(span, rewrite); false @@ -1028,12 +1032,16 @@ impl<'b, 'a: 'b> FmtVisitor<'a> { .snippet_provider .opt_span_after(self.next_span(end_pos), "\n") { + let span = self.next_span(pos); if let Some(snippet) = self.opt_snippet(self.next_span(pos)) { - if snippet.trim().is_empty() { - self.last_pos = pos; - } else { + if !snippet.trim().is_empty() { + return; + } + + if out_of_file_lines_range!(self, span) { return; } + self.last_pos = pos; } } } diff --git a/tests/source/issue-5136-1.rs b/tests/source/issue-5136-1.rs new file mode 100644 index 00000000000..75231555232 --- /dev/null +++ b/tests/source/issue-5136-1.rs @@ -0,0 +1,7 @@ + + +// Test that newlines at the top of this file are preserved when they're not +// in the --file-lines range. + +// This should prevent rustfmt from many any formatting changes at all: +// rustfmt-file_lines: [] diff --git a/tests/source/issue-5136-2.rs b/tests/source/issue-5136-2.rs new file mode 100644 index 00000000000..fe3cfcf37b8 --- /dev/null +++ b/tests/source/issue-5136-2.rs @@ -0,0 +1,5 @@ + use std; +// Test that whitespace at beginning of file is preserved when not in +// --file-lines range. +// This should prevent rustfmt from making any formatting changes at all: +// rustfmt-file_lines: [] diff --git a/tests/source/issue-5136-3.rs b/tests/source/issue-5136-3.rs new file mode 100644 index 00000000000..c152181bc2f --- /dev/null +++ b/tests/source/issue-5136-3.rs @@ -0,0 +1,6 @@ +// rustfmt-file_lines: [] +// Test that a missing newline at the end of the file is preserved when the last +// line is not in the --file-lines range. +// Important: When editing this file, make sure not to add a newline at the end +// of the last line. +use std; \ No newline at end of file diff --git a/tests/source/issue-5136-4.rs b/tests/source/issue-5136-4.rs new file mode 100644 index 00000000000..005167dff63 --- /dev/null +++ b/tests/source/issue-5136-4.rs @@ -0,0 +1,4 @@ +// rustfmt-file_lines: [] +// Test that a missing space at the end of a doc comment is preserved when the +// line is not in the --file-lines range. +//! diff --git a/tests/source/issue-5136-5.rs b/tests/source/issue-5136-5.rs new file mode 100644 index 00000000000..0f836aa989f --- /dev/null +++ b/tests/source/issue-5136-5.rs @@ -0,0 +1,6 @@ +// rustfmt-file_lines: [] +// Test that the space before the comment is not removed if the line is not +// contained in `--file-lines`. +// Note: It's important for the bug to repro that there is no newline at the +// end of the comment +fn f(){} // what \ No newline at end of file diff --git a/tests/target/issue-5136-1.rs b/tests/target/issue-5136-1.rs new file mode 100644 index 00000000000..75231555232 --- /dev/null +++ b/tests/target/issue-5136-1.rs @@ -0,0 +1,7 @@ + + +// Test that newlines at the top of this file are preserved when they're not +// in the --file-lines range. + +// This should prevent rustfmt from many any formatting changes at all: +// rustfmt-file_lines: [] diff --git a/tests/target/issue-5136-2.rs b/tests/target/issue-5136-2.rs new file mode 100644 index 00000000000..fe3cfcf37b8 --- /dev/null +++ b/tests/target/issue-5136-2.rs @@ -0,0 +1,5 @@ + use std; +// Test that whitespace at beginning of file is preserved when not in +// --file-lines range. +// This should prevent rustfmt from making any formatting changes at all: +// rustfmt-file_lines: [] diff --git a/tests/target/issue-5136-3.rs b/tests/target/issue-5136-3.rs new file mode 100644 index 00000000000..c152181bc2f --- /dev/null +++ b/tests/target/issue-5136-3.rs @@ -0,0 +1,6 @@ +// rustfmt-file_lines: [] +// Test that a missing newline at the end of the file is preserved when the last +// line is not in the --file-lines range. +// Important: When editing this file, make sure not to add a newline at the end +// of the last line. +use std; \ No newline at end of file diff --git a/tests/target/issue-5136-4.rs b/tests/target/issue-5136-4.rs new file mode 100644 index 00000000000..005167dff63 --- /dev/null +++ b/tests/target/issue-5136-4.rs @@ -0,0 +1,4 @@ +// rustfmt-file_lines: [] +// Test that a missing space at the end of a doc comment is preserved when the +// line is not in the --file-lines range. +//! diff --git a/tests/target/issue-5136-5.rs b/tests/target/issue-5136-5.rs new file mode 100644 index 00000000000..0f836aa989f --- /dev/null +++ b/tests/target/issue-5136-5.rs @@ -0,0 +1,6 @@ +// rustfmt-file_lines: [] +// Test that the space before the comment is not removed if the line is not +// contained in `--file-lines`. +// Note: It's important for the bug to repro that there is no newline at the +// end of the comment +fn f(){} // what \ No newline at end of file