diff --git a/crates/red_knot_test/src/parser.rs b/crates/red_knot_test/src/parser.rs index 2f5f3d5635..2a25efc48c 100644 --- a/crates/red_knot_test/src/parser.rs +++ b/crates/red_knot_test/src/parser.rs @@ -617,8 +617,9 @@ impl<'s> Parser<'s> { .extension() .is_none_or(|extension| extension.eq_ignore_ascii_case(expected_extension)) { + let backtick_start = self.line_index(backtick_offsets.0); bail!( - "File extension of test file path `{explicit_path}` in test `{test_name}` does not match language specified `{lang}` of code block" + "File extension of test file path `{explicit_path}` in test `{test_name}` does not match language specified `{lang}` of code block at line `{backtick_start}`" ); } } @@ -750,6 +751,10 @@ impl<'s> Parser<'s> { fn offset(&self) -> TextSize { self.source_len - self.cursor.text_len() } + + fn line_index(&self, char_index: TextSize) -> u32 { + self.source.count_lines(TextRange::up_to(char_index)) + } } #[cfg(test)] @@ -1221,7 +1226,7 @@ mod tests { let err = super::parse("file.md", &source).expect_err("Should fail to parse"); assert_eq!( err.to_string(), - "File extension of test file path `a.py` in test `Accidental stub` does not match language specified `pyi` of code block" + "File extension of test file path `a.py` in test `Accidental stub` does not match language specified `pyi` of code block at line `5`" ); }