doc links: Filter away autolinks in both rustc and rustdoc

This commit is contained in:
Vadim Petrochenkov 2023-02-18 14:56:31 +04:00
parent ccdb598d1b
commit 97e73eea84
2 changed files with 27 additions and 18 deletions

View File

@ -1,4 +1,4 @@
use pulldown_cmark::{BrokenLink, Event, Options, Parser, Tag};
use pulldown_cmark::{BrokenLink, Event, LinkType, Options, Parser, Tag};
use rustc_ast as ast;
use rustc_ast::util::comments::beautify_doc_string;
use rustc_data_structures::fx::FxHashMap;
@ -347,6 +347,21 @@ fn preprocess_link(link: &str) -> String {
strip_generics_from_path(link).unwrap_or_else(|_| link.to_string())
}
/// Keep inline and reference links `[]`,
/// but skip autolinks `<>` which we never consider to be intra-doc links.
pub fn may_be_doc_link(link_type: LinkType) -> bool {
match link_type {
LinkType::Inline
| LinkType::Reference
| LinkType::ReferenceUnknown
| LinkType::Collapsed
| LinkType::CollapsedUnknown
| LinkType::Shortcut
| LinkType::ShortcutUnknown => true,
LinkType::Autolink | LinkType::Email => false,
}
}
/// Simplified version of `preprocessed_markdown_links` from rustdoc.
/// Must return at least the same links as it, but may add some more links on top of that.
pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec<String> {
@ -359,7 +374,9 @@ pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec<Strin
Some(&mut |link: BrokenLink<'_>| Some((link.reference, "".into()))),
)
.filter_map(|event| match event {
Event::Start(Tag::Link(_, dest, _)) => Some(preprocess_link(&dest)),
Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => {
Some(preprocess_link(&dest))
}
_ => None,
})
.collect()

View File

@ -29,6 +29,7 @@
use rustc_hir::def_id::DefId;
use rustc_middle::ty::TyCtxt;
pub(crate) use rustc_resolve::rustdoc::main_body_opts;
use rustc_resolve::rustdoc::may_be_doc_link;
use rustc_span::edition::Edition;
use rustc_span::{Span, Symbol};
@ -1269,22 +1270,13 @@ pub(crate) fn markdown_links<R>(
)
.into_offset_iter()
.filter_map(|(event, span)| match event {
Event::Start(Tag::Link(
// `<>` links cannot be intra-doc links so we skip them.
kind @ (LinkType::Inline
| LinkType::Reference
| LinkType::ReferenceUnknown
| LinkType::Collapsed
| LinkType::CollapsedUnknown
| LinkType::Shortcut
| LinkType::ShortcutUnknown),
dest,
_,
)) => preprocess_link(MarkdownLink {
kind,
range: span_for_link(&dest, span),
link: dest.into_string(),
}),
Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => {
preprocess_link(MarkdownLink {
kind: link_type,
range: span_for_link(&dest, span),
link: dest.into_string(),
})
}
_ => None,
})
.collect()