Skip to content

Commit 80476f3

Browse files
committed
Fix panic in annotated_snippet dependency (#4968).
* Internally, rustfmt preserves tabs and counts them as multiple characters (based on configuration). * The annotated_snippet dependency always counts tabs as 1 character. * If rustfmt tries to display an error on a line containing tabs, the indicies are mismatched. * In the extreme case, annotated_snippet may try to access out-of-range indices, and panic. * This change is based on the code review by camsteffen on PR #5039 by karyon: have rustfmt internally replace tabs with the corresponding number of spaces, so that columns/indices in the buffer passed to annotated_snippet are counted (unambiguously and) the same.
1 parent 0439486 commit 80476f3

File tree

2 files changed

+15
-2
lines changed

2 files changed

+15
-2
lines changed

src/formatting.rs

+4-2
Original file line numberDiff line numberDiff line change
@@ -589,12 +589,14 @@ impl<'a> FormatLines<'a> {
589589
fn char(&mut self, c: char, kind: FullCodeCharKind) {
590590
self.newline_count = 0;
591591
self.line_len += if c == '\t' {
592+
self.line_buffer
593+
.push_str(&" ".repeat(self.config.tab_spaces()));
592594
self.config.tab_spaces()
593595
} else {
594-
1
596+
self.line_buffer.push(c);
597+
c.len_utf8()
595598
};
596599
self.last_was_space = c.is_whitespace();
597-
self.line_buffer.push(c);
598600
if kind.is_string() {
599601
self.current_line_contains_string_literal = true;
600602
}

tests/target/issue-4968.rs

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
// rustfmt-hard_tabs: true
2+
// rustfmt-max_width: 40
3+
// rustfmt-error_on_unformatted: true
4+
5+
fn foo(x: u32) {
6+
if x > 10 {
7+
if x > 20 {
8+
println!("0123456789abcdefghijklmnopqrstuvwxyz");
9+
}
10+
}
11+
}

0 commit comments

Comments
 (0)