Auto merge of #113167 - ChAoSUnItY:redundant_explicit_link, r=GuillaumeGomez
rustdoc: Add lint `redundant_explicit_links` Closes #87799. - Lint warns by default - Reworks link parser to cache original link's display text r? `@jyn514`
This commit is contained in:
commit
9c699a40cc
24 changed files with 2066 additions and 118 deletions
|
@ -30,7 +30,7 @@ pub use super::{
|
|||
/// will be retrieved.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub enum ConsumerOptions {
|
||||
/// Retrieve the [`Body`] along with the [`BorrowSet`](super::borrow_set::BorrowSet)
|
||||
/// Retrieve the [`Body`] along with the [`BorrowSet`]
|
||||
/// and [`RegionInferenceContext`]. If you would like the body only, use
|
||||
/// [`TyCtxt::mir_promoted`].
|
||||
///
|
||||
|
|
|
@ -452,11 +452,11 @@ struct HandlerInner {
|
|||
/// have been converted.
|
||||
check_unstable_expect_diagnostics: bool,
|
||||
|
||||
/// Expected [`Diagnostic`][diagnostic::Diagnostic]s store a [`LintExpectationId`] as part of
|
||||
/// Expected [`Diagnostic`][struct@diagnostic::Diagnostic]s store a [`LintExpectationId`] as part of
|
||||
/// the lint level. [`LintExpectationId`]s created early during the compilation
|
||||
/// (before `HirId`s have been defined) are not stable and can therefore not be
|
||||
/// stored on disk. This buffer stores these diagnostics until the ID has been
|
||||
/// replaced by a stable [`LintExpectationId`]. The [`Diagnostic`][diagnostic::Diagnostic]s are the
|
||||
/// replaced by a stable [`LintExpectationId`]. The [`Diagnostic`][struct@diagnostic::Diagnostic]s are the
|
||||
/// submitted for storage and added to the list of fulfilled expectations.
|
||||
unstable_expect_diagnostics: Vec<Diagnostic>,
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use pulldown_cmark::{BrokenLink, Event, LinkType, Options, Parser, Tag};
|
||||
use pulldown_cmark::{BrokenLink, CowStr, Event, LinkType, Options, Parser, Tag};
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast::util::comments::beautify_doc_string;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
|
@ -392,16 +392,73 @@ pub(crate) fn attrs_to_preprocessed_links(attrs: &[ast::Attribute]) -> Vec<Box<s
|
|||
let (doc_fragments, _) = attrs_to_doc_fragments(attrs.iter().map(|attr| (attr, None)), true);
|
||||
let doc = prepare_to_doc_link_resolution(&doc_fragments).into_values().next().unwrap();
|
||||
|
||||
Parser::new_with_broken_link_callback(
|
||||
parse_links(&doc)
|
||||
}
|
||||
|
||||
/// Similiar version of `markdown_links` from rustdoc.
|
||||
/// This will collect destination links and display text if exists.
|
||||
fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
|
||||
let mut broken_link_callback = |link: BrokenLink<'md>| Some((link.reference, "".into()));
|
||||
let mut event_iter = Parser::new_with_broken_link_callback(
|
||||
&doc,
|
||||
main_body_opts(),
|
||||
Some(&mut |link: BrokenLink<'_>| Some((link.reference, "".into()))),
|
||||
Some(&mut broken_link_callback),
|
||||
)
|
||||
.filter_map(|event| match event {
|
||||
Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => {
|
||||
Some(preprocess_link(&dest))
|
||||
.into_iter();
|
||||
let mut links = Vec::new();
|
||||
|
||||
while let Some(event) = event_iter.next() {
|
||||
match event {
|
||||
Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => {
|
||||
if matches!(
|
||||
link_type,
|
||||
LinkType::Inline
|
||||
| LinkType::ReferenceUnknown
|
||||
| LinkType::Reference
|
||||
| LinkType::Shortcut
|
||||
| LinkType::ShortcutUnknown
|
||||
) {
|
||||
if let Some(display_text) = collect_link_data(&mut event_iter) {
|
||||
links.push(display_text);
|
||||
}
|
||||
}
|
||||
|
||||
links.push(preprocess_link(&dest));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
links
|
||||
}
|
||||
|
||||
/// Collects additional data of link.
|
||||
fn collect_link_data<'input, 'callback>(
|
||||
event_iter: &mut Parser<'input, 'callback>,
|
||||
) -> Option<Box<str>> {
|
||||
let mut display_text: Option<String> = None;
|
||||
let mut append_text = |text: CowStr<'_>| {
|
||||
if let Some(display_text) = &mut display_text {
|
||||
display_text.push_str(&text);
|
||||
} else {
|
||||
display_text = Some(text.to_string());
|
||||
}
|
||||
};
|
||||
|
||||
while let Some(event) = event_iter.next() {
|
||||
match event {
|
||||
Event::Text(text) => {
|
||||
append_text(text);
|
||||
}
|
||||
Event::Code(code) => {
|
||||
append_text(code);
|
||||
}
|
||||
Event::End(_) => {
|
||||
break;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
display_text.map(String::into_boxed_str)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue