From 75565ce13349bc2ef65111d586e19e4313c18fe9 Mon Sep 17 00:00:00 2001 From: Raekye Date: Sat, 30 Dec 2023 18:46:33 -0500 Subject: [PATCH] Test case that can validate fix for rust-lang#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. --- src/test/parser.rs | 19 +++++++++++++++++++ tests/parser/issue_4968.rs | 12 ++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 tests/parser/issue_4968.rs diff --git a/src/test/parser.rs b/src/test/parser.rs index d951c8469e6..a4ce27708a4 100644 --- a/src/test/parser.rs +++ b/src/test/parser.rs @@ -4,6 +4,7 @@ use std::path::PathBuf; use super::read_config; use crate::modules::{ModuleResolutionError, ModuleResolutionErrorKind}; +use crate::FormatReportFormatterBuilder; use crate::{ErrorKind, Input, Session}; #[test] @@ -69,3 +70,21 @@ fn crate_parsing_stashed_diag2() { let filename = "tests/parser/stashed-diag2.rs"; assert_parser_error(filename); } + +#[test] +fn indexing_mismatch_with_annotated_snippet() { + // See also https://github.com/rust-lang/rustfmt/issues/4968 + let filename = "tests/parser/issue_4968.rs"; + let file = PathBuf::from(filename); + let config = read_config(&file); + let mut session = Session::::new(config, None); + let report = session.format(Input::File(filename.into())).unwrap(); + let report = FormatReportFormatterBuilder::new(&report).build(); + { + // Panic can only be triggered if we actually try to write the report + // and call into the annotated_snippet dependency. + use std::io::Write; + + write!(&mut Vec::new(), "{report}").unwrap(); + } +} diff --git a/tests/parser/issue_4968.rs b/tests/parser/issue_4968.rs new file mode 100644 index 00000000000..eb0c65756ef --- /dev/null +++ b/tests/parser/issue_4968.rs @@ -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"); + } + } +}