From f41055266537a3dfa9ea22970df73403e618e963 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 10 Jun 2025 04:00:02 -0600 Subject: [PATCH 1/2] test: Add rustc test with empty source --- tests/rustc_tests.rs | 114 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/tests/rustc_tests.rs b/tests/rustc_tests.rs index 0a1c531..13924c8 100644 --- a/tests/rustc_tests.rs +++ b/tests/rustc_tests.rs @@ -2680,3 +2680,117 @@ LL | | */ let renderer = Renderer::plain().anonymized_line_numbers(true); assert_data_eq!(renderer.render(input), expected); } + +#[test] +#[should_panic(expected = "called `Option::unwrap()` on a `None` value")] +fn mismatched_types1() { + // tests/ui/include-macros/mismatched-types.rs + + let file_txt_source = r#""#; + + let rust_source = r#"fn main() { + let b: &[u8] = include_str!("file.txt"); //~ ERROR mismatched types + let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types +}"#; + + let input = Level::ERROR.header("mismatched types").id("E0308").group( + Group::new() + .element( + Snippet::source(file_txt_source) + .fold(true) + .line_start(3) + .origin("$DIR/file.txt") + .annotation( + AnnotationKind::Primary + .span(0..0) + .label("expected `&[u8]`, found `&str`"), + ), + ) + .element( + Snippet::source(rust_source) + .origin("$DIR/mismatched-types.rs") + .fold(true) + .annotation( + AnnotationKind::Context + .span(23..28) + .label("expected due to this"), + ) + .annotation( + AnnotationKind::Context + .span(31..55) + .label("in this macro invocation"), + ), + ) + .element( + Level::NOTE.title("expected reference `&[u8]`\n found reference `&'static str`"), + ), + ); + + let expected = str![[r#" +error[E0308]: mismatched types + --> $DIR/file.txt:3:1 + | +LL | + | ^ expected `&[u8]`, found `&str` + | + ::: $DIR/mismatched-types.rs:2:12 + | +LL | let b: &[u8] = include_str!("file.txt"); //~ ERROR mismatched types + | ----- ------------------------ in this macro invocation + | | + | expected due to this + | + = note: expected reference `&[u8]` + found reference `&'static str` +"#]]; + let renderer = Renderer::plain().anonymized_line_numbers(true); + assert_data_eq!(renderer.render(input), expected); +} + +#[test] +fn mismatched_types2() { + // tests/ui/include-macros/mismatched-types.rs + + let source = r#"fn main() { + let b: &[u8] = include_str!("file.txt"); //~ ERROR mismatched types + let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types +}"#; + + let input = Level::ERROR.header("mismatched types").id("E0308").group( + Group::new() + .element( + Snippet::source(source) + .origin("$DIR/mismatched-types.rs") + .fold(true) + .annotation( + AnnotationKind::Primary + .span(105..131) + .label("expected `&str`, found `&[u8; 0]`"), + ) + .annotation( + AnnotationKind::Context + .span(98..102) + .label("expected due to this"), + ), + ) + .element( + Level::NOTE + .title("expected reference `&str`\n found reference `&'static [u8; 0]`"), + ), + ); + + let expected = str![[r#" +error[E0308]: mismatched types + --> $DIR/mismatched-types.rs:3:19 + | +LL | let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types + | ---- ^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&str`, found `&[u8; 0]` + | | + | expected due to this + | + = note: expected reference `&str` + found reference `&'static [u8; 0]` +"#]]; + let renderer = Renderer::plain().anonymized_line_numbers(true); + assert_data_eq!(renderer.render(input), expected); +} From 23242144f51cc7902d6bcc5d69420600f9426459 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Wed, 4 Jun 2025 15:16:07 -0600 Subject: [PATCH 2/2] fix: Ensure empty sources have one "line" --- src/renderer/source_map.rs | 15 +++++++++++++++ tests/formatter.rs | 1 + tests/rustc_tests.rs | 1 - 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/renderer/source_map.rs b/src/renderer/source_map.rs index d5f91a1..7401fb9 100644 --- a/src/renderer/source_map.rs +++ b/src/renderer/source_map.rs @@ -11,6 +11,21 @@ pub(crate) struct SourceMap<'a> { impl<'a> SourceMap<'a> { pub(crate) fn new(source: &'a str, line_start: usize) -> Self { + // Empty sources do have a "line", but it is empty, so we need to add + // a line with an empty string to the source map. + if source.is_empty() { + return Self { + lines: vec![LineInfo { + line: "", + line_index: line_start, + start_byte: 0, + end_byte: 0, + end_line_size: 0, + }], + source, + }; + } + let mut current_index = 0; let mut mapping = vec![]; diff --git a/tests/formatter.rs b/tests/formatter.rs index e5647b8..61277ec 100644 --- a/tests/formatter.rs +++ b/tests/formatter.rs @@ -303,6 +303,7 @@ fn test_only_source() { error: --> file.rs | +1 | "#]]; let renderer = Renderer::plain(); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/rustc_tests.rs b/tests/rustc_tests.rs index 13924c8..b1505d7 100644 --- a/tests/rustc_tests.rs +++ b/tests/rustc_tests.rs @@ -2682,7 +2682,6 @@ LL | | */ } #[test] -#[should_panic(expected = "called `Option::unwrap()` on a `None` value")] fn mismatched_types1() { // tests/ui/include-macros/mismatched-types.rs