Skip to content

Commit 3b5525b

Browse files
Improve code and documentation
1 parent 78cbcaf commit 3b5525b

File tree

4 files changed

+77
-30
lines changed

4 files changed

+77
-30
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
}
@@ -509,16 +509,20 @@ fn collect_link_data<'input, F: BrokenLinkCallback<'input>>(
509509
display_text.map(String::into_boxed_str)
510510
}
511511

512-
/// Returns a span encompassing all the document fragments.
512+
/// Returns a tuple containing a span encompassing all the document fragments and a boolean that is
513+
/// `true` if any of the fragments are from a macro expansion.
513514
pub fn span_of_fragments_with_expansion(fragments: &[DocFragment]) -> Option<(Span, bool)> {
514-
let Some(first_fragment) = fragments.first() else { return None };
515+
let (first_fragment, last_fragment) = match fragments {
516+
[] => return None,
517+
[first, .., last] => (first, last),
518+
[first] => (first, first),
519+
};
515520
if first_fragment.span == DUMMY_SP {
516521
return None;
517522
}
518-
let last_fragment = fragments.last().expect("no doc strings provided");
519523
Some((
520524
first_fragment.span.to(last_fragment.span),
521-
first_fragment.from_expansion || last_fragment.from_expansion,
525+
fragments.iter().any(|frag| frag.from_expansion),
522526
))
523527
}
524528

@@ -538,12 +542,16 @@ pub fn span_of_fragments(fragments: &[DocFragment]) -> Option<Span> {
538542
/// This method will return `Some` only if one of the following is true:
539543
///
540544
/// - The doc is made entirely from sugared doc comments, which cannot contain escapes
541-
/// - The doc is entirely from a single doc fragment with a string literal exactly equal to `markdown`.
545+
/// - The doc is entirely from a single doc fragment with a string literal exactly equal to
546+
/// `markdown`.
542547
/// - The doc comes from `include_str!`
543-
/// - The doc includes exactly one substring matching `markdown[md_range]` which is contained in a single doc fragment.
548+
/// - The doc includes exactly one substring matching `markdown[md_range]` which is contained in a
549+
/// single doc fragment.
550+
///
551+
/// This function is defined in the compiler so it can be used by both `rustdoc` and `clippy`.
544552
///
545-
/// This function is defined in the compiler so it can be used by
546-
/// both `rustdoc` and `clippy`.
553+
/// It returns a tuple containing a span encompassing all the document fragments and a boolean that
554+
/// is `true` if any of the *matched* fragments are from a macro expansion.
547555
pub fn source_span_for_markdown_range(
548556
tcx: TyCtxt<'_>,
549557
markdown: &str,
@@ -678,12 +686,13 @@ pub fn source_span_for_markdown_range_inner(
678686
}
679687
}
680688

681-
let (span, from_expansion) = span_of_fragments_with_expansion(fragments)?;
689+
let (span, _) = span_of_fragments_with_expansion(fragments)?;
690+
let src_span = span.from_inner(InnerSpan::new(
691+
md_range.start + start_bytes,
692+
md_range.end + start_bytes + end_bytes,
693+
));
682694
Some((
683-
span.from_inner(InnerSpan::new(
684-
md_range.start + start_bytes,
685-
md_range.end + start_bytes + end_bytes,
686-
)),
687-
from_expansion,
695+
src_span,
696+
fragments.iter().any(|frag| frag.span.overlaps(src_span) && frag.from_expansion),
688697
))
689698
}

src/librustdoc/passes/lint/redundant_explicit_links.rs

Lines changed: 22 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -171,21 +171,26 @@ fn check_inline_or_reference_unknown_redundancy(
171171
}
172172
None => item.attr_span(cx.tcx),
173173
};
174-
let (explicit_span, from_expansion) = source_span_for_markdown_range(
174+
let (explicit_span, false) = source_span_for_markdown_range(
175175
cx.tcx,
176176
doc,
177177
&offset_explicit_range(doc, link_range, open, close),
178178
&item.attrs.doc_strings,
179-
)?;
180-
if from_expansion {
179+
)?
180+
else {
181+
// This `span` comes from macro expansion so skipping it.
181182
return None;
182-
}
183-
let (display_span, _) = source_span_for_markdown_range(
183+
};
184+
let (display_span, false) = source_span_for_markdown_range(
184185
cx.tcx,
185186
doc,
186187
resolvable_link_range,
187188
&item.attrs.doc_strings,
188-
)?;
189+
)?
190+
else {
191+
// This `span` comes from macro expansion so skipping it.
192+
return None;
193+
};
189194

190195
cx.tcx.node_span_lint(crate::lint::REDUNDANT_EXPLICIT_LINKS, hir_id, explicit_span, |lint| {
191196
lint.primary_message("redundant explicit link target")
@@ -227,21 +232,26 @@ fn check_reference_redundancy(
227232
}
228233
None => item.attr_span(cx.tcx),
229234
};
230-
let (explicit_span, from_expansion) = source_span_for_markdown_range(
235+
let (explicit_span, false) = source_span_for_markdown_range(
231236
cx.tcx,
232237
doc,
233238
&offset_explicit_range(doc, link_range.clone(), b'[', b']'),
234239
&item.attrs.doc_strings,
235-
)?;
236-
if from_expansion {
240+
)?
241+
else {
242+
// This `span` comes from macro expansion so skipping it.
237243
return None;
238-
}
239-
let (display_span, _) = source_span_for_markdown_range(
244+
};
245+
let (display_span, false) = source_span_for_markdown_range(
240246
cx.tcx,
241247
doc,
242248
resolvable_link_range,
243249
&item.attrs.doc_strings,
244-
)?;
250+
)?
251+
else {
252+
// This `span` comes from macro expansion so skipping it.
253+
return None;
254+
};
245255
let (def_span, _) = source_span_for_markdown_range(
246256
cx.tcx,
247257
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)