From 49322a7599e21ce5b7b251eff2a297ff522eefa8 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 1 Jul 2025 16:23:45 -0500 Subject: [PATCH] fix: Force group levels to be explicitly given Moved from `Group::new().primary_level(level)` to `Group::with_level(level)`. As a convenience for titled-groups, we have `Group::with_title(title)`. I had considered `child`/`children` methods on `Title` to make a group but that didn't work out well for title-only groups and I feel like this design is more consistent / easier to discover. --- benches/bench.rs | 16 +- examples/custom_error.rs | 33 +- examples/custom_level.rs | 68 +- examples/elide_header.rs | 3 +- examples/expected_type.rs | 8 +- examples/footer.rs | 15 +- examples/format.rs | 8 +- examples/highlight_source.rs | 2 +- examples/highlight_title.rs | 19 +- examples/id_hyperlink.rs | 45 +- examples/multislice.rs | 3 +- src/renderer/mod.rs | 44 +- src/snippet.rs | 28 +- tests/color/ann_eof.rs | 8 +- tests/color/ann_insertion.rs | 8 +- tests/color/ann_multiline.rs | 33 +- tests/color/ann_multiline2.rs | 8 +- tests/color/ann_removed_nl.rs | 8 +- tests/color/ensure_emoji_highlight_width.rs | 3 +- tests/color/fold_ann_multiline.rs | 8 +- tests/color/fold_bad_origin_line.rs | 2 +- tests/color/fold_leading.rs | 25 +- tests/color/fold_trailing.rs | 25 +- tests/color/issue_9.rs | 2 +- tests/color/multiline_removal_suggestion.rs | 8 +- tests/color/multiple_annotations.rs | 2 +- tests/color/simple.rs | 35 +- tests/color/strip_line.rs | 8 +- tests/color/strip_line_char.rs | 8 +- tests/color/strip_line_non_ws.rs | 8 +- tests/formatter.rs | 788 +++++++++-------- tests/rustc_tests.rs | 896 ++++++++++---------- 32 files changed, 1038 insertions(+), 1137 deletions(-) diff --git a/benches/bench.rs b/benches/bench.rs index 6390628f..4e03ae8c 100644 --- a/benches/bench.rs +++ b/benches/bench.rs @@ -24,9 +24,8 @@ fn simple() -> String { _ => continue, } }"#; - let message = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( + let message = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element( Snippet::source(source) .line_start(51) .path("src/format.rs") @@ -40,7 +39,8 @@ fn simple() -> String { .span(26..724) .label("expected enum `std::option::Option`"), ), - )]; + ), + ]; let renderer = Renderer::plain(); let rendered = renderer.render(message); @@ -69,9 +69,8 @@ fn fold(bencher: divan::Bencher<'_, '_>, context: usize) { (input, span) }) .bench_values(|(input, span)| { - let message = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( + let message = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element( Snippet::source(&input) .fold(true) .path("src/format.rs") @@ -80,7 +79,8 @@ fn fold(bencher: divan::Bencher<'_, '_>, context: usize) { .span(span) .label("expected `Option` because of return type"), ), - )]; + ), + ]; let renderer = Renderer::plain(); let rendered = renderer.render(message); diff --git a/examples/custom_error.rs b/examples/custom_error.rs index e80b1466..a26dc4af 100644 --- a/examples/custom_error.rs +++ b/examples/custom_error.rs @@ -15,23 +15,22 @@ fn main() { pub static C: u32 = 0 - 1; //~^ ERROR could not evaluate static initializer "#; - let message = &[Group::new() - .element( - Level::ERROR - .text(Some("error: internal compiler error")) - .title("could not evaluate static initializer") - .id("E0080"), - ) - .element( - Snippet::source(source) - .path("$DIR/err.rs") - .fold(true) - .annotation( - AnnotationKind::Primary - .span(386..391) - .label("attempt to compute `0_u32 - 1_u32`, which would overflow"), - ), - )]; + let message = &[Group::with_title( + Level::ERROR + .text(Some("error: internal compiler error")) + .title("could not evaluate static initializer") + .id("E0080"), + ) + .element( + Snippet::source(source) + .path("$DIR/err.rs") + .fold(true) + .annotation( + AnnotationKind::Primary + .span(386..391) + .label("attempt to compute `0_u32 - 1_u32`, which would overflow"), + ), + )]; let renderer = Renderer::styled().theme(OutputTheme::Unicode); anstream::println!("{}", renderer.render(message)); diff --git a/examples/custom_level.rs b/examples/custom_level.rs index b500c063..3cf475d0 100644 --- a/examples/custom_level.rs +++ b/examples/custom_level.rs @@ -30,41 +30,39 @@ fn main() { } "#; let message = &[ - Group::new() - .element( - Level::ERROR - .title("`break` with value from a `while` loop") - .id("E0571"), - ) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/issue-114529-illegal-break-with-value.rs") - .fold(true) - .annotation( - AnnotationKind::Primary - .span(483..581) - .label("can only break with a value inside `loop` or breakable block"), - ) - .annotation( - AnnotationKind::Context - .span(462..472) - .label("you can't `break` with a value in a `while` loop"), - ), - ), - Group::new() - .element( - Level::HELP - .text(Some("suggestion")) - .title("use `break` on its own without a value inside this `while` loop"), - ) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/issue-114529-illegal-break-with-value.rs") - .fold(true) - .patch(Patch::new(483..581, "break")), - ), + Group::with_title( + Level::ERROR + .title("`break` with value from a `while` loop") + .id("E0571"), + ) + .element( + Snippet::source(source) + .line_start(1) + .path("$DIR/issue-114529-illegal-break-with-value.rs") + .fold(true) + .annotation( + AnnotationKind::Primary + .span(483..581) + .label("can only break with a value inside `loop` or breakable block"), + ) + .annotation( + AnnotationKind::Context + .span(462..472) + .label("you can't `break` with a value in a `while` loop"), + ), + ), + Group::with_title( + Level::HELP + .text(Some("suggestion")) + .title("use `break` on its own without a value inside this `while` loop"), + ) + .element( + Snippet::source(source) + .line_start(1) + .path("$DIR/issue-114529-illegal-break-with-value.rs") + .fold(true) + .patch(Patch::new(483..581, "break")), + ), ]; let renderer = Renderer::styled().theme(OutputTheme::Unicode); diff --git a/examples/elide_header.rs b/examples/elide_header.rs index a280616c..436bb25e 100644 --- a/examples/elide_header.rs +++ b/examples/elide_header.rs @@ -8,8 +8,7 @@ def foobar(door, bar={}): """ "#; - let message = &[Group::new() - .primary_level(Level::NOTE) + let message = &[Group::with_level(Level::NOTE) .element( Snippet::source(source) .fold(false) diff --git a/examples/expected_type.rs b/examples/expected_type.rs index 0fce9938..6bbf0812 100644 --- a/examples/expected_type.rs +++ b/examples/expected_type.rs @@ -6,9 +6,8 @@ fn main() { , range: <22, 25>,"#; let message = - &[Group::new() - .element(Level::ERROR.title("expected type, found `22`")) - .element( + &[ + Group::with_title(Level::ERROR.title("expected type, found `22`")).element( Snippet::source(source) .line_start(26) .path("examples/footer.rs") @@ -21,7 +20,8 @@ fn main() { .span(34..50) .label("while parsing this struct"), ), - )]; + ), + ]; let renderer = Renderer::styled(); anstream::println!("{}", renderer.render(message)); diff --git a/examples/footer.rs b/examples/footer.rs index aa9b784f..e9d6b7ee 100644 --- a/examples/footer.rs +++ b/examples/footer.rs @@ -1,10 +1,9 @@ use annotate_snippets::{AnnotationKind, Group, Level, Renderer, Snippet}; fn main() { - let message = &[ - Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( + let message = + &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element( Snippet::source(" slices: vec![\"A\",") .line_start(13) .path("src/multislice.rs") @@ -12,10 +11,10 @@ fn main() { "expected struct `annotate_snippets::snippet::Slice`, found reference", )), ), - Group::new().element(Level::NOTE.title( - "expected type: `snippet::Annotation`\n found type: `__&__snippet::Annotation`", - )), - ]; + Group::with_title(Level::NOTE.title( + "expected type: `snippet::Annotation`\n found type: `__&__snippet::Annotation`", + )), + ]; let renderer = Renderer::styled(); anstream::println!("{}", renderer.render(message)); diff --git a/examples/format.rs b/examples/format.rs index ae603259..384453b2 100644 --- a/examples/format.rs +++ b/examples/format.rs @@ -23,9 +23,8 @@ fn main() { _ => continue, } }"#; - let message = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( + let message = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element( Snippet::source(source) .line_start(51) .path("src/format.rs") @@ -39,7 +38,8 @@ fn main() { .span(26..724) .label("expected enum `std::option::Option`"), ), - )]; + ), + ]; let renderer = Renderer::styled(); anstream::println!("{}", renderer.render(message)); diff --git a/examples/highlight_source.rs b/examples/highlight_source.rs index f897a3f5..297ad871 100644 --- a/examples/highlight_source.rs +++ b/examples/highlight_source.rs @@ -9,7 +9,7 @@ const CON: Vec = vec![1, 2, 3]; //~ ERROR E0010 //~| ERROR cannot call non-const method fn main() {} "#; - let message = &[Group::new().element(Level::ERROR.title("allocations are not allowed in constants") + let message = &[Group::with_title(Level::ERROR.title("allocations are not allowed in constants") .id("E0010")) .element( Snippet::source(source) diff --git a/examples/highlight_title.rs b/examples/highlight_title.rs index 6ed3817f..7f6ccb77 100644 --- a/examples/highlight_title.rs +++ b/examples/highlight_title.rs @@ -42,8 +42,7 @@ fn main() { ); let message = &[ - Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")) .element( Snippet::source(source) .fold(true) @@ -60,15 +59,13 @@ fn main() { ), ) .element(Level::NOTE.pre_styled_title(&title)), - Group::new() - .element(Level::NOTE.title("function defined here")) - .element( - Snippet::source(source) - .fold(true) - .path("$DIR/highlighting.rs") - .annotation(AnnotationKind::Context.span(200..333).label("")) - .annotation(AnnotationKind::Primary.span(194..199)), - ), + Group::with_title(Level::NOTE.title("function defined here")).element( + Snippet::source(source) + .fold(true) + .path("$DIR/highlighting.rs") + .annotation(AnnotationKind::Context.span(200..333).label("")) + .annotation(AnnotationKind::Primary.span(194..199)), + ), ]; let renderer = Renderer::styled().anonymized_line_numbers(true); diff --git a/examples/id_hyperlink.rs b/examples/id_hyperlink.rs index 2d49b275..6259e4d1 100644 --- a/examples/id_hyperlink.rs +++ b/examples/id_hyperlink.rs @@ -7,29 +7,28 @@ fn main() { let () = 4; //~ ERROR } "#; - let message = &[Group::new() - .element( - Level::ERROR - .title("mismatched types") - .id("E0308") - .id_url("https://doc.rust-lang.org/error_codes/E0308.html"), - ) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/terminal_urls.rs") - .fold(true) - .annotation( - AnnotationKind::Primary - .span(59..61) - .label("expected integer, found `()`"), - ) - .annotation( - AnnotationKind::Context - .span(64..65) - .label("this expression has type `{integer}`"), - ), - )]; + let message = &[Group::with_title( + Level::ERROR + .title("mismatched types") + .id("E0308") + .id_url("https://doc.rust-lang.org/error_codes/E0308.html"), + ) + .element( + Snippet::source(source) + .line_start(1) + .path("$DIR/terminal_urls.rs") + .fold(true) + .annotation( + AnnotationKind::Primary + .span(59..61) + .label("expected integer, found `()`"), + ) + .annotation( + AnnotationKind::Context + .span(64..65) + .label("this expression has type `{integer}`"), + ), + )]; let renderer = Renderer::styled().theme(OutputTheme::Unicode); anstream::println!("{}", renderer.render(message)); diff --git a/examples/multislice.rs b/examples/multislice.rs index 9393aadb..35b745c1 100644 --- a/examples/multislice.rs +++ b/examples/multislice.rs @@ -1,8 +1,7 @@ use annotate_snippets::{Annotation, Group, Level, Renderer, Snippet}; fn main() { - let message = &[Group::new() - .element(Level::ERROR.title("mismatched types")) + let message = &[Group::with_title(Level::ERROR.title("mismatched types")) .element( Snippet::>::source("Foo") .line_start(51) diff --git a/src/renderer/mod.rs b/src/renderer/mod.rs index 9d89026c..fe29822f 100644 --- a/src/renderer/mod.rs +++ b/src/renderer/mod.rs @@ -20,23 +20,22 @@ //! "#; //! //! -//! Group::new() -//! .element( -//! Level::ERROR -//! .title("unresolved import `baz::zed`") -//! .id("E0432") -//! ) -//! .element( -//! Snippet::source(source) -//! .path("temp.rs") -//! .line_start(1) -//! .fold(true) -//! .annotation( -//! AnnotationKind::Primary -//! .span(10..13) -//! .label("could not find `zed` in `baz`"), -//! ) -//! ); +//! Group::with_title( +//! Level::ERROR +//! .title("unresolved import `baz::zed`") +//! .id("E0432") +//! ) +//! .element( +//! Snippet::source(source) +//! .path("temp.rs") +//! .line_start(1) +//! .fold(true) +//! .annotation( +//! AnnotationKind::Primary +//! .span(10..13) +//! .label("could not find `zed` in `baz`"), +//! ) +//! ); //! ``` mod margin; @@ -275,16 +274,7 @@ impl Renderer { if og_primary_path.is_none() && primary_path.is_some() { og_primary_path = primary_path; } - let level = group.primary_level.clone().unwrap_or_else(|| { - group - .elements - .first() - .and_then(|s| match &s { - Element::Title(title) => Some(title.level.clone()), - _ => None, - }) - .unwrap_or(Level::ERROR) - }); + let level = group.primary_level.clone(); let mut source_map_annotated_lines = VecDeque::new(); let mut max_depth = 0; for e in &group.elements { diff --git a/src/snippet.rs b/src/snippet.rs index 8206f600..3045b2a7 100644 --- a/src/snippet.rs +++ b/src/snippet.rs @@ -20,20 +20,21 @@ pub(crate) struct Id<'a> { /// An [`Element`] container #[derive(Clone, Debug)] pub struct Group<'a> { - pub(crate) primary_level: Option>, + pub(crate) primary_level: Level<'a>, pub(crate) elements: Vec>, } -impl Default for Group<'_> { - fn default() -> Self { - Self::new() +impl<'a> Group<'a> { + /// Create group with a title, deriving the primary [`Level`] for [`Annotation`]s from it + pub fn with_title(title: Title<'a>) -> Self { + let level = title.level.clone(); + Self::with_level(level).element(title) } -} -impl<'a> Group<'a> { - pub fn new() -> Self { + /// Create a title-less group with a primary [`Level`] for [`Annotation`]s + pub fn with_level(level: Level<'a>) -> Self { Self { - primary_level: None, + primary_level: level, elements: vec![], } } @@ -48,15 +49,6 @@ impl<'a> Group<'a> { self } - /// Set the primary [`Level`] for this [`Group`]. - /// - /// If not specified, use the [`Level`] of the first element in a [`Group`] - /// if it is a [`Title`]. If not it will default to [`Level::ERROR`]. - pub fn primary_level(mut self, level: Level<'a>) -> Self { - self.primary_level = Some(level); - self - } - pub fn is_empty(&self) -> bool { self.elements.is_empty() } @@ -277,7 +269,7 @@ impl<'a> Annotation<'a> { pub enum AnnotationKind { /// Match the primary [`Level`] of the group. /// - /// See [`Group::primary_level`] for details about how this is determined + /// See [`Group::with_level`] for details about how this is determined Primary, /// Additional context to explain the [`Primary`][Self::Primary] /// [`Annotation`] diff --git a/tests/color/ann_eof.rs b/tests/color/ann_eof.rs index e550ba55..d188fd1a 100644 --- a/tests/color/ann_eof.rs +++ b/tests/color/ann_eof.rs @@ -4,14 +4,14 @@ use snapbox::{assert_data_eq, file}; #[test] fn case() { - let input = &[Group::new() - .element(Level::ERROR.title("expected `.`, `=`")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("expected `.`, `=`")).element( Snippet::source("asdf") .path("Cargo.toml") .line_start(1) .annotation(AnnotationKind::Primary.span(4..4).label("")), - )]; + ), + ]; let expected = file!["ann_eof.term.svg"]; let renderer = Renderer::styled(); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/color/ann_insertion.rs b/tests/color/ann_insertion.rs index 73dd7d80..a0748e59 100644 --- a/tests/color/ann_insertion.rs +++ b/tests/color/ann_insertion.rs @@ -4,14 +4,14 @@ use snapbox::{assert_data_eq, file}; #[test] fn case() { - let input = &[Group::new() - .element(Level::ERROR.title("expected `.`, `=`")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("expected `.`, `=`")).element( Snippet::source("asf") .path("Cargo.toml") .line_start(1) .annotation(AnnotationKind::Primary.span(2..2).label("'d' belongs here")), - )]; + ), + ]; let expected = file!["ann_insertion.term.svg"]; let renderer = Renderer::styled(); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/color/ann_multiline.rs b/tests/color/ann_multiline.rs index 29d4c309..1801c3bc 100644 --- a/tests/color/ann_multiline.rs +++ b/tests/color/ann_multiline.rs @@ -9,23 +9,22 @@ fn case() { } = body[body_idx] "#; - let input = &[Group::new() - .element( - Level::ERROR - .title("pattern does not mention fields `lineno`, `content`") - .id("E0027"), - ) - .element( - Snippet::source(source) - .path("src/display_list.rs") - .line_start(139) - .fold(false) - .annotation( - AnnotationKind::Primary - .span(31..128) - .label("missing fields `lineno`, `content`"), - ), - )]; + let input = &[Group::with_title( + Level::ERROR + .title("pattern does not mention fields `lineno`, `content`") + .id("E0027"), + ) + .element( + Snippet::source(source) + .path("src/display_list.rs") + .line_start(139) + .fold(false) + .annotation( + AnnotationKind::Primary + .span(31..128) + .label("missing fields `lineno`, `content`"), + ), + )]; let expected = file!["ann_multiline.term.svg"]; let renderer = Renderer::styled(); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/color/ann_multiline2.rs b/tests/color/ann_multiline2.rs index cf21e5ea..b8fa6152 100644 --- a/tests/color/ann_multiline2.rs +++ b/tests/color/ann_multiline2.rs @@ -9,9 +9,8 @@ of an edge case of an annotation overflowing to exactly one character on next line. "#; - let input = &[Group::new() - .element(Level::ERROR.title("spacing error found").id("E####")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("spacing error found").id("E####")).element( Snippet::source(source) .path("foo.txt") .line_start(26) @@ -21,7 +20,8 @@ to exactly one character on next line. .span(11..19) .label("this should not be on separate lines"), ), - )]; + ), + ]; let expected = file!["ann_multiline2.term.svg"]; let renderer = Renderer::styled(); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/color/ann_removed_nl.rs b/tests/color/ann_removed_nl.rs index 68ec8326..e13b4bd5 100644 --- a/tests/color/ann_removed_nl.rs +++ b/tests/color/ann_removed_nl.rs @@ -4,14 +4,14 @@ use snapbox::{assert_data_eq, file}; #[test] fn case() { - let input = &[Group::new() - .element(Level::ERROR.title("expected `.`, `=`")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("expected `.`, `=`")).element( Snippet::source("asdf") .path("Cargo.toml") .line_start(1) .annotation(AnnotationKind::Primary.span(4..5).label("")), - )]; + ), + ]; let expected = file!["ann_removed_nl.term.svg"]; let renderer = Renderer::styled(); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/color/ensure_emoji_highlight_width.rs b/tests/color/ensure_emoji_highlight_width.rs index bc22f9ab..c454e238 100644 --- a/tests/color/ensure_emoji_highlight_width.rs +++ b/tests/color/ensure_emoji_highlight_width.rs @@ -7,8 +7,7 @@ fn case() { let source = r#""haha this isn't a valid name 🐛" = { package = "libc", version = "0.1" } "#; - let input = &[Group::new() - .element(Level::ERROR.title("invalid character ` ` in package name: `haha this isn't a valid name 🐛`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters)")) + let input = &[Group::with_title(Level::ERROR.title("invalid character ` ` in package name: `haha this isn't a valid name 🐛`, characters must be Unicode XID characters (numbers, `-`, `_`, or most letters)")) .element( Snippet::source(source) .path("") diff --git a/tests/color/fold_ann_multiline.rs b/tests/color/fold_ann_multiline.rs index 1c035f41..68fd4f1b 100644 --- a/tests/color/fold_ann_multiline.rs +++ b/tests/color/fold_ann_multiline.rs @@ -28,9 +28,8 @@ fn case() { } "#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element( Snippet::source(source) .path("src/format.rs") .line_start(51) @@ -43,7 +42,8 @@ fn case() { .span(22..766) .label("expected enum `std::option::Option`, found ()"), ), - )]; + ), + ]; let expected = file!["fold_ann_multiline.term.svg"]; let renderer = Renderer::styled(); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/color/fold_bad_origin_line.rs b/tests/color/fold_bad_origin_line.rs index 9e4c5c0c..99da3c5d 100644 --- a/tests/color/fold_bad_origin_line.rs +++ b/tests/color/fold_bad_origin_line.rs @@ -9,7 +9,7 @@ fn case() { invalid syntax "#; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("path/to/error.rs") .line_start(1) diff --git a/tests/color/fold_leading.rs b/tests/color/fold_leading.rs index 0e4ae61d..e941c805 100644 --- a/tests/color/fold_leading.rs +++ b/tests/color/fold_leading.rs @@ -17,19 +17,18 @@ edition = "2021" workspace = 20 "#; - let input = &[Group::new() - .element( - Level::ERROR - .title("invalid type: integer `20`, expected a bool") - .id("E0308"), - ) - .element( - Snippet::source(source) - .path("Cargo.toml") - .line_start(1) - .fold(true) - .annotation(AnnotationKind::Primary.span(132..134).label("")), - )]; + let input = &[Group::with_title( + Level::ERROR + .title("invalid type: integer `20`, expected a bool") + .id("E0308"), + ) + .element( + Snippet::source(source) + .path("Cargo.toml") + .line_start(1) + .fold(true) + .annotation(AnnotationKind::Primary.span(132..134).label("")), + )]; let expected = file!["fold_leading.term.svg"]; let renderer = Renderer::styled(); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/color/fold_trailing.rs b/tests/color/fold_trailing.rs index 6421dd45..9c85d873 100644 --- a/tests/color/fold_trailing.rs +++ b/tests/color/fold_trailing.rs @@ -16,19 +16,18 @@ rust-version = "1.70" edition = "2021" "#; - let input = &[Group::new() - .element( - Level::ERROR - .title("invalid type: integer `20`, expected a lints table") - .id("E0308"), - ) - .element( - Snippet::source(source) - .path("Cargo.toml") - .line_start(1) - .fold(true) - .annotation(AnnotationKind::Primary.span(8..10).label("")), - )]; + let input = &[Group::with_title( + Level::ERROR + .title("invalid type: integer `20`, expected a lints table") + .id("E0308"), + ) + .element( + Snippet::source(source) + .path("Cargo.toml") + .line_start(1) + .fold(true) + .annotation(AnnotationKind::Primary.span(8..10).label("")), + )]; let expected = file!["fold_trailing.term.svg"]; let renderer = Renderer::styled(); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/color/issue_9.rs b/tests/color/issue_9.rs index f42c30b9..0ac5d4de 100644 --- a/tests/color/issue_9.rs +++ b/tests/color/issue_9.rs @@ -4,7 +4,7 @@ use snapbox::{assert_data_eq, file}; #[test] fn case() { - let input = &[Group::new().element(Level::ERROR.title("expected one of `.`, `;`, `?`, or an operator, found `for`")) + let input = &[Group::with_title(Level::ERROR.title("expected one of `.`, `;`, `?`, or an operator, found `for`")) .element( Snippet::source("let x = vec![1];") .path("/code/rust/src/test/ui/annotate-snippet/suggestion.rs") diff --git a/tests/color/multiline_removal_suggestion.rs b/tests/color/multiline_removal_suggestion.rs index fbaf4fff..6a98ec40 100644 --- a/tests/color/multiline_removal_suggestion.rs +++ b/tests/color/multiline_removal_suggestion.rs @@ -65,8 +65,7 @@ fn main() {} "#; let input = &[ - Group::new() - .element( + Group::with_title( Level::ERROR .title("`(bool, HashSet)` is not an iterator") .id("E0277"), @@ -88,14 +87,13 @@ fn main() {} .element( Level::NOTE.title("required for `(bool, HashSet)` to implement `IntoIterator`"), ), - Group::new() - .element(Level::NOTE.title("required by a bound in `flatten`")) + Group::with_title(Level::NOTE.title("required by a bound in `flatten`")) .element( Origin::new("/rustc/FAKE_PREFIX/library/core/src/iter/traits/iterator.rs") .line(1556) .char_column(4), ), - Group::new().element(Level::HELP.title("consider removing this method call, as the receiver has type `std::vec::IntoIter>` and `std::vec::IntoIter>: Iterator` trivially holds")).element( + Group::with_title(Level::HELP.title("consider removing this method call, as the receiver has type `std::vec::IntoIter>` and `std::vec::IntoIter>: Iterator` trivially holds")).element( Snippet::source(source) .path("$DIR/multiline-removal-suggestion.rs") .fold(true) diff --git a/tests/color/multiple_annotations.rs b/tests/color/multiple_annotations.rs index 464d7672..4533019a 100644 --- a/tests/color/multiple_annotations.rs +++ b/tests/color/multiple_annotations.rs @@ -15,7 +15,7 @@ fn case() { } "#; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .line_start(96) .annotation( diff --git a/tests/color/simple.rs b/tests/color/simple.rs index 17287d94..9e35cf58 100644 --- a/tests/color/simple.rs +++ b/tests/color/simple.rs @@ -9,23 +9,24 @@ fn case() { for line in &self.body { "#; - let input = &[Group::new() - .element(Level::ERROR.title("expected one of `.`, `;`, `?`, or an operator, found `for`")) - .element( - Snippet::source(source) - .path("src/format_color.rs") - .line_start(169) - .annotation( - AnnotationKind::Primary - .span(20..23) - .label("unexpected token"), - ) - .annotation( - AnnotationKind::Context - .span(10..11) - .label("expected one of `.`, `;`, `?`, or an operator here"), - ), - )]; + let input = &[Group::with_title( + Level::ERROR.title("expected one of `.`, `;`, `?`, or an operator, found `for`"), + ) + .element( + Snippet::source(source) + .path("src/format_color.rs") + .line_start(169) + .annotation( + AnnotationKind::Primary + .span(20..23) + .label("unexpected token"), + ) + .annotation( + AnnotationKind::Context + .span(10..11) + .label("expected one of `.`, `;`, `?`, or an operator here"), + ), + )]; let expected = file!["simple.term.svg"]; let renderer = Renderer::styled(); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/color/strip_line.rs b/tests/color/strip_line.rs index fbb72506..8e30ac4e 100644 --- a/tests/color/strip_line.rs +++ b/tests/color/strip_line.rs @@ -6,9 +6,8 @@ use snapbox::{assert_data_eq, file}; fn case() { let source = r#" let _: () = 42;"#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element( Snippet::source(source) .path("$DIR/whitespace-trimming.rs") .line_start(4) @@ -17,7 +16,8 @@ fn case() { .span(192..194) .label("expected (), found integer"), ), - )]; + ), + ]; let expected = file!["strip_line.term.svg"]; let renderer = Renderer::styled().anonymized_line_numbers(true); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/color/strip_line_char.rs b/tests/color/strip_line_char.rs index 090e1dba..e78b530b 100644 --- a/tests/color/strip_line_char.rs +++ b/tests/color/strip_line_char.rs @@ -6,9 +6,8 @@ use snapbox::{assert_data_eq, file}; fn case() { let source = r#" let _: () = 42ñ"#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element( Snippet::source(source) .path("$DIR/whitespace-trimming.rs") .line_start(4) @@ -17,7 +16,8 @@ fn case() { .span(192..194) .label("expected (), found integer"), ), - )]; + ), + ]; let expected = file!["strip_line_char.term.svg"]; let renderer = Renderer::styled().anonymized_line_numbers(true); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/color/strip_line_non_ws.rs b/tests/color/strip_line_non_ws.rs index da65e6a3..7ef3ad57 100644 --- a/tests/color/strip_line_non_ws.rs +++ b/tests/color/strip_line_non_ws.rs @@ -7,9 +7,8 @@ fn case() { let source = r#" let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = 42; let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); let _: () = (); "#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element( Snippet::source(source) .path("$DIR/non-whitespace-trimming.rs") .line_start(4) @@ -23,7 +22,8 @@ fn case() { .span(232..234) .label("expected due to this"), ), - )]; + ), + ]; let expected = file!["strip_line_non_ws.term.svg"]; let renderer = Renderer::styled().anonymized_line_numbers(true); assert_data_eq!(renderer.render(input), expected); diff --git a/tests/formatter.rs b/tests/formatter.rs index c538a9e8..a4c6f6ff 100644 --- a/tests/formatter.rs +++ b/tests/formatter.rs @@ -5,7 +5,7 @@ use snapbox::{assert_data_eq, str}; #[test] fn test_i_29() { - let snippets = &[Group::new().element(Level::ERROR.title("oops")).element( + let snippets = &[Group::with_title(Level::ERROR.title("oops")).element( Snippet::source("First line\r\nSecond oops line") .path("") .annotation(AnnotationKind::Primary.span(19..23).label("oops")) @@ -25,7 +25,7 @@ error: oops #[test] fn test_point_to_double_width_characters() { - let snippets = &[Group::new().element(Level::ERROR.title("")).element( + let snippets = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source("こんにちは、世界") .path("") .annotation(AnnotationKind::Primary.span(18..24).label("world")), @@ -45,7 +45,7 @@ error: #[test] fn test_point_to_double_width_characters_across_lines() { - let snippets = &[Group::new().element(Level::ERROR.title("")).element( + let snippets = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source("おはよう\nございます") .path("") .annotation(AnnotationKind::Primary.span(6..22).label("Good morning")), @@ -67,7 +67,7 @@ error: #[test] fn test_point_to_double_width_characters_multiple() { - let snippets = &[Group::new().element(Level::ERROR.title("")).element( + let snippets = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source("お寿司\n食べたい🍣") .path("") .annotation(AnnotationKind::Primary.span(0..9).label("Sushi1")) @@ -90,7 +90,7 @@ error: #[test] fn test_point_to_double_width_characters_mixed() { - let snippets = &[Group::new().element(Level::ERROR.title("")).element( + let snippets = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source("こんにちは、新しいWorld!") .path("") .annotation(AnnotationKind::Primary.span(18..32).label("New world")), @@ -110,7 +110,9 @@ error: #[test] fn test_format_title() { - let input = &[Group::new().element(Level::ERROR.title("This is a title").id("E0001"))]; + let input = &[Group::with_title( + Level::ERROR.title("This is a title").id("E0001"), + )]; let expected = str![r#"error[E0001]: This is a title"#]; let renderer = Renderer::plain(); @@ -120,8 +122,7 @@ fn test_format_title() { #[test] fn test_format_snippet_only() { let source = "This is line 1\nThis is line 2"; - let input = &[Group::new() - .element(Level::ERROR.title("")) + let input = &[Group::with_title(Level::ERROR.title("")) .element(Snippet::>::source(source).line_start(5402))]; let expected = str![[r#" @@ -138,8 +139,7 @@ error: fn test_format_snippets_continuation() { let src_0 = "This is slice 1"; let src_1 = "This is slice 2"; - let input = &[Group::new() - .element(Level::ERROR.title("")) + let input = &[Group::with_title(Level::ERROR.title("")) .element( Snippet::>::source(src_0) .line_start(5402) @@ -171,7 +171,7 @@ fn test_format_snippet_annotation_standalone() { let source = [line_1, line_2].join("\n"); // In line 2 let range = 22..24; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(&source).line_start(5402).annotation( AnnotationKind::Context .span(range.clone()) @@ -191,8 +191,7 @@ error: #[test] fn test_format_footer_title() { - let input = &[Group::new() - .element(Level::ERROR.title("")) + let input = &[Group::with_title(Level::ERROR.title("")) .element(Level::ERROR.title("This __is__ a title"))]; let expected = str![[r#" error: @@ -208,7 +207,7 @@ error: fn test_i26() { let source = "short"; let label = "label"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source).line_start(0).annotation( AnnotationKind::Primary .span(0..source.len() + 2) @@ -222,8 +221,7 @@ fn test_i26() { #[test] fn test_source_content() { let source = "This is an example\nof content lines"; - let input = &[Group::new() - .element(Level::ERROR.title("")) + let input = &[Group::with_title(Level::ERROR.title("")) .element(Snippet::>::source(source).line_start(56))]; let expected = str![[r#" error: @@ -238,7 +236,7 @@ error: #[test] fn test_source_annotation_standalone_singleline() { let source = "tests"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .line_start(1) .annotation(AnnotationKind::Context.span(0..5).label("Example string")), @@ -256,7 +254,7 @@ error: #[test] fn test_source_annotation_standalone_multiline() { let source = "tests"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .line_start(1) .annotation(AnnotationKind::Context.span(0..5).label("Example string")) @@ -277,8 +275,7 @@ error: #[test] fn test_only_source() { - let input = &[Group::new() - .element(Level::ERROR.title("")) + let input = &[Group::with_title(Level::ERROR.title("")) .element(Snippet::>::source("").path("file.rs"))]; let expected = str![[r#" error: @@ -293,8 +290,7 @@ error: #[test] fn test_anon_lines() { let source = "This is an example\nof content lines\n\nabc"; - let input = &[Group::new() - .element(Level::ERROR.title("")) + let input = &[Group::with_title(Level::ERROR.title("")) .element(Snippet::>::source(source).line_start(56))]; let expected = str![[r#" error: @@ -310,7 +306,7 @@ LL | abc #[test] fn issue_130() { - let input = &[Group::new().element(Level::ERROR.title("dummy")).element( + let input = &[Group::with_title(Level::ERROR.title("dummy")).element( Snippet::source("foo\nbar\nbaz") .path("file/path") .line_start(3) @@ -337,7 +333,7 @@ fn unterminated_string_multiline() { a\" // ... "; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -360,7 +356,7 @@ error: #[test] fn char_and_nl_annotate_char() { let source = "a\r\nb"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -382,7 +378,7 @@ error: #[test] fn char_eol_annotate_char() { let source = "a\r\nb"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -403,7 +399,7 @@ error: #[test] fn char_eol_annotate_char_double_width() { - let snippets = &[Group::new().element(Level::ERROR.title("")).element( + let snippets = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source("こん\r\nにちは\r\n世界") .path("") .annotation(AnnotationKind::Primary.span(3..8)), @@ -428,7 +424,7 @@ error: #[test] fn annotate_eol() { let source = "a\r\nb"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -450,7 +446,7 @@ error: #[test] fn annotate_eol2() { let source = "a\r\nb"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -473,7 +469,7 @@ error: #[test] fn annotate_eol3() { let source = "a\r\nb"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -496,7 +492,7 @@ error: #[test] fn annotate_eol4() { let source = "a\r\nb"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -517,7 +513,7 @@ error: #[test] fn annotate_eol_double_width() { - let snippets = &[Group::new().element(Level::ERROR.title("")).element( + let snippets = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source("こん\r\nにちは\r\n世界") .path("") .annotation(AnnotationKind::Primary.span(7..8)), @@ -542,7 +538,7 @@ error: #[test] fn multiline_eol_start() { let source = "a\r\nb"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -565,7 +561,7 @@ error: #[test] fn multiline_eol_start2() { let source = "a\r\nb"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -588,7 +584,7 @@ error: #[test] fn multiline_eol_start3() { let source = "a\nb"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -610,7 +606,7 @@ error: #[test] fn multiline_eol_start_double_width() { - let snippets = &[Group::new().element(Level::ERROR.title("")).element( + let snippets = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source("こん\r\nにちは\r\n世界") .path("") .annotation(AnnotationKind::Primary.span(7..11)), @@ -635,7 +631,7 @@ error: #[test] fn multiline_eol_start_eol_end() { let source = "a\nb\nc"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -659,7 +655,7 @@ error: #[test] fn multiline_eol_start_eol_end2() { let source = "a\r\nb\r\nc"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -683,7 +679,7 @@ error: #[test] fn multiline_eol_start_eol_end3() { let source = "a\r\nb\r\nc"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -707,7 +703,7 @@ error: #[test] fn multiline_eol_start_eof_end() { let source = "a\r\nb"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -730,7 +726,7 @@ error: #[test] fn multiline_eol_start_eof_end_double_width() { let source = "ん\r\nに"; - let input = &[Group::new().element(Level::ERROR.title("")).element( + let input = &[Group::with_title(Level::ERROR.title("")).element( Snippet::source(source) .path("file/path") .line_start(3) @@ -753,9 +749,8 @@ error: #[test] fn two_single_line_same_line() { let source = r#"bar = { version = "0.1.0", optional = true }"#; - let input = &[Group::new() - .element(Level::ERROR.title("unused optional dependency")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("unused optional dependency")).element( Snippet::source(source) .path("Cargo.toml") .line_start(4) @@ -769,7 +764,8 @@ fn two_single_line_same_line() { .span(27..42) .label("This should also be long but not too long"), ), - )]; + ), + ]; let expected = str![[r#" error: unused optional dependency --> Cargo.toml:4:1 @@ -790,9 +786,8 @@ this is another line so is this bar = { version = "0.1.0", optional = true } "#; - let input = &[Group::new() - .element(Level::ERROR.title("unused optional dependency")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("unused optional dependency")).element( Snippet::source(source) .line_start(4) .annotation( @@ -805,7 +800,8 @@ bar = { version = "0.1.0", optional = true } .span(27..42) .label("This should also be long but not too long"), ), - )]; + ), + ]; let expected = str![[r#" error: unused optional dependency | @@ -829,9 +825,8 @@ this is another line so is this bar = { version = "0.1.0", optional = true } "#; - let input = &[Group::new() - .element(Level::ERROR.title("unused optional dependency")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("unused optional dependency")).element( Snippet::source(source) .line_start(4) .annotation( @@ -849,7 +844,8 @@ bar = { version = "0.1.0", optional = true } .span(27..42) .label("This should also be long but not too long"), ), - )]; + ), + ]; let expected = str![[r#" error: unused optional dependency | @@ -877,9 +873,8 @@ so is this bar = { version = "0.1.0", optional = true } this is another line "#; - let input = &[Group::new() - .element(Level::ERROR.title("unused optional dependency")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("unused optional dependency")).element( Snippet::source(source) .line_start(4) .annotation( @@ -902,7 +897,8 @@ this is another line .span(27..42) .label("This should also be long but not too long"), ), - )]; + ), + ]; let expected = str![[r#" error: unused optional dependency | @@ -928,7 +924,7 @@ error: unused optional dependency #[test] fn origin_correct_start_line() { let source = "aaa\nbbb\nccc\nddd\n"; - let input = &[Group::new().element(Level::ERROR.title("title")).element( + let input = &[Group::with_title(Level::ERROR.title("title")).element( Snippet::source(source) .path("origin.txt") .fold(false) @@ -952,7 +948,7 @@ error: title #[test] fn origin_correct_mid_line() { let source = "aaa\nbbb\nccc\nddd\n"; - let input = &[Group::new().element(Level::ERROR.title("title")).element( + let input = &[Group::with_title(Level::ERROR.title("title")).element( Snippet::source(source) .path("origin.txt") .fold(false) @@ -981,31 +977,29 @@ error: title fn two_suggestions_same_span() { let source = r#" A.foo();"#; let input_new = &[ - Group::new() - .element( - Level::ERROR - .title("expected value, found enum `A`") - .id("E0423"), - ) - .element( - Snippet::source(source) - .fold(true) - .annotation(AnnotationKind::Primary.span(4..5)), - ), - Group::new() - .element( - Level::HELP.title("you might have meant to use one of the following enum variants"), - ) - .element( - Snippet::source(source) - .fold(true) - .patch(Patch::new(4..5, "(A::Tuple())")), - ) - .element( - Snippet::source(source) - .fold(true) - .patch(Patch::new(4..5, "A::Unit")), - ), + Group::with_title( + Level::ERROR + .title("expected value, found enum `A`") + .id("E0423"), + ) + .element( + Snippet::source(source) + .fold(true) + .annotation(AnnotationKind::Primary.span(4..5)), + ), + Group::with_title( + Level::HELP.title("you might have meant to use one of the following enum variants"), + ) + .element( + Snippet::source(source) + .fold(true) + .patch(Patch::new(4..5, "(A::Tuple())")), + ) + .element( + Snippet::source(source) + .fold(true) + .patch(Patch::new(4..5, "A::Unit")), + ), ]; let expected = str![[r#" @@ -1048,7 +1042,7 @@ fn main() { banana::Chaenomeles.pick() }"#; let input_new = - &[Group::new().element(Level::ERROR + &[Group::with_title(Level::ERROR .title("no method named `pick` found for struct `Chaenomeles` in the current scope") .id("E0599")).element( Snippet::source(source) @@ -1065,8 +1059,7 @@ fn main() { .label("method not found in `Chaenomeles`"), ), ), - Group::new() - .element(Level::HELP.title( + Group::with_title(Level::HELP.title( "the following traits which provide `pick` are implemented but not in scope; perhaps you want to import one of them", )) .element( @@ -1104,27 +1097,24 @@ fn single_line_non_overlapping_suggestions() { let source = r#" A.foo();"#; let input_new = &[ - Group::new() - .element( - Level::ERROR - .title("expected value, found enum `A`") - .id("E0423"), - ) - .element( - Snippet::source(source) - .fold(true) - .line_start(1) - .annotation(AnnotationKind::Primary.span(4..5)), - ), - Group::new() - .element(Level::HELP.title("make these changes and things will work")) - .element( - Snippet::source(source) - .fold(true) - .fold(true) - .patch(Patch::new(4..5, "(A::Tuple())")) - .patch(Patch::new(6..9, "bar")), - ), + Group::with_title( + Level::ERROR + .title("expected value, found enum `A`") + .id("E0423"), + ) + .element( + Snippet::source(source) + .fold(true) + .line_start(1) + .annotation(AnnotationKind::Primary.span(4..5)), + ), + Group::with_title(Level::HELP.title("make these changes and things will work")).element( + Snippet::source(source) + .fold(true) + .fold(true) + .patch(Patch::new(4..5, "(A::Tuple())")) + .patch(Patch::new(6..9, "bar")), + ), ]; let expected = str![[r#" @@ -1147,23 +1137,19 @@ LL + (A::Tuple()).bar(); fn single_line_non_overlapping_suggestions2() { let source = r#" ThisIsVeryLong.foo();"#; let input_new = &[ - Group::new() - .element(Level::ERROR.title("Found `ThisIsVeryLong`").id("E0423")) - .element( - Snippet::source(source) - .fold(true) - .line_start(1) - .annotation(AnnotationKind::Primary.span(4..18)), - ), - Group::new() - .element(Level::HELP.title("make these changes and things will work")) - .element( - Snippet::source(source) - .fold(true) - .fold(true) - .patch(Patch::new(4..18, "(A::Tuple())")) - .patch(Patch::new(19..22, "bar")), - ), + Group::with_title(Level::ERROR.title("Found `ThisIsVeryLong`").id("E0423")).element( + Snippet::source(source) + .fold(true) + .line_start(1) + .annotation(AnnotationKind::Primary.span(4..18)), + ), + Group::with_title(Level::HELP.title("make these changes and things will work")).element( + Snippet::source(source) + .fold(true) + .fold(true) + .patch(Patch::new(4..18, "(A::Tuple())")) + .patch(Patch::new(19..22, "bar")), + ), ]; let expected = str![[r#" @@ -1193,50 +1179,46 @@ fn multiple_replacements() { "#; let input_new = &[ - Group::new() - .element( - Level::ERROR - .title( - "cannot borrow `*self` as mutable because it is also borrowed as immutable", - ) - .id("E0502"), - ) - .element( - Snippet::source(source) - .line_start(1) - .fold(true) - .annotation( - AnnotationKind::Primary - .span(49..59) - .label("mutable borrow occurs here"), - ) - .annotation( - AnnotationKind::Primary - .span(13..15) - .label("immutable borrow occurs here"), - ) - .annotation( - AnnotationKind::Primary - .span(26..30) - .label("first borrow occurs due to use of `*self` in closure"), - ) - .annotation( - AnnotationKind::Primary - .span(65..66) - .label("immutable borrow later used here"), - ), - ), - Group::new() - .element( - Level::HELP.title("try explicitly pass `&Self` into the Closure as an argument"), - ) - .element( - Snippet::source(source) - .fold(true) - .patch(Patch::new(14..14, "this: &Self")) - .patch(Patch::new(26..30, "this")) - .patch(Patch::new(66..68, "(self)")), - ), + Group::with_title( + Level::ERROR + .title("cannot borrow `*self` as mutable because it is also borrowed as immutable") + .id("E0502"), + ) + .element( + Snippet::source(source) + .line_start(1) + .fold(true) + .annotation( + AnnotationKind::Primary + .span(49..59) + .label("mutable borrow occurs here"), + ) + .annotation( + AnnotationKind::Primary + .span(13..15) + .label("immutable borrow occurs here"), + ) + .annotation( + AnnotationKind::Primary + .span(26..30) + .label("first borrow occurs due to use of `*self` in closure"), + ) + .annotation( + AnnotationKind::Primary + .span(65..66) + .label("immutable borrow later used here"), + ), + ), + Group::with_title( + Level::HELP.title("try explicitly pass `&Self` into the Closure as an argument"), + ) + .element( + Snippet::source(source) + .fold(true) + .patch(Patch::new(14..14, "this: &Self")) + .patch(Patch::new(26..30, "this")) + .patch(Patch::new(66..68, "(self)")), + ), ]; let expected = str![[r#" error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable @@ -1278,43 +1260,46 @@ fn main() { test1(); }"#; - let input_new = &[Group::new().element(Level::ERROR - .title("cannot borrow `chars` as mutable more than once at a time") - .id("E0499")).element( - Snippet::source(source) - .line_start(1) - .fold(true) - .annotation( - AnnotationKind::Context - .span(65..70) - .label("first mutable borrow occurs here"), - ) - .annotation( - AnnotationKind::Primary - .span(90..95) - .label("second mutable borrow occurs here"), - ) - .annotation( - AnnotationKind::Context - .span(65..79) - .label("first borrow later used here"), - ), - ), - Group::new() - .element( - Level::HELP - .title("if you want to call `next` on a iterator within the loop, consider using `while let`") + let input_new = &[ + Group::with_title( + Level::ERROR + .title("cannot borrow `chars` as mutable more than once at a time") + .id("E0499"), + ) + .element( + Snippet::source(source) + .line_start(1) + .fold(true) + .annotation( + AnnotationKind::Context + .span(65..70) + .label("first mutable borrow occurs here"), ) - .element( - Snippet::source(source) - .fold(true) - .patch(Patch::new( - 55..59, - "let iter = chars.by_ref();\n while let Some(", - )) - .patch(Patch::new(61..79, ") = iter.next()")) - .patch(Patch::new(90..95, "iter")), - )]; + .annotation( + AnnotationKind::Primary + .span(90..95) + .label("second mutable borrow occurs here"), + ) + .annotation( + AnnotationKind::Context + .span(65..79) + .label("first borrow later used here"), + ), + ), + Group::with_title(Level::HELP.title( + "if you want to call `next` on a iterator within the loop, consider using `while let`", + )) + .element( + Snippet::source(source) + .fold(true) + .patch(Patch::new( + 55..59, + "let iter = chars.by_ref();\n while let Some(", + )) + .patch(Patch::new(61..79, ") = iter.next()")) + .patch(Patch::new(90..95, "iter")), + ), + ]; let expected = str![[r#" error[E0499]: cannot borrow `chars` as mutable more than once at a time @@ -1358,40 +1343,34 @@ struct Foo { fn main() {}"#; let input_new = &[ - Group::new() - .element( - Level::ERROR - .title("failed to resolve: use of undeclared crate or module `st`") - .id("E0433"), - ) - .element( - Snippet::source(source).line_start(1).fold(true).annotation( - AnnotationKind::Primary - .span(122..124) - .label("use of undeclared crate or module `st`"), - ), + Group::with_title( + Level::ERROR + .title("failed to resolve: use of undeclared crate or module `st`") + .id("E0433"), + ) + .element( + Snippet::source(source).line_start(1).fold(true).annotation( + AnnotationKind::Primary + .span(122..124) + .label("use of undeclared crate or module `st`"), ), - Group::new() - .element(Level::HELP.title("there is a crate or module with a similar name")) + ), + Group::with_title(Level::HELP.title("there is a crate or module with a similar name")) .element( Snippet::source(source) .fold(true) .patch(Patch::new(122..124, "std")), ), - Group::new() - .element(Level::HELP.title("consider importing this module")) - .element( - Snippet::source(source) - .fold(true) - .patch(Patch::new(1..1, "use std::cell;\n")), - ), - Group::new() - .element(Level::HELP.title("if you import `cell`, refer to it directly")) - .element( - Snippet::source(source) - .fold(true) - .patch(Patch::new(122..126, "")), - ), + Group::with_title(Level::HELP.title("consider importing this module")).element( + Snippet::source(source) + .fold(true) + .patch(Patch::new(1..1, "use std::cell;\n")), + ), + Group::with_title(Level::HELP.title("if you import `cell`, refer to it directly")).element( + Snippet::source(source) + .fold(true) + .patch(Patch::new(122..126, "")), + ), ]; let expected = str![[r#" error[E0433]: failed to resolve: use of undeclared crate or module `st` @@ -1437,38 +1416,35 @@ where fn main() {}"#; let input_new = &[ - Group::new() - .element( - Level::ERROR - .title("the size for values of type `T` cannot be known at compilation time") - .id("E0277"), - ) - .element( - Snippet::source(source) - .line_start(1) - .fold(true) - .annotation( - AnnotationKind::Primary - .span(39..49) - .label("doesn't have a size known at compile-time"), - ) - .annotation( - AnnotationKind::Context - .span(31..32) - .label("this type parameter needs to be `Sized`"), - ), - ), - Group::new() - .element( - Level::HELP.title( - "consider removing the `?Sized` bound to make the type parameter `Sized`", + Group::with_title( + Level::ERROR + .title("the size for values of type `T` cannot be known at compilation time") + .id("E0277"), + ) + .element( + Snippet::source(source) + .line_start(1) + .fold(true) + .annotation( + AnnotationKind::Primary + .span(39..49) + .label("doesn't have a size known at compile-time"), + ) + .annotation( + AnnotationKind::Context + .span(31..32) + .label("this type parameter needs to be `Sized`"), ), - ) - .element( - Snippet::source(source) - .fold(true) - .patch(Patch::new(52..85, "")), - ), + ), + Group::with_title( + Level::HELP + .title("consider removing the `?Sized` bound to make the type parameter `Sized`"), + ) + .element( + Snippet::source(source) + .fold(true) + .patch(Patch::new(52..85, "")), + ), ]; let expected = str![[r#" error[E0277]: the size for values of type `T` cannot be known at compilation time @@ -1508,7 +1484,7 @@ and where } fn main() {}"#; - let input_new = &[Group::new().element(Level::ERROR + let input_new = &[Group::with_title(Level::ERROR .title("the size for values of type `T` cannot be known at compilation time") .id("E0277")).element(Snippet::source(source) .line_start(1) @@ -1524,7 +1500,7 @@ fn main() {}"#; .span(31..32) .label("this type parameter needs to be `Sized`"), )) - ,Group::new().element( + ,Group::with_title( Level::NOTE .title("required by an implicit `Sized` bound in `Wrapper`") ).element( @@ -1537,7 +1513,7 @@ fn main() {}"#; .span(16..17) .label("required by the implicit `Sized` requirement on this type parameter in `Wrapper`"), ) - ), Group::new().element( + ), Group::with_title( Level::HELP .title("you could relax the implicit `Sized` bound on `T` if it were used through indirection like `&T` or `Box`") ) @@ -1557,7 +1533,7 @@ fn main() {}"#; .label("...if indirection were used here: `Box`"), ) - ),Group::new().element( + ),Group::with_title( Level::HELP .title("consider removing the `?Sized` bound to make the type parameter `Sized`") ).element( @@ -1614,26 +1590,25 @@ quack zappy "#; - let input_new = - &[ - Group::new().element( - Level::ERROR - .title("the size for values of type `T` cannot be known at compilation time") - .id("E0277"), - ), - // We need an empty group here to ensure the HELP line is rendered correctly - Group::new() - .element(Level::HELP.title( - "consider removing the `?Sized` bound to make the type parameter `Sized`", - )) - .element( - Snippet::source(source) - .line_start(7) - .fold(true) - .patch(Patch::new(3..21, "")) - .patch(Patch::new(22..40, "")), - ), - ]; + let input_new = &[ + Group::with_title( + Level::ERROR + .title("the size for values of type `T` cannot be known at compilation time") + .id("E0277"), + ), + // We need an empty group here to ensure the HELP line is rendered correctly + Group::with_title( + Level::HELP + .title("consider removing the `?Sized` bound to make the type parameter `Sized`"), + ) + .element( + Snippet::source(source) + .line_start(7) + .fold(true) + .patch(Patch::new(3..21, "")) + .patch(Patch::new(22..40, "")), + ), + ]; let expected = str![[r#" error[E0277]: the size for values of type `T` cannot be known at compilation time | @@ -1686,7 +1661,7 @@ fn main() { } "#; - let input_new = &[Group::new().element(Level::ERROR + let input_new = &[Group::with_title(Level::ERROR .title("type mismatch resolving `>, ...>>, ...>>, ...> as Future>::Error == Foo`") .id("E0271")).element(Snippet::source(source) .line_start(4) @@ -1696,7 +1671,7 @@ fn main() { AnnotationKind::Primary .span(208..510) .label("type mismatch resolving `, ...>>, ...> as Future>::Error == Foo`"), - )),Group::new().element( + )),Group::with_title( Level::NOTE.title("expected this to be `Foo`") ).element( Snippet::source(source) @@ -1772,7 +1747,7 @@ fn main() { } "#; - let input_new = &[Group::new().element(Level::ERROR + let input_new = &[Group::with_title(Level::ERROR .title("type mismatch resolving `>, ...>>, ...>>, ...> as Future>::Error == Foo`") .id("E0271")).element(Snippet::source(source) .line_start(4) @@ -1782,7 +1757,7 @@ fn main() { AnnotationKind::Primary .span(208..510) .label("type mismatch resolving `, ...>>, ...> as Future>::Error == Foo`"), - )),Group::new().element( + )),Group::with_title( Level::NOTE.title("expected this to be `Foo`") ).element( Snippet::source(source) @@ -1923,7 +1898,7 @@ fn main() { } "#; - let input_new = &[Group::new().element(Level::ERROR + let input_new = &[Group::with_title(Level::ERROR .title("mismatched types") .id("E0308")).element( Snippet::source(source) @@ -2007,7 +1982,7 @@ fn main() { } "#; - let input_new = &[Group::new().element(Level::ERROR + let input_new = &[Group::with_title(Level::ERROR .title("mismatched types") .id("E0308")).element( Snippet::source(source) @@ -2028,7 +2003,7 @@ fn main() { Level::NOTE .title("expected fn pointer `for<'a> fn(Box<(dyn Any + Send + 'a)>) -> Pin<_>`\n found fn item `fn(Box<(dyn Any + Send + 'static)>) -> Pin<_> {wrapped_fn}`") , - ),Group::new().element( + ),Group::with_title( Level::NOTE.title("function defined here"), ).element( Snippet::source(source) @@ -2074,7 +2049,7 @@ LL │ ┃ )>>) {} #[test] fn unicode_cut_handling() { let source = "version = \"0.1.0\"\n# Ensure that the spans from toml handle utf-8 correctly\nauthors = [\n { name = \"Z\u{351}\u{36b}\u{343}\u{36a}\u{302}\u{36b}\u{33d}\u{34f}\u{334}\u{319}\u{324}\u{31e}\u{349}\u{35a}\u{32f}\u{31e}\u{320}\u{34d}A\u{36b}\u{357}\u{334}\u{362}\u{335}\u{31c}\u{330}\u{354}L\u{368}\u{367}\u{369}\u{358}\u{320}G\u{311}\u{357}\u{30e}\u{305}\u{35b}\u{341}\u{334}\u{33b}\u{348}\u{34d}\u{354}\u{339}O\u{342}\u{30c}\u{30c}\u{358}\u{328}\u{335}\u{339}\u{33b}\u{31d}\u{333}\", email = 1 }\n]\n"; - let input = &[Group::new().element(Level::ERROR.title("title")).element( + let input = &[Group::with_title(Level::ERROR.title("title")).element( Snippet::source(source) .fold(false) .annotation(AnnotationKind::Primary.span(85..228).label("annotation")), @@ -2111,7 +2086,7 @@ error: title #[test] fn unicode_cut_handling2() { let source = "/*这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。*/?"; - let input = &[Group::new().element(Level::ERROR + let input = &[Group::with_title(Level::ERROR .title("expected item, found `?`")).element( Snippet::source(source) .fold(false) @@ -2148,7 +2123,7 @@ error: expected item, found `?` #[test] fn unicode_cut_handling3() { let source = "/*这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。这是宽的。*/?"; - let input = &[Group::new().element(Level::ERROR + let input = &[Group::with_title(Level::ERROR .title("expected item, found `?`")).element( Snippet::source(source) .fold(false) @@ -2185,7 +2160,7 @@ error: expected item, found `?` #[test] fn unicode_cut_handling4() { let source = "/*aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa*/?"; - let input = &[Group::new().element(Level::ERROR + let input = &[Group::with_title(Level::ERROR .title("expected item, found `?`")).element( Snippet::source(source) .fold(false) @@ -2228,9 +2203,8 @@ fn main() { //~^ ERROR mismatched types } "##; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element( Snippet::source(source) .path("$DIR/non-whitespace-trimming-unicode.rs") .fold(true) @@ -2244,7 +2218,8 @@ fn main() { .span(1202..1204) .label("expected due to this"), ), - )]; + ), + ]; let expected_ascii = str![[r#" error[E0308]: mismatched types @@ -2285,29 +2260,25 @@ fn main() { } "##; let input = &[ - Group::new() - .element( - Level::ERROR - .title("cannot add `&str` to `&str`") - .id("E0369"), - ) - .element( - Snippet::source(source) - .path("$DIR/non-1-width-unicode-multiline-label.rs") - .fold(true) - .annotation(AnnotationKind::Context.span(970..984).label("&str")) - .annotation(AnnotationKind::Context.span(987..1001).label("&str")) - .annotation( - AnnotationKind::Primary - .span(985..986) - .label("`+` cannot be used to concatenate two `&str` strings"), - ), - ) - .element( - Level::NOTE.title("string concatenation requires an owned `String` on the left"), - ), - Group::new() - .element(Level::HELP.title("create an owned `String` from a string reference")) + Group::with_title( + Level::ERROR + .title("cannot add `&str` to `&str`") + .id("E0369"), + ) + .element( + Snippet::source(source) + .path("$DIR/non-1-width-unicode-multiline-label.rs") + .fold(true) + .annotation(AnnotationKind::Context.span(970..984).label("&str")) + .annotation(AnnotationKind::Context.span(987..1001).label("&str")) + .annotation( + AnnotationKind::Primary + .span(985..986) + .label("`+` cannot be used to concatenate two `&str` strings"), + ), + ) + .element(Level::NOTE.title("string concatenation requires an owned `String` on the left")), + Group::with_title(Level::HELP.title("create an owned `String` from a string reference")) .element( Snippet::source(source) .path("$DIR/non-1-width-unicode-multiline-label.rs") @@ -2368,15 +2339,14 @@ fn foo() { } "##; let bin_source = "�|�\u{0002}!5�cc\u{0015}\u{0002}�Ӻi��WWj�ȥ�'�}�\u{0012}�J�ȉ��W�\u{001e}O�@����\u{001c}w�V���LO����\u{0014}[ \u{0003}_�'���SQ�~ذ��ų&��-\t��lN~��!@␌ _#���kQ��h�\u{001d}�:�\u{001c}\u{0007}�"; - let input = &[Group::new().element(Level::ERROR + let input = &[Group::with_title(Level::ERROR .title("couldn't read `$DIR/not-utf8.bin`: stream did not contain valid UTF-8")).element( Snippet::source(source) .path("$DIR/not-utf8.rs") .fold(true) .annotation(AnnotationKind::Primary.span(136..160)), ), - Group::new() - .element(Level::NOTE.title("byte `193` is not valid utf-8")) + Group::with_title(Level::NOTE.title("byte `193` is not valid utf-8")) .element( Snippet::source(bin_source) .path("$DIR/not-utf8.bin") @@ -2429,28 +2399,29 @@ fn secondary_title_no_level_text() { let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types }"#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( - Snippet::source(source) - .path("$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 - .text(None::<&str>) - .title("expected reference `&str`\nfound reference `&'static [u8; 0]`"), - )]; + let input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")) + .element( + Snippet::source(source) + .path("$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 + .text(None::<&str>) + .title("expected reference `&str`\nfound reference `&'static [u8; 0]`"), + ), + ]; let expected = str![[r#" error[E0308]: mismatched types @@ -2474,28 +2445,29 @@ fn secondary_title_custom_level_text() { let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types }"#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( - Snippet::source(source) - .path("$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 - .text(Some("custom")) - .title("expected reference `&str`\nfound reference `&'static [u8; 0]`"), - )]; + let input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")) + .element( + Snippet::source(source) + .path("$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 + .text(Some("custom")) + .title("expected reference `&str`\nfound reference `&'static [u8; 0]`"), + ), + ]; let expected = str![[r#" error[E0308]: mismatched types @@ -2543,42 +2515,40 @@ fn main() { } "#; let input = &[ - Group::new() - .element( - Level::ERROR - .title("`break` with value from a `while` loop") - .id("E0571"), - ) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/issue-114529-illegal-break-with-value.rs") - .fold(true) - .annotation( - AnnotationKind::Primary - .span(483..581) - .label("can only break with a value inside `loop` or breakable block"), - ) - .annotation( - AnnotationKind::Context - .span(462..472) - .label("you can't `break` with a value in a `while` loop"), - ), - ), - Group::new() - .element( - Level::HELP - .text(Some("suggestion")) - .title("use `break` on its own without a value inside this `while` loop") - .id("S0123"), - ) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/issue-114529-illegal-break-with-value.rs") - .fold(true) - .patch(Patch::new(483..581, "break")), - ), + Group::with_title( + Level::ERROR + .title("`break` with value from a `while` loop") + .id("E0571"), + ) + .element( + Snippet::source(source) + .line_start(1) + .path("$DIR/issue-114529-illegal-break-with-value.rs") + .fold(true) + .annotation( + AnnotationKind::Primary + .span(483..581) + .label("can only break with a value inside `loop` or breakable block"), + ) + .annotation( + AnnotationKind::Context + .span(462..472) + .label("you can't `break` with a value in a `while` loop"), + ), + ), + Group::with_title( + Level::HELP + .text(Some("suggestion")) + .title("use `break` on its own without a value inside this `while` loop") + .id("S0123"), + ) + .element( + Snippet::source(source) + .line_start(1) + .path("$DIR/issue-114529-illegal-break-with-value.rs") + .fold(true) + .patch(Patch::new(483..581, "break")), + ), ]; let expected_ascii = str![[r#" diff --git a/tests/rustc_tests.rs b/tests/rustc_tests.rs index de5f615f..29b84006 100644 --- a/tests/rustc_tests.rs +++ b/tests/rustc_tests.rs @@ -13,7 +13,7 @@ fn ends_on_col0() { fn foo() { } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -41,7 +41,7 @@ fn foo() { } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -70,7 +70,7 @@ fn foo() { X2 Y2 } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -111,7 +111,7 @@ fn foo() { Y1 X1 } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -153,7 +153,7 @@ fn foo() { X3 Y3 Z3 } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -195,7 +195,7 @@ fn foo() { X2 Y2 Z2 } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -240,7 +240,7 @@ fn foo() { X2 Y2 Z2 } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -286,7 +286,7 @@ fn foo() { X3 Y3 Z3 } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -334,7 +334,7 @@ fn foo() { X3 Y3 Z3 } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -376,7 +376,7 @@ fn foo() { X3 Y3 Z3 } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -417,7 +417,7 @@ fn foo() { a { b { c } d } } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -448,7 +448,7 @@ fn foo() { a { b { c } d } } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -478,7 +478,7 @@ fn foo() { a { b { c } d } } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -511,7 +511,7 @@ fn foo() { a { b { c } d } } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -543,7 +543,7 @@ fn foo() { a bc d } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -575,7 +575,7 @@ fn foo() { a { b { c } d } } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -601,7 +601,7 @@ fn foo() { a { b { c } d } } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -628,7 +628,7 @@ fn foo() { a { b { c } d } } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -665,7 +665,7 @@ fn foo() { a { b { c } d } } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -694,7 +694,7 @@ fn foo() { a { b { c } d } } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -732,7 +732,7 @@ fn foo() { X3 Y3 Z3 } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -790,7 +790,7 @@ fn foo() { X3 Y3 Z3 } "#; - let input = &[Group::new().element(Level::ERROR.title("foo")).element( + let input = &[Group::with_title(Level::ERROR.title("foo")).element( Snippet::source(source) .line_start(1) .path("test.rs") @@ -842,30 +842,32 @@ fn issue_91334() { fn f(){||yield(((){), "#; - let input = &[Group::new() - .element(Level::ERROR.title("this file contains an unclosed delimiter")) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/issue-91334.rs") - .fold(true) - .annotation( - AnnotationKind::Context - .span(151..152) - .label("unclosed delimiter"), - ) - .annotation( - AnnotationKind::Context - .span(159..160) - .label("unclosed delimiter"), - ) - .annotation( - AnnotationKind::Context - .span(164..164) - .label("missing open `(` for this delimiter"), - ) - .annotation(AnnotationKind::Primary.span(167..167)), - )]; + let input = + &[ + Group::with_title(Level::ERROR.title("this file contains an unclosed delimiter")) + .element( + Snippet::source(source) + .line_start(1) + .path("$DIR/issue-91334.rs") + .fold(true) + .annotation( + AnnotationKind::Context + .span(151..152) + .label("unclosed delimiter"), + ) + .annotation( + AnnotationKind::Context + .span(159..160) + .label("unclosed delimiter"), + ) + .annotation( + AnnotationKind::Context + .span(164..164) + .label("missing open `(` for this delimiter"), + ) + .annotation(AnnotationKind::Primary.span(167..167)), + ), + ]; let expected = str![[r#" error: this file contains an unclosed delimiter --> $DIR/issue-91334.rs:7:23 @@ -912,40 +914,37 @@ fn main() { } "#; let input = &[ - Group::new() - .element( - Level::ERROR - .title("`break` with value from a `while` loop") - .id("E0571"), - ) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/issue-114529-illegal-break-with-value.rs") - .fold(true) - .annotation( - AnnotationKind::Primary - .span(483..581) - .label("can only break with a value inside `loop` or breakable block"), - ) - .annotation( - AnnotationKind::Context - .span(462..472) - .label("you can't `break` with a value in a `while` loop"), - ), - ), - Group::new() - .element( - Level::HELP - .title("use `break` on its own without a value inside this `while` loop"), - ) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/issue-114529-illegal-break-with-value.rs") - .fold(true) - .annotation(AnnotationKind::Context.span(483..581).label("break")), - ), + Group::with_title( + Level::ERROR + .title("`break` with value from a `while` loop") + .id("E0571"), + ) + .element( + Snippet::source(source) + .line_start(1) + .path("$DIR/issue-114529-illegal-break-with-value.rs") + .fold(true) + .annotation( + AnnotationKind::Primary + .span(483..581) + .label("can only break with a value inside `loop` or breakable block"), + ) + .annotation( + AnnotationKind::Context + .span(462..472) + .label("you can't `break` with a value in a `while` loop"), + ), + ), + Group::with_title( + Level::HELP.title("use `break` on its own without a value inside this `while` loop"), + ) + .element( + Snippet::source(source) + .line_start(1) + .path("$DIR/issue-114529-illegal-break-with-value.rs") + .fold(true) + .annotation(AnnotationKind::Context.span(483..581).label("break")), + ), ]; let expected = str![[r#" error[E0571]: `break` with value from a `while` loop @@ -1121,42 +1120,40 @@ fn nsize() { } } "#; - let input = - &[ - Group::new() - .element( - Level::ERROR - .title("`V0usize` cannot be safely transmuted into `[usize; 2]`") - .id("E0277"), - ) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/primitive_reprs_should_have_correct_length.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(4375..4381).label( - "the size of `V0usize` is smaller than the size of `[usize; 2]`", - )), + let input = &[ + Group::with_title( + Level::ERROR + .title("`V0usize` cannot be safely transmuted into `[usize; 2]`") + .id("E0277"), + ) + .element( + Snippet::source(source) + .line_start(1) + .path("$DIR/primitive_reprs_should_have_correct_length.rs") + .fold(true) + .annotation( + AnnotationKind::Primary + .span(4375..4381) + .label("the size of `V0usize` is smaller than the size of `[usize; 2]`"), ), - Group::new() - .element(Level::NOTE.title("required by a bound in `is_transmutable`")) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/primitive_reprs_should_have_correct_length.rs") - .fold(true) - .annotation( - AnnotationKind::Context - .span(225..240) - .label("required by a bound in this function"), - ) - .annotation( - AnnotationKind::Primary - .span(276..470) - .label("required by this bound in `is_transmutable`"), - ), + ), + Group::with_title(Level::NOTE.title("required by a bound in `is_transmutable`")).element( + Snippet::source(source) + .line_start(1) + .path("$DIR/primitive_reprs_should_have_correct_length.rs") + .fold(true) + .annotation( + AnnotationKind::Context + .span(225..240) + .label("required by a bound in this function"), + ) + .annotation( + AnnotationKind::Primary + .span(276..470) + .label("required by this bound in `is_transmutable`"), ), - ]; + ), + ]; let expected = str![[r#" error[E0277]: `V0usize` cannot be safely transmuted into `[usize; 2]` --> $DIR/primitive_reprs_should_have_correct_length.rs:144:44 @@ -1209,7 +1206,7 @@ fn main() { assert::is_maybe_transmutable::<&'static [u8; 0], &'static [u16; 0]>(); //~ ERROR `&[u8; 0]` cannot be safely transmuted into `&[u16; 0]` } "#; - let input = &[Group::new().element(Level::ERROR + let input = &[Group::with_title(Level::ERROR .title("`&[u8; 0]` cannot be safely transmuted into `&[u16; 0]`") .id("E027s7")).element( Snippet::source(source) @@ -1275,33 +1272,33 @@ fn g() { } fn main() {} "#; - let input = - &[Group::new() - .element( - Level::ERROR - .title("expected function, found `{integer}`") - .id("E0618"), + let input = &[Group::with_title( + Level::ERROR + .title("expected function, found `{integer}`") + .id("E0618"), + ) + .element( + Snippet::source(source) + .line_start(1) + .path("$DIR/missing-semicolon.rs") + .fold(true) + .annotation( + AnnotationKind::Context + .span(108..144) + .label("call expression requires function"), ) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/missing-semicolon.rs") - .fold(true) - .annotation( - AnnotationKind::Context - .span(108..144) - .label("call expression requires function"), - ) - .annotation( - AnnotationKind::Context - .span(89..90) - .label("`x` has type `{integer}`"), - ) - .annotation(AnnotationKind::Context.span(109..109).label( - "help: consider using a semicolon here to finish the statement: `;`", - )) - .annotation(AnnotationKind::Primary.span(108..109)), - )]; + .annotation( + AnnotationKind::Context + .span(89..90) + .label("`x` has type `{integer}`"), + ) + .annotation( + AnnotationKind::Context + .span(109..109) + .label("help: consider using a semicolon here to finish the statement: `;`"), + ) + .annotation(AnnotationKind::Primary.span(108..109)), + )]; let expected = str![[r#" error[E0618]: expected function, found `{integer}` --> $DIR/missing-semicolon.rs:5:13 @@ -1369,7 +1366,7 @@ macro_rules! outer_macro { outer_macro!(FirstStruct, FirstAttrStruct); "#; let input = - &[ Group::new().element(Level::WARNING + &[ Group::with_title(Level::WARNING .title("non-local `macro_rules!` definition, `#[macro_export]` macro should be written at top level module")) .element( Snippet::source(aux_source) @@ -1402,8 +1399,7 @@ outer_macro!(FirstStruct, FirstAttrStruct); Level::NOTE .title("a `macro_rules!` definition is non-local if it is nested inside an item and has a `#[macro_export]` attribute") ), - Group::new() - .element(Level::NOTE.title("the lint level is defined here")) + Group::with_title(Level::NOTE.title("the lint level is defined here")) .element( Snippet::source(source) .line_start(1) @@ -1498,28 +1494,28 @@ macro_rules! inline { } "#; let input = &[ - Group::new() - .element( - Level::ERROR - .title("can't call method `pow` on ambiguous numeric type `{integer}`") - .id("E0689"), - ) - .element( - Snippet::source(source) - .line_start(1) - .path("$DIR/method-on-ambiguous-numeric-type.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(916..919)), - ), - Group::new() - .element(Level::HELP.title("you must specify a type for this binding, like `i32`")) - .element( - Snippet::source(aux_source) - .line_start(1) - .path("$DIR/auxiliary/macro-in-other-crate.rs") - .fold(true) - .annotation(AnnotationKind::Context.span(69..69).label(": i32")), - ), + Group::with_title( + Level::ERROR + .title("can't call method `pow` on ambiguous numeric type `{integer}`") + .id("E0689"), + ) + .element( + Snippet::source(source) + .line_start(1) + .path("$DIR/method-on-ambiguous-numeric-type.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(916..919)), + ), + Group::with_title( + Level::HELP.title("you must specify a type for this binding, like `i32`"), + ) + .element( + Snippet::source(aux_source) + .line_start(1) + .path("$DIR/auxiliary/macro-in-other-crate.rs") + .fold(true) + .annotation(AnnotationKind::Context.span(69..69).label(": i32")), + ), ]; let expected = str![[r#" error[E0689]: can't call method `pow` on ambiguous numeric type `{integer}` @@ -1562,9 +1558,8 @@ fn courier_to_des_moines_and_points_west(data: &[u32]) -> String { fn main() {} "#; - let input = &[Group::new() - .element(Level::ERROR.title("type annotations needed").id("E0282")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("type annotations needed").id("E0282")).element( Snippet::source(source) .line_start(1) .path("$DIR/issue-42234-unknown-receiver-type.rs") @@ -1572,7 +1567,8 @@ fn main() {} .annotation(AnnotationKind::Primary.span(536..539).label( "cannot infer type of the type parameter `S` declared on the method `sum`", )), - )]; + ), + ]; let expected = str![[r#" error[E0282]: type annotations needed --> $DIR/issue-42234-unknown-receiver-type.rs:15:10 @@ -1666,7 +1662,7 @@ fn main() {} "##; let input = - &[ Group::new().element( Level::ERROR + &[ Group::with_title( Level::ERROR .title( "non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered" ) @@ -1681,8 +1677,7 @@ fn main() {} .label("patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered") ), ), - Group::new() - .element(Level::NOTE.title("`NonEmptyEnum5` defined here")) + Group::with_title(Level::NOTE.title("`NonEmptyEnum5` defined here")) .element( Snippet::source(source) .line_start(1) @@ -1698,8 +1693,7 @@ fn main() {} .element(Level::NOTE.title("the matched value is of type `NonEmptyEnum5`")) .element(Level::NOTE.title("match arms with guards don't count towards exhaustivity") ), - Group::new() - .element( + Group::with_title( Level::HELP .title("ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms") ) @@ -1763,7 +1757,7 @@ fn main() { //~^ ERROR must be specified } "#; - let input = &[Group::new().element(Level::ERROR + let input = &[Group::with_title(Level::ERROR .title("the trait alias `EqAlias` is not dyn compatible") .id("E0038")).element( Snippet::source(source) @@ -1776,8 +1770,7 @@ fn main() { .label("`EqAlias` is not dyn compatible"), ), ), - Group::new() - .element( + Group::with_title( Level::NOTE .title("for a trait to be dyn compatible it needs to allow building a vtable\nfor more information, visit ")) .element( @@ -1830,9 +1823,8 @@ const C: u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fn main() {} "#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0038")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0038")).element( Snippet::source(source) .path("$DIR/long-span.rs") .fold(true) @@ -1841,7 +1833,8 @@ fn main() {} .span(15..5055) .label("expected `u8`, found `[{integer}; 1680]`"), ), - )]; + ), + ]; let expected = str![[r#" error[E0038]: mismatched types --> $DIR/long-span.rs:2:15 @@ -1864,9 +1857,8 @@ const C: u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fn main() {} "#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0038")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0038")).element( Snippet::source(source) .path("$DIR/long-span.rs") .fold(true) @@ -1875,7 +1867,8 @@ fn main() {} .span(15..5055) .label("expected `u8`, found `[{integer}; 1680]`"), ), - )]; + ), + ]; let expected = str![[r#" error[E0038]: mismatched types ╭▸ $DIR/long-span.rs:2:15 @@ -1899,9 +1892,8 @@ const C: u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fn main() {} "#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0038")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0038")).element( Snippet::source(source) .path("$DIR/long-span.rs") .fold(true) @@ -1910,7 +1902,8 @@ fn main() {} .span(15..5055) .label("expected `u8`, found `[{integer}; 1680]`"), ), - )]; + ), + ]; let expected = str![[r#" error[E0038]: mismatched types ╭▸ $DIR/long-span.rs:2:15 @@ -1934,9 +1927,8 @@ const C: u8 = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, fn main() {} "#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0038")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0038")).element( Snippet::source(source) .path("$DIR/long-span.rs") .fold(true) @@ -1945,7 +1937,8 @@ fn main() {} .span(15..5055) .label("expected `u8`, found `[{integer}; 1680]`"), ), - )]; + ), + ]; let expected = str![[r#" error[E0038]: mismatched types --> $DIR/long-span.rs:2:15 @@ -1985,7 +1978,7 @@ fn main() { } "#; - let input = &[Group::new().element(Level::ERROR + let input = &[Group::with_title(Level::ERROR .title("`Iterator::map` call that discard the iterator's values")) .element( Snippet::source(source) @@ -2008,8 +2001,7 @@ fn main() { ) .element( Level::NOTE.title("`Iterator::map`, like many of the methods on `Iterator`, gets executed lazily, meaning that its effects won't be visible until it is iterated")), - Group::new() - .element(Level::HELP.title("you might have meant to use `Iterator::for_each`")) + Group::with_title(Level::HELP.title("you might have meant to use `Iterator::for_each`")) .element( Snippet::source(source) .path("$DIR/lint_map_unit_fn.rs") @@ -2076,23 +2068,19 @@ fn main() { "#; let input = &[ - Group::new() - .element(Level::ERROR.title("character constant must be escaped: `\\n`")) - .element( - Snippet::source(source) - .path("$DIR/bad-char-literals.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(204..205)), - ), - Group::new() - .element(Level::HELP.title("escape the character")) - .element( - Snippet::source(source) - .path("$DIR/bad-char-literals.rs") - .line_start(1) - .fold(true) - .patch(Patch::new(204..205, r#"\n"#)), - ), + Group::with_title(Level::ERROR.title("character constant must be escaped: `\\n`")).element( + Snippet::source(source) + .path("$DIR/bad-char-literals.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(204..205)), + ), + Group::with_title(Level::HELP.title("escape the character")).element( + Snippet::source(source) + .path("$DIR/bad-char-literals.rs") + .line_start(1) + .fold(true) + .patch(Patch::new(204..205, r#"\n"#)), + ), ]; let expected = str![[r#" error: character constant must be escaped: `/n` @@ -2129,22 +2117,18 @@ fn main() {} "#; let input = &[ - Group::new() - .element(Level::ERROR.title("unclosed frontmatter")) - .element( - Snippet::source(source) - .path("$DIR/unclosed-1.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(0..221)), - ), - Group::new() - .element(Level::NOTE.title("frontmatter opening here was not closed")) - .element( - Snippet::source(source) - .path("$DIR/unclosed-1.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(0..4)), - ), + Group::with_title(Level::ERROR.title("unclosed frontmatter")).element( + Snippet::source(source) + .path("$DIR/unclosed-1.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(0..221)), + ), + Group::with_title(Level::NOTE.title("frontmatter opening here was not closed")).element( + Snippet::source(source) + .path("$DIR/unclosed-1.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(0..4)), + ), ]; let expected = str![[r#" error: unclosed frontmatter @@ -2187,22 +2171,18 @@ fn foo() -> &str { "#; let input = &[ - Group::new() - .element(Level::ERROR.title("unclosed frontmatter")) - .element( - Snippet::source(source) - .path("$DIR/unclosed-2.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(0..377)), - ), - Group::new() - .element(Level::NOTE.title("frontmatter opening here was not closed")) - .element( - Snippet::source(source) - .path("$DIR/unclosed-2.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(0..4)), - ), + Group::with_title(Level::ERROR.title("unclosed frontmatter")).element( + Snippet::source(source) + .path("$DIR/unclosed-2.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(0..377)), + ), + Group::with_title(Level::NOTE.title("frontmatter opening here was not closed")).element( + Snippet::source(source) + .path("$DIR/unclosed-2.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(0..4)), + ), ]; let expected = str![[r#" error: unclosed frontmatter @@ -2247,22 +2227,22 @@ fn foo(x: i32) -> i32 { "#; let input = &[ - Group::new() - .element(Level::ERROR.title("invalid preceding whitespace for frontmatter close")) + Group::with_title(Level::ERROR.title("invalid preceding whitespace for frontmatter close")) .element( Snippet::source(source) .path("$DIR/unclosed-3.rs") .fold(true) .annotation(AnnotationKind::Primary.span(302..310)), ), - Group::new() - .element(Level::NOTE.title("frontmatter close should not be preceded by whitespace")) - .element( - Snippet::source(source) - .path("$DIR/unclosed-3.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(302..306)), - ), + Group::with_title( + Level::NOTE.title("frontmatter close should not be preceded by whitespace"), + ) + .element( + Snippet::source(source) + .path("$DIR/unclosed-3.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(302..306)), + ), ]; let expected = str![[r#" error: invalid preceding whitespace for frontmatter close @@ -2297,22 +2277,18 @@ fn main() {} "#; let input = &[ - Group::new() - .element(Level::ERROR.title("unclosed frontmatter")) - .element( - Snippet::source(source) - .path("$DIR/unclosed-4.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(0..43)), - ), - Group::new() - .element(Level::NOTE.title("frontmatter opening here was not closed")) - .element( - Snippet::source(source) - .path("$DIR/unclosed-4.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(0..4)), - ), + Group::with_title(Level::ERROR.title("unclosed frontmatter")).element( + Snippet::source(source) + .path("$DIR/unclosed-4.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(0..43)), + ), + Group::with_title(Level::NOTE.title("frontmatter opening here was not closed")).element( + Snippet::source(source) + .path("$DIR/unclosed-4.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(0..4)), + ), ]; let expected = str![[r#" error: unclosed frontmatter @@ -2350,22 +2326,18 @@ fn main() {} "#; let input = &[ - Group::new() - .element(Level::ERROR.title("unclosed frontmatter")) - .element( - Snippet::source(source) - .path("$DIR/unclosed-5.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(0..176)), - ), - Group::new() - .element(Level::NOTE.title("frontmatter opening here was not closed")) - .element( - Snippet::source(source) - .path("$DIR/unclosed-5.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(0..4)), - ), + Group::with_title(Level::ERROR.title("unclosed frontmatter")).element( + Snippet::source(source) + .path("$DIR/unclosed-5.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(0..176)), + ), + Group::with_title(Level::NOTE.title("frontmatter opening here was not closed")).element( + Snippet::source(source) + .path("$DIR/unclosed-5.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(0..4)), + ), ]; let expected = str![[r#" @@ -2471,46 +2443,49 @@ pub enum E2 { } "#; - let input = &[Group::new().element(Level::ERROR - .title("expected unit struct, unit variant or constant, found tuple variant `E1::Z1`") - .id(r#"E0532"#)) - .element( - Snippet::source(source) - .path("$DIR/pat-tuple-field-count-cross.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(1760..1766)), + let input = &[ + Group::with_title( + Level::ERROR + .title( + "expected unit struct, unit variant or constant, found tuple variant `E1::Z1`", ) - .element( - Snippet::source(source1) - .path("$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::new() - .element(Level::HELP.title("use the tuple variant pattern syntax instead")) - .element( - Snippet::source(source) - .path("$DIR/pat-tuple-field-count-cross.rs") - .fold(true) - .patch(Patch::new(1760..1766, r#"E1::Z1()"#)), + .id(r#"E0532"#), + ) + .element( + Snippet::source(source) + .path("$DIR/pat-tuple-field-count-cross.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(1760..1766)), + ) + .element( + Snippet::source(source1) + .path("$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::new() - .element(Level::HELP.title("a unit variant with a similar name exists")) - .element( - Snippet::source(source) - .path("$DIR/pat-tuple-field-count-cross.rs") - .fold(true) - .patch(Patch::new(1764..1766, r#"Z0"#)), - )]; + ), + Group::with_title(Level::HELP.title("use the tuple variant pattern syntax instead")) + .element( + Snippet::source(source) + .path("$DIR/pat-tuple-field-count-cross.rs") + .fold(true) + .patch(Patch::new(1760..1766, r#"E1::Z1()"#)), + ), + Group::with_title(Level::HELP.title("a unit variant with a similar name exists")).element( + Snippet::source(source) + .path("$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 @@ -2549,9 +2524,8 @@ fn unterminated_nested_comment() { */ "#; - let input = &[Group::new() - .element(Level::ERROR.title("unterminated block comment").id("E0758")) - .element( + let input = &[ + Group::with_title(Level::ERROR.title("unterminated block comment").id("E0758")).element( Snippet::source(source) .path("$DIR/unterminated-nested-comment.rs") .fold(true) @@ -2569,7 +2543,8 @@ fn unterminated_nested_comment() { .label("...and last nested comment terminates here."), ) .annotation(AnnotationKind::Primary.span(0..31)), - )]; + ), + ]; let expected = str![[r#" error[E0758]: unterminated block comment @@ -2605,37 +2580,38 @@ fn mismatched_types1() { let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types }"#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( - Snippet::source(file_txt_source) - .fold(true) - .line_start(3) - .path("$DIR/file.txt") - .annotation( - AnnotationKind::Primary - .span(0..0) - .label("expected `&[u8]`, found `&str`"), - ), - ) - .element( - Snippet::source(rust_source) - .path("$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 input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")) + .element( + Snippet::source(file_txt_source) + .fold(true) + .line_start(3) + .path("$DIR/file.txt") + .annotation( + AnnotationKind::Primary + .span(0..0) + .label("expected `&[u8]`, found `&str`"), + ), + ) + .element( + Snippet::source(rust_source) + .path("$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 @@ -2667,26 +2643,28 @@ fn mismatched_types2() { let s: &str = include_bytes!("file.txt"); //~ ERROR mismatched types }"#; - let input = &[Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( - Snippet::source(source) - .path("$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 input = &[ + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")) + .element( + Snippet::source(source) + .path("$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 @@ -2720,32 +2698,28 @@ fn main() { "#; let input = &[ - Group::new() - .element(Level::ERROR.title("mismatched types").id("E0308")) - .element( - Snippet::source(source) - .path("$DIR/short-error-format.rs") - .fold(true) - .annotation( - AnnotationKind::Primary - .span(80..100) - .label("expected `u32`, found `String`"), - ) - .annotation( - AnnotationKind::Context - .span(76..79) - .label("arguments to this function are incorrect"), - ), - ), - Group::new() - .element(Level::NOTE.title("function defined here")) - .element( - Snippet::source(source) - .path("$DIR/short-error-format.rs") - .fold(true) - .annotation(AnnotationKind::Context.span(48..54).label("")) - .annotation(AnnotationKind::Primary.span(44..47)), - ), + Group::with_title(Level::ERROR.title("mismatched types").id("E0308")).element( + Snippet::source(source) + .path("$DIR/short-error-format.rs") + .fold(true) + .annotation( + AnnotationKind::Primary + .span(80..100) + .label("expected `u32`, found `String`"), + ) + .annotation( + AnnotationKind::Context + .span(76..79) + .label("arguments to this function are incorrect"), + ), + ), + Group::with_title(Level::NOTE.title("function defined here")).element( + Snippet::source(source) + .path("$DIR/short-error-format.rs") + .fold(true) + .annotation(AnnotationKind::Context.span(48..54).label("")) + .annotation(AnnotationKind::Primary.span(44..47)), + ), ]; let expected = str![[r#" @@ -2772,22 +2746,21 @@ fn main() { } "#; - let input = &[Group::new() - .element( - Level::ERROR - .title("no method named `salut` found for type `u32` in the current scope") - .id("E0599"), - ) - .element( - Snippet::source(source) - .path("$DIR/short-error-format.rs") - .fold(true) - .annotation( - AnnotationKind::Primary - .span(127..132) - .label("method not found in `u32`"), - ), - )]; + let input = &[Group::with_title( + Level::ERROR + .title("no method named `salut` found for type `u32` in the current scope") + .id("E0599"), + ) + .element( + Snippet::source(source) + .path("$DIR/short-error-format.rs") + .fold(true) + .annotation( + AnnotationKind::Primary + .span(127..132) + .label("method not found in `u32`"), + ), + )]; let expected = str![[r#" $DIR/short-error-format.rs:8:7: error[E0599]: no method named `salut` found for type `u32` in the current scope: method not found in `u32` @@ -2812,8 +2785,7 @@ pub struct Foo; //~^ ERROR "#; let input = &[ - Group::new() - .element(Level::ERROR.title("this URL is not a hyperlink")) + Group::with_title(Level::ERROR.title("this URL is not a hyperlink")) .element( Snippet::source(source_0) .path("$DIR/diagnostic-width.rs") @@ -2823,24 +2795,20 @@ pub struct Foo; //~^ ERROR .element( Level::NOTE.title("bare URLs are not automatically turned into clickable links"), ), - Group::new() - .element(Level::NOTE.title("the lint level is defined here")) - .element( - Snippet::source(source_0) - .path("$DIR/diagnostic-width.rs") - .fold(true) - .annotation(AnnotationKind::Primary.span(49..67)), - ), - Group::new() - .element(Level::HELP.title("use an automatic link instead")) - .element( - Snippet::source(source_1) - .path("$DIR/diagnostic-width.rs") - .line_start(4) - .fold(true) - .patch(Patch::new(40..40, "<")) - .patch(Patch::new(55..55, ">")), - ), + Group::with_title(Level::NOTE.title("the lint level is defined here")).element( + Snippet::source(source_0) + .path("$DIR/diagnostic-width.rs") + .fold(true) + .annotation(AnnotationKind::Primary.span(49..67)), + ), + Group::with_title(Level::HELP.title("use an automatic link instead")).element( + Snippet::source(source_1) + .path("$DIR/diagnostic-width.rs") + .line_start(4) + .fold(true) + .patch(Patch::new(40..40, "<")) + .patch(Patch::new(55..55, ">")), + ), ]; let expected = str![[r#" @@ -2882,8 +2850,7 @@ fn main() { let long_title3 = "or use `IntoIterator::into_iter(..)` instead of `.into_iter()` to explicitly iterate by value"; let input = &[ - Group::new() - .element(Level::WARNING.title(long_title1)) + Group::with_title(Level::WARNING.title(long_title1)) .element( Snippet::source(source1) .path("lint_example.rs") @@ -2893,27 +2860,24 @@ fn main() { .element(Level::WARNING.title("this changes meaning in Rust 2021")) .element(Level::NOTE.title(long_title2)) .element(Level::NOTE.title("`#[warn(array_into_iter)]` on by default")), - Group::new() - .element( - Level::HELP.title("use `.iter()` instead of `.into_iter()` to avoid ambiguity"), - ) - .element( - Snippet::source(source2) - .path("lint_example.rs") - .line_start(3) - .fold(true) - .patch(Patch::new(10..19, "iter")), - ), - Group::new() - .element(Level::HELP.title(long_title3)) - .element( - Snippet::source(source2) - .path("lint_example.rs") - .line_start(3) - .fold(true) - .patch(Patch::new(0..0, "IntoIterator::into_iter(")) - .patch(Patch::new(9..21, ")")), - ), + Group::with_title( + Level::HELP.title("use `.iter()` instead of `.into_iter()` to avoid ambiguity"), + ) + .element( + Snippet::source(source2) + .path("lint_example.rs") + .line_start(3) + .fold(true) + .patch(Patch::new(10..19, "iter")), + ), + Group::with_title(Level::HELP.title(long_title3)).element( + Snippet::source(source2) + .path("lint_example.rs") + .line_start(3) + .fold(true) + .patch(Patch::new(0..0, "IntoIterator::into_iter(")) + .patch(Patch::new(9..21, ")")), + ), ]; let expected = str![[r#"