Skip to content

Commit 5e8ce93

Browse files
committed
Test case that can validate fix for #4968.
* With hard_tabs, rustfmt preserves tabs and counts them as multiple characters/columns (based on configuration). * The annotated_snippet dependency, used to display errors, always counts tabs as 1 character. * If rustfmt tries to report an error on a line containing tabs, the indices are mismatched. * annotated_snippet will display the wrong range of the source code slice; in the extreme case, it can panic with out-of-bounds access. * The test case added in this commit is expected to currently fail, since this commit doesn't include the fix.
1 parent fb50767 commit 5e8ce93

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

src/test/parser.rs

+19
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::path::PathBuf;
33

44
use super::read_config;
55

6+
use crate::FormatReportFormatterBuilder;
67
use crate::modules::{ModuleResolutionError, ModuleResolutionErrorKind};
78
use crate::{ErrorKind, Input, Session};
89

@@ -69,3 +70,21 @@ fn crate_parsing_stashed_diag2() {
6970
let filename = "tests/parser/stashed-diag2.rs";
7071
assert_parser_error(filename);
7172
}
73+
74+
#[test]
75+
fn indexing_mismatch_with_annotated_snippet() {
76+
// See also https://github.com/rust-lang/rustfmt/issues/4968
77+
let filename = "tests/parser/issue_4968.rs";
78+
let file = PathBuf::from(filename);
79+
let config = read_config(&file);
80+
let mut session = Session::<io::Stdout>::new(config, None);
81+
let report = session.format(Input::File(filename.into())).unwrap();
82+
let report = FormatReportFormatterBuilder::new(&report).build();
83+
{
84+
// Panic can only be triggered if we actually try to write the report
85+
// and call into the annotated_snippet dependency.
86+
use std::io::Write;
87+
88+
write!(&mut Vec::new(), "{report}").unwrap();
89+
}
90+
}

tests/parser/issue_4968.rs

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

0 commit comments

Comments
 (0)