From 7a77fce612eecced766a905074ed5bd0c33e6c49 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 3 Jun 2025 09:45:06 -0600 Subject: [PATCH 1/2] test: Add rustc tests for annotation sorting --- tests/rustc_tests.rs | 212 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/tests/rustc_tests.rs b/tests/rustc_tests.rs index 4979e77..ec8ee7f 100644 --- a/tests/rustc_tests.rs +++ b/tests/rustc_tests.rs @@ -2466,3 +2466,215 @@ LL | ----cargo let renderer = Renderer::plain().anonymized_line_numbers(true); assert_data_eq!(renderer.render(input), expected); } + +#[test] +fn pat_tuple_field_count_cross() { + // tests/ui/pattern/pat-tuple-field-count-cross.stderr + + let source = r#"//@ aux-build:declarations-for-tuple-field-count-errors.rs + +extern crate declarations_for_tuple_field_count_errors; + +use declarations_for_tuple_field_count_errors::*; + +fn main() { + match Z0 { + Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0` + Z0(x) => {} //~ ERROR expected tuple struct or tuple variant, found unit struct `Z0` + } + match Z1() { + Z1 => {} //~ ERROR match bindings cannot shadow tuple structs + Z1(x) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 0 fields + } + + match S(1, 2, 3) { + S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple struct has 3 fields + S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 3 fields + S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple struct has 3 fields + S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields + } + match M(1, 2, 3) { + M() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple struct has 3 fields + M(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple struct has 3 fields + M(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple struct has 3 fields + M(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple struct has 3 fields + } + + match E1::Z0 { + E1::Z0() => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0` + E1::Z0(x) => {} //~ ERROR expected tuple struct or tuple variant, found unit variant `E1::Z0` + } + match E1::Z1() { + E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1` + E1::Z1(x) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 0 fields + } + match E1::S(1, 2, 3) { + E1::S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields + E1::S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields + E1::S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields + E1::S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields + } + + match E2::S(1, 2, 3) { + E2::S() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields + E2::S(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields + E2::S(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields + E2::S(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields + } + match E2::M(1, 2, 3) { + E2::M() => {} //~ ERROR this pattern has 0 fields, but the corresponding tuple variant has 3 fields + E2::M(1) => {} //~ ERROR this pattern has 1 field, but the corresponding tuple variant has 3 fields + E2::M(xyz, abc) => {} //~ ERROR this pattern has 2 fields, but the corresponding tuple variant has 3 fields + E2::M(1, 2, 3, 4) => {} //~ ERROR this pattern has 4 fields, but the corresponding tuple variant has 3 fields + } +} +"#; + let source1 = r#"pub struct Z0; +pub struct Z1(); + +pub struct S(pub u8, pub u8, pub u8); +pub struct M( + pub u8, + pub u8, + pub u8, +); + +pub enum E1 { Z0, Z1(), S(u8, u8, u8) } + +pub enum E2 { + S(u8, u8, u8), + M( + u8, + u8, + u8, + ), +} +"#; + + let input = Level::ERROR + .header("expected unit struct, unit variant or constant, found tuple variant `E1::Z1`") + .id(r#"E0532"#) + .group( + Group::new() + .element( + Snippet::source(source) + .origin("$DIR/pat-tuple-field-count-cross.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(1760..1766)), + ) + .element( + Snippet::source(source1) + .origin("$DIR/auxiliary/declarations-for-tuple-field-count-errors.rs") + .fold(true) + .annotation( + AnnotationKind::Context + .span(143..145) + .label("`E1::Z1` defined here"), + ) + .annotation( + AnnotationKind::Context + .span(139..141) + .label("similarly named unit variant `Z0` defined here"), + ), + ), + ) + .group( + Group::new() + .element(Level::HELP.title("use the tuple variant pattern syntax instead")) + .element( + Snippet::source(source) + .origin("$DIR/pat-tuple-field-count-cross.rs") + .fold(true) + .patch(Patch::new(1760..1766, r#"E1::Z1()"#)), + ), + ) + .group( + Group::new() + .element(Level::HELP.title("a unit variant with a similar name exists")) + .element( + Snippet::source(source) + .origin("$DIR/pat-tuple-field-count-cross.rs") + .fold(true) + .patch(Patch::new(1764..1766, r#"Z0"#)), + ), + ); + let expected = str![[r#" +error[E0532]: expected unit struct, unit variant or constant, found tuple variant `E1::Z1` + --> $DIR/pat-tuple-field-count-cross.rs:35:9 + | +LL | E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1` + | ^^^^^^ + | + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:15 + | +LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } + | -- -- `E1::Z1` defined here + | | + | similarly named unit variant `Z0` defined here + | +help: use the tuple variant pattern syntax instead + | +LL | E1::Z1() => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1` + | ++ +help: a unit variant with a similar name exists + | +LL - E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1` +LL + E1::Z0 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1` + | +"#]]; + let renderer = Renderer::plain().anonymized_line_numbers(true); + assert_data_eq!(renderer.render(input), expected); +} + +#[test] +fn unterminated_nested_comment() { + // tests/ui/lexer/unterminated-nested-comment.rs + + let source = r#"/* //~ ERROR E0758 +/* */ +/* +*/ +"#; + + let input = Level::ERROR.header("unterminated block comment").id("E0758").group( + Group::new().element( + Snippet::source(source) + .origin("$DIR/unterminated-nested-comment.rs") + .fold(true) + .annotation( + AnnotationKind::Context + .span(0..2) + .label("unterminated block comment"), + ) + .annotation(AnnotationKind::Context.span(25..27).label( + "...as last nested comment starts here, maybe you want to close this instead?", + )) + .annotation( + AnnotationKind::Context + .span(28..30) + .label("...and last nested comment terminates here."), + ) + .annotation(AnnotationKind::Primary.span(0..31)), + ), + ); + + let expected = str![[r#" +error[E0758]: unterminated block comment + --> $DIR/unterminated-nested-comment.rs:1:1 + | +LL | /* //~ ERROR E0758 + | ^- + | | + | _unterminated block comment + | | +LL | | /* */ +LL | | /* + | | -- ...as last nested comment starts here, maybe you want to close this instead? +LL | | */ + | |_--^ + | | + | ...and last nested comment terminates here. +"#]]; + let renderer = Renderer::plain().anonymized_line_numbers(true); + assert_data_eq!(renderer.render(input), expected); +} From 0c8bb3717a24627fd6576acd56757996074dc098 Mon Sep 17 00:00:00 2001 From: Scott Schafer Date: Tue, 3 Jun 2025 09:45:06 -0600 Subject: [PATCH 2/2] fix: Remove unneeded annotation sorting --- src/renderer/mod.rs | 3 +-- src/renderer/source_map.rs | 4 ---- tests/rustc_tests.rs | 6 ++++-- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index ab791ed..590c83d 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -695,8 +695,7 @@ impl Renderer { if let Some(first_annotation) = primary_line .annotations .iter() - .find(|a| a.is_primary()) - .or(primary_line.annotations.first()) + .min_by_key(|a| (Reverse(a.is_primary()), a.start.char)) { origin.char_column = Some(first_annotation.start.char + 1); } diff --git a/src/renderer/source_map.rs b/src/renderer/source_map.rs index 403c1c6..d5f91a1 100644 --- a/src/renderer/source_map.rs +++ b/src/renderer/source_map.rs @@ -293,10 +293,6 @@ impl<'a> SourceMap<'a> { annotated_line_infos.retain(|l| !l.annotations.is_empty()); } - for l in annotated_line_infos.iter_mut() { - l.annotations.sort_by(|a, b| a.start.cmp(&b.start)); - } - (max_depth, annotated_line_infos) } diff --git a/tests/rustc_tests.rs b/tests/rustc_tests.rs index ec8ee7f..eec19e5 100644 --- a/tests/rustc_tests.rs +++ b/tests/rustc_tests.rs @@ -2605,7 +2605,7 @@ error[E0532]: expected unit struct, unit variant or constant, found tuple varian LL | E1::Z1 => {} //~ ERROR expected unit struct, unit variant or constant, found tuple variant `E1::Z1` | ^^^^^^ | - ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:15 + ::: $DIR/auxiliary/declarations-for-tuple-field-count-errors.rs:11:19 | LL | pub enum E1 { Z0, Z1(), S(u8, u8, u8) } | -- -- `E1::Z1` defined here @@ -2669,7 +2669,9 @@ LL | /* //~ ERROR E0758 | | LL | | /* */ LL | | /* - | | -- ...as last nested comment starts here, maybe you want to close this instead? + | | -- + | | | + | | ...as last nested comment starts here, maybe you want to close this instead? LL | | */ | |_--^ | |