diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-05-27 15:16:51 +0200 |
|---|---|---|
| committer | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2025-06-23 16:02:33 +0200 |
| commit | 7e683cc4d1f8dff6c777b2eecec4c1173dbff1db (patch) | |
| tree | d067004e8d61f6f0103d8afd448739c333b29848 /compiler/rustc_resolve/src/rustdoc.rs | |
| parent | 22be76b7e259f27bf3e55eb931f354cd8b69d55f (diff) | |
| download | rust-7e683cc4d1f8dff6c777b2eecec4c1173dbff1db.tar.gz rust-7e683cc4d1f8dff6c777b2eecec4c1173dbff1db.zip | |
Do not emit `redundant_explicit_links` rustdoc lint if the doc comment comes from expansion
Diffstat (limited to 'compiler/rustc_resolve/src/rustdoc.rs')
| -rw-r--r-- | compiler/rustc_resolve/src/rustdoc.rs | 82 |
1 files changed, 50 insertions, 32 deletions
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 931c6241bf2..2d84178bede 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -49,6 +49,9 @@ pub struct DocFragment { pub doc: Symbol, pub kind: DocFragmentKind, pub indent: usize, + /// Because we temper with the spans context, this information cannot be correctly retrieved + /// later on. So instead, we compute it and store it here. + pub from_expansion: bool, } #[derive(Clone, Copy, Debug)] @@ -208,17 +211,18 @@ pub fn attrs_to_doc_fragments<'a, A: AttributeExt + Clone + 'a>( for (attr, item_id) in attrs { if let Some((doc_str, comment_kind)) = attr.doc_str_and_comment_kind() { let doc = beautify_doc_string(doc_str, comment_kind); - let (span, kind) = if attr.is_doc_comment() { - (attr.span(), DocFragmentKind::SugaredDoc) + let (span, kind, from_expansion) = if attr.is_doc_comment() { + let span = attr.span(); + (span, DocFragmentKind::SugaredDoc, span.from_expansion()) } else { - ( - attr.value_span() - .map(|i| i.with_ctxt(attr.span().ctxt())) - .unwrap_or(attr.span()), - DocFragmentKind::RawDoc, - ) + let attr_span = attr.span(); + let (span, from_expansion) = match attr.value_span() { + Some(sp) => (sp.with_ctxt(attr_span.ctxt()), sp.from_expansion()), + None => (attr_span, attr_span.from_expansion()), + }; + (span, DocFragmentKind::RawDoc, from_expansion) }; - let fragment = DocFragment { span, doc, kind, item_id, indent: 0 }; + let fragment = DocFragment { span, doc, kind, item_id, indent: 0, from_expansion }; doc_fragments.push(fragment); } else if !doc_only { other_attrs.push(attr.clone()); @@ -506,16 +510,21 @@ fn collect_link_data<'input, F: BrokenLinkCallback<'input>>( } /// Returns a span encompassing all the document fragments. -pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> { - if fragments.is_empty() { - return None; - } - let start = fragments[0].span; - if start == DUMMY_SP { +pub fn span_of_fragments_with_expansion(fragments: &[DocFragment]) -> Option<(Span, bool)> { + let Some(first_fragment) = fragments.first() else { return None }; + if first_fragment.span == DUMMY_SP { return None; } - let end = fragments.last().expect("no doc strings provided").span; - Some(start.to(end)) + let last_fragment = fragments.last().expect("no doc strings provided"); + Some(( + first_fragment.span.to(last_fragment.span), + first_fragment.from_expansion || last_fragment.from_expansion, + )) +} + +/// Returns a span encompassing all the document fragments. +pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> { + span_of_fragments_with_expansion(fragments).map(|(sp, _)| sp) } /// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code. @@ -540,7 +549,7 @@ pub fn source_span_for_markdown_range( markdown: &str, md_range: &Range<usize>, fragments: &[DocFragment], -) -> Option<Span> { +) -> Option<(Span, bool)> { let map = tcx.sess.source_map(); source_span_for_markdown_range_inner(map, markdown, md_range, fragments) } @@ -551,7 +560,7 @@ pub fn source_span_for_markdown_range_inner( markdown: &str, md_range: &Range<usize>, fragments: &[DocFragment], -) -> Option<Span> { +) -> Option<(Span, bool)> { use rustc_span::BytePos; if let &[fragment] = &fragments @@ -562,11 +571,14 @@ pub fn source_span_for_markdown_range_inner( && let Ok(md_range_hi) = u32::try_from(md_range.end) { // Single fragment with string that contains same bytes as doc. - return Some(Span::new( - fragment.span.lo() + rustc_span::BytePos(md_range_lo), - fragment.span.lo() + rustc_span::BytePos(md_range_hi), - fragment.span.ctxt(), - fragment.span.parent(), + return Some(( + Span::new( + fragment.span.lo() + rustc_span::BytePos(md_range_lo), + fragment.span.lo() + rustc_span::BytePos(md_range_hi), + fragment.span.ctxt(), + fragment.span.parent(), + ), + fragment.from_expansion, )); } @@ -598,19 +610,21 @@ pub fn source_span_for_markdown_range_inner( { match_data = Some((i, match_start)); } else { - // Heirustic produced ambiguity, return nothing. + // Heuristic produced ambiguity, return nothing. return None; } } } if let Some((i, match_start)) = match_data { - let sp = fragments[i].span; + let fragment = &fragments[i]; + let sp = fragment.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( + return Some(( sp.with_lo(lo).with_hi(lo + BytePos((md_range.end - md_range.start) as u32)), - ); + fragment.from_expansion, + )); } return None; } @@ -664,8 +678,12 @@ pub fn source_span_for_markdown_range_inner( } } - Some(span_of_fragments(fragments)?.from_inner(InnerSpan::new( - md_range.start + start_bytes, - md_range.end + start_bytes + end_bytes, - ))) + let (span, from_expansion) = span_of_fragments_with_expansion(fragments)?; + Some(( + span.from_inner(InnerSpan::new( + md_range.start + start_bytes, + md_range.end + start_bytes + end_bytes, + )), + from_expansion, + )) } |
