From 9f1044ef76de2ae88ac5c38a27b2bd49f5507d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Fri, 13 Dec 2024 18:18:19 +0000 Subject: [PATCH] Account for `///` when rendering multiline spans Don't consider `///` and `//!` docstrings to be empty for the purposes of multiline span rendering. --- compiler/rustc_errors/src/emitter.rs | 17 +++---- .../tests/ui/doc/unbalanced_ticks.stderr | 4 +- .../ui/empty_line_after/doc_comments.stderr | 3 ++ .../clippy/tests/ui/needless_doc_main.stderr | 14 ++++-- .../suspicious_doc_comments_unfixable.stderr | 9 +++- .../too_long_first_doc_paragraph-fix.stderr | 4 +- .../ui/too_long_first_doc_paragraph.stderr | 7 ++- ...ustom_code_classes_in_docs-warning3.stderr | 6 +++ .../rustdoc-ui/doctest/check-attr-test.stderr | 48 ++++++++++++++----- .../doctest/private-item-doc-test.stderr | 4 +- .../private-public-item-doc-test.stderr | 4 +- .../doctest/standalone-warning-2024.stderr | 12 ++++- tests/rustdoc-ui/invalid-syntax.stderr | 7 ++- tests/rustdoc-ui/lints/check-attr.stderr | 29 +++++++++-- tests/rustdoc-ui/lints/check-fail.stderr | 8 +++- tests/rustdoc-ui/lints/lint-group.stderr | 4 +- tests/rustdoc-ui/unescaped_backticks.stderr | 4 ++ tests/ui/macros/issue-112342-1.stderr | 3 +- 18 files changed, 144 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 04b18b92a0c81..ac2f91cdeb3fe 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -3050,13 +3050,17 @@ impl FileWithAnnotatedLines { // We'll show up to 4 lines past the beginning of the multispan start. // We will *not* include the tail of lines that are only whitespace, a comment or // a bare delimiter. + let filter = |s: &str| { + let s = s.trim(); + // Consider comments as empty, but don't consider docstrings to be empty. + !(s.starts_with("//") && !(s.starts_with("///") || s.starts_with("//!"))) + // Consider lines with nothing but whitespace, a single delimiter as empty. + && !["", "{", "}", "(", ")", "[", "]"].contains(&s) + }; let until = (ann.line_start..middle) .rev() .filter_map(|line| file.get_line(line - 1).map(|s| (line + 1, s))) - .find(|(_, s)| { - let s = s.trim(); - !["", "{", "}", "(", ")", "[", "]"].contains(&s) && !s.starts_with("//") - }) + .find(|(_, s)| filter(s)) .map(|(line, _)| line) .unwrap_or(ann.line_start); for line in ann.line_start + 1..until { @@ -3064,10 +3068,7 @@ impl FileWithAnnotatedLines { add_annotation_to_file(&mut output, Lrc::clone(&file), line, ann.as_line()); } let line_end = ann.line_end - 1; - let end_is_empty = file.get_line(line_end - 1).map_or(false, |s| { - let s = s.trim(); - ["", "{", "}", "(", ")", "[", "]"].contains(&s) || s.starts_with("//") - }); + let end_is_empty = file.get_line(line_end - 1).map_or(false, |s| !filter(&s)); if middle < line_end && !end_is_empty { add_annotation_to_file(&mut output, Lrc::clone(&file), line_end, ann.as_line()); } diff --git a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr index 3bcf65c4595de..50324010e97f7 100644 --- a/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr +++ b/src/tools/clippy/tests/ui/doc/unbalanced_ticks.stderr @@ -3,7 +3,9 @@ error: backticks are unbalanced | LL | /// This is a doc comment with `unbalanced_tick marks and several words that | _____^ -... | +LL | | +LL | | /// should be `encompassed_by` tick marks because they `contain_underscores`. +LL | | /// Because of the initial `unbalanced_tick` pair, the error message is LL | | /// very `confusing_and_misleading`. | |____________________________________^ | diff --git a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr index c4d4dde7f73fe..c5d5f3d375947 100644 --- a/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr +++ b/src/tools/clippy/tests/ui/empty_line_after/doc_comments.stderr @@ -96,6 +96,9 @@ error: empty lines after doc comment --> tests/ui/empty_line_after/doc_comments.rs:63:5 | LL | / /// for OldA +LL | | // struct OldA; +LL | | +LL | | /// Docs ... | LL | | | |_^ diff --git a/src/tools/clippy/tests/ui/needless_doc_main.stderr b/src/tools/clippy/tests/ui/needless_doc_main.stderr index cfb389801db03..7e362cf377ce4 100644 --- a/src/tools/clippy/tests/ui/needless_doc_main.stderr +++ b/src/tools/clippy/tests/ui/needless_doc_main.stderr @@ -3,7 +3,9 @@ error: needless `fn main` in doctest | LL | /// fn main() { | _____^ -... | +LL | | +LL | | +LL | | /// unimplemented!(); LL | | /// } | |_____^ | @@ -15,7 +17,8 @@ error: needless `fn main` in doctest | LL | /// fn main() -> () { | _____^ -... | +LL | | +LL | | /// unimplemented!(); LL | | /// } | |_____^ @@ -24,7 +27,8 @@ error: needless `fn main` in doctest | LL | /// fn main() { | _____^ -... | +LL | | +LL | | /// unimplemented!(); LL | | /// } | |_____^ @@ -33,7 +37,9 @@ error: needless `fn main` in doctest | LL | /// // the fn is not always the first line | _____^ -... | +LL | | +LL | | /// fn main() { +LL | | /// unimplemented!(); LL | | /// } | |_____^ diff --git a/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr b/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr index 2209a63d2c0f2..d15f16f7c5032 100644 --- a/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr +++ b/src/tools/clippy/tests/ui/suspicious_doc_comments_unfixable.stderr @@ -2,7 +2,10 @@ error: this is an outer doc comment and does not apply to the parent module or c --> tests/ui/suspicious_doc_comments_unfixable.rs:4:1 | LL | / ///! a -... | +LL | | +LL | | +LL | | ///! b +LL | | /// c LL | | ///! d | |______^ | @@ -22,7 +25,9 @@ error: this is an outer doc comment and does not apply to the parent module or c --> tests/ui/suspicious_doc_comments_unfixable.rs:12:1 | LL | / ///! a -... | +LL | | +LL | | ///! b +LL | | /// c LL | | ///! d | |______^ | diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr index 5925d2f902a7d..6ef333f0cfd29 100644 --- a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr +++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph-fix.stderr @@ -2,7 +2,9 @@ error: first doc comment paragraph is too long --> tests/ui/too_long_first_doc_paragraph-fix.rs:3:1 | LL | / /// A very short summary. -... | +LL | | /// A much longer explanation that goes into a lot more detail about +LL | | /// how the thing works, possibly with doclinks and so one, +LL | | /// and probably spanning a many rows. Blablabla, it needs to be over LL | | /// 200 characters so I needed to write something longeeeeeeer. | |_^ | diff --git a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr index c40ee2fcb48f9..95f42349b9b35 100644 --- a/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr +++ b/src/tools/clippy/tests/ui/too_long_first_doc_paragraph.stderr @@ -2,7 +2,9 @@ error: first doc comment paragraph is too long --> tests/ui/too_long_first_doc_paragraph.rs:8:5 | LL | / //! A very short summary. -... | +LL | | //! A much longer explanation that goes into a lot more detail about +LL | | //! how the thing works, possibly with doclinks and so one, +LL | | //! and probably spanning a many rows. Blablabla, it needs to be over LL | | //! 200 characters so I needed to write something longeeeeeeer. | |____^ | @@ -27,7 +29,8 @@ error: first doc comment paragraph is too long --> tests/ui/too_long_first_doc_paragraph.rs:36:1 | LL | / /// Lorem -... | +LL | | /// ipsum dolor sit amet, consectetur adipiscing elit. Nunc turpis nunc, lacinia +LL | | /// a dolor in, pellentesque aliquet enim. Cras nec maximus sem. Mauris arcu libero, LL | | /// gravida non lacinia at, rhoncus eu lacus. | |_^ diff --git a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr index a72e21fed8558..385b2ccacc1b3 100644 --- a/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr +++ b/tests/rustdoc-ui/custom_code_classes_in_docs-warning3.stderr @@ -2,7 +2,10 @@ error: unclosed quote string `"` --> $DIR/custom_code_classes_in_docs-warning3.rs:8:1 | LL | / /// ```{class="} +LL | | /// main; +LL | | /// ``` ... | +LL | | /// main; LL | | /// ``` | |_______^ | @@ -17,7 +20,10 @@ error: unclosed quote string `"` --> $DIR/custom_code_classes_in_docs-warning3.rs:8:1 | LL | / /// ```{class="} +LL | | /// main; +LL | | /// ``` ... | +LL | | /// main; LL | | /// ``` | |_______^ | diff --git a/tests/rustdoc-ui/doctest/check-attr-test.stderr b/tests/rustdoc-ui/doctest/check-attr-test.stderr index 2703885b18416..257136d1633d3 100644 --- a/tests/rustdoc-ui/doctest/check-attr-test.stderr +++ b/tests/rustdoc-ui/doctest/check-attr-test.stderr @@ -2,7 +2,9 @@ error: unknown attribute `compile-fail` --> $DIR/check-attr-test.rs:5:1 | 5 | / /// foo -... | +6 | | /// +7 | | /// ```compile-fail,compilefail,comPile_fail +8 | | /// boo 9 | | /// ``` | |_______^ | @@ -18,7 +20,9 @@ error: unknown attribute `compilefail` --> $DIR/check-attr-test.rs:5:1 | 5 | / /// foo -... | +6 | | /// +7 | | /// ```compile-fail,compilefail,comPile_fail +8 | | /// boo 9 | | /// ``` | |_______^ | @@ -29,7 +33,9 @@ error: unknown attribute `comPile_fail` --> $DIR/check-attr-test.rs:5:1 | 5 | / /// foo -... | +6 | | /// +7 | | /// ```compile-fail,compilefail,comPile_fail +8 | | /// boo 9 | | /// ``` | |_______^ | @@ -40,7 +46,9 @@ error: unknown attribute `should-panic` --> $DIR/check-attr-test.rs:12:1 | 12 | / /// bar -... | +13 | | /// +14 | | /// ```should-panic,shouldpanic,shOuld_panic +15 | | /// boo 16 | | /// ``` | |_______^ | @@ -51,7 +59,9 @@ error: unknown attribute `shouldpanic` --> $DIR/check-attr-test.rs:12:1 | 12 | / /// bar -... | +13 | | /// +14 | | /// ```should-panic,shouldpanic,shOuld_panic +15 | | /// boo 16 | | /// ``` | |_______^ | @@ -62,7 +72,9 @@ error: unknown attribute `shOuld_panic` --> $DIR/check-attr-test.rs:12:1 | 12 | / /// bar -... | +13 | | /// +14 | | /// ```should-panic,shouldpanic,shOuld_panic +15 | | /// boo 16 | | /// ``` | |_______^ | @@ -73,7 +85,9 @@ error: unknown attribute `no-run` --> $DIR/check-attr-test.rs:19:1 | 19 | / /// foobar -... | +20 | | /// +21 | | /// ```no-run,norun,nO_run +22 | | /// boo 23 | | /// ``` | |_______^ | @@ -84,7 +98,9 @@ error: unknown attribute `norun` --> $DIR/check-attr-test.rs:19:1 | 19 | / /// foobar -... | +20 | | /// +21 | | /// ```no-run,norun,nO_run +22 | | /// boo 23 | | /// ``` | |_______^ | @@ -95,7 +111,9 @@ error: unknown attribute `nO_run` --> $DIR/check-attr-test.rs:19:1 | 19 | / /// foobar -... | +20 | | /// +21 | | /// ```no-run,norun,nO_run +22 | | /// boo 23 | | /// ``` | |_______^ | @@ -106,7 +124,9 @@ error: unknown attribute `test-harness` --> $DIR/check-attr-test.rs:26:1 | 26 | / /// b -... | +27 | | /// +28 | | /// ```test-harness,testharness,tesT_harness +29 | | /// boo 30 | | /// ``` | |_______^ | @@ -117,7 +137,9 @@ error: unknown attribute `testharness` --> $DIR/check-attr-test.rs:26:1 | 26 | / /// b -... | +27 | | /// +28 | | /// ```test-harness,testharness,tesT_harness +29 | | /// boo 30 | | /// ``` | |_______^ | @@ -128,7 +150,9 @@ error: unknown attribute `tesT_harness` --> $DIR/check-attr-test.rs:26:1 | 26 | / /// b -... | +27 | | /// +28 | | /// ```test-harness,testharness,tesT_harness +29 | | /// boo 30 | | /// ``` | |_______^ | diff --git a/tests/rustdoc-ui/doctest/private-item-doc-test.stderr b/tests/rustdoc-ui/doctest/private-item-doc-test.stderr index 7ce1f0314991f..5177057c7284d 100644 --- a/tests/rustdoc-ui/doctest/private-item-doc-test.stderr +++ b/tests/rustdoc-ui/doctest/private-item-doc-test.stderr @@ -2,7 +2,9 @@ error: documentation test in private item --> $DIR/private-item-doc-test.rs:4:5 | LL | / /// private doc test -... | +LL | | /// +LL | | /// ``` +LL | | /// assert!(false); LL | | /// ``` | |___________^ | diff --git a/tests/rustdoc-ui/doctest/private-public-item-doc-test.stderr b/tests/rustdoc-ui/doctest/private-public-item-doc-test.stderr index aa01f39314c98..38b8dd652d3ed 100644 --- a/tests/rustdoc-ui/doctest/private-public-item-doc-test.stderr +++ b/tests/rustdoc-ui/doctest/private-public-item-doc-test.stderr @@ -2,7 +2,9 @@ error: documentation test in private item --> $DIR/private-public-item-doc-test.rs:4:5 | LL | / /// private doc test -... | +LL | | /// +LL | | /// ``` +LL | | /// assert!(false); LL | | /// ``` | |___________^ | diff --git a/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr b/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr index 662f07f3a4cc1..bfc1e91940453 100644 --- a/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr +++ b/tests/rustdoc-ui/doctest/standalone-warning-2024.stderr @@ -2,7 +2,11 @@ error: unknown attribute `standalone` --> $DIR/standalone-warning-2024.rs:11:1 | 11 | / //! ```standalone -... | +12 | | //! bla +13 | | //! ``` +14 | | //! +15 | | //! ```standalone-crate +16 | | //! bla 17 | | //! ``` | |_______^ | @@ -19,7 +23,11 @@ error: unknown attribute `standalone-crate` --> $DIR/standalone-warning-2024.rs:11:1 | 11 | / //! ```standalone -... | +12 | | //! bla +13 | | //! ``` +14 | | //! +15 | | //! ```standalone-crate +16 | | //! bla 17 | | //! ``` | |_______^ | diff --git a/tests/rustdoc-ui/invalid-syntax.stderr b/tests/rustdoc-ui/invalid-syntax.stderr index f30660017d9dc..c6e1f6fd41384 100644 --- a/tests/rustdoc-ui/invalid-syntax.stderr +++ b/tests/rustdoc-ui/invalid-syntax.stderr @@ -21,7 +21,9 @@ warning: could not parse code block as Rust code | LL | /// ``` | _____^ -... | +LL | | /// | +LL | | /// LL | use foobar::Baz; +LL | | /// | ^^^^^^ did you mean `baz::foobar`? LL | | /// ``` | |_______^ | @@ -112,7 +114,8 @@ warning: Rust code block is empty | LL | /// ``` | _____^ -... | +LL | | /// +LL | | /// LL | | /// ``` | |_______^ | diff --git a/tests/rustdoc-ui/lints/check-attr.stderr b/tests/rustdoc-ui/lints/check-attr.stderr index 4576dea79cbdd..3366c021727cd 100644 --- a/tests/rustdoc-ui/lints/check-attr.stderr +++ b/tests/rustdoc-ui/lints/check-attr.stderr @@ -3,6 +3,7 @@ error: unknown attribute `compile-fail` | LL | / /// foo ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -19,6 +20,7 @@ error: unknown attribute `compilefail` | LL | / /// foo ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -30,6 +32,7 @@ error: unknown attribute `comPile_fail` | LL | / /// foo ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -41,6 +44,7 @@ error: unknown attribute `should-panic` | LL | / /// bar ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -52,6 +56,7 @@ error: unknown attribute `shouldpanic` | LL | / /// bar ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -63,6 +68,7 @@ error: unknown attribute `sHould_panic` | LL | / /// bar ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -74,6 +80,7 @@ error: unknown attribute `no-run` | LL | / /// foobar ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -85,6 +92,7 @@ error: unknown attribute `norun` | LL | / /// foobar ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -96,6 +104,7 @@ error: unknown attribute `no_Run` | LL | / /// foobar ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -107,6 +116,7 @@ error: unknown attribute `test-harness` | LL | / /// b ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -118,6 +128,7 @@ error: unknown attribute `testharness` | LL | / /// b ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -129,6 +140,7 @@ error: unknown attribute `teSt_harness` | LL | / /// b ... | +LL | | /// boo LL | | /// ``` | |_______^ | @@ -139,7 +151,10 @@ error: unknown attribute `rust2018` --> $DIR/check-attr.rs:43:1 | LL | / /// b -... | +LL | | +LL | | /// +LL | | /// ```rust2018 +LL | | /// boo LL | | /// ``` | |_______^ | @@ -149,7 +164,11 @@ error: unknown attribute `rust2018` --> $DIR/check-attr.rs:51:1 | LL | / /// b -... | +LL | | +LL | | +LL | | /// +LL | | /// ```rust2018 shouldpanic +LL | | /// boo LL | | /// ``` | |_______^ | @@ -159,7 +178,11 @@ error: unknown attribute `shouldpanic` --> $DIR/check-attr.rs:51:1 | LL | / /// b -... | +LL | | +LL | | +LL | | /// +LL | | /// ```rust2018 shouldpanic +LL | | /// boo LL | | /// ``` | |_______^ | diff --git a/tests/rustdoc-ui/lints/check-fail.stderr b/tests/rustdoc-ui/lints/check-fail.stderr index f021f0c42e5a4..2eb9496e5dc94 100644 --- a/tests/rustdoc-ui/lints/check-fail.stderr +++ b/tests/rustdoc-ui/lints/check-fail.stderr @@ -26,7 +26,8 @@ error: unknown attribute `testharness` --> $DIR/check-fail.rs:8:1 | LL | / //! ```rust,testharness -... | +LL | | +LL | | //! let x = 12; LL | | //! ``` | |_______^ | @@ -43,7 +44,10 @@ error: unknown attribute `testharness` --> $DIR/check-fail.rs:17:1 | LL | / /// hello -... | +LL | | +LL | | /// +LL | | /// ```rust,testharness +LL | | /// let x = 12; LL | | /// ``` | |_______^ | diff --git a/tests/rustdoc-ui/lints/lint-group.stderr b/tests/rustdoc-ui/lints/lint-group.stderr index 4b5b64c4378f0..7ff09fcc45a12 100644 --- a/tests/rustdoc-ui/lints/lint-group.stderr +++ b/tests/rustdoc-ui/lints/lint-group.stderr @@ -14,7 +14,9 @@ error: documentation test in private item --> $DIR/lint-group.rs:22:1 | LL | / /// wait, this *does* have a doctest? -... | +LL | | /// +LL | | /// ``` +LL | | /// println!("sup"); LL | | /// ``` | |_______^ | diff --git a/tests/rustdoc-ui/unescaped_backticks.stderr b/tests/rustdoc-ui/unescaped_backticks.stderr index 01b2fd1fa272b..d93aaf5f3ca94 100644 --- a/tests/rustdoc-ui/unescaped_backticks.stderr +++ b/tests/rustdoc-ui/unescaped_backticks.stderr @@ -272,6 +272,7 @@ error: unescaped backtick | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max LL | | /// level changes. | |______________________^ | @@ -287,6 +288,7 @@ error: unescaped backtick | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max LL | | /// level changes. | |______________________^ | @@ -300,6 +302,7 @@ error: unescaped backtick | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max LL | | /// level changes. | |______________________^ | @@ -315,6 +318,7 @@ error: unescaped backtick | LL | / /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`], ... | +LL | | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max LL | | /// level changes. | |______________________^ | diff --git a/tests/ui/macros/issue-112342-1.stderr b/tests/ui/macros/issue-112342-1.stderr index 73a7fe3a12773..f2d82bf599e99 100644 --- a/tests/ui/macros/issue-112342-1.stderr +++ b/tests/ui/macros/issue-112342-1.stderr @@ -55,7 +55,8 @@ error: repetition matches empty token tree | LL | $( | __________^ -... | +LL | | /// +LL | | /// LL | | )* | |_________^