Skip to content

Commit 8c7779b

Browse files
Improve code and documentation
1 parent 54b443c commit 8c7779b

File tree

4 files changed

+65
-21
lines changed

4 files changed

+65
-21
lines changed

compiler/rustc_resolve/src/rustdoc.rs

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ pub struct DocFragment {
4949
pub doc: Symbol,
5050
pub kind: DocFragmentKind,
5151
pub indent: usize,
52-
/// Because we temper with the spans context, this information cannot be correctly retrieved
52+
/// Because we tamper with the spans context, this information cannot be correctly retrieved
5353
/// later on. So instead, we compute it and store it here.
5454
pub from_expansion: bool,
5555
}
@@ -504,16 +504,20 @@ fn collect_link_data<'input, F: BrokenLinkCallback<'input>>(
504504
display_text.map(String::into_boxed_str)
505505
}
506506

507-
/// Returns a span encompassing all the document fragments.
507+
/// Returns a tuple containing a span encompassing all the document fragments and a boolean that is
508+
/// `true` if any of the fragments are from a macro expansion.
508509
pub fn span_of_fragments_with_expansion(fragments: &[DocFragment]) -> Option<(Span, bool)> {
509-
let Some(first_fragment) = fragments.first() else { return None };
510+
let (first_fragment, last_fragment) = match fragments {
511+
[] => return None,
512+
[first, .., last] => (first, last),
513+
[first] => (first, first),
514+
};
510515
if first_fragment.span == DUMMY_SP {
511516
return None;
512517
}
513-
let last_fragment = fragments.last().expect("no doc strings provided");
514518
Some((
515519
first_fragment.span.to(last_fragment.span),
516-
first_fragment.from_expansion || last_fragment.from_expansion,
520+
fragments.iter().any(|frag| frag.from_expansion),
517521
))
518522
}
519523

@@ -533,12 +537,16 @@ pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> {
533537
/// This method will return `Some` only if one of the following is true:
534538
///
535539
/// - The doc is made entirely from sugared doc comments, which cannot contain escapes
536-
/// - The doc is entirely from a single doc fragment with a string literal exactly equal to `markdown`.
540+
/// - The doc is entirely from a single doc fragment with a string literal exactly equal to
541+
/// `markdown`.
537542
/// - The doc comes from `include_str!`
538-
/// - The doc includes exactly one substring matching `markdown[md_range]` which is contained in a single doc fragment.
543+
/// - The doc includes exactly one substring matching `markdown[md_range]` which is contained in a
544+
/// single doc fragment.
545+
///
546+
/// This function is defined in the compiler so it can be used by both `rustdoc` and `clippy`.
539547
///
540-
/// This function is defined in the compiler so it can be used by
541-
/// both `rustdoc` and `clippy`.
548+
/// It returns a tuple containing a span encompassing all the document fragments and a boolean that
549+
/// is `true` if any of the *matched* fragments are from a macro expansion.
542550
pub fn source_span_for_markdown_range(
543551
tcx: TyCtxt<'_>,
544552
markdown: &str,
@@ -673,12 +681,13 @@ pub fn source_span_for_markdown_range_inner(
673681
}
674682
}
675683

676-
let (span, from_expansion) = span_of_fragments_with_expansion(fragments)?;
684+
let (span, _) = span_of_fragments_with_expansion(fragments)?;
685+
let src_span = span.from_inner(InnerSpan::new(
686+
md_range.start + start_bytes,
687+
md_range.end + start_bytes + end_bytes,
688+
));
677689
Some((
678-
span.from_inner(InnerSpan::new(
679-
md_range.start + start_bytes,
680-
md_range.end + start_bytes + end_bytes,
681-
)),
682-
from_expansion,
690+
src_span,
691+
fragments.iter().any(|frag| frag.span.overlaps(src_span) && frag.from_expansion),
683692
))
684693
}

src/librustdoc/passes/lint/redundant_explicit_links.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,16 @@ fn check_inline_or_reference_unknown_redundancy(
180180
if from_expansion {
181181
return None;
182182
}
183-
let (display_span, _) = source_span_for_markdown_range(
183+
let (display_span, false) = source_span_for_markdown_range(
184184
cx.tcx,
185185
doc,
186186
resolvable_link_range,
187187
&item.attrs.doc_strings,
188-
)?;
188+
)?
189+
else {
190+
// This `span` comes from macro expansion so skipping it.
191+
return None;
192+
};
189193

190194
cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, |lint| {
191195
lint.primary_message("redundant explicit link target")
@@ -236,12 +240,15 @@ fn check_reference_redundancy(
236240
if from_expansion {
237241
return None;
238242
}
239-
let (display_span, _) = source_span_for_markdown_range(
243+
let (display_span, from_expansion) = source_span_for_markdown_range(
240244
cx.tcx,
241245
doc,
242246
resolvable_link_range,
243247
&item.attrs.doc_strings,
244248
)?;
249+
if from_expansion {
250+
return None;
251+
}
245252
let (def_span, _) = source_span_for_markdown_range(
246253
cx.tcx,
247254
doc,

tests/rustdoc-ui/lints/redundant_explicit_links-expansion.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ macro_rules! mac2 {
1616
}
1717
}
1818

19+
macro_rules! mac3 {
20+
() => {
21+
"Provided by"
22+
};
23+
}
24+
1925
// Should not lint.
2026
#[doc = mac1!()]
2127
pub struct Foo;
@@ -24,5 +30,11 @@ pub struct Foo;
2430
mac2!{}
2531

2632
#[doc = "provided by a [`BufferProvider`](crate::BufferProvider)."]
27-
//~^ ERROR: redundant_explicit_links
33+
/// bla
34+
//~^^ ERROR: redundant_explicit_links
2835
pub struct Bla;
36+
37+
#[doc = mac3!()]
38+
/// a [`BufferProvider`](crate::BufferProvider).
39+
//~^ ERROR: redundant_explicit_links
40+
pub fn f() {}

tests/rustdoc-ui/lints/redundant_explicit_links-expansion.stderr

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: redundant explicit link target
2-
--> $DIR/redundant_explicit_links-expansion.rs:26:43
2+
--> $DIR/redundant_explicit_links-expansion.rs:32:43
33
|
44
LL | #[doc = "provided by a [`BufferProvider`](crate::BufferProvider)."]
55
| ---------------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant
@@ -19,5 +19,21 @@ LL - #[doc = "provided by a [`BufferProvider`](crate::BufferProvider)."]
1919
LL + #[doc = "provided by a [`BufferProvider`]."]
2020
|
2121

22-
error: aborting due to 1 previous error
22+
error: redundant explicit link target
23+
--> $DIR/redundant_explicit_links-expansion.rs:38:26
24+
|
25+
LL | /// a [`BufferProvider`](crate::BufferProvider).
26+
| ---------------- ^^^^^^^^^^^^^^^^^^^^^ explicit target is redundant
27+
| |
28+
| because label contains path that resolves to same destination
29+
|
30+
= note: when a link's destination is not specified,
31+
the label is used to resolve intra-doc links
32+
help: remove explicit link target
33+
|
34+
LL - /// a [`BufferProvider`](crate::BufferProvider).
35+
LL + /// a [`BufferProvider`].
36+
|
37+
38+
error: aborting due to 2 previous errors
2339

0 commit comments

Comments
 (0)