Skip to content

Commit

Permalink
Fix panic in annotated_snippet dependency (#4968).
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
Raekye committed Dec 3, 2023
1 parent 37489e4 commit 82142db
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 2 deletions.
6 changes: 4 additions & 2 deletions src/formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -589,12 +589,14 @@ impl<'a> FormatLines<'a> {
fn char(&mut self, c: char, kind: FullCodeCharKind) {
self.newline_count = 0;
self.line_len += if c == '\t' {
self.line_buffer
.push_str(&" ".repeat(self.config.tab_spaces()));
self.config.tab_spaces()
} else {
1
self.line_buffer.push(c);
c.len_utf8()
};
self.last_was_space = c.is_whitespace();
self.line_buffer.push(c);
if kind.is_string() {
self.current_line_contains_string_literal = true;
}
Expand Down
12 changes: 12 additions & 0 deletions tests/target/issue-4968.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// rustfmt-hard_tabs: true
// rustfmt-max_width: 40
// rustfmt-error_on_unformatted: true
// rustfmt-error_on_line_overflow: true

fn foo(x: u32) {
if x > 10 {
if x > 20 {
println!("0123456789abcdefghijklmnopqrstuvwxyz");
}
}
}

0 comments on commit 82142db

Please sign in to comment.