Repository: rust-lang/rust
Pull request #136400: Improve handling of rustdoc lints when used with raw doc fragments.
Author: login: lolbinarycat
Labels: name: T-rustdoc
description: Relevant to the rustdoc team, which will review and decide on the PR/issue.
name: T-compiler
description: Relevant to the compiler team, which will review and decide on the PR/issue.
name: S-waiting-on-bors
description: Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Created: 2025-02-01T21:03:51Z | Merged: 2025-05-23T20:33:38Z

<!-- homu-ignore:start -->
<!--
If this PR is related to an unstable feature or an otherwise tracked effort,
please link to the relevant tracking issue here. If you don't know of a related
tracking issue or there are none, feel free to ignore this.

This PR will get automatically assigned to a reviewer. In case you would like
a specific user to review your work, you can assign it to them by using

    r? <reviewer name>
-->
<!-- homu-ignore:end -->

1. `rustdoc::bare_urls` no longer outputs incoherent suggestions if `source_span_for_markdown_range` returns None, instead outputting no suggestion
2. `source_span_for_markdown_range` has one more heuristic, so it will return `None` less often. 
3. add ui test to make sure we don't emit nonsense suggestions.

fixes https://github.com/rust-lang/rust/issues/135851


Diff:
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs
index a32fe6990160c..24ebb4ddfbc2d 100644
--- a/compiler/rustc_resolve/src/rustdoc.rs
+++ b/compiler/rustc_resolve/src/rustdoc.rs
@@ -514,20 +514,30 @@ pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> {
 /// This method does not always work, because markdown bytes don't necessarily match source bytes,
 /// like if escapes are used in the string. In this case, it returns `None`.
 ///
-/// This method will return `Some` only if:
+/// `markdown` is typically the entire documentation for an item,
+/// after combining fragments.
+///
+/// This method will return `Some` only if one of the following is true:
 ///
 /// - The doc is made entirely from sugared doc comments, which cannot contain escapes
-/// - The doc is entirely from a single doc fragment, with a string literal, exactly equal
+/// - The doc is entirely from a single doc fragment with a string literal exactly equal to `markdown`.
 /// - The doc comes from `include_str!`
+/// - The doc includes exactly one substring matching `markdown[md_range]` which is contained in a single doc fragment.
+///
+/// This function is defined in the compiler so it can be used by
+/// both `rustdoc` and `clippy`.
 pub fn source_span_for_markdown_range(
     tcx: TyCtxt<'_>,
     markdown: &str,
     md_range: &Range<usize>,
     fragments: &[DocFragment],
 ) -> Option<Span> {
+    use rustc_span::BytePos;
+
+    let map = tcx.sess.source_map();
     if let &[fragment] = &fragments
         && fragment.kind == DocFragmentKind::RawDoc
-        && let Ok(snippet) = tcx.sess.source_map().span_to_snippet(fragment.span)
+        && let Ok(snippet) = map.span_to_snippet(fragment.span)
         && snippet.trim_end() == markdown.trim_end()
         && let Ok(md_range_lo) = u32::try_from(md_range.start)
         && let Ok(md_range_hi) = u32::try_from(md_range.end)
@@ -544,10 +554,43 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // This case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // This heirustic doesn't make sense with a zero-sized range.
+        if pat.is_empty() {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = map.span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // If there is either a match in a previous fragment, or
+                // multiple matches in this fragment, there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // Heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            let sp = fragments[i].span;
+            // we need to calculate the span start,
+            // then use that in our calulations for the span end
+            let lo = sp.lo() + BytePos(match_start as u32);
+            return Some(
+                sp.with_lo(lo).with_hi(lo + BytePos((md_range.end - md_range.start) as u32)),
+            );
+        }
         return None;
     }
 
-    let snippet = tcx.sess.source_map().span_to_snippet(span_of_fragments(fragments)?).ok()?;
+    let snippet = map.span_to_snippet(span_of_fragments(fragments)?).ok()?;
 
     let starting_line = markdown[..md_range.start].matches('\n').count();
     let ending_line = starting_line + markdown[md_range.start..md_range.end].matches('\n').count();
diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs
index 1e07277d38e5c..3b3ce3e92202a 100644
--- a/src/librustdoc/passes/lint/bare_urls.rs
+++ b/src/librustdoc/passes/lint/bare_urls.rs
@@ -18,12 +18,15 @@ use crate::html::markdown::main_body_opts;
 
 pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) {
     let report_diag = |cx: &DocContext<'_>, msg: &'static str, range: Range<usize>| {
-        let sp = source_span_for_markdown_range(cx.tcx, dox, &range, &item.attrs.doc_strings)
-            .unwrap_or_else(|| item.attr_span(cx.tcx));
+        let maybe_sp = source_span_for_markdown_range(cx.tcx, dox, &range, &item.attrs.doc_strings);
+        let sp = maybe_sp.unwrap_or_else(|| item.attr_span(cx.tcx));
         cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| {
             lint.primary_message(msg)
-                .note("bare URLs are not automatically turned into clickable links")
-                .multipart_suggestion(
+                .note("bare URLs are not automatically turned into clickable links");
+            // The fallback of using the attribute span is suitable for
+            // highlighting where the error is, but not for placing the < and >
+            if let Some(sp) = maybe_sp {
+                lint.multipart_suggestion(
                     "use an automatic link instead",
                     vec![
                         (sp.shrink_to_lo(), "<".to_string()),
@@ -31,6 +34,7 @@ pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
                     ],
                     Applicability::MachineApplicable,
                 );
+            }
         });
     };
 
diff --git a/tests/rustdoc-ui/intra-doc/warning.stderr b/tests/rustdoc-ui/intra-doc/warning.stderr
index 3a06f1787e093..9b3f6f822d75b 100644
--- a/tests/rustdoc-ui/intra-doc/warning.stderr
+++ b/tests/rustdoc-ui/intra-doc/warning.stderr
@@ -69,29 +69,19 @@ LL | bar [BarC] bar
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: unresolved link to `BarD`
-  --> $DIR/warning.rs:45:9
+  --> $DIR/warning.rs:45:20
    |
 LL | #[doc = "Foo\nbar [BarD] bar\nbaz"]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                    ^^^^ no item named `BarD` in scope
    |
-   = note: the link appears in this line:
-           
-           bar [BarD] bar
-                ^^^^
-   = note: no item named `BarD` in scope
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: unresolved link to `BarF`
-  --> $DIR/warning.rs:54:4
+  --> $DIR/warning.rs:54:15
    |
 LL | f!("Foo\nbar [BarF] bar\nbaz");
-   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |               ^^^^ no item named `BarF` in scope
    |
-   = note: the link appears in this line:
-           
-           bar [BarF] bar
-                ^^^^
-   = note: no item named `BarF` in scope
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
    = note: this warning originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)
 
@@ -112,29 +102,19 @@ LL |  * time to introduce a link [error]
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: unresolved link to `error`
-  --> $DIR/warning.rs:68:9
+  --> $DIR/warning.rs:68:23
    |
 LL | #[doc = "single line [error]"]
-   |         ^^^^^^^^^^^^^^^^^^^^^
+   |                       ^^^^^ no item named `error` in scope
    |
-   = note: the link appears in this line:
-           
-           single line [error]
-                        ^^^^^
-   = note: no item named `error` in scope
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: unresolved link to `error`
-  --> $DIR/warning.rs:71:9
+  --> $DIR/warning.rs:71:41
    |
 LL | #[doc = "single line with \"escaping\" [error]"]
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                         ^^^^^ no item named `error` in scope
    |
-   = note: the link appears in this line:
-           
-           single line with "escaping" [error]
-                                        ^^^^^
-   = note: no item named `error` in scope
    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
 
 warning: unresolved link to `error`
diff --git a/tests/rustdoc-ui/lints/bare-urls-limit.rs b/tests/rustdoc-ui/lints/bare-urls-limit.rs
new file mode 100644
index 0000000000000..f64154b049698
--- /dev/null
+++ b/tests/rustdoc-ui/lints/bare-urls-limit.rs
@@ -0,0 +1,12 @@
+//@ check-fail
+
+#![deny(rustdoc::bare_urls)]
+
+// examples of bare urls that are beyond our ability to generate suggestions for
+
+// this falls through every heuristic in `source_span_for_markdown_range`,
+// and thus does not get any suggestion.
+#[doc = "good: <https://example.com/> \n\n"]
+//~^ ERROR this URL is not a hyperlink
+#[doc = "bad: https://example.com/"]
+pub fn duplicate_raw() {}
diff --git a/tests/rustdoc-ui/lints/bare-urls-limit.stderr b/tests/rustdoc-ui/lints/bare-urls-limit.stderr
new file mode 100644
index 0000000000000..9573665cb1311
--- /dev/null
+++ b/tests/rustdoc-ui/lints/bare-urls-limit.stderr
@@ -0,0 +1,18 @@
+error: this URL is not a hyperlink
+  --> $DIR/bare-urls-limit.rs:9:9
+   |
+LL |   #[doc = "good: <https://example.com/> \n\n"]
+   |  _________^
+LL | |
+LL | | #[doc = "bad: https://example.com/"]
+   | |___________________________________^
+   |
+   = note: bare URLs are not automatically turned into clickable links
+note: the lint level is defined here
+  --> $DIR/bare-urls-limit.rs:3:9
+   |
+LL | #![deny(rustdoc::bare_urls)]
+   |         ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/rustdoc-ui/lints/bare-urls.fixed b/tests/rustdoc-ui/lints/bare-urls.fixed
index 7938d715199de..a91573146b823 100644
--- a/tests/rustdoc-ui/lints/bare-urls.fixed
+++ b/tests/rustdoc-ui/lints/bare-urls.fixed
@@ -38,6 +38,16 @@
 //~^ ERROR this URL is not a hyperlink
 pub fn c() {}
 
+#[doc = "here's a thing: <https://example.com/>"]
+//~^ ERROR this URL is not a hyperlink
+pub fn f() {}
+
+/// <https://example.com/sugar>
+//~^ ERROR this URL is not a hyperlink
+#[doc = "<https://example.com/raw>"]
+//~^ ERROR this URL is not a hyperlink
+pub fn mixed() {}
+
 /// <https://somewhere.com>
 /// [a](http://a.com)
 /// [b]
diff --git a/tests/rustdoc-ui/lints/bare-urls.rs b/tests/rustdoc-ui/lints/bare-urls.rs
index 75f42b78ffbbe..5b008cdafa232 100644
--- a/tests/rustdoc-ui/lints/bare-urls.rs
+++ b/tests/rustdoc-ui/lints/bare-urls.rs
@@ -38,6 +38,16 @@
 //~^ ERROR this URL is not a hyperlink
 pub fn c() {}
 
+#[doc = "here's a thing: https://example.com/"]
+//~^ ERROR this URL is not a hyperlink
+pub fn f() {}
+
+/// https://example.com/sugar
+//~^ ERROR this URL is not a hyperlink
+#[doc = "https://example.com/raw"]
+//~^ ERROR this URL is not a hyperlink
+pub fn mixed() {}
+
 /// <https://somewhere.com>
 /// [a](http://a.com)
 /// [b]
diff --git a/tests/rustdoc-ui/lints/bare-urls.stderr b/tests/rustdoc-ui/lints/bare-urls.stderr
index ddfc387eaf66e..e1108c7e7f84e 100644
--- a/tests/rustdoc-ui/lints/bare-urls.stderr
+++ b/tests/rustdoc-ui/lints/bare-urls.stderr
@@ -207,5 +207,41 @@ help: use an automatic link instead
 LL | /// hey! <https://somewhere.com/a?hello=12&bye=11#xyz>
    |          +                                           +
 
-error: aborting due to 17 previous errors
+error: this URL is not a hyperlink
+  --> $DIR/bare-urls.rs:41:26
+   |
+LL | #[doc = "here's a thing: https://example.com/"]
+   |                          ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | #[doc = "here's a thing: <https://example.com/>"]
+   |                          +                    +
+
+error: this URL is not a hyperlink
+  --> $DIR/bare-urls.rs:45:5
+   |
+LL | /// https://example.com/sugar
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | /// <https://example.com/sugar>
+   |     +                         +
+
+error: this URL is not a hyperlink
+  --> $DIR/bare-urls.rs:47:10
+   |
+LL | #[doc = "https://example.com/raw"]
+   |          ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: bare URLs are not automatically turned into clickable links
+help: use an automatic link instead
+   |
+LL | #[doc = "<https://example.com/raw>"]
+   |          +                       +
+
+error: aborting due to 20 previous errors
 
diff --git a/tests/rustdoc-ui/unescaped_backticks.stderr b/tests/rustdoc-ui/unescaped_backticks.stderr
index d93aaf5f3ca94..1bcb88e108f20 100644
--- a/tests/rustdoc-ui/unescaped_backticks.stderr
+++ b/tests/rustdoc-ui/unescaped_backticks.stderr
@@ -628,10 +628,10 @@ LL | /// or even to add a number `n` to 42 (`add(42, n)\`)!
    |                                                   +
 
 error: unescaped backtick
-  --> $DIR/unescaped_backticks.rs:108:9
+  --> $DIR/unescaped_backticks.rs:108:10
    |
 LL | #[doc = "`"]
-   |         ^^^
+   |          ^
    |
    = help: the opening or closing backtick of an inline code may be missing
    = help: if you meant to use a literal backtick, escape it
@@ -639,10 +639,10 @@ LL | #[doc = "`"]
            to this: \`
 
 error: unescaped backtick
-  --> $DIR/unescaped_backticks.rs:115:9
+  --> $DIR/unescaped_backticks.rs:115:26
    |
 LL | #[doc = concat!("\\", "`")]
-   |         ^^^^^^^^^^^^^^^^^^^^
+   |                          ^
    |
    = help: the opening backtick of an inline code may be missing
             change: \`


Reviews:
user: login: petrochenkov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-03T21:19:38Z
user: login: lolbinarycat
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-03T23:11:12Z
user: login: lolbinarycat
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-04T01:05:35Z
user: login: fmease
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-02-04T01:42:48Z
user: login: lolbinarycat
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-04T01:45:57Z
user: login: petrochenkov
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-05T14:05:10Z
user: login: lolbinarycat
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-02-05T19:20:34Z
user: login: fmease
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-04-02T12:16:15Z
user: login: GuillaumeGomez
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T15:26:43Z
user: login: GuillaumeGomez
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T15:27:05Z
user: login: GuillaumeGomez
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T15:28:38Z
user: login: fmease
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T15:31:03Z
user: login: GuillaumeGomez
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T15:32:32Z
user: login: GuillaumeGomez
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T15:33:10Z
user: login: GuillaumeGomez
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T15:34:38Z
user: login: GuillaumeGomez
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T15:42:08Z
user: login: GuillaumeGomez
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-14T15:43:12Z
user: login: GuillaumeGomez
body: Code logic is good, just some nits and then it's good to go.
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-05-14T15:44:27Z
user: login: lolbinarycat
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-21T20:42:00Z
user: login: GuillaumeGomez
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-21T20:48:08Z
user: login: lolbinarycat
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-21T23:07:53Z
user: login: GuillaumeGomez
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-22T12:31:20Z
user: login: lolbinarycat
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-22T15:01:25Z
user: login: GuillaumeGomez
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-22T20:49:26Z

Review comments:
diff_hunk: @@ -528,6 +533,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
+        }
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: petrochenkov
body: This logic is run on a compiler's happy path, when rustdoc and its lints are not involved.
Could you do a perf run before merging this?
created_at: 2025-02-03T21:19:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -528,6 +533,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
+        }
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: lolbinarycat
body: `source_span_to_markdown_range` is? for what purpose?
created_at: 2025-02-03T23:11:12Z
author_association: CONTRIBUTOR
diff_hunk: @@ -528,6 +533,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
+        }
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: lolbinarycat
body: i just checked every usage of this function in this repo, and they're all in rustdoc lints 
created_at: 2025-02-04T01:05:35Z
author_association: CONTRIBUTOR
diff_hunk: @@ -528,6 +533,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
+        }
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: fmease
body: Huh, that's odd. `source_span_to_markdown_range` is indeed not used in the compiler. It should be part of rustdoc instead (it doesn't rely on any compiler-internal APIs, so that would technically work) — **except** that this situation is slightly suspicious. Maybe it used to be used by the compiler in the past, we need to check the history. Also, it might indicate that whoever uses that function doesn't handle cross-crate intra-doc links correctly.
created_at: 2025-02-04T01:42:48Z
author_association: MEMBER
diff_hunk: @@ -528,6 +533,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
+        }
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: lolbinarycat
body: i feel like i'm missing something, i don't see how intra-doc lints are relevant here.
created_at: 2025-02-04T01:45:57Z
author_association: CONTRIBUTOR
diff_hunk: @@ -528,6 +533,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
+        }
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: petrochenkov
body: > i just checked every usage of this function in this repo, and they're all in rustdoc lints

If something is not used in the compiler, then it should not live in `compiler/rustc_resolve`.
created_at: 2025-02-05T14:05:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -528,6 +533,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
+        }
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: lolbinarycat
body: do you want me to move it in this PR, or can it be done in a followup?
created_at: 2025-02-05T19:20:34Z
author_association: CONTRIBUTOR
diff_hunk: @@ -18,19 +18,23 @@ use crate::html::markdown::main_body_opts;
 
 pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) {
     let report_diag = |cx: &DocContext<'_>, msg: &'static str, range: Range<usize>| {
-        let sp = source_span_for_markdown_range(cx.tcx, dox, &range, &item.attrs.doc_strings)
-            .unwrap_or_else(|| item.attr_span(cx.tcx));
+        let maybe_sp = source_span_for_markdown_range(cx.tcx, dox, &range, &item.attrs.doc_strings);
+        let sp = maybe_sp.unwrap_or_else(|| item.attr_span(cx.tcx));
         cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| {
             lint.primary_message(msg)
-                .note("bare URLs are not automatically turned into clickable links")
-                .multipart_suggestion(
+                .note("bare URLs are not automatically turned into clickable links");
+            // the fallback of using the item span is suitible for
path: src/librustdoc/passes/lint/bare_urls.rs
user: login: fmease
body: ```suggestion
// the fallback of using the attribute span is suitable for
```
created_at: 2025-04-02T11:54:55Z
author_association: MEMBER
diff_hunk: @@ -498,20 +498,25 @@ pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> {
 /// This method does not always work, because markdown bytes don't necessarily match source bytes,
 /// like if escapes are used in the string. In this case, it returns `None`.
 ///
+/// `markdown` is typically the entire documentation for an item,
+/// after combining fragments.
+///
 /// This method will return `Some` only if:
 ///
 /// - The doc is made entirely from sugared doc comments, which cannot contain escapes
 /// - The doc is entirely from a single doc fragment, with a string literal, exactly equal
 /// - The doc comes from `include_str!`
+/// - The doc includes exactly one substring matching `markdown[md_range]` which is contained in a single doc fragment.
 pub fn source_span_for_markdown_range(
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: fmease
body: Since #115689 this function resides in compiler, so Clippy can use it, too. You could add a comment explaining that but it's not super necessary since moving this function would lead to the Clippy subtree failing to build
created_at: 2025-04-02T12:03:23Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,12 @@
+//@ check-fail
+
+#![deny(rustdoc::bare_urls)]
+
+// examples of bare urls that are beyond our ability to generate suggestions for
+
+// this falls through every heirustic in `source_span_for_markdown_range`,
path: tests/rustdoc-ui/lints/bare-urls-limit.rs
user: login: fmease
body: ```suggestion
// this falls through every heuristic in `source_span_for_markdown_range`,
```
created_at: 2025-04-02T12:09:21Z
author_association: MEMBER
diff_hunk: @@ -498,20 +498,28 @@ pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> {
 /// This method does not always work, because markdown bytes don't necessarily match source bytes,
 /// like if escapes are used in the string. In this case, it returns `None`.
 ///
-/// This method will return `Some` only if:
+/// `markdown` is typically the entire documentation for an item,
+/// after combining fragments.
+///
+/// This method will return `Some` only if one of the following is true:
 ///
 /// - The doc is made entirely from sugared doc comments, which cannot contain escapes
-/// - The doc is entirely from a single doc fragment, with a string literal, exactly equal
+/// - The doc is entirely from a single doc fragment with a string literal exactly equal to `markdown`.
 /// - The doc comes from `include_str!`
+/// - The doc includes exactly one substring matching `markdown[md_range]` which is contained in a single doc fragment.
+///
+/// This function is defined in the compiler so it can be used by
+/// both `rustdoc` and `clippy`.
 pub fn source_span_for_markdown_range(
     tcx: TyCtxt<'_>,
     markdown: &str,
     md_range: &Range<usize>,
     fragments: &[DocFragment],
 ) -> Option<Span> {
+    let span_to_snippet = |span| tcx.sess.source_map().span_to_snippet(span);
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: fmease
body: style: just do `let map = tcx.sess.source_map();` and change call sites to `map.snap_to_snippet(…)`, it's hardly longer
created_at: 2025-05-14T11:05:25Z
author_association: MEMBER
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: GuillaumeGomez
body: ```suggestion
        if pat.is_empty() {
```
created_at: 2025-05-14T15:26:43Z
author_association: MEMBER
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: GuillaumeGomez
body: ```suggestion
        // This case ignores the markdown outside of the range so that it can
```
created_at: 2025-05-14T15:27:05Z
author_association: MEMBER
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: GuillaumeGomez
body: ```suggestion
        // This heuristic doesn't make sense with a zero-sized range.
```
created_at: 2025-05-14T15:28:37Z
author_association: MEMBER
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: GuillaumeGomez
body: ```suggestion
                // If there is either a match in a previous fragment, or
                // multiple matches in this fragment, there is ambiguity.
```
created_at: 2025-05-14T15:32:32Z
author_association: MEMBER
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: GuillaumeGomez
body: Please move this import either at the beginning of the function or at the top of the file.
created_at: 2025-05-14T15:33:10Z
author_association: MEMBER
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: GuillaumeGomez
body: ```suggestion
                    // Heuristic produced ambiguity, return nothing.
```
created_at: 2025-05-14T15:34:38Z
author_association: MEMBER
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: GuillaumeGomez
body: ```suggestion
            return Some(fragments[i].span.with_lo(sp.lo() + BytePos(match_start as u32)).with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32)));
```
created_at: 2025-05-14T15:42:07Z
author_association: MEMBER
diff_hunk: @@ -18,19 +18,23 @@ use crate::html::markdown::main_body_opts;
 
 pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) {
     let report_diag = |cx: &DocContext<'_>, msg: &'static str, range: Range<usize>| {
-        let sp = source_span_for_markdown_range(cx.tcx, dox, &range, &item.attrs.doc_strings)
-            .unwrap_or_else(|| item.attr_span(cx.tcx));
+        let maybe_sp = source_span_for_markdown_range(cx.tcx, dox, &range, &item.attrs.doc_strings);
+        let sp = maybe_sp.unwrap_or_else(|| item.attr_span(cx.tcx));
         cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| {
             lint.primary_message(msg)
-                .note("bare URLs are not automatically turned into clickable links")
-                .multipart_suggestion(
+                .note("bare URLs are not automatically turned into clickable links");
+            // the fallback of using the attribute span is suitable for
+            // highlighting where the error is, but not for placing the < and >
path: src/librustdoc/passes/lint/bare_urls.rs
user: login: GuillaumeGomez
body: ```suggestion
            // The fallback of using the attribute span is suitable for
            // highlighting where the error is, but not for placing the `<` and `>`.
```
created_at: 2025-05-14T15:43:11Z
author_association: MEMBER
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: lolbinarycat
body: this actually meaningfully changes the semantics drastically.

the reason it's done in 2 starts is we need to mutate `sp.lo` and then use the *new* `sp.lo` in the calculation for `sp.hi`
created_at: 2025-05-21T20:42:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: GuillaumeGomez
body: Oh I see. Instead, why do you think about (making it explicit which `lo` we're using):

```suggestion
            let sp = fragments[i].span;
            let lo = sp.lo() + BytePos(match_start as u32);
            return Some(sp.with_lo(lo).with_hi(lo + BytePos((md_range.end - md_range.start) as u32));
```
created_at: 2025-05-21T20:48:08Z
author_association: MEMBER
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: lolbinarycat
body: That looks.. ok? It does lose all the pleasing alignment from the imperative solution, its quite nested so I'm not sure its any easier to read, and also, I've already iterated on this section like 5 times, and I'm not particularly keen to rewrite it again.
created_at: 2025-05-21T23:07:53Z
author_association: CONTRIBUTOR
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: GuillaumeGomez
body: It's easy to misunderstand this code because `sp`'s `lo` is modified then the new `lo` is used right after. How many times this code was modified is irrelevant here (and 5 times is not that big, believe me :sweat_smile:).
created_at: 2025-05-22T12:31:20Z
author_association: MEMBER
diff_hunk: @@ -528,6 +536,38 @@ pub fn source_span_for_markdown_range(
     let is_all_sugared_doc = fragments.iter().all(|frag| frag.kind == DocFragmentKind::SugaredDoc);
 
     if !is_all_sugared_doc {
+        // this case ignores the markdown outside of the range so that it can
+        // work in cases where the markdown is made from several different
+        // doc fragments, but the target range does not span across multiple
+        // fragments.
+        let mut match_data = None;
+        let pat = &markdown[md_range.clone()];
+        // this heirustic doesn't make sense with a zero-sized range.
+        if pat.len() == 0 {
+            return None;
+        }
+        for (i, fragment) in fragments.iter().enumerate() {
+            if let Ok(snippet) = span_to_snippet(fragment.span)
+                && let Some(match_start) = snippet.find(pat)
+            {
+                // if there is either a match in a previous fragment,
+                // or multiple matches in this fragment,
+                // there is ambiguity.
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
+                    match_data = Some((i, match_start));
+                } else {
+                    // heirustic produced ambiguity, return nothing.
+                    return None;
+                }
+            }
+        }
+        if let Some((i, match_start)) = match_data {
+            use rustc_span::BytePos;
+            let mut sp = fragments[i].span;
+            sp = sp.with_lo(sp.lo() + BytePos(match_start as u32));
+            sp = sp.with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32));
+            return Some(sp);
path: compiler/rustc_resolve/src/rustdoc.rs
user: login: lolbinarycat
body: yeahhh alright i'll rewrite it again, what's one more on the pile.
created_at: 2025-05-22T15:01:24Z
author_association: CONTRIBUTOR

PR comments:
user: login: rustbot
created_at: 2025-02-01T21:03:58Z
body: r? @fmease

rustbot has assigned @fmease.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use `r?` to explicitly pick a reviewer
author_association: COLLABORATOR
user: login: rust-log-analyzer
created_at: 2025-02-01T21:46:07Z
body: 
The job **`x86_64-gnu-llvm-18`** failed! Check out the build log: [(web)](https://github.com/rust-lang/rust/actions/runs/13092412636/job/36530621429) [(plain)](https://github.com/rust-lang/rust/commit/1b359d73f1ce0eaec61c96e2a1446fb8eb4fb0e2/checks/36530621429/logs)

<details><summary><i>Click to see the possible cause of the failure (guessed by this bot)</i></summary>

```plain
#21 exporting to docker image format
#21 sending tarball 27.0s done
#21 DONE 36.4s
##[endgroup]
Setting extra environment values for docker:  --env ENABLE_GCC_CODEGEN=1 --env GCC_EXEC_PREFIX=/usr/lib/gcc/
[CI_JOB_NAME=x86_64-gnu-llvm-18]
debug: `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` configured.
---
sccache: Starting the server...
##[group]Configure the build
configure: processing command line
configure: 
configure: build.configure-args := ['--build=x86_64-unknown-linux-gnu', '--llvm-root=/usr/lib/llvm-18', '--enable-llvm-link-shared', '--set', 'rust.randomize-layout=true', '--set', 'rust.thin-lto-import-instr-limit=10', '--enable-verbose-configure', '--enable-sccache', '--disable-manage-submodules', '--enable-locked-deps', '--enable-cargo-native-static', '--set', 'rust.codegen-units-std=1', '--set', 'dist.compression-profile=balanced', '--dist-compression-formats=xz', '--set', 'rust.lld=false', '--disable-dist-src', '--release-channel=nightly', '--enable-debug-assertions', '--enable-overflow-checks', '--enable-llvm-assertions', '--set', 'rust.verify-llvm-ir', '--set', 'rust.codegen-backends=llvm,cranelift,gcc', '--set', 'llvm.static-libstdcpp', '--enable-new-symbol-mangling']
configure: target.x86_64-unknown-linux-gnu.llvm-config := /usr/lib/llvm-18/bin/llvm-config
configure: llvm.link-shared     := True
configure: rust.randomize-layout := True
configure: rust.thin-lto-import-instr-limit := 10
---
  Downloaded boml v0.3.1
   Compiling boml v0.3.1
   Compiling y v0.1.0 (/checkout/compiler/rustc_codegen_gcc/build_system)
    Finished `release` profile [optimized] target(s) in 3.97s
     Running `/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-codegen/x86_64-unknown-linux-gnu/release/y test --use-system-gcc --use-backend gcc --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools/cg_gcc --release --mini-tests --std-tests`
Using system GCC
warning: target feature `x87` must be enabled to ensure that the ABI of the current target can be implemented correctly
  |
  = note: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
  = note: for more information, see issue #116344 <https://github.com/rust-lang/rust/issues/116344>
---
71 warning: unresolved link to `BarD`
-   --> $DIR/warning.rs:45:9
+   --> $DIR/warning.rs:45:20
73    |
74 LL | #[doc = "Foo\nbar [BarD] bar\nbaz"]
+    |                    ^^^^ no item named `BarD` in scope
76    |
-    = note: the link appears in this line:
-            
-            
-            bar [BarD] bar
-    = note: no item named `BarD` in scope
82    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
83 
84 warning: unresolved link to `BarF`
84 warning: unresolved link to `BarF`

-   --> $DIR/warning.rs:54:4
+   --> $DIR/warning.rs:54:15
86    |
87 LL | f!("Foo\nbar [BarF] bar\nbaz");
+    |               ^^^^ no item named `BarF` in scope
89    |
-    = note: the link appears in this line:
-            
-            
-            bar [BarF] bar
-    = note: no item named `BarF` in scope
95    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
96    = note: this warning originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)
97 
97 

112    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
113 
114 warning: unresolved link to `error`
-   --> $DIR/warning.rs:68:9
+   --> $DIR/warning.rs:68:23
116    |
117 LL | #[doc = "single line [error]"]
+    |                       ^^^^^ no item named `error` in scope
119    |
-    = note: the link appears in this line:
-            
---

-   --> $DIR/warning.rs:71:9
+   --> $DIR/warning.rs:71:41
129    |
130 LL | #[doc = "single line with \"escaping\" [error]"]
+    |                                         ^^^^^ no item named `error` in scope
132    |
-    = note: the link appears in this line:
-            
-            
-            single line with "escaping" [error]
-    = note: no item named `error` in scope
138    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
139 
140 warning: unresolved link to `error`
---
To only update this specific test, also pass `--test-args intra-doc/warning.rs`

error: 1 errors occurred comparing output.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "/checkout/tests/rustdoc-ui/intra-doc/warning.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/intra-doc/warning" "-A" "internal_features" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers"
--- stderr -------------------------------
warning: unresolved link to `Foo::baz`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:3:23
   |
   |
LL |        //! Test with [Foo::baz], [Bar::foo], ...
   |                       ^^^^^^^^ the struct `Foo` has no field or associated item named `baz`
   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

warning: unresolved link to `Bar::foo`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:3:35
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:3:35
   |
LL |        //! Test with [Foo::baz], [Bar::foo], ...
   |                                   ^^^^^^^^ no item named `Bar` in scope

warning: unresolved link to `Uniooon::X`
   |
   |
LL |      //! , [Uniooon::X] and [Qux::Z].
   |             ^^^^^^^^^^ no item named `Uniooon` in scope

warning: unresolved link to `Qux::Z`
   |
   |
LL |      //! , [Uniooon::X] and [Qux::Z].
   |                              ^^^^^^ no item named `Qux` in scope

warning: unresolved link to `Uniooon::X`
   |
   |
LL |       //! , [Uniooon::X] and [Qux::Z].
   |              ^^^^^^^^^^ no item named `Uniooon` in scope

warning: unresolved link to `Qux::Z`
   |
   |
LL |       //! , [Uniooon::X] and [Qux::Z].
   |                               ^^^^^^ no item named `Qux` in scope
warning: unresolved link to `Qux:Y`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:14:13
   |
   |
LL |        /// [Qux:Y]
   |             ^^^^^ no item named `Qux:Y` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `BarA`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:21:10
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:21:10
   |
LL | /// bar [BarA] bar //~ WARNING `BarA`
   |          ^^^^ no item named `BarA` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `BarB`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:27:9
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:27:9
   |
LL |  * bar [BarB] bar //~ WARNING `BarB`
   |         ^^^^ no item named `BarB` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `BarC`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:34:6
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:34:6
   |
LL | bar [BarC] bar //~ WARNING `BarC`
   |      ^^^^ no item named `BarC` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `BarD`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:45:20
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:45:20
   |
LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] //~ WARNING `BarD`
   |                    ^^^^ no item named `BarD` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `BarF`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:54:15
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:54:15
   |
LL | f!("Foo\nbar [BarF] bar\nbaz"); //~ WARNING `BarF`
   |               ^^^^ no item named `BarF` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
   = note: this warning originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: unresolved link to `error`
warning: unresolved link to `error`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:58:30
   |
LL |  * time to introduce a link [error]*/ //~ WARNING `error`
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error`
warning: unresolved link to `error`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:64:30
   |
LL |  * time to introduce a link [error] //~ WARNING `error`
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error`
warning: unresolved link to `error`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:68:23
   |
LL | #[doc = "single line [error]"] //~ WARNING `error`
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error`
warning: unresolved link to `error`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:71:41
   |
LL | #[doc = "single line with \"escaping\" [error]"] //~ WARNING `error`
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error`
warning: unresolved link to `error`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:74:1
   |
LL | / /// Item docs. //~ WARNING `error`
LL | | #[doc="Hello there!"]
LL | | /// [error]
   |
   = note: the link appears in this line:
           
           [error]
           [error]
            ^^^^^
   = note: no item named `error` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error1`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:80:11
   |
LL | /// docs [error1] //~ WARNING `error1`
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error2`
warning: unresolved link to `error2`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:82:11
   |
LL | /// docs [error2] //~ WARNING `error2`
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: 19 warnings emitted
warning: 19 warnings emitted
------------------------------------------


---- [ui] tests/rustdoc-ui/lints/bare-urls.rs stdout ----
Saved the actual stderr to "/checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/lints/bare-urls/bare-urls.stderr"
diff of stderr:

- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 0..43
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 0..21
5 error: this URL is not a hyperlink
7    |

19 LL | /// <https://somewhere.com>
20    |     +                     +
20    |     +                     +
21 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 22..45
24 error: this URL is not a hyperlink
26    |

33 LL | /// <https://somewhere.com/a>
34    |     +                       +
34    |     +                       +
35 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 46..71
38 error: this URL is not a hyperlink
40    |


47 LL | /// <https://www.somewhere.com>
49 
49 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 72..99
52 error: this URL is not a hyperlink
54    |


61 LL | /// <https://www.somewhere.com/a>
63 
63 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 100..129
66 error: this URL is not a hyperlink
68    |


75 LL | /// <https://subdomain.example.com>
77 
77 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 130..152
80 error: this URL is not a hyperlink
82    |


89 LL | /// <https://somewhere.com?>
91 
91 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 153..177
94 error: this URL is not a hyperlink
96    |


103 LL | /// <https://somewhere.com/a?>
105 
105 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 178..208
108 error: this URL is not a hyperlink
110    |


117 LL | /// <https://somewhere.com?hello=12>
119 
119 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 209..241
122 error: this URL is not a hyperlink
124    |


131 LL | /// <https://somewhere.com/a?hello=12>
133 
133 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 242..274
136 error: this URL is not a hyperlink
138    |


145 LL | /// <https://example.com?hello=12#xyz>
147 
147 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 275..309
150 error: this URL is not a hyperlink
152    |


159 LL | /// <https://example.com/a?hello=12#xyz>
161 
161 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 310..333
164 error: this URL is not a hyperlink
166    |


173 LL | /// <https://example.com#xyz>
175 
175 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 334..359
178 error: this URL is not a hyperlink
180    |


187 LL | /// <https://example.com/a#xyz>
189 
189 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 360..397
192 error: this URL is not a hyperlink
194    |


201 LL | /// <https://somewhere.com?hello=12&bye=11>
203 
203 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 398..437
206 error: this URL is not a hyperlink
208    |


215 LL | /// <https://somewhere.com/a?hello=12&bye=11>
217 
217 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 438..479
220 error: this URL is not a hyperlink
222    |


229 LL | /// <https://somewhere.com?hello=12&bye=11#xyz>
231 
231 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://somewhere.com\nhttps://somewhere.com/a\nhttps://www.somewhere.com\nhttps://www.somewhere.com/a\nhttps://subdomain.example.com\nhttps://somewhere.com?\nhttps://somewhere.com/a?\nhttps://somewhere.com?hello=12\nhttps://somewhere.com/a?hello=12\nhttps://example.com?hello=12#xyz\nhttps://example.com/a?hello=12#xyz\nhttps://example.com#xyz\nhttps://example.com/a#xyz\nhttps://somewhere.com?hello=12&bye=11\nhttps://somewhere.com/a?hello=12&bye=11\nhttps://somewhere.com?hello=12&bye=11#xyz\nhey! https://somewhere.com/a?hello=12&bye=11#xyz"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 485..528
234 error: this URL is not a hyperlink
236    |


243 LL | /// hey! <https://somewhere.com/a?hello=12&bye=11#xyz>
245 
245 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "here's a thing: https://example.com/"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 16..36
248 error: this URL is not a hyperlink
250    |


257 LL | #[doc = "here's a thing: <https://example.com/>"]
259 
259 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://example.com/sugar\nhttps://example.com/raw"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 0..25
262 error: this URL is not a hyperlink
264    |

271 LL | /// <https://example.com/sugar>
272    |     +                         +
272    |     +                         +
273 
- [src/librustdoc/passes/lint/bare_urls.rs:21:63] dox = "https://example.com/sugar\nhttps://example.com/raw"
- [src/librustdoc/passes/lint/bare_urls.rs:21:74] &range = 26..49
276 error: this URL is not a hyperlink
278    |


The actual stderr differed from the expected stderr.
The actual stderr differed from the expected stderr.
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args lints/bare-urls.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "/checkout/tests/rustdoc-ui/lints/bare-urls.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/lints/bare-urls" "-A" "internal_features" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers"
--- stderr -------------------------------
error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:5:5
   |
---
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://www.somewhere.com>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:11:5
   |
   |
LL | /// https://www.somewhere.com/a
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://www.somewhere.com/a>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:13:5
   |
   |
LL | /// https://subdomain.example.com
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | /// <https://subdomain.example.com>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:15:5
   |
   |
LL | /// https://somewhere.com?
   |     ^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://somewhere.com?>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:17:5
   |
   |
LL | /// https://somewhere.com/a?
   |     ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://somewhere.com/a?>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:19:5
   |
   |
LL | /// https://somewhere.com?hello=12
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | /// <https://somewhere.com?hello=12>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:21:5
   |
   |
LL | /// https://somewhere.com/a?hello=12
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | /// <https://somewhere.com/a?hello=12>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:23:5
   |
   |
LL | /// https://example.com?hello=12#xyz
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | /// <https://example.com?hello=12#xyz>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:25:5
   |
   |
LL | /// https://example.com/a?hello=12#xyz
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | /// <https://example.com/a?hello=12#xyz>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:27:5
   |
   |
LL | /// https://example.com#xyz
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | /// <https://example.com#xyz>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:29:5
   |
   |
LL | /// https://example.com/a#xyz
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | /// <https://example.com/a#xyz>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:31:5
   |
   |
LL | /// https://somewhere.com?hello=12&bye=11
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | /// <https://somewhere.com?hello=12&bye=11>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:33:5
   |
   |
LL | /// https://somewhere.com/a?hello=12&bye=11
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | /// <https://somewhere.com/a?hello=12&bye=11>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:35:5
   |
   |
LL | /// https://somewhere.com?hello=12&bye=11#xyz
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | /// <https://somewhere.com?hello=12&bye=11#xyz>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:37:10
   |
   |
LL | /// hey! https://somewhere.com/a?hello=12&bye=11#xyz
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | /// hey! <https://somewhere.com/a?hello=12&bye=11#xyz>

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:41:26
   |
   |
LL | #[doc = "here's a thing: https://example.com/"]
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | #[doc = "here's a thing: <https://example.com/>"]

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:45:5
   |
---

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:47:10
   |
LL | #[doc = "https://example.com/raw"]
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
   |
LL | #[doc = "<https://example.com/raw>"]

error: aborting due to 20 previous errors
------------------------------------------

---
630 error: unescaped backtick
-   --> $DIR/unescaped_backticks.rs:108:9
+   --> $DIR/unescaped_backticks.rs:108:10
632    |
633 LL | #[doc = "`"]
+    |          ^
635    |
636    = help: the opening or closing backtick of an inline code may be missing
-    = help: if you meant to use a literal backtick, escape it
-    = help: if you meant to use a literal backtick, escape it
-             change: `
-            to this: \`
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \"`"]
640 
641 error: unescaped backtick
-   --> $DIR/unescaped_backticks.rs:115:9
+   --> $DIR/unescaped_backticks.rs:115:26
+   --> $DIR/unescaped_backticks.rs:115:26
643    |
644 LL | #[doc = concat!("\\", "`")]
+    |                          ^
646    |
-    = help: the opening backtick of an inline code may be missing
-             change: \`
-             change: \`
-            to this: `\`
-    = help: if you meant to use a literal backtick, escape it
-             change: \`
-            to this: \\`
+ help: the opening backtick of an inline code may be missing
+    |
+ LL | #[doc = `concat!("\\", "`")]
+    |         +
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \concat!("\\", "`")]
653 
654 error: unescaped backtick
-   --> $DIR/unescaped_backticks.rs:119:9
+   --> $DIR/unescaped_backticks.rs:119:61
+   --> $DIR/unescaped_backticks.rs:119:61
656    |
657 LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."]
+    |                                                             ^
659    |
-    = help: the opening backtick of a previous inline code may be missing
-    = help: the opening backtick of a previous inline code may be missing
-             change: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`.
-            to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
-    = help: if you meant to use a literal backtick, escape it
-             change: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`.
-            to this: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`.
+ help: the opening backtick of a previous inline code may be missing
+    |
+ LL | #[doc = `"Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."]
+    |         +
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \"Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."]
666 
667 error: unescaped backtick
-   --> $DIR/unescaped_backticks.rs:123:9
+   --> $DIR/unescaped_backticks.rs:123:52
+   --> $DIR/unescaped_backticks.rs:123:52
669    |
670 LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."]
+    |                                                    ^
672    |
-    = help: a previous inline code might be longer than expected
-    = help: a previous inline code might be longer than expected
-             change: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`.
-            to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
-    = help: if you meant to use a literal backtick, escape it
-             change: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`.
-            to this: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`.
+ help: a previous inline code might be longer than expected
+    |
+ LL | #[doc = `"Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."]
+    |         +
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \"Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."]
679 
680 error: unescaped backtick
-   --> $DIR/unescaped_backticks.rs:127:9
+   --> $DIR/unescaped_backticks.rs:127:52
+   --> $DIR/unescaped_backticks.rs:127:52
682    |
683 LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."]
+    |                                                    ^
685    |
-    = help: the opening backtick of an inline code may be missing
-    = help: the opening backtick of an inline code may be missing
-             change: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`.
-            to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
-    = help: if you meant to use a literal backtick, escape it
-             change: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`.
-            to this: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`.
+ help: the opening backtick of an inline code may be missing
+    |
+ LL | #[doc = `"Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."]
+    |         +
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \"Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."]
692 
693 error: unescaped backtick
-   --> $DIR/unescaped_backticks.rs:131:9
+   --> $DIR/unescaped_backticks.rs:131:52
+   --> $DIR/unescaped_backticks.rs:131:52
695    |
696 LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."]
+    |                                                    ^
698    |
-    = help: the closing backtick of an inline code may be missing
-    = help: the closing backtick of an inline code may be missing
-             change: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a).
-            to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
-    = help: if you meant to use a literal backtick, escape it
-             change: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a).
-            to this: Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a).
+ help: the closing backtick of an inline code may be missing
+    |
+ LL | #[doc = `"Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."]
+    |         +
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \"Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."]
705 
706 error: unescaped backtick
707   --> $DIR/unescaped_backticks.rs:136:5


Note: some mismatched output was normalized before being compared
-   --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:108:10
-   --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:115:26
- LL | #[doc = `concat!("\\\\", "`")]
- LL | #[doc = \concat!("\\\\", "`")]
-   --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:123:52
-   --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:127:52
-   --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:131:52
+   --> $DIR/unescaped_backticks.rs:108:10
+   --> $DIR/unescaped_backticks.rs:108:10
+    |          ^
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \"`"]
+   --> $DIR/unescaped_backticks.rs:115:26
+    |                          ^
+ help: the opening backtick of an inline code may be missing
+    |
+    |
+ LL | #[doc = `concat!("\\", "`")]
+    |         +
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \concat!("\\", "`")]
+   --> $DIR/unescaped_backticks.rs:119:61
+    |                                                             ^
+ help: the opening backtick of a previous inline code may be missing
+    |
+    |
+ LL | #[doc = `"Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."]
+    |         +
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \"Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."]
+   --> $DIR/unescaped_backticks.rs:123:52
+    |                                                    ^
+ help: a previous inline code might be longer than expected
+    |
+    |
+ LL | #[doc = `"Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."]
+    |         +
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \"Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."]
+   --> $DIR/unescaped_backticks.rs:127:52
+    |                                                    ^
+ help: the opening backtick of an inline code may be missing
+    |
+    |
+ LL | #[doc = `"Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."]
+    |         +
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \"Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."]
+   --> $DIR/unescaped_backticks.rs:131:52
+    |                                                    ^
+ help: the closing backtick of an inline code may be missing
+    |
+    |
+ LL | #[doc = `"Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."]
+    |         +
+ help: if you meant to use a literal backtick, escape it
+    |
+ LL | #[doc = \"Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."]


The actual stderr differed from the expected stderr.
To update references, rerun the tests and pass the `--bless` flag
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args unescaped_backticks.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "/checkout/tests/rustdoc-ui/unescaped_backticks.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/unescaped_backticks" "-A" "internal_features" "-Cdebuginfo=0" "-Lnative=/checkout/obj/build/x86_64-unknown-linux-gnu/native/rust-test-helpers"
--- stderr -------------------------------
error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:187:70
   |
   |
LL | /// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect =
   |
note: the lint level is defined here
  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:1:9
   |
   |
LL | #![deny(rustdoc::unescaped_backticks)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the closing backtick of an inline code may be missing
   |
LL | /// "runtime", phase = "optimized")]` if you don't.
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// if you want your MIR to be modified by the full MIR pipeline, or \`#![custom_mir(dialect =

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:232:13
   |
   |
LL |         //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL |         //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]`
help: if you meant to use a literal backtick, escape it
   |
   |
LL |         //! \`#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:237:13
   |
   |
LL |         /// `cfg=...
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL |         /// `cfg=...`
help: if you meant to use a literal backtick, escape it
   |
   |
LL |         /// \`cfg=...

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:241:42
   |
   |
LL |         /// `cfg=... and not `#[cfg_attr]`
   |
help: a previous inline code might be longer than expected
   |
   |
LL |         /// `cfg=...` and not `#[cfg_attr]`
help: if you meant to use a literal backtick, escape it
   |
   |
LL |         /// `cfg=... and not `#[cfg_attr]\`

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:193:93
   |
   |
LL |     /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL |     /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg` to
help: if you meant to use a literal backtick, escape it
   |
   |
LL |     /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given \`msg to

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:202:34
   |
   |
LL |         /// in `nt_to_tokenstream`
   |                                  ^
   |
help: a previous inline code might be longer than expected
   |
LL |         /// if we parsed no predicates (e.g. `struct` Foo where {}
help: if you meant to use a literal backtick, escape it
   |
LL |         /// in `nt_to_tokenstream\`
   |                                  +
   |                                  +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:208:62
   |
LL |     /// that `Option<Symbol>` only takes up 4 bytes, because `newtype_index! reserves
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL |     /// that `Option<Symbol>` only takes up 4 bytes, because `newtype_index!` reserves
help: if you meant to use a literal backtick, escape it
   |
   |
LL |     /// that `Option<Symbol>` only takes up 4 bytes, because \`newtype_index! reserves

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:216:52
   |
   |
LL |     /// also avoids the need to import `OpenOptions`.
   |                                                    ^
   |
help: a previous inline code might be longer than expected
   |
LL |     /// you can write `File::with_options().read(true).open("foo.txt")`. This
help: if you meant to use a literal backtick, escape it
   |
   |
LL |     /// also avoids the need to import `OpenOptions\`.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:221:47
   |
   |
LL |     /// `ChunkedBitSet`. Has no effect if `row` does not exist.
   |
help: a previous inline code might be longer than expected
   |
   |
LL |     /// Subtracts `set` from `row`. `set` can be either `BitSet` or
help: if you meant to use a literal backtick, escape it
   |
   |
LL |     /// `ChunkedBitSet`. Has no effect if `row\` does not exist.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:247:12
   |
   |
LL |     /// RWU`s can get very large, so it uses a more compact representation.
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL |     /// `RWU`s can get very large, so it uses a more compact representation.
help: if you meant to use a literal backtick, escape it
   |
   |
LL |     /// RWU\`s can get very large, so it uses a more compact representation.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:254:15
   |
   |
LL |     /// in `U2`.
   |               ^
   |
help: the opening backtick of a previous inline code may be missing
   |
LL |     /// `'?1` is in `U3` would be canonicalized to have `?0` in `U1` and `'?1`
help: if you meant to use a literal backtick, escape it
   |
LL |     /// in `U2\`.
   |               +
   |               +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:271:42
   |
LL |     /// because it contains `[type error]`. Yuck! (See issue #29857 for
   |
help: a previous inline code might be longer than expected
   |
   |
LL |     /// as Trait>::Foo == $0`. Here, normalizing `<MyType<$0>` as
help: if you meant to use a literal backtick, escape it
   |
   |
LL |     /// because it contains `[type error]\`. Yuck! (See issue #29857 for

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:281:53
   |
   |
LL |     /// well as the second instance of `A: AutoTrait`) to suppress
   |
help: a previous inline code might be longer than expected
   |
   |
LL |     /// encountered a problem (later on) with `A:` AutoTrait. So we
help: if you meant to use a literal backtick, escape it
   |
   |
LL |     /// well as the second instance of `A: AutoTrait\`) to suppress

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:291:40
   |
   |
LL |     /// `'a` with `'b` and not `'static`. But it will have to do for
   |
   = help: the opening or closing backtick of an inline code may be missing
help: if you meant to use a literal backtick, escape it
   |
   |
LL |     /// `'a` with `'b` and not `'static\`. But it will have to do for

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:300:54
   |
   |
LL | /// `None`. Otherwise, it will return `Some(Dispatch)`.
   |
help: the opening backtick of a previous inline code may be missing
   |
   |
LL | /// The `Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// `None`. Otherwise, it will return `Some(Dispatch)\`.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:304:13
   |
   |
LL | /// or `None` if it isn't.
   |             ^
   |
   = help: the opening or closing backtick of an inline code may be missing
help: if you meant to use a literal backtick, escape it
   |
LL | /// or `None\` if it isn't.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:308:14
   |
   |
LL | /// `on_event` should be called.
   |              ^
   |
help: a previous inline code might be longer than expected
   |
LL | /// Called before the filtered [`Layer`]'s [`on_event`], to determine if
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// `on_event\` should be called.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:313:29
   |
   |
LL | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
   |
help: a previous inline code might be longer than expected
   |
LL | /// Therefore, if the `Filter` will change the value returned by this
LL | /// Therefore, if the `Filter` will change the value returned by this
   |                              +
help: if you meant to use a literal backtick, escape it
   |
LL | /// [`rebuild_interest_cache\`][rebuild] is called after the value of the max

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:323:5
   |
   |
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.
   |
   = help: the opening backtick of a previous inline code may be missing
   = help: the opening backtick of a previous inline code may be missing
            change: The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
           to this: The `Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
   = help: if you meant to use a literal backtick, escape it
            change: `None`. Otherwise, it will return `Some(Dispatch)`.
           to this: `None`. Otherwise, it will return `Some(Dispatch)\`.
error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:323:5
   |
   |
LL | /     /// The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
---

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:26:6
   |
LL | /// [`link1]
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// [`link1`]
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// [\`link1]

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:30:11
   |
   |
LL | /// [link2`]
   |           ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// [`link2`]
help: if you meant to use a literal backtick, escape it
   |
LL | /// [link2\`]
   |           +
   |           +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:34:6
   |
LL | /// [`link_long](link_long)
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// [`link_long`](link_long)
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// [\`link_long](link_long)

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:38:6
   |
   |
LL | /// [`broken-link]
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// [`broken-link`]
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// [\`broken-link]

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:45:8
   |
   |
LL | /// <x:`>
   |        ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// `<x:`>
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// <x:\`>

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:55:6
   |
---
LL | /// `foo(`
   |          +
help: if you meant to use a literal backtick, escape it
   |
LL | /// \`foo(

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:65:14
   |
   |
LL | /// `foo `bar`
   |
help: a previous inline code might be longer than expected
   |
   |
LL | /// `foo` `bar`
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// `foo `bar\`

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:71:5
   |
---
LL | /// not paragraph`
   |                  +
help: if you meant to use a literal backtick, escape it
   |
LL | /// \`foo(

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:76:83
   |
   |
LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`.
   |
help: the opening backtick of a previous inline code may be missing
   |
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:80:51
   |
   |
LL | /// or even to add a number `n` to 42 (`add(42, b)`)!
   |
help: the opening backtick of a previous inline code may be missing
   |
   |
LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`),
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// or even to add a number `n` to 42 (`add(42, b)\`)!

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:84:83
   |
   |
LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`.
   |
help: a previous inline code might be longer than expected
   |
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:88:51
   |
   |
LL | /// or even to add a number `n` to 42 (`add(42, n)`)!
   |
help: a previous inline code might be longer than expected
   |
   |
LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`),
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// or even to add a number `n` to 42 (`add(42, n)\`)!

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:92:83
   |
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`.
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:96:50
   |
   |
LL | /// or even to add a number `n` to 42 (add(42, n)`)!
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | /// or even to add a number `n` to 42 (`add(42, n)`)!
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// or even to add a number `n` to 42 (add(42, n)\`)!

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:100:74
   |
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a).
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a).

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:104:51
   |
   |
LL | /// or even to add a number `n` to 42 (`add(42, n)`)!
   |
help: a previous inline code might be longer than expected
   |
   |
LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`),
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// or even to add a number `n` to 42 (`add(42, n)\`)!

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:108:10
   |
   |
LL | #[doc = "`"]
   |
   = help: the opening or closing backtick of an inline code may be missing
help: if you meant to use a literal backtick, escape it
   |
   |
LL | #[doc = \"`"]

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:115:26
   |
   |
LL | #[doc = concat!("\\\\", "`")]
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | #[doc = `concat!("\\\\", "`")]
help: if you meant to use a literal backtick, escape it
   |
   |
LL | #[doc = \concat!("\\\\", "`")]

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:119:61
   |
   |
LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."]
   |
help: the opening backtick of a previous inline code may be missing
   |
   |
LL | #[doc = `"Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."]
help: if you meant to use a literal backtick, escape it
   |
   |
LL | #[doc = \"Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."]

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:123:52
   |
   |
LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."]
   |
help: a previous inline code might be longer than expected
   |
   |
LL | #[doc = `"Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."]
help: if you meant to use a literal backtick, escape it
   |
   |
LL | #[doc = \"Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."]

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:127:52
   |
   |
LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."]
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | #[doc = `"Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."]
help: if you meant to use a literal backtick, escape it
   |
   |
LL | #[doc = \"Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."]

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:131:52
   |
   |
LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."]
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL | #[doc = `"Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."]
help: if you meant to use a literal backtick, escape it
   |
   |
LL | #[doc = \"Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."]

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:136:5
   |
---

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:140:7
   |
LL | /// # `(heading
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// # `(heading`
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// # \`(heading

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:142:17
   |
   |
LL | /// ## heading2)`
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | /// ## `heading2)`
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// ## heading2)\`

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:145:11
   |
---

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:151:10
   |
LL | /// para)`(graph
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | /// `para)`(graph
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// para)`(graph`
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// para)\`(graph

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:154:10
   |
   |
LL | /// para)`(graph2
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | /// `para)`(graph2
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// para)`(graph2`
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// para)\`(graph2

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:157:12
   |
   |
LL | /// 1. foo)`
   |            ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// 1. `foo)`
help: if you meant to use a literal backtick, escape it
   |
LL | /// 1. foo)\`
   |            +
   |            +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:159:8
   |
LL | /// 2. `(bar
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// 2. `(bar`
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// 2. \`(bar

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:161:11
   |
   |
LL | /// * baz)`
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | /// * `baz)`
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// * baz)\`

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:163:7
   |
   |
LL | /// * `(quux
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// * `(quux`
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// * \`(quux

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:166:5
   |
   |
LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")]
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// `#`![this_is_actually_an_image(and(not), an = "attribute")]
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// \`#![this_is_actually_an_image(and(not), an = "attribute")]

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:169:62
   |
   |
LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]`
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")]`
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]\`

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:174:7
   |
   |
LL | /// | `table( | )head` |
   |
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// | `table(` | )head` |
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// | \`table( | )head` |

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:174:22
   |
   |
LL | /// | `table( | )head` |
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | /// | `table( | `)head` |
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// | `table( | )head\` |

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:178:12
   |
   |
LL | /// | table`( | )`body |
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | /// | `table`( | )`body |
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// | table\`( | )`body |

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:178:18
   |
   |
LL | /// | table`( | )`body |
   |
help: the opening backtick of an inline code may be missing
   |
   |
LL | /// | table`( | `)`body |
help: the closing backtick of an inline code may be missing
   |
   |
LL | /// | table`( | )`body` |
help: if you meant to use a literal backtick, escape it
   |
   |
LL | /// | table`( | )\`body |

error: aborting due to 64 previous errors
------------------------------------------

```

</details>
        
author_association: COLLABORATOR
user: login: rust-log-analyzer
created_at: 2025-02-03T19:20:42Z
body: 
The job **`mingw-check-tidy`** failed! Check out the build log: [(web)](https://github.com/rust-lang/rust/actions/runs/13121036227/job/36606790671) [(plain)](https://github.com/rust-lang/rust/commit/a9a435b5c87fbc16a6592a1130003bac55474507/checks/36606790671/logs)

<details><summary><i>Click to see the possible cause of the failure (guessed by this bot)</i></summary>

```plain
info: removing rustup binaries
info: rustup is uninstalled
##[group]Image checksum input
mingw-check-tidy
# We use the ghcr base image because ghcr doesn't have a rate limit
# and the mingw-check-tidy job doesn't cache docker images in CI.
FROM ghcr.io/rust-lang/ubuntu:22.04
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
  g++ \
  make \
---

COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/

# NOTE: intentionally uses python2 for x.py so we can test it still works.
# validate-toolstate only runs in our CI, so it's ok for it to only support python3.
ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \
           --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
---
#12 2.734 Building wheels for collected packages: reuse
#12 2.735   Building wheel for reuse (pyproject.toml): started
#12 2.942   Building wheel for reuse (pyproject.toml): finished with status 'done'
#12 2.943   Created wheel for reuse: filename=reuse-4.0.3-cp310-cp310-manylinux_2_35_x86_64.whl size=132719 sha256=be6760d5849de4a58bbe52b85ca57a55f2b32b518b17029a5ad2e530db0d4303
#12 2.943   Stored in directory: /tmp/pip-ephem-wheel-cache-p8zg6vj5/wheels/3d/8d/0a/e0fc6aba4494b28a967ab5eaf951c121d9c677958714e34532
#12 2.946 Installing collected packages: boolean-py, binaryornot, tomlkit, reuse, python-debian, markupsafe, license-expression, jinja2, chardet, attrs
#12 3.341 Successfully installed attrs-23.2.0 binaryornot-0.4.4 boolean-py-4.0 chardet-5.2.0 jinja2-3.1.4 license-expression-30.3.0 markupsafe-2.1.5 python-debian-0.1.49 reuse-4.0.3 tomlkit-0.13.0
#12 3.342 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#12 3.869 Collecting virtualenv
#12 3.869 Collecting virtualenv
#12 3.907   Downloading virtualenv-20.29.1-py3-none-any.whl (4.3 MB)
#12 3.973      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 4.3/4.3 MB 66.3 MB/s eta 0:00:00
#12 4.028 Collecting platformdirs<5,>=3.9.1
#12 4.031   Downloading platformdirs-4.3.6-py3-none-any.whl (18 kB)
#12 4.048 Collecting distlib<1,>=0.3.7
#12 4.059      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 469.0/469.0 KB 82.8 MB/s eta 0:00:00
#12 4.095 Collecting filelock<4,>=3.12.2
#12 4.098   Downloading filelock-3.17.0-py3-none-any.whl (16 kB)
#12 4.098   Downloading filelock-3.17.0-py3-none-any.whl (16 kB)
#12 4.180 Installing collected packages: distlib, platformdirs, filelock, virtualenv
#12 4.358 Successfully installed distlib-0.3.9 filelock-3.17.0 platformdirs-4.3.6 virtualenv-20.29.1
#12 DONE 4.4s

#13 [7/8] COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
#13 DONE 0.0s
---
DirectMap4k:      131008 kB
DirectMap2M:     8257536 kB
DirectMap1G:    10485760 kB
##[endgroup]
Executing TIDY_PRINT_DIFF=1 python2.7 ../x.py test            --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
+ TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
    Finished `dev` profile [unoptimized] target(s) in 0.05s
##[endgroup]
WARN: currently no CI rustc builds have rustc debug assertions enabled. Please either set `rust.debug-assertions` to `false` if you want to use download CI rustc or set `rust.download-rustc` to `false`.
downloading https://static.rust-lang.org/dist/2025-01-08/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz
---
   Compiling tidy v0.1.0 (/checkout/src/tools/tidy)
    Finished `release` profile [optimized] target(s) in 30.46s
##[endgroup]
fmt check
Diff in /checkout/src/librustdoc/passes/lint/unescaped_backticks.rs:48:
                     &(backtick_index..backtick_index + 1),
                     &item.attrs.doc_strings,
                 )
-                    .unwrap_or_else(|| item.attr_span(tcx));
+                .unwrap_or_else(|| item.attr_span(tcx));
 
                 tcx.node_span_lint(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, |lint| {
                     lint.primary_message("unescaped backtick");
Diff in /checkout/compiler/rustc_resolve/src/rustdoc.rs:550:
                 // if there is either a match in a previous fragment,
                 // or multiple matches in this fragment,
                 // there is ambiguity.
-                if match_data.is_none() &&
-                    !snippet[match_start+1..].contains(pat) {
+                if match_data.is_none() && !snippet[match_start + 1..].contains(pat) {
                     match_data = Some((i, match_start));
                 } else {
                     // heirustic produced ambiguity, return nothing.
Build completed unsuccessfully in 0:01:09
  local time: Mon Feb  3 19:20:30 UTC 2025
  network time: Mon, 03 Feb 2025 19:20:31 GMT
##[error]Process completed with exit code 1.
```

</details>
        
author_association: COLLABORATOR
user: login: lolbinarycat
created_at: 2025-02-06T22:07:45Z
body: @fmease what module do you want me to move `source_span_to_markdown_range` into, or should that be left for a followup PR?
author_association: CONTRIBUTOR
user: login: lolbinarycat
created_at: 2025-03-13T20:09:34Z
body: @fmease reminder to look at this.
author_association: CONTRIBUTOR
user: login: lolbinarycat
created_at: 2025-03-22T23:03:12Z
body: @fmease it's been a week, are you going to get to this, or should I reroll reviewers?
author_association: CONTRIBUTOR
user: login: fmease
created_at: 2025-04-02T12:16:41Z
body: @bors try @rust-timer queue
author_association: MEMBER
user: login: rust-timer
created_at: 2025-04-02T12:16:44Z
body: Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

<!-- rust-timer: temporary -->
author_association: COLLABORATOR
user: login: bors
created_at: 2025-04-02T12:17:58Z
body: :hourglass: Trying commit c6d769601f24511287e1fae32a166f6d28e44ddf with merge 75eefd14476b7cd550f9b8b82f8fccfa949bf30e...
<!-- homu: {"type":"TryBuildStarted","head_sha":"c6d769601f24511287e1fae32a166f6d28e44ddf","merge_sha":"75eefd14476b7cd550f9b8b82f8fccfa949bf30e"} -->
author_association: COLLABORATOR
user: login: bors
created_at: 2025-04-02T14:24:42Z
body: :sunny: Try build successful - [checks-actions](https://github.com/rust-lang-ci/rust/actions/runs/14219398729/job/39852409748)
Build commit: 75eefd14476b7cd550f9b8b82f8fccfa949bf30e (`75eefd14476b7cd550f9b8b82f8fccfa949bf30e`)
<!-- homu: {"type":"TryBuildCompleted","builders":{"checks-actions":"https://github.com/rust-lang-ci/rust/actions/runs/14219398729/job/39852409748"},"merge_sha":"75eefd14476b7cd550f9b8b82f8fccfa949bf30e"} -->
author_association: COLLABORATOR
user: login: rust-timer
created_at: 2025-04-02T14:24:45Z
body: Queued 75eefd14476b7cd550f9b8b82f8fccfa949bf30e with parent 79de6c0bbe76904ac7086b05327ee5756fb302b1, future [comparison URL](https://perf.rust-lang.org/compare.html?start=79de6c0bbe76904ac7086b05327ee5756fb302b1&end=75eefd14476b7cd550f9b8b82f8fccfa949bf30e).
There is currently 1 preceding artifact in the [queue](https://perf.rust-lang.org/status.html).
It will probably take at least ~2.4 hours until the benchmark run finishes.
<!-- rust-timer: temporary -->
author_association: COLLABORATOR
user: login: rust-timer
created_at: 2025-04-02T16:49:32Z
body: Finished benchmarking commit (75eefd14476b7cd550f9b8b82f8fccfa949bf30e): [comparison URL](https://perf.rust-lang.org/compare.html?start=79de6c0bbe76904ac7086b05327ee5756fb302b1&end=75eefd14476b7cd550f9b8b82f8fccfa949bf30e&stat=instructions:u).

### Overall result: no relevant changes - no action needed


Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR may lead to changes in compiler perf.

@bors rollup=never
@rustbot label: -S-waiting-on-perf -perf-regression


### [Instruction count](https://perf.rust-lang.org/compare.html?start=79de6c0bbe76904ac7086b05327ee5756fb302b1&end=75eefd14476b7cd550f9b8b82f8fccfa949bf30e&stat=instructions:u)
This benchmark run did not return any relevant results for this metric.

### [Max RSS (memory usage)](https://perf.rust-lang.org/compare.html?start=79de6c0bbe76904ac7086b05327ee5756fb302b1&end=75eefd14476b7cd550f9b8b82f8fccfa949bf30e&stat=max-rss)
<details>
<summary>Results (secondary -4.0%)</summary>

This is a less reliable metric that may be of interest but was not used to determine the overall result at the top of this comment.

|                                    | mean  | range          | count |
|:----------------------------------:|:-----:|:--------------:|:-----:|
| Regressions ❌ <br /> (primary)    | -     | -              | 0     |
| Regressions ❌ <br /> (secondary)  | -     | -              | 0     |
| Improvements ✅ <br /> (primary)   | -     | -              | 0     |
| Improvements ✅ <br /> (secondary) | -4.0% | [-5.0%, -3.0%] | 2     |
| All ❌✅ (primary)                 | -     | -              | 0     |
</details>

### [Cycles](https://perf.rust-lang.org/compare.html?start=79de6c0bbe76904ac7086b05327ee5756fb302b1&end=75eefd14476b7cd550f9b8b82f8fccfa949bf30e&stat=cycles:u)
This benchmark run did not return any relevant results for this metric.

### [Binary size](https://perf.rust-lang.org/compare.html?start=79de6c0bbe76904ac7086b05327ee5756fb302b1&end=75eefd14476b7cd550f9b8b82f8fccfa949bf30e&stat=size:linked_artifact)
This benchmark run did not return any relevant results for this metric.

**Bootstrap**: 776.227s -> 775.389s (-0.11%)
**Artifact size**: 365.99 MiB -> 365.98 MiB (-0.00%)
author_association: COLLABORATOR
user: login: lolbinarycat
created_at: 2025-04-02T19:02:11Z
body: @fmease all recommended changes added
author_association: CONTRIBUTOR
user: login: lolbinarycat
created_at: 2025-05-16T08:39:16Z
body: Addressed all nits and squashed commits! @GuillaumeGomez @fmease 
author_association: CONTRIBUTOR
user: login: rust-log-analyzer
created_at: 2025-05-16T08:45:17Z
body: 
The job **`x86_64-gnu-llvm-19`** failed! Check out the build log: [(web)](https://github.com/rust-lang/rust/actions/runs/15064320525/job/42345698074) [(plain)](https://github.com/rust-lang/rust/commit/0d3d6502303c0a7863ce760daa3ac97a45ea3a75/checks/42345698074/logs)

<details><summary><i>Click to see the possible cause of the failure (guessed by this bot)</i></summary>

```plain
#19 exporting to docker image format
#19 sending tarball 20.2s done
#19 DONE 26.4s
##[endgroup]
Setting extra environment values for docker:  --env ENABLE_GCC_CODEGEN=1 --env GCC_EXEC_PREFIX=/usr/lib/gcc/
[CI_JOB_NAME=x86_64-gnu-llvm-19]
[CI_JOB_NAME=x86_64-gnu-llvm-19]
debug: `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` configured.
---
sccache: Listening on address 127.0.0.1:4226
##[group]Configure the build
configure: processing command line
configure: 
configure: build.configure-args := ['--build=x86_64-unknown-linux-gnu', '--llvm-root=/usr/lib/llvm-19', '--enable-llvm-link-shared', '--set', 'rust.randomize-layout=true', '--set', 'rust.thin-lto-import-instr-limit=10', '--set', 'build.print-step-timings', '--enable-verbose-tests', '--set', 'build.metrics', '--enable-verbose-configure', '--enable-sccache', '--disable-manage-submodules', '--enable-locked-deps', '--enable-cargo-native-static', '--set', 'rust.codegen-units-std=1', '--set', 'dist.compression-profile=balanced', '--dist-compression-formats=xz', '--set', 'rust.lld=false', '--disable-dist-src', '--release-channel=nightly', '--enable-debug-assertions', '--enable-overflow-checks', '--enable-llvm-assertions', '--set', 'rust.verify-llvm-ir', '--set', 'rust.codegen-backends=llvm,cranelift,gcc', '--set', 'llvm.static-libstdcpp', '--set', 'gcc.download-ci-gcc=true', '--enable-new-symbol-mangling']
configure: build.build          := x86_64-unknown-linux-gnu
configure: target.x86_64-unknown-linux-gnu.llvm-config := /usr/lib/llvm-19/bin/llvm-config
configure: llvm.link-shared     := True
configure: rust.randomize-layout := True
configure: rust.thin-lto-import-instr-limit := 10
---
   Compiling rustc_resolve v0.0.0 (/checkout/compiler/rustc_resolve)
error[E0425]: cannot find value `sp` in this scope
   --> compiler/rustc_resolve/src/rustdoc.rs:585:30
    |
585 |                     .with_lo(sp.lo() + BytePos(match_start as u32))
    |                              ^^ not found in this scope

error[E0425]: cannot find value `sp` in this scope
   --> compiler/rustc_resolve/src/rustdoc.rs:586:30
    |
586 |                     .with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32)),
    |                              ^^ not found in this scope

[RUSTC-TIMING] rustc_symbol_mangling test:false 6.615
   Compiling stable_mir v0.1.0-preview (/checkout/compiler/stable_mir)
[RUSTC-TIMING] stable_mir test:false 0.060
---

error[E0609]: no field `map` on type `&SourceMap`
   --> compiler/rustc_resolve/src/rustdoc.rs:592:41
    |
592 |     let snippet = tcx.sess.source_map().map.span_to_snippet(span_of_fragments(fragments)?).ok()?;
    |                                         ^^^ unknown field

[RUSTC-TIMING] rustc_pattern_analysis test:false 9.058
Some errors have detailed explanations: E0425, E0609, E0615.
For more information about an error, try `rustc --explain E0425`.
```

</details>

author_association: COLLABORATOR
user: login: rust-log-analyzer
created_at: 2025-05-16T09:59:29Z
body: 
The job **`mingw-check-tidy`** failed! Check out the build log: [(web)](https://github.com/rust-lang/rust/actions/runs/15065659491/job/42349838449) [(plain)](https://github.com/rust-lang/rust/commit/ec390f082f7c3e51798ee35a492fe6a839c5a69e/checks/42349838449/logs)

<details><summary><i>Click to see the possible cause of the failure (guessed by this bot)</i></summary>

```plain
info: removing rustup binaries
info: rustup is uninstalled
##[group]Image checksum input
mingw-check-tidy
# We use the ghcr base image because ghcr doesn't have a rate limit
# and the mingw-check-tidy job doesn't cache docker images in CI.
FROM ghcr.io/rust-lang/ubuntu:22.04

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
  g++ \
---

COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/

# NOTE: intentionally uses python2 for x.py so we can test it still works.
# validate-toolstate only runs in our CI, so it's ok for it to only support python3.
ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \
           --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
---
#12 2.794 Building wheels for collected packages: reuse
#12 2.795   Building wheel for reuse (pyproject.toml): started
#12 3.013   Building wheel for reuse (pyproject.toml): finished with status 'done'
#12 3.014   Created wheel for reuse: filename=reuse-4.0.3-cp310-cp310-manylinux_2_35_x86_64.whl size=132719 sha256=d2a2565e7037ad3883fb9337653f2e25bbb588534fbef3697286cbc26d1bf634
#12 3.014   Stored in directory: /tmp/pip-ephem-wheel-cache-qqjlrk8r/wheels/3d/8d/0a/e0fc6aba4494b28a967ab5eaf951c121d9c677958714e34532
#12 3.017 Successfully built reuse
#12 3.017 Installing collected packages: boolean-py, binaryornot, tomlkit, reuse, python-debian, markupsafe, license-expression, jinja2, chardet, attrs
#12 3.413 Successfully installed attrs-23.2.0 binaryornot-0.4.4 boolean-py-4.0 chardet-5.2.0 jinja2-3.1.4 license-expression-30.3.0 markupsafe-2.1.5 python-debian-0.1.49 reuse-4.0.3 tomlkit-0.13.0
#12 3.414 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#12 3.957 Collecting virtualenv
#12 4.010   Downloading virtualenv-20.31.2-py3-none-any.whl (6.1 MB)
#12 4.095      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.1/6.1 MB 73.2 MB/s eta 0:00:00
#12 4.155 Collecting filelock<4,>=3.12.2
#12 4.158   Downloading filelock-3.18.0-py3-none-any.whl (16 kB)
#12 4.194 Collecting platformdirs<5,>=3.9.1
#12 4.197   Downloading platformdirs-4.3.8-py3-none-any.whl (18 kB)
#12 4.216 Collecting distlib<1,>=0.3.7
#12 4.219   Downloading distlib-0.3.9-py2.py3-none-any.whl (468 kB)
#12 4.228      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 469.0/469.0 KB 80.2 MB/s eta 0:00:00
#12 4.309 Installing collected packages: distlib, platformdirs, filelock, virtualenv
#12 4.502 Successfully installed distlib-0.3.9 filelock-3.18.0 platformdirs-4.3.8 virtualenv-20.31.2
#12 4.503 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#12 DONE 4.6s

#13 [7/8] COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
#13 DONE 0.0s
---
DirectMap4k:      141248 kB
DirectMap2M:     8247296 kB
DirectMap1G:    10485760 kB
##[endgroup]
Executing TIDY_PRINT_DIFF=1 python2.7 ../x.py test            --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
+ TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
##[group]Building bootstrap
    Finished `dev` profile [unoptimized] target(s) in 0.05s
##[endgroup]
WARN: currently no CI rustc builds have rustc debug assertions enabled. Please either set `rust.debug-assertions` to `false` if you want to use download CI rustc or set `rust.download-rustc` to `false`.
downloading https://static.rust-lang.org/dist/2025-05-12/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz
---
##[endgroup]
[TIMING] core::build_steps::tool::ToolBuild { compiler: Compiler { stage: 0, host: x86_64-unknown-linux-gnu, forced_compiler: false }, target: x86_64-unknown-linux-gnu, tool: "tidy", path: "src/tools/tidy", mode: ToolBootstrap, source_type: InTree, extra_features: [], allow_features: "", cargo_args: [], artifact_kind: Binary } -- 37.006
[TIMING] core::build_steps::tool::Tidy { compiler: Compiler { stage: 0, host: x86_64-unknown-linux-gnu, forced_compiler: false }, target: x86_64-unknown-linux-gnu } -- 0.000
fmt check
Diff in /checkout/compiler/rustc_resolve/src/rustdoc.rs:581:
         if let Some((i, match_start)) = match_data {
             let sp = fragments[i].span;
             return Some(
-                sp
-                    .with_lo(sp.lo() + BytePos(match_start as u32))
+                sp.with_lo(sp.lo() + BytePos(match_start as u32))
                     .with_hi(sp.lo() + BytePos((md_range.end - md_range.start) as u32)),
             );
         }
fmt: checked 6014 files
Build completed unsuccessfully in 0:01:18
  local time: Fri May 16 09:59:19 UTC 2025
```

</details>

author_association: COLLABORATOR
user: login: rust-log-analyzer
created_at: 2025-05-21T15:05:19Z
body: 
The job **`mingw-check-tidy`** failed! Check out the build log: [(web)](https://github.com/rust-lang/rust/actions/runs/15165456223/job/42642073208) [(plain)](https://github.com/rust-lang/rust/commit/dce6e86a65fcf185077e8f8a3d048b48dfde3230/checks/42642073208/logs)

<details><summary><i>Click to see the possible cause of the failure (guessed by this bot)</i></summary>

```plain
info: removing rustup binaries
info: rustup is uninstalled
##[group]Image checksum input
mingw-check-tidy
# We use the ghcr base image because ghcr doesn't have a rate limit
# and the mingw-check-tidy job doesn't cache docker images in CI.
FROM ghcr.io/rust-lang/ubuntu:22.04

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
  g++ \
---

COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/

# NOTE: intentionally uses python2 for x.py so we can test it still works.
# validate-toolstate only runs in our CI, so it's ok for it to only support python3.
ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \
           --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
---
#12 7.840 Building wheels for collected packages: reuse
#12 7.841   Building wheel for reuse (pyproject.toml): started
#12 8.059   Building wheel for reuse (pyproject.toml): finished with status 'done'
#12 8.060   Created wheel for reuse: filename=reuse-4.0.3-cp310-cp310-manylinux_2_35_x86_64.whl size=132719 sha256=d2a2565e7037ad3883fb9337653f2e25bbb588534fbef3697286cbc26d1bf634
#12 8.060   Stored in directory: /tmp/pip-ephem-wheel-cache-hgefaie3/wheels/3d/8d/0a/e0fc6aba4494b28a967ab5eaf951c121d9c677958714e34532
#12 8.063 Successfully built reuse
#12 8.063 Installing collected packages: boolean-py, binaryornot, tomlkit, reuse, python-debian, markupsafe, license-expression, jinja2, chardet, attrs
#12 8.462 Successfully installed attrs-23.2.0 binaryornot-0.4.4 boolean-py-4.0 chardet-5.2.0 jinja2-3.1.4 license-expression-30.3.0 markupsafe-2.1.5 python-debian-0.1.49 reuse-4.0.3 tomlkit-0.13.0
#12 8.463 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#12 8.997 Collecting virtualenv
#12 9.034   Downloading virtualenv-20.31.2-py3-none-any.whl (6.1 MB)
#12 9.107      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.1/6.1 MB 85.3 MB/s eta 0:00:00
#12 9.167 Collecting filelock<4,>=3.12.2
#12 9.170   Downloading filelock-3.18.0-py3-none-any.whl (16 kB)
#12 9.187 Collecting distlib<1,>=0.3.7
#12 9.191   Downloading distlib-0.3.9-py2.py3-none-any.whl (468 kB)
#12 9.198      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 469.0/469.0 KB 94.4 MB/s eta 0:00:00
#12 9.231 Collecting platformdirs<5,>=3.9.1
#12 9.234   Downloading platformdirs-4.3.8-py3-none-any.whl (18 kB)
#12 9.317 Installing collected packages: distlib, platformdirs, filelock, virtualenv
#12 9.513 Successfully installed distlib-0.3.9 filelock-3.18.0 platformdirs-4.3.8 virtualenv-20.31.2
#12 9.513 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#12 DONE 9.6s

#13 [7/8] COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
#13 DONE 0.0s
---
DirectMap4k:      126912 kB
DirectMap2M:     7213056 kB
DirectMap1G:    11534336 kB
##[endgroup]
Executing TIDY_PRINT_DIFF=1 python2.7 ../x.py test            --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
+ TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
##[group]Building bootstrap
    Finished `dev` profile [unoptimized] target(s) in 0.05s
##[endgroup]
WARN: currently no CI rustc builds have rustc debug assertions enabled. Please either set `rust.debug-assertions` to `false` if you want to use download CI rustc or set `rust.download-rustc` to `false`.
downloading https://static.rust-lang.org/dist/2025-05-12/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz
---
fmt check
fmt: checked 6021 files
tidy check
tidy: Skipping binary file check, read-only filesystem
##[error]tidy error: /checkout/src/librustdoc/clean/types.rs:637: `dbg!` macro is intended as a debugging tool. It should not be in version control.
removing old virtual environment
creating virtual environment at '/checkout/obj/build/venv' using 'python3.10' and 'venv'
creating virtual environment at '/checkout/obj/build/venv' using 'python3.10' and 'virtualenv'
Requirement already satisfied: pip in ./build/venv/lib/python3.10/site-packages (25.1.1)
linting python files
All checks passed!
checking python file formatting
26 files already formatted
checking C++ file formatting
some tidy checks failed
Command has failed. Rerun with -v to see more details.
Build completed unsuccessfully in 0:01:49
  local time: Wed May 21 15:05:07 UTC 2025
  network time: Wed, 21 May 2025 15:05:07 GMT
##[error]Process completed with exit code 1.
Post job cleanup.
```

</details>

author_association: COLLABORATOR
user: login: rust-log-analyzer
created_at: 2025-05-21T16:50:54Z
body: 
The job **`x86_64-gnu-llvm-19`** failed! Check out the build log: [(web)](https://github.com/rust-lang/rust/actions/runs/15167079541/job/42647656700) [(plain)](https://github.com/rust-lang/rust/commit/c83a7b1d9095c00e6e153fc00d91e0bf4630ffe2/checks/42647656700/logs)

<details><summary><i>Click to see the possible cause of the failure (guessed by this bot)</i></summary>

```plain
#18 exporting to docker image format
#18 sending tarball 21.4s done
#18 DONE 30.9s
##[endgroup]
Setting extra environment values for docker:  --env ENABLE_GCC_CODEGEN=1 --env GCC_EXEC_PREFIX=/usr/lib/gcc/
[CI_JOB_NAME=x86_64-gnu-llvm-19]
[CI_JOB_NAME=x86_64-gnu-llvm-19]
debug: `DISABLE_CI_RUSTC_IF_INCOMPATIBLE` configured.
---
sccache: Listening on address 127.0.0.1:4226
##[group]Configure the build
configure: processing command line
configure: 
configure: build.configure-args := ['--build=x86_64-unknown-linux-gnu', '--llvm-root=/usr/lib/llvm-19', '--enable-llvm-link-shared', '--set', 'rust.randomize-layout=true', '--set', 'rust.thin-lto-import-instr-limit=10', '--set', 'build.print-step-timings', '--enable-verbose-tests', '--set', 'build.metrics', '--enable-verbose-configure', '--enable-sccache', '--disable-manage-submodules', '--enable-locked-deps', '--enable-cargo-native-static', '--set', 'rust.codegen-units-std=1', '--set', 'dist.compression-profile=balanced', '--dist-compression-formats=xz', '--set', 'rust.lld=false', '--disable-dist-src', '--release-channel=nightly', '--enable-debug-assertions', '--enable-overflow-checks', '--enable-llvm-assertions', '--set', 'rust.verify-llvm-ir', '--set', 'rust.codegen-backends=llvm,cranelift,gcc', '--set', 'llvm.static-libstdcpp', '--set', 'gcc.download-ci-gcc=true', '--enable-new-symbol-mangling']
configure: build.build          := x86_64-unknown-linux-gnu
configure: target.x86_64-unknown-linux-gnu.llvm-config := /usr/lib/llvm-19/bin/llvm-config
configure: llvm.link-shared     := True
configure: rust.randomize-layout := True
configure: rust.thin-lto-import-instr-limit := 10
---
[RUSTC-TIMING] proc_macro test:false 5.576
[RUSTC-TIMING] test test:false 9.555
    Finished `release` profile [optimized] target(s) in 1m 19s
##[endgroup]
[TIMING] core::build_steps::compile::Std { target: x86_64-unknown-linux-gnu, compiler: Compiler { stage: 1, host: x86_64-unknown-linux-gnu, forced_compiler: true }, crates: [], force_recompile: false, extra_rust_args: ["-Csymbol-mangling-version=v0", "-Cpanic=abort"], is_for_mir_opt_tests: false } -- 79.488
Testing GCC stage1 (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
 Downloading crates ...
  Downloaded boml v0.3.1
   Compiling boml v0.3.1
[RUSTC-TIMING] boml test:false 0.774
   Compiling y v0.1.0 (/checkout/compiler/rustc_codegen_gcc/build_system)
[RUSTC-TIMING] y test:false 2.871
    Finished `release` profile [optimized] target(s) in 4.04s
     Running `/checkout/obj/build/x86_64-unknown-linux-gnu/stage1-codegen/x86_64-unknown-linux-gnu/release/y test --use-backend gcc --gcc-path /checkout/obj/build/x86_64-unknown-linux-gnu/ci-gcc/lib --out-dir /checkout/obj/build/x86_64-unknown-linux-gnu/stage1-tools/cg_gcc --release --mini-tests --std-tests`
`--gcc-path` was provided, ignoring config file. Using `/checkout/obj/build/x86_64-unknown-linux-gnu/ci-gcc/lib` as path for libgccjit
[BUILD] mini_core
[RUSTC-TIMING] mini_core test:false 0.206
[BUILD] example
[AOT] mini_core_hello_world
[RUSTC-TIMING] mini_core_hello_world test:false 0.181
---
71 warning: unresolved link to `BarD`
-   --> $DIR/warning.rs:45:20
+   --> $DIR/warning.rs:45:13
73    |
74 LL | #[doc = "Foo\nbar [BarD] bar\nbaz"]
-    |                    ^^^^ no item named `BarD` in scope
+    |             ^^^^^^^ no item named `BarD` in scope
76    |
77    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
78 

79 warning: unresolved link to `BarF`
-   --> $DIR/warning.rs:54:15
+   --> $DIR/warning.rs:54:8
81    |
82 LL | f!("Foo\nbar [BarF] bar\nbaz");
-    |               ^^^^ no item named `BarF` in scope
+    |        ^^^^^^^ no item named `BarF` in scope
84    |
85    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
86    = note: this warning originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)

102    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
103 
104 warning: unresolved link to `error`
-   --> $DIR/warning.rs:68:23
+   --> $DIR/warning.rs:68:14
106    |
107 LL | #[doc = "single line [error]"]
-    |                       ^^^^^ no item named `error` in scope
+    |              ^^^^^^^^^ no item named `error` in scope
109    |
110    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
111 

112 warning: unresolved link to `error`
-   --> $DIR/warning.rs:71:41
+   --> $DIR/warning.rs:71:14
114    |
115 LL | #[doc = "single line with \"escaping\" [error]"]
-    |                                         ^^^^^ no item named `error` in scope
+    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `error` in scope
117    |
118    = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
119 
---
To only update this specific test, also pass `--test-args intra-doc/warning.rs`

error: 1 errors occurred comparing output.
status: exit status: 0
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "/checkout/tests/rustdoc-ui/intra-doc/warning.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/intra-doc/warning" "-A" "internal_features" "-Cdebuginfo=0"
stdout: none
--- stderr -------------------------------
warning: unresolved link to `Foo::baz`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:3:23
   |
LL |        //! Test with [Foo::baz], [Bar::foo], ...
   |                       ^^^^^^^^ the struct `Foo` has no field or associated item named `baz`
   |
   = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default

warning: unresolved link to `Bar::foo`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:3:35
   |
LL |        //! Test with [Foo::baz], [Bar::foo], ...
   |                                   ^^^^^^^^ no item named `Bar` in scope

warning: unresolved link to `Uniooon::X`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:6:13
   |
LL |      //! , [Uniooon::X] and [Qux::Z].
   |             ^^^^^^^^^^ no item named `Uniooon` in scope

warning: unresolved link to `Qux::Z`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:6:30
   |
LL |      //! , [Uniooon::X] and [Qux::Z].
   |                              ^^^^^^ no item named `Qux` in scope

warning: unresolved link to `Uniooon::X`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:10:14
   |
LL |       //! , [Uniooon::X] and [Qux::Z].
   |              ^^^^^^^^^^ no item named `Uniooon` in scope

warning: unresolved link to `Qux::Z`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:10:31
   |
LL |       //! , [Uniooon::X] and [Qux::Z].
   |                               ^^^^^^ no item named `Qux` in scope

warning: unresolved link to `Qux:Y`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:14:13
   |
LL |        /// [Qux:Y]
   |             ^^^^^ no item named `Qux:Y` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `BarA`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:21:10
   |
LL | /// bar [BarA] bar //~ WARNING `BarA`
   |          ^^^^ no item named `BarA` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `BarB`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:27:9
   |
LL |  * bar [BarB] bar //~ WARNING `BarB`
   |         ^^^^ no item named `BarB` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `BarC`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:34:6
   |
LL | bar [BarC] bar //~ WARNING `BarC`
   |      ^^^^ no item named `BarC` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `BarD`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:45:13
   |
LL | #[doc = "Foo\nbar [BarD] bar\nbaz"] //~ WARNING `BarD`
   |             ^^^^^^^ no item named `BarD` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `BarF`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:54:8
   |
LL | f!("Foo\nbar [BarF] bar\nbaz"); //~ WARNING `BarF`
   |        ^^^^^^^ no item named `BarF` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`
   = note: this warning originates in the macro `f` (in Nightly builds, run with -Z macro-backtrace for more info)

warning: unresolved link to `error`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:58:30
   |
LL |  * time to introduce a link [error]*/ //~ WARNING `error`
   |                              ^^^^^ no item named `error` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:64:30
   |
LL |  * time to introduce a link [error] //~ WARNING `error`
   |                              ^^^^^ no item named `error` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:68:14
   |
LL | #[doc = "single line [error]"] //~ WARNING `error`
   |              ^^^^^^^^^ no item named `error` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:71:14
   |
LL | #[doc = "single line with \"escaping\" [error]"] //~ WARNING `error`
   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no item named `error` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:74:1
   |
LL | / /// Item docs. //~ WARNING `error`
LL | | #[doc="Hello there!"]
LL | | /// [error]
   | |___________^
   |
   = note: the link appears in this line:
           
           [error]
            ^^^^^
   = note: no item named `error` in scope
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error1`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:80:11
   |
LL | /// docs [error1] //~ WARNING `error1`
   |           ^^^^^^ no item named `error1` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: unresolved link to `error2`
##[warning]  --> /checkout/tests/rustdoc-ui/intra-doc/warning.rs:82:11
   |
LL | /// docs [error2] //~ WARNING `error2`
   |           ^^^^^^ no item named `error2` in scope
   |
   = help: to escape `[` and `]` characters, add '\' before them like `\[` or `\]`

warning: 19 warnings emitted
---
diff of stderr:

211   --> $DIR/bare-urls.rs:41:26
212    |
213 LL | #[doc = "here's a thing: https://example.com/"]
-    |                          ^^^^^^^^^^^^^^^^^^^^
+    |                          ^^^
215    |
216    = note: bare URLs are not automatically turned into clickable links
217 help: use an automatic link instead

218    |
- LL | #[doc = "here's a thing: <https://example.com/>"]
-    |                          +                    +
+ LL | #[doc = "here's a thing: <htt>ps://example.com/"]
+    |                          +   +
221 
222 error: this URL is not a hyperlink
223   --> $DIR/bare-urls.rs:45:5

224    |
---

230    |
- LL | /// <https://example.com/sugar>
-    |     +                         +
+ LL | /// <https://example.com/s>ugar
+    |     +                     +
233 
234 error: this URL is not a hyperlink
235   --> $DIR/bare-urls.rs:47:10

236    |
237 LL | #[doc = "https://example.com/raw"]
-    |          ^^^^^^^^^^^^^^^^^^^^^^^
+    |          ^^^^^^^^^^^^^^^^^^^^^^
239    |
240    = note: bare URLs are not automatically turned into clickable links
241 help: use an automatic link instead

242    |
- LL | #[doc = "<https://example.com/raw>"]
-    |          +                       +
+ LL | #[doc = "<https://example.com/ra>w"]
+    |          +                      +
245 
246 error: aborting due to 20 previous errors
247 

---

38 //~^ ERROR this URL is not a hyperlink
39 pub fn c() {}
40 
- #[doc = "here's a thing: <https://example.com/>"]
+ #[doc = "here's a thing: <htt>ps://example.com/"]
42 //~^ ERROR this URL is not a hyperlink
43 pub fn f() {}
44 

- /// <https://example.com/sugar>
+ /// <https://example.com/s>ugar
46 //~^ ERROR this URL is not a hyperlink
- #[doc = "<https://example.com/raw>"]
+ #[doc = "<https://example.com/ra>w"]
48 //~^ ERROR this URL is not a hyperlink
49 pub fn mixed() {}
50 


The actual fixed differed from the expected fixed
To update references, rerun the tests and pass the `--bless` flag
To only update this specific test, also pass `--test-args lints/bare-urls.rs`

error: 2 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "/checkout/tests/rustdoc-ui/lints/bare-urls.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/lints/bare-urls" "-A" "internal_features" "-Cdebuginfo=0"
stdout: none
--- stderr -------------------------------
error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:5:5
   |
---
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://www.somewhere.com>
   |     +                         +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:11:5
   |
LL | /// https://www.somewhere.com/a
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://www.somewhere.com/a>
   |     +                           +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:13:5
   |
LL | /// https://subdomain.example.com
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://subdomain.example.com>
   |     +                             +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:15:5
   |
LL | /// https://somewhere.com?
   |     ^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://somewhere.com?>
   |     +                      +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:17:5
   |
LL | /// https://somewhere.com/a?
   |     ^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://somewhere.com/a?>
   |     +                        +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:19:5
   |
LL | /// https://somewhere.com?hello=12
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://somewhere.com?hello=12>
   |     +                              +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:21:5
   |
LL | /// https://somewhere.com/a?hello=12
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://somewhere.com/a?hello=12>
   |     +                                +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:23:5
   |
LL | /// https://example.com?hello=12#xyz
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://example.com?hello=12#xyz>
   |     +                                +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:25:5
   |
LL | /// https://example.com/a?hello=12#xyz
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://example.com/a?hello=12#xyz>
   |     +                                  +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:27:5
   |
LL | /// https://example.com#xyz
   |     ^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://example.com#xyz>
   |     +                       +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:29:5
   |
LL | /// https://example.com/a#xyz
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://example.com/a#xyz>
   |     +                         +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:31:5
   |
LL | /// https://somewhere.com?hello=12&bye=11
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://somewhere.com?hello=12&bye=11>
   |     +                                     +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:33:5
   |
LL | /// https://somewhere.com/a?hello=12&bye=11
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://somewhere.com/a?hello=12&bye=11>
   |     +                                       +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:35:5
   |
LL | /// https://somewhere.com?hello=12&bye=11#xyz
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://somewhere.com?hello=12&bye=11#xyz>
   |     +                                         +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:37:10
   |
LL | /// hey! https://somewhere.com/a?hello=12&bye=11#xyz
   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// hey! <https://somewhere.com/a?hello=12&bye=11#xyz>
   |          +                                           +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:41:26
   |
LL | #[doc = "here's a thing: https://example.com/"]
   |                          ^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | #[doc = "here's a thing: <htt>ps://example.com/"]
   |                          +   +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:45:5
   |
LL | /// https://example.com/sugar
   |     ^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | /// <https://example.com/s>ugar
   |     +                     +

error: this URL is not a hyperlink
##[error]  --> /checkout/tests/rustdoc-ui/lints/bare-urls.rs:47:10
   |
LL | #[doc = "https://example.com/raw"]
   |          ^^^^^^^^^^^^^^^^^^^^^^
   |
   = note: bare URLs are not automatically turned into clickable links
help: use an automatic link instead
   |
LL | #[doc = "<https://example.com/ra>w"]
   |          +                      +

error: aborting due to 20 previous errors
------------------------------------------

---
641 error: unescaped backtick
-   --> $DIR/unescaped_backticks.rs:115:26
+   --> $DIR/unescaped_backticks.rs:115:10
643    |
644 LL | #[doc = concat!("\\", "`")]
-    |                          ^
+    |          ^^^^^^^^^^^^^^^^
646    |
647    = help: the opening backtick of an inline code may be missing
648             change: \`
---
To only update this specific test, also pass `--test-args unescaped_backticks.rs`

error: 1 errors occurred comparing output.
status: exit status: 1
command: env -u RUSTC_LOG_COLOR RUSTC_ICE="0" RUST_BACKTRACE="short" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2/bin/rustdoc" "/checkout/tests/rustdoc-ui/unescaped_backticks.rs" "-Zthreads=1" "-Zsimulate-remapped-rust-src-base=/rustc/FAKE_PREFIX" "-Ztranslate-remapped-path-to-local-path=no" "-Z" "ignore-directory-in-diagnostics-source-blocks=/cargo" "-Z" "ignore-directory-in-diagnostics-source-blocks=/checkout/vendor" "--sysroot" "/checkout/obj/build/x86_64-unknown-linux-gnu/stage2" "--target=x86_64-unknown-linux-gnu" "--check-cfg" "cfg(test,FALSE)" "--error-format" "json" "--json" "future-incompat" "-Ccodegen-units=1" "-Zui-testing" "-Zdeduplicate-diagnostics=no" "-Zwrite-long-types-to-disk=no" "-Cstrip=debuginfo" "-o" "/checkout/obj/build/x86_64-unknown-linux-gnu/test/rustdoc-ui/unescaped_backticks" "-A" "internal_features" "-Cdebuginfo=0"
stdout: none
--- stderr -------------------------------
error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:187:70
   |
LL | /// if you want your MIR to be modified by the full MIR pipeline, or `#![custom_mir(dialect =
   |                                                                      ^
   |
note: the lint level is defined here
  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:1:9
   |
LL | #![deny(rustdoc::unescaped_backticks)]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
help: the closing backtick of an inline code may be missing
   |
LL | /// "runtime", phase = "optimized")]` if you don't.
   |                                     +
help: if you meant to use a literal backtick, escape it
   |
LL | /// if you want your MIR to be modified by the full MIR pipeline, or \`#![custom_mir(dialect =
   |                                                                      +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:232:13
   |
LL |         //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]
   |             ^
   |
help: the closing backtick of an inline code may be missing
   |
LL |         //! `#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]`
   |                                                                                         +
help: if you meant to use a literal backtick, escape it
   |
LL |         //! \`#![rustc_expected_cgu_reuse(module="spike", cfg="rpass2", kind="post-lto")]
   |             +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:237:13
   |
LL |         /// `cfg=...
   |             ^
   |
help: the closing backtick of an inline code may be missing
   |
LL |         /// `cfg=...`
   |                     +
help: if you meant to use a literal backtick, escape it
   |
LL |         /// \`cfg=...
   |             +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:241:42
   |
LL |         /// `cfg=... and not `#[cfg_attr]`
   |                                          ^
   |
help: a previous inline code might be longer than expected
   |
LL |         /// `cfg=...` and not `#[cfg_attr]`
   |                     +
help: if you meant to use a literal backtick, escape it
   |
LL |         /// `cfg=... and not `#[cfg_attr]\`
   |                                          +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:193:93
   |
LL |     /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg to
   |                                                                                             ^
   |
help: the closing backtick of an inline code may be missing
   |
LL |     /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given `msg` to
   |                                                                                                 +
help: if you meant to use a literal backtick, escape it
   |
LL |     /// Constructs a `TyKind::Error` type and registers a `span_delayed_bug` with the given \`msg to
   |                                                                                             +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:202:34
   |
LL |         /// in `nt_to_tokenstream`
   |                                  ^
   |
help: a previous inline code might be longer than expected
   |
LL |         /// if we parsed no predicates (e.g. `struct` Foo where {}
   |                                                     +
help: if you meant to use a literal backtick, escape it
   |
LL |         /// in `nt_to_tokenstream\`
   |                                  +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:208:62
   |
LL |     /// that `Option<Symbol>` only takes up 4 bytes, because `newtype_index! reserves
   |                                                              ^
   |
help: the closing backtick of an inline code may be missing
   |
LL |     /// that `Option<Symbol>` only takes up 4 bytes, because `newtype_index!` reserves
   |                                                                             +
help: if you meant to use a literal backtick, escape it
   |
LL |     /// that `Option<Symbol>` only takes up 4 bytes, because \`newtype_index! reserves
   |                                                              +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:216:52
   |
LL |     /// also avoids the need to import `OpenOptions`.
   |                                                    ^
   |
help: a previous inline code might be longer than expected
   |
LL |     /// you can write `File::with_options().read(true).open("foo.txt")`. This
   |                                                                       +
help: if you meant to use a literal backtick, escape it
   |
LL |     /// also avoids the need to import `OpenOptions\`.
   |                                                    +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:221:47
   |
LL |     /// `ChunkedBitSet`. Has no effect if `row` does not exist.
   |                                               ^
   |
help: a previous inline code might be longer than expected
   |
LL |     /// Subtracts `set` from `row`. `set` can be either `BitSet` or
   |                       +
help: if you meant to use a literal backtick, escape it
   |
LL |     /// `ChunkedBitSet`. Has no effect if `row\` does not exist.
   |                                               +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:247:12
   |
LL |     /// RWU`s can get very large, so it uses a more compact representation.
   |            ^
   |
help: the opening backtick of an inline code may be missing
   |
LL |     /// `RWU`s can get very large, so it uses a more compact representation.
   |         +
help: if you meant to use a literal backtick, escape it
   |
LL |     /// RWU\`s can get very large, so it uses a more compact representation.
   |            +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:254:15
   |
LL |     /// in `U2`.
   |               ^
   |
help: the opening backtick of a previous inline code may be missing
   |
LL |     /// `'?1` is in `U3` would be canonicalized to have `?0` in `U1` and `'?1`
   |                                                         +
help: if you meant to use a literal backtick, escape it
   |
LL |     /// in `U2\`.
   |               +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:271:42
   |
LL |     /// because it contains `[type error]`. Yuck! (See issue #29857 for
   |                                          ^
   |
help: a previous inline code might be longer than expected
   |
LL |     /// as Trait>::Foo == $0`. Here, normalizing `<MyType<$0>` as
   |                                                              +
help: if you meant to use a literal backtick, escape it
   |
LL |     /// because it contains `[type error]\`. Yuck! (See issue #29857 for
   |                                          +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:281:53
   |
LL |     /// well as the second instance of `A: AutoTrait`) to suppress
   |                                                     ^
   |
help: a previous inline code might be longer than expected
   |
LL |     /// encountered a problem (later on) with `A:` AutoTrait. So we
   |                                                  +
help: if you meant to use a literal backtick, escape it
   |
LL |     /// well as the second instance of `A: AutoTrait\`) to suppress
   |                                                     +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:291:40
   |
LL |     /// `'a` with `'b` and not `'static`. But it will have to do for
   |                                        ^
   |
   = help: the opening or closing backtick of an inline code may be missing
help: if you meant to use a literal backtick, escape it
   |
LL |     /// `'a` with `'b` and not `'static\`. But it will have to do for
   |                                        +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:300:54
   |
LL | /// `None`. Otherwise, it will return `Some(Dispatch)`.
   |                                                      ^
   |
help: the opening backtick of a previous inline code may be missing
   |
LL | /// The `Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
   |         +
help: if you meant to use a literal backtick, escape it
   |
LL | /// `None`. Otherwise, it will return `Some(Dispatch)\`.
   |                                                      +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:304:13
   |
LL | /// or `None` if it isn't.
   |             ^
   |
   = help: the opening or closing backtick of an inline code may be missing
help: if you meant to use a literal backtick, escape it
   |
LL | /// or `None\` if it isn't.
   |             +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:308:14
   |
LL | /// `on_event` should be called.
   |              ^
   |
help: a previous inline code might be longer than expected
   |
LL | /// Called before the filtered [`Layer`]'s [`on_event`], to determine if
   |                                       +
help: if you meant to use a literal backtick, escape it
   |
LL | /// `on_event\` should be called.
   |              +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:313:29
   |
LL | /// [`rebuild_interest_cache`][rebuild] is called after the value of the max
   |                             ^
   |
help: a previous inline code might be longer than expected
   |
LL | /// Therefore, if the `Filter` will change the value returned by this
   |                              +
help: if you meant to use a literal backtick, escape it
   |
LL | /// [`rebuild_interest_cache\`][rebuild] is called after the value of the max
   |                             +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:323:5
   |
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.
   | |______________________^
   |
   = help: the opening backtick of a previous inline code may be missing
            change: The Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
           to this: The `Subscriber` may be accessed by calling [`WeakDispatch::upgrade`],
   = help: if you meant to use a literal backtick, escape it
            change: `None`. Otherwise, it will return `Some(Dispatch)`.
           to this: `None`. Otherwise, it will return `Some(Dispatch)\`.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:323:5
   |
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.
   | |______________________^
   |
   = help: the opening or closing backtick of an inline code may be missing
   = help: if you meant to use a literal backtick, escape it
            change: or `None` if it isn't.
           to this: or `None\` if it isn't.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:323:5
   |
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.
   | |______________________^
   |
   = help: a previous inline code might be longer than expected
            change: Called before the filtered [`Layer]'s [`on_event`], to determine if
           to this: Called before the filtered [`Layer`]'s [`on_event`], to determine if
   = help: if you meant to use a literal backtick, escape it
            change: `on_event` should be called.
           to this: `on_event\` should be called.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:323:5
   |
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.
   | |______________________^
   |
   = help: a previous inline code might be longer than expected
            change: Therefore, if the `Filter will change the value returned by this
           to this: Therefore, if the `Filter` will change the value returned by this
   = help: if you meant to use a literal backtick, escape it
            change: [`rebuild_interest_cache`][rebuild] is called after the value of the max
           to this: [`rebuild_interest_cache\`][rebuild] is called after the value of the max

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:349:56
   |
LL |     /// instead and use [`CloneCounterObserver::counter`] to increment.
   |                                                        ^
   |
   = help: the opening or closing backtick of an inline code may be missing
help: if you meant to use a literal backtick, escape it
   |
LL |     /// instead and use [`CloneCounterObserver::counter\`] to increment.
   |                                                        +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:12:5
   |
---

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:26:6
   |
LL | /// [`link1]
   |      ^
   |
help: the closing backtick of an inline code may be missing
   |
LL | /// [`link1`]
   |            +
help: if you meant to use a literal backtick, escape it
   |
LL | /// [\`link1]
   |      +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:30:11
   |
LL | /// [link2`]
   |           ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// [`link2`]
   |      +
help: if you meant to use a literal backtick, escape it
   |
LL | /// [link2\`]
   |           +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:34:6
   |
LL | /// [`link_long](link_long)
   |      ^
   |
help: the closing backtick of an inline code may be missing
   |
LL | /// [`link_long`](link_long)
   |                +
help: if you meant to use a literal backtick, escape it
   |
LL | /// [\`link_long](link_long)
   |      +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:38:6
   |
LL | /// [`broken-link]
   |      ^
   |
help: the closing backtick of an inline code may be missing
   |
LL | /// [`broken-link`]
   |                  +
help: if you meant to use a literal backtick, escape it
   |
LL | /// [\`broken-link]
   |      +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:45:8
   |
LL | /// <x:`>
   |        ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// `<x:`>
   |     +
help: if you meant to use a literal backtick, escape it
   |
LL | /// <x:\`>
   |        +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:55:6
   |
---
LL | /// `foo(`
   |          +
help: if you meant to use a literal backtick, escape it
   |
LL | /// \`foo(
   |     +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:65:14
   |
LL | /// `foo `bar`
   |              ^
   |
help: a previous inline code might be longer than expected
   |
LL | /// `foo` `bar`
   |         +
help: if you meant to use a literal backtick, escape it
   |
LL | /// `foo `bar\`
   |              +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:71:5
   |
---
LL | /// not paragraph`
   |                  +
help: if you meant to use a literal backtick, escape it
   |
LL | /// \`foo(
   |     +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:76:83
   |
LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`.
   |                                                                                   ^
   |
help: the opening backtick of a previous inline code may be missing
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
   |                                               +
help: if you meant to use a literal backtick, escape it
   |
LL | /// Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`.
   |                                                                                   +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:80:51
   |
LL | /// or even to add a number `n` to 42 (`add(42, b)`)!
   |                                                   ^
   |
help: the opening backtick of a previous inline code may be missing
   |
LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`),
   |                                                            +
help: if you meant to use a literal backtick, escape it
   |
LL | /// or even to add a number `n` to 42 (`add(42, b)\`)!
   |                                                   +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:84:83
   |
LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`.
   |                                                                                   ^
   |
help: a previous inline code might be longer than expected
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
   |                                                         +
help: if you meant to use a literal backtick, escape it
   |
LL | /// Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`.
   |                                                                                   +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:88:51
   |
LL | /// or even to add a number `n` to 42 (`add(42, n)`)!
   |                                                   ^
   |
help: a previous inline code might be longer than expected
   |
LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`),
   |                                                                       +
help: if you meant to use a literal backtick, escape it
   |
LL | /// or even to add a number `n` to 42 (`add(42, n)\`)!
   |                                                   +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:92:83
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`.
   |                                                                                   ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
   |                                                                          +
help: if you meant to use a literal backtick, escape it
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`.
   |                                                                                   +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:96:50
   |
LL | /// or even to add a number `n` to 42 (add(42, n)`)!
   |                                                  ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// or even to add a number `n` to 42 (`add(42, n)`)!
   |                                        +
help: if you meant to use a literal backtick, escape it
   |
LL | /// or even to add a number `n` to 42 (add(42, n)\`)!
   |                                                  +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:100:74
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a).
   |                                                                          ^
   |
help: the closing backtick of an inline code may be missing
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
   |                                                                                    +
help: if you meant to use a literal backtick, escape it
   |
LL | /// Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a).
   |                                                                          +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:104:51
   |
LL | /// or even to add a number `n` to 42 (`add(42, n)`)!
   |                                                   ^
   |
help: a previous inline code might be longer than expected
   |
LL | /// You could use this function to add 42 to a number `n` (`add(n, 42)`),
   |                                                                       +
help: if you meant to use a literal backtick, escape it
   |
LL | /// or even to add a number `n` to 42 (`add(42, n)\`)!
   |                                                   +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:108:10
   |
LL | #[doc = "`"]
   |          ^
   |
   = help: the opening or closing backtick of an inline code may be missing
   = help: if you meant to use a literal backtick, escape it
            change: `
           to this: \`

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:115:10
   |
LL | #[doc = concat!("\\\\", "`")]
   |          ^^^^^^^^^^^^^^^^
   |
   = help: the opening backtick of an inline code may be missing
            change: \\`
           to this: `\\`
   = help: if you meant to use a literal backtick, escape it
            change: \\`
           to this: \\\`

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:119:9
   |
LL | #[doc = "Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`."]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: the opening backtick of a previous inline code may be missing
            change: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`.
           to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
   = help: if you meant to use a literal backtick, escape it
            change: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)`.
           to this: Addition is commutative, which means that add(a, b)` is the same as `add(b, a)\`.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:123:9
   |
LL | #[doc = "Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`."]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: a previous inline code might be longer than expected
            change: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`.
           to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
   = help: if you meant to use a literal backtick, escape it
            change: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)`.
           to this: Addition is commutative, which means that `add(a, b) is the same as `add(b, a)\`.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:127:9
   |
LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`."]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: the opening backtick of an inline code may be missing
            change: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`.
           to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
   = help: if you meant to use a literal backtick, escape it
            change: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)`.
           to this: Addition is commutative, which means that `add(a, b)` is the same as add(b, a)\`.

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:131:9
   |
LL | #[doc = "Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)."]
   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
   |
   = help: the closing backtick of an inline code may be missing
            change: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a).
           to this: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a)`.
   = help: if you meant to use a literal backtick, escape it
            change: Addition is commutative, which means that `add(a, b)` is the same as `add(b, a).
           to this: Addition is commutative, which means that `add(a, b)` is the same as \`add(b, a).

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:136:5
   |
LL | /// `foo
---

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:140:7
   |
LL | /// # `(heading
   |       ^
   |
help: the closing backtick of an inline code may be missing
   |
LL | /// # `(heading`
   |                +
help: if you meant to use a literal backtick, escape it
   |
LL | /// # \`(heading
   |       +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:142:17
   |
LL | /// ## heading2)`
   |                 ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// ## `heading2)`
   |        +
help: if you meant to use a literal backtick, escape it
   |
LL | /// ## heading2)\`
   |                 +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:145:11
   |
---

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:151:10
   |
LL | /// para)`(graph
   |          ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// `para)`(graph
   |     +
help: the closing backtick of an inline code may be missing
   |
LL | /// para)`(graph`
   |                 +
help: if you meant to use a literal backtick, escape it
   |
LL | /// para)\`(graph
   |          +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:154:10
   |
LL | /// para)`(graph2
   |          ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// `para)`(graph2
   |     +
help: the closing backtick of an inline code may be missing
   |
LL | /// para)`(graph2`
   |                  +
help: if you meant to use a literal backtick, escape it
   |
LL | /// para)\`(graph2
   |          +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:157:12
   |
LL | /// 1. foo)`
   |            ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// 1. `foo)`
   |        +
help: if you meant to use a literal backtick, escape it
   |
LL | /// 1. foo)\`
   |            +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:159:8
   |
LL | /// 2. `(bar
   |        ^
   |
help: the closing backtick of an inline code may be missing
   |
LL | /// 2. `(bar`
   |             +
help: if you meant to use a literal backtick, escape it
   |
LL | /// 2. \`(bar
   |        +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:161:11
   |
LL | /// * baz)`
   |           ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// * `baz)`
   |       +
help: if you meant to use a literal backtick, escape it
   |
LL | /// * baz)\`
   |           +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:163:7
   |
LL | /// * `(quux
   |       ^
   |
help: the closing backtick of an inline code may be missing
   |
LL | /// * `(quux`
   |             +
help: if you meant to use a literal backtick, escape it
   |
LL | /// * \`(quux
   |       +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:166:5
   |
LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")]
   |     ^
   |
help: the closing backtick of an inline code may be missing
   |
LL | /// `#`![this_is_actually_an_image(and(not), an = "attribute")]
   |       +
help: if you meant to use a literal backtick, escape it
   |
LL | /// \`#![this_is_actually_an_image(and(not), an = "attribute")]
   |     +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:169:62
   |
LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]`
   |                                                              ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// `#![this_is_actually_an_image(and(not), an = "attribute")]`
   |     +
help: if you meant to use a literal backtick, escape it
   |
LL | /// #![this_is_actually_an_image(and(not), an = "attribute")]\`
   |                                                              +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:174:7
   |
LL | /// | `table( | )head` |
   |       ^
   |
help: the closing backtick of an inline code may be missing
   |
LL | /// | `table(` | )head` |
   |              +
help: if you meant to use a literal backtick, escape it
   |
LL | /// | \`table( | )head` |
   |       +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:174:22
   |
LL | /// | `table( | )head` |
   |                      ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// | `table( | `)head` |
   |                 +
help: if you meant to use a literal backtick, escape it
   |
LL | /// | `table( | )head\` |
   |                      +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:178:12
   |
LL | /// | table`( | )`body |
   |            ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// | `table`( | )`body |
   |       +
help: if you meant to use a literal backtick, escape it
   |
LL | /// | table\`( | )`body |
   |            +

error: unescaped backtick
##[error]  --> /checkout/tests/rustdoc-ui/unescaped_backticks.rs:178:18
   |
LL | /// | table`( | )`body |
   |                  ^
   |
help: the opening backtick of an inline code may be missing
   |
LL | /// | table`( | `)`body |
   |                 +
help: the closing backtick of an inline code may be missing
   |
LL | /// | table`( | )`body` |
   |                       +
help: if you meant to use a literal backtick, escape it
   |
LL | /// | table`( | )\`body |
   |                  +

error: aborting due to 64 previous errors
------------------------------------------

```

</details>

author_association: COLLABORATOR
user: login: rust-log-analyzer
created_at: 2025-05-22T17:17:51Z
body: 
The job **`mingw-check-tidy`** failed! Check out the build log: [(web)](https://github.com/rust-lang/rust/actions/runs/15192614475/job/42729036166) [(plain)](https://github.com/rust-lang/rust/commit/314ac8936665b87a0113cfec0f72beb9493843d2/checks/42729036166/logs)

<details><summary><i>Click to see the possible cause of the failure (guessed by this bot)</i></summary>

```plain
info: removing rustup binaries
info: rustup is uninstalled
##[group]Image checksum input
mingw-check-tidy
# We use the ghcr base image because ghcr doesn't have a rate limit
# and the mingw-check-tidy job doesn't cache docker images in CI.
FROM ghcr.io/rust-lang/ubuntu:22.04

ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
  g++ \
---

COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
COPY host-x86_64/mingw-check/validate-error-codes.sh /scripts/

# NOTE: intentionally uses python2 for x.py so we can test it still works.
# validate-toolstate only runs in our CI, so it's ok for it to only support python3.
ENV SCRIPT TIDY_PRINT_DIFF=1 python2.7 ../x.py test \
           --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
#
# This file is autogenerated by pip-compile with Python 3.10
# by the following command:
#
#    pip-compile --allow-unsafe --generate-hashes reuse-requirements.in
---
#12 3.022 Building wheels for collected packages: reuse
#12 3.023   Building wheel for reuse (pyproject.toml): started
#12 3.250   Building wheel for reuse (pyproject.toml): finished with status 'done'
#12 3.251   Created wheel for reuse: filename=reuse-4.0.3-cp310-cp310-manylinux_2_35_x86_64.whl size=132719 sha256=d2a2565e7037ad3883fb9337653f2e25bbb588534fbef3697286cbc26d1bf634
#12 3.252   Stored in directory: /tmp/pip-ephem-wheel-cache-72np2gwh/wheels/3d/8d/0a/e0fc6aba4494b28a967ab5eaf951c121d9c677958714e34532
#12 3.254 Successfully built reuse
#12 3.254 Installing collected packages: boolean-py, binaryornot, tomlkit, reuse, python-debian, markupsafe, license-expression, jinja2, chardet, attrs
#12 3.687 Successfully installed attrs-23.2.0 binaryornot-0.4.4 boolean-py-4.0 chardet-5.2.0 jinja2-3.1.4 license-expression-30.3.0 markupsafe-2.1.5 python-debian-0.1.49 reuse-4.0.3 tomlkit-0.13.0
#12 3.688 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#12 4.272 Collecting virtualenv
#12 4.325   Downloading virtualenv-20.31.2-py3-none-any.whl (6.1 MB)
#12 4.525      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.1/6.1 MB 30.6 MB/s eta 0:00:00
#12 4.573 Collecting distlib<1,>=0.3.7
#12 4.581   Downloading distlib-0.3.9-py2.py3-none-any.whl (468 kB)
#12 4.592      ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 469.0/469.0 KB 50.6 MB/s eta 0:00:00
#12 4.631 Collecting platformdirs<5,>=3.9.1
#12 4.639   Downloading platformdirs-4.3.8-py3-none-any.whl (18 kB)
#12 4.682 Collecting filelock<4,>=3.12.2
#12 4.689   Downloading filelock-3.18.0-py3-none-any.whl (16 kB)
#12 4.774 Installing collected packages: distlib, platformdirs, filelock, virtualenv
#12 4.971 Successfully installed distlib-0.3.9 filelock-3.18.0 platformdirs-4.3.8 virtualenv-20.31.2
#12 4.971 WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
#12 DONE 5.1s

#13 [7/8] COPY host-x86_64/mingw-check/validate-toolstate.sh /scripts/
#13 DONE 0.0s
---
DirectMap4k:      145344 kB
DirectMap2M:     7194624 kB
DirectMap1G:    11534336 kB
##[endgroup]
Executing TIDY_PRINT_DIFF=1 python2.7 ../x.py test            --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
+ TIDY_PRINT_DIFF=1 python2.7 ../x.py test --stage 0 src/tools/tidy tidyselftest --extra-checks=py,cpp
##[group]Building bootstrap
    Finished `dev` profile [unoptimized] target(s) in 0.05s
##[endgroup]
WARN: currently no CI rustc builds have rustc debug assertions enabled. Please either set `rust.debug-assertions` to `false` if you want to use download CI rustc or set `rust.download-rustc` to `false`.
downloading https://static.rust-lang.org/dist/2025-05-12/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz
---
[TIMING] core::build_steps::tool::Tidy { compiler: Compiler { stage: 0, host: x86_64-unknown-linux-gnu, forced_compiler: false }, target: x86_64-unknown-linux-gnu } -- 0.000
fmt check
Diff in /checkout/compiler/rustc_resolve/src/rustdoc.rs:583:
             // we need to calculate the span start,
             // then use that in our calulations for the span end
             let lo = sp.lo() + BytePos(match_start as u32);
-            return Some(sp.with_lo(lo).with_hi(lo + BytePos((md_range.end - md_range.start) as u32)));
+            return Some(
+                sp.with_lo(lo).with_hi(lo + BytePos((md_range.end - md_range.start) as u32)),
+            );
         }
         return None;
     }
fmt: checked 6022 files
```

</details>

author_association: COLLABORATOR
user: login: GuillaumeGomez
created_at: 2025-05-22T20:49:49Z
body: Looks all good to me. This is a very nice improvement, thanks!

@bors r+ rollup
author_association: MEMBER
user: login: bors
created_at: 2025-05-22T20:49:52Z
body: :pushpin: Commit 3005a09fedd5c874c36ca1c788954e51e3fa0617 has been approved by `GuillaumeGomez`

It is now in the [queue](https://bors.rust-lang.org/homu/queue/rust) for this repository.

<!-- @bors r=GuillaumeGomez 3005a09fedd5c874c36ca1c788954e51e3fa0617 -->
<!-- homu: {"type":"Approved","sha":"3005a09fedd5c874c36ca1c788954e51e3fa0617","approver":"GuillaumeGomez","queue":"https://bors.rust-lang.org/homu/queue/rust"} -->
author_association: COLLABORATOR