Skip to content

Commit 53709ae

Browse files
committed
Auto merge of #108209 - petrochenkov:doclean, r=notriddle
rustdoc: Cleanup doc link extraction
2 parents 3eb5c45 + 97e73ee commit 53709ae

File tree

3 files changed

+61
-72
lines changed

3 files changed

+61
-72
lines changed

compiler/rustc_resolve/src/rustdoc.rs

+27-13
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use pulldown_cmark::{BrokenLink, Event, Options, Parser, Tag};
1+
use pulldown_cmark::{BrokenLink, Event, LinkType, Options, Parser, Tag};
22
use rustc_ast as ast;
33
use rustc_ast::util::comments::beautify_doc_string;
44
use rustc_data_structures::fx::FxHashMap;
55
use rustc_span::def_id::DefId;
66
use rustc_span::symbol::{kw, Symbol};
77
use rustc_span::Span;
8-
use std::cell::RefCell;
98
use std::{cmp, mem};
109

1110
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
@@ -348,22 +347,37 @@ fn preprocess_link(link: &str) -> String {
348347
strip_generics_from_path(link).unwrap_or_else(|_| link.to_string())
349348
}
350349

350+
/// Keep inline and reference links `[]`,
351+
/// but skip autolinks `<>` which we never consider to be intra-doc links.
352+
pub fn may_be_doc_link(link_type: LinkType) -> bool {
353+
match link_type {
354+
LinkType::Inline
355+
| LinkType::Reference
356+
| LinkType::ReferenceUnknown
357+
| LinkType::Collapsed
358+
| LinkType::CollapsedUnknown
359+
| LinkType::Shortcut
360+
| LinkType::ShortcutUnknown => true,
361+
LinkType::Autolink | LinkType::Email => false,
362+
}
363+
}
364+
351365
/// Simplified version of `preprocessed_markdown_links` from rustdoc.
352366
/// Must return at least the same links as it, but may add some more links on top of that.
353367
pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec<String> {
354368
let (doc_fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true);
355369
let doc = prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap();
356370

357-
let links = RefCell::new(Vec::new());
358-
let mut callback = |link: BrokenLink<'_>| {
359-
links.borrow_mut().push(preprocess_link(&link.reference));
360-
None
361-
};
362-
for event in Parser::new_with_broken_link_callback(&doc, main_body_opts(), Some(&mut callback))
363-
{
364-
if let Event::Start(Tag::Link(_, dest, _)) = event {
365-
links.borrow_mut().push(preprocess_link(&dest));
371+
Parser::new_with_broken_link_callback(
372+
&doc,
373+
main_body_opts(),
374+
Some(&mut |link: BrokenLink<'_>| Some((link.reference, "".into()))),
375+
)
376+
.filter_map(|event| match event {
377+
Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => {
378+
Some(preprocess_link(&dest))
366379
}
367-
}
368-
links.into_inner()
380+
_ => None,
381+
})
382+
.collect()
369383
}

src/librustdoc/html/markdown.rs

+18-43
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@ use rustc_data_structures::fx::FxHashMap;
2929
use rustc_hir::def_id::DefId;
3030
use rustc_middle::ty::TyCtxt;
3131
pub(crate) use rustc_resolve::rustdoc::main_body_opts;
32+
use rustc_resolve::rustdoc::may_be_doc_link;
3233
use rustc_span::edition::Edition;
3334
use rustc_span::{Span, Symbol};
3435

3536
use once_cell::sync::Lazy;
3637
use std::borrow::Cow;
37-
use std::cell::RefCell;
3838
use std::collections::VecDeque;
3939
use std::default::Default;
4040
use std::fmt::Write;
@@ -1226,14 +1226,12 @@ pub(crate) struct MarkdownLink {
12261226

12271227
pub(crate) fn markdown_links<R>(
12281228
md: &str,
1229-
filter_map: impl Fn(MarkdownLink) -> Option<R>,
1229+
preprocess_link: impl Fn(MarkdownLink) -> Option<R>,
12301230
) -> Vec<R> {
12311231
if md.is_empty() {
12321232
return vec![];
12331233
}
12341234

1235-
let links = RefCell::new(vec![]);
1236-
12371235
// FIXME: remove this function once pulldown_cmark can provide spans for link definitions.
12381236
let locate = |s: &str, fallback: Range<usize>| unsafe {
12391237
let s_start = s.as_ptr();
@@ -1265,46 +1263,23 @@ pub(crate) fn markdown_links<R>(
12651263
}
12661264
};
12671265

1268-
let mut push = |link: BrokenLink<'_>| {
1269-
let span = span_for_link(&link.reference, link.span);
1270-
filter_map(MarkdownLink {
1271-
kind: LinkType::ShortcutUnknown,
1272-
link: link.reference.to_string(),
1273-
range: span,
1274-
})
1275-
.map(|link| links.borrow_mut().push(link));
1276-
None
1277-
};
1278-
let p = Parser::new_with_broken_link_callback(md, main_body_opts(), Some(&mut push))
1279-
.into_offset_iter();
1280-
1281-
// There's no need to thread an IdMap through to here because
1282-
// the IDs generated aren't going to be emitted anywhere.
1283-
let mut ids = IdMap::new();
1284-
let iter = Footnotes::new(HeadingLinks::new(p, None, &mut ids, HeadingOffset::H1));
1285-
1286-
for ev in iter {
1287-
if let Event::Start(Tag::Link(
1288-
// `<>` links cannot be intra-doc links so we skip them.
1289-
kind @ (LinkType::Inline
1290-
| LinkType::Reference
1291-
| LinkType::ReferenceUnknown
1292-
| LinkType::Collapsed
1293-
| LinkType::CollapsedUnknown
1294-
| LinkType::Shortcut
1295-
| LinkType::ShortcutUnknown),
1296-
dest,
1297-
_,
1298-
)) = ev.0
1299-
{
1300-
debug!("found link: {dest}");
1301-
let span = span_for_link(&dest, ev.1);
1302-
filter_map(MarkdownLink { kind, link: dest.into_string(), range: span })
1303-
.map(|link| links.borrow_mut().push(link));
1266+
Parser::new_with_broken_link_callback(
1267+
md,
1268+
main_body_opts(),
1269+
Some(&mut |link: BrokenLink<'_>| Some((link.reference, "".into()))),
1270+
)
1271+
.into_offset_iter()
1272+
.filter_map(|(event, span)| match event {
1273+
Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => {
1274+
preprocess_link(MarkdownLink {
1275+
kind: link_type,
1276+
range: span_for_link(&dest, span),
1277+
link: dest.into_string(),
1278+
})
13041279
}
1305-
}
1306-
1307-
links.into_inner()
1280+
_ => None,
1281+
})
1282+
.collect()
13081283
}
13091284

13101285
#[derive(Debug)]

tests/rustdoc-ui/intra-doc/unknown-disambiguator.stderr

+16-16
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,6 @@ LL | //! Linking to [foo@banana] and [`bar@banana!()`].
2020
|
2121
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
2222

23-
error: unknown disambiguator `foo`
24-
--> $DIR/unknown-disambiguator.rs:10:34
25-
|
26-
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
27-
| ^^^
28-
|
29-
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
30-
31-
error: unknown disambiguator `foo`
32-
--> $DIR/unknown-disambiguator.rs:10:48
33-
|
34-
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
35-
| ^^^
36-
|
37-
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
38-
3923
error: unknown disambiguator ``
4024
--> $DIR/unknown-disambiguator.rs:7:31
4125
|
@@ -52,5 +36,21 @@ LL | //! And to [no disambiguator](@nectarine) and [another](@apricot!()).
5236
|
5337
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
5438

39+
error: unknown disambiguator `foo`
40+
--> $DIR/unknown-disambiguator.rs:10:34
41+
|
42+
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
43+
| ^^^
44+
|
45+
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
46+
47+
error: unknown disambiguator `foo`
48+
--> $DIR/unknown-disambiguator.rs:10:48
49+
|
50+
LL | //! And with weird backticks: [``foo@hello``] [foo`@`hello].
51+
| ^^^
52+
|
53+
= note: see https://doc.rust-lang.org/$CHANNEL/rustdoc/write-documentation/linking-to-items-by-name.html#namespaces-and-disambiguators for more info about disambiguators
54+
5555
error: aborting due to 6 previous errors
5656

0 commit comments

Comments
 (0)