about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMatthias Krüger <476013+matthiaskrgr@users.noreply.github.com>2025-06-26 15:47:18 +0200
committerGitHub <noreply@github.com>2025-06-26 15:47:18 +0200
commitcbcf183711f637054e18f272ecfbf8d2ae8588c0 (patch)
tree2d380249b6afbf5e5229751d2d02d35942233a22 /src
parent158340f5617f7e6a555046802133536ab61764ba (diff)
parent3b5525bc420551c9c32ad3b5b6c8d673dd25da0d (diff)
downloadrust-cbcf183711f637054e18f272ecfbf8d2ae8588c0.tar.gz
rust-cbcf183711f637054e18f272ecfbf8d2ae8588c0.zip
Rollup merge of #141648 - GuillaumeGomez:redundant_explicit_links-expansion, r=lolbinarycat
[rustdoc] Do not emit redundant_explicit_links lint if the doc comment comes from expansion

Fixes https://github.com/rust-lang/rust/issues/141553.

The problem was that we change the context for the attributes in some cases to get better error output, preventing us to detect if the attribute comes from expansion. Most of the changes are about keeping track of the "does this span comes from expansion" information.

r? ```@Manishearth```
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/clean/types/tests.rs1
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs13
-rw-r--r--src/librustdoc/passes/lint/bare_urls.rs3
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs2
-rw-r--r--src/librustdoc/passes/lint/html_tags.rs4
-rw-r--r--src/librustdoc/passes/lint/redundant_explicit_links.rs58
-rw-r--r--src/librustdoc/passes/lint/unescaped_backticks.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/doc/mod.rs4
8 files changed, 67 insertions, 28 deletions
diff --git a/src/librustdoc/clean/types/tests.rs b/src/librustdoc/clean/types/tests.rs
index 7ff5026150b..9499507b2c0 100644
--- a/src/librustdoc/clean/types/tests.rs
+++ b/src/librustdoc/clean/types/tests.rs
@@ -10,6 +10,7 @@ fn create_doc_fragment(s: &str) -> Vec<DocFragment> {
         doc: Symbol::intern(s),
         kind: DocFragmentKind::SugaredDoc,
         indent: 0,
+        from_expansion: false,
     }]
 }
 
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 1daaba3b86c..ca6f67eb6df 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -1387,13 +1387,15 @@ impl LinkCollector<'_, '_> {
         ori_link: &MarkdownLinkRange,
         item: &Item,
     ) {
-        let span = source_span_for_markdown_range(
+        let span = match source_span_for_markdown_range(
             self.cx.tcx,
             dox,
             ori_link.inner_range(),
             &item.attrs.doc_strings,
-        )
-        .unwrap_or_else(|| item.attr_span(self.cx.tcx));
+        ) {
+            Some((sp, _)) => sp,
+            None => item.attr_span(self.cx.tcx),
+        };
         rustc_session::parse::feature_err(
             self.cx.tcx.sess,
             sym::intra_doc_pointers,
@@ -1836,7 +1838,7 @@ fn report_diagnostic(
                 let mut md_range = md_range.clone();
                 let sp =
                     source_span_for_markdown_range(tcx, dox, &md_range, &item.attrs.doc_strings)
-                        .map(|mut sp| {
+                        .map(|(mut sp, _)| {
                             while dox.as_bytes().get(md_range.start) == Some(&b' ')
                                 || dox.as_bytes().get(md_range.start) == Some(&b'`')
                             {
@@ -1854,7 +1856,8 @@ fn report_diagnostic(
                 (sp, MarkdownLinkRange::Destination(md_range))
             }
             MarkdownLinkRange::WholeLink(md_range) => (
-                source_span_for_markdown_range(tcx, dox, md_range, &item.attrs.doc_strings),
+                source_span_for_markdown_range(tcx, dox, md_range, &item.attrs.doc_strings)
+                    .map(|(sp, _)| sp),
                 link_range.clone(),
             ),
         };
diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs
index 3b3ce3e9220..f70bdf4e4fe 100644
--- a/src/librustdoc/passes/lint/bare_urls.rs
+++ b/src/librustdoc/passes/lint/bare_urls.rs
@@ -18,7 +18,8 @@ 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 maybe_sp = source_span_for_markdown_range(cx.tcx, dox, &range, &item.attrs.doc_strings);
+        let maybe_sp = source_span_for_markdown_range(cx.tcx, dox, &range, &item.attrs.doc_strings)
+            .map(|(sp, _)| sp);
         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)
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
index 91cddbe5a5b..b08533317ab 100644
--- a/src/librustdoc/passes/lint/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -87,7 +87,7 @@ fn check_rust_syntax(
         &code_block.range,
         &item.attrs.doc_strings,
     ) {
-        Some(sp) => (sp, true),
+        Some((sp, _)) => (sp, true),
         None => (item.attr_span(cx.tcx), false),
     };
 
diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs
index b9739726c95..19cf15d40a3 100644
--- a/src/librustdoc/passes/lint/html_tags.rs
+++ b/src/librustdoc/passes/lint/html_tags.rs
@@ -16,7 +16,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
     let tcx = cx.tcx;
     let report_diag = |msg: String, range: &Range<usize>, is_open_tag: bool| {
         let sp = match source_span_for_markdown_range(tcx, dox, range, &item.attrs.doc_strings) {
-            Some(sp) => sp,
+            Some((sp, _)) => sp,
             None => item.attr_span(tcx),
         };
         tcx.node_span_lint(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| {
@@ -55,7 +55,7 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
                     &(generics_start..generics_end),
                     &item.attrs.doc_strings,
                 ) {
-                    Some(sp) => sp,
+                    Some((sp, _)) => sp,
                     None => item.attr_span(tcx),
                 };
                 // Sometimes, we only extract part of a path. For example, consider this:
diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs
index 6bc4374c06b..5757b6a9740 100644
--- a/src/librustdoc/passes/lint/redundant_explicit_links.rs
+++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs
@@ -161,20 +161,36 @@ fn check_inline_or_reference_unknown_redundancy(
 
     if dest_res == display_res {
         let link_span =
-            source_span_for_markdown_range(cx.tcx, doc, &link_range, &item.attrs.doc_strings)
-                .unwrap_or(item.attr_span(cx.tcx));
-        let explicit_span = source_span_for_markdown_range(
+            match source_span_for_markdown_range(cx.tcx, doc, &link_range, &item.attrs.doc_strings)
+            {
+                Some((sp, from_expansion)) => {
+                    if from_expansion {
+                        return None;
+                    }
+                    sp
+                }
+                None => item.attr_span(cx.tcx),
+            };
+        let (explicit_span, false) = source_span_for_markdown_range(
             cx.tcx,
             doc,
             &offset_explicit_range(doc, link_range, open, close),
             &item.attrs.doc_strings,
-        )?;
-        let display_span = source_span_for_markdown_range(
+        )?
+        else {
+            // This `span` comes from macro expansion so skipping it.
+            return None;
+        };
+        let (display_span, false) = source_span_for_markdown_range(
             cx.tcx,
             doc,
             resolvable_link_range,
             &item.attrs.doc_strings,
-        )?;
+        )?
+        else {
+            // This `span` comes from macro expansion so skipping it.
+            return None;
+        };
 
         cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, |lint| {
             lint.primary_message("redundant explicit link target")
@@ -206,21 +222,37 @@ fn check_reference_redundancy(
 
     if dest_res == display_res {
         let link_span =
-            source_span_for_markdown_range(cx.tcx, doc, &link_range, &item.attrs.doc_strings)
-                .unwrap_or(item.attr_span(cx.tcx));
-        let explicit_span = source_span_for_markdown_range(
+            match source_span_for_markdown_range(cx.tcx, doc, &link_range, &item.attrs.doc_strings)
+            {
+                Some((sp, from_expansion)) => {
+                    if from_expansion {
+                        return None;
+                    }
+                    sp
+                }
+                None => item.attr_span(cx.tcx),
+            };
+        let (explicit_span, false) = source_span_for_markdown_range(
             cx.tcx,
             doc,
             &offset_explicit_range(doc, link_range.clone(), b'[', b']'),
             &item.attrs.doc_strings,
-        )?;
-        let display_span = source_span_for_markdown_range(
+        )?
+        else {
+            // This `span` comes from macro expansion so skipping it.
+            return None;
+        };
+        let (display_span, false) = source_span_for_markdown_range(
             cx.tcx,
             doc,
             resolvable_link_range,
             &item.attrs.doc_strings,
-        )?;
-        let def_span = source_span_for_markdown_range(
+        )?
+        else {
+            // This `span` comes from macro expansion so skipping it.
+            return None;
+        };
+        let (def_span, _) = source_span_for_markdown_range(
             cx.tcx,
             doc,
             &offset_reference_def_range(doc, dest, link_range),
diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs
index 88f4c3ac1cd..7f5643f4ba8 100644
--- a/src/librustdoc/passes/lint/unescaped_backticks.rs
+++ b/src/librustdoc/passes/lint/unescaped_backticks.rs
@@ -42,13 +42,15 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
 
                 // If we can't get a span of the backtick, because it is in a `#[doc = ""]` attribute,
                 // use the span of the entire attribute as a fallback.
-                let span = source_span_for_markdown_range(
+                let span = match source_span_for_markdown_range(
                     tcx,
                     dox,
                     &(backtick_index..backtick_index + 1),
                     &item.attrs.doc_strings,
-                )
-                .unwrap_or_else(|| item.attr_span(tcx));
+                ) {
+                    Some((sp, _)) => sp,
+                    None => item.attr_span(tcx),
+                };
 
                 tcx.node_span_lint(crate::lint::UNESCAPED_BACKTICKS, hir_id, span, |lint| {
                     lint.primary_message("unescaped backtick");
@@ -419,7 +421,7 @@ fn suggest_insertion(
     /// Maximum bytes of context to show around the insertion.
     const CONTEXT_MAX_LEN: usize = 80;
 
-    if let Some(span) = source_span_for_markdown_range(
+    if let Some((span, _)) = source_span_for_markdown_range(
         cx.tcx,
         dox,
         &(insert_index..insert_index),
diff --git a/src/tools/clippy/clippy_lints/src/doc/mod.rs b/src/tools/clippy/clippy_lints/src/doc/mod.rs
index e0fc2fd9347..d38588bb799 100644
--- a/src/tools/clippy/clippy_lints/src/doc/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/doc/mod.rs
@@ -765,8 +765,8 @@ impl Fragments<'_> {
     /// get the span for the markdown range. Note that this function is not cheap, use it with
     /// caution.
     #[must_use]
-    fn span(&self, cx: &LateContext<'_>, range: Range<usize>) -> Option<Span> {
-        source_span_for_markdown_range(cx.tcx, self.doc, &range, self.fragments)
+    fn span(self, cx: &LateContext<'_>, range: Range<usize>) -> Option<Span> {
+        source_span_for_markdown_range(cx.tcx, self.doc, &range, self.fragments).map(|(sp, _)| sp)
     }
 }