From 1598c653a9993d07fd8bf902f9f5652784766c19 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Mon, 27 Oct 2025 19:25:51 -0600 Subject: [PATCH 1/3] test: Overflow when whitespace annotated small term width --- tests/rustc_tests.rs | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/tests/rustc_tests.rs b/tests/rustc_tests.rs index 298320f..d4b942b 100644 --- a/tests/rustc_tests.rs +++ b/tests/rustc_tests.rs @@ -5646,3 +5646,34 @@ LL │ static ROOK_ATTACKS_TABLE: () = { let renderer = renderer.decor_style(DecorStyle::Unicode); assert_data_eq!(renderer.render(input), expected_unicode); } + +#[test] +#[should_panic = "attempt to subtract with overflow"] +fn emitter_overflow_bad_whitespace() { + // tests/ui/errors/emitter-overflow-bad-whitespace.rs + let source = r#"                                        fn main() { return; } +"#; + let title_0 = "Unicode character ' ' (No-Break Space) looks like ' ' (Space), but it is not"; + + let report = &[ + Group::with_title(Level::ERROR.primary_title("unknown start of token: \u{a0}")).element( + Snippet::source(source) + .path("$DIR/emitter-overflow-bad-whitespace.rs") + .line_start(10) + .annotation(AnnotationKind::Primary.span(0..2)), + ), + Group::with_title(Level::HELP.secondary_title(title_0)).element( + Snippet::source(source) + .path("$DIR/emitter-overflow-bad-whitespace.rs") + .line_start(10) + .patch(Patch::new(0..2, " ")), + ), + ]; + let expected_ascii = str![[r#""#]]; + let renderer_ascii = Renderer::plain().term_width(1); + assert_data_eq!(renderer_ascii.render(report), expected_ascii); + + let expected_unicode = str![[r#""#]]; + let renderer_unicode = renderer_ascii.decor_style(DecorStyle::Unicode); + assert_data_eq!(renderer_unicode.render(report), expected_unicode); +} From 6d00258c62b1b225969180934feb202f04c158e6 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Mon, 27 Oct 2025 17:01:35 -0600 Subject: [PATCH 2/3] fix: Properly handle annotating leading whitespace --- src/renderer/margin.rs | 7 ++++++- tests/rustc_tests.rs | 27 ++++++++++++++++++++++++--- 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/src/renderer/margin.rs b/src/renderer/margin.rs index 6d3989b..4fb1e87 100644 --- a/src/renderer/margin.rs +++ b/src/renderer/margin.rs @@ -71,7 +71,12 @@ impl Margin { if self.computed_right - self.computed_left > self.term_width { // Trimming only whitespace isn't enough, let's get craftier. - if self.label_right - self.whitespace_left <= self.term_width { + if self.label_right.saturating_sub(self.whitespace_left) <= self.term_width + // Trimming whitespace when the right-most label is somewhrere + // within it would result in the label pointing to the wrong + // place + && self.label_right >= self.whitespace_left + { // Attempt to fit the code window only trimming whitespace. self.computed_left = self.whitespace_left; self.computed_right = self.computed_left + self.term_width; diff --git a/tests/rustc_tests.rs b/tests/rustc_tests.rs index d4b942b..4990a05 100644 --- a/tests/rustc_tests.rs +++ b/tests/rustc_tests.rs @@ -5648,7 +5648,6 @@ LL │ static ROOK_ATTACKS_TABLE: () = { } #[test] -#[should_panic = "attempt to subtract with overflow"] fn emitter_overflow_bad_whitespace() { // tests/ui/errors/emitter-overflow-bad-whitespace.rs let source = r#"                                        fn main() { return; } @@ -5669,11 +5668,33 @@ fn emitter_overflow_bad_whitespace() { .patch(Patch::new(0..2, " ")), ), ]; - let expected_ascii = str![[r#""#]]; + let expected_ascii = str![[r#" +error: unknown start of token:   + --> $DIR/emitter-overflow-bad-whitespace.rs:10:1 + | +10 |     ... + | ^ + | +help: Unicode character ' ' (No-Break Space) looks like ' ' (Space), but it is not + | +10 |                                       fn main() { return; } + | + +"#]]; let renderer_ascii = Renderer::plain().term_width(1); assert_data_eq!(renderer_ascii.render(report), expected_ascii); - let expected_unicode = str![[r#""#]]; + let expected_unicode = str![[r#" +error: unknown start of token:   + ╭▸ $DIR/emitter-overflow-bad-whitespace.rs:10:1 + │ +10 │       … + │ ━ + ╰╴ +help: Unicode character ' ' (No-Break Space) looks like ' ' (Space), but it is not + ╭╴ +10 │                                       fn main() { return; } + ╰╴+ +"#]]; let renderer_unicode = renderer_ascii.decor_style(DecorStyle::Unicode); assert_data_eq!(renderer_unicode.render(report), expected_unicode); } From 7d7322a747a7dd663bc1fe60b260d60e2cdf384a Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Mon, 27 Oct 2025 20:59:43 -0600 Subject: [PATCH 3/3] chore: Remove misleading comment --- src/renderer/render.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/renderer/render.rs b/src/renderer/render.rs index 03c7005..939ae75 100644 --- a/src/renderer/render.rs +++ b/src/renderer/render.rs @@ -622,11 +622,6 @@ fn render_snippet_annotations( // Get the left-side margin to remove it let mut whitespace_margin = usize::MAX; for line_info in annotated_lines { - // Whitespace can only be removed (aka considered leading) - // if the lexer considers it whitespace. - // non-rustc_lexer::is_whitespace() chars are reported as an - // error (ex. no-break-spaces \u{a0}), and thus can't be considered - // for removal during error reporting. let leading_whitespace = line_info .line .chars()