narrow down the lint trigger constraint

This commit is contained in:
Kyle Lin 2023-07-02 23:32:46 +08:00
parent 78c85f439f
commit ecb26376e5
5 changed files with 65 additions and 28 deletions

View file

@ -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 as ast;
use rustc_ast::util::comments::beautify_doc_string; use rustc_ast::util::comments::beautify_doc_string;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
@ -436,15 +436,22 @@ fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
fn collect_link_data<'input, 'callback>( fn collect_link_data<'input, 'callback>(
event_iter: &mut Parser<'input, 'callback>, event_iter: &mut Parser<'input, 'callback>,
) -> Option<Box<str>> { ) -> Option<Box<str>> {
let mut display_text = None; 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() { while let Some(event) = event_iter.next() {
match event { match event {
Event::Text(code) => { Event::Text(text) => {
display_text = Some(code.to_string().into_boxed_str()); append_text(text);
} }
Event::Code(code) => { Event::Code(code) => {
display_text = Some(code.to_string().into_boxed_str()); append_text(code);
} }
Event::End(_) => { Event::End(_) => {
break; break;
@ -453,5 +460,5 @@ fn collect_link_data<'input, 'callback>(
} }
} }
display_text display_text.map(String::into_boxed_str)
} }

View file

@ -1240,7 +1240,7 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
pub(crate) struct MarkdownLink { pub(crate) struct MarkdownLink {
pub kind: LinkType, pub kind: LinkType,
pub link: String, pub link: String,
pub display_text: String, pub display_text: Option<String>,
pub range: MarkdownLinkRange, pub range: MarkdownLinkRange,
} }
@ -1402,13 +1402,23 @@ pub(crate) fn markdown_links<'md, R>(
LinkType::Autolink | LinkType::Email => unreachable!(), LinkType::Autolink | LinkType::Email => unreachable!(),
}; };
let display_text = let display_text = if matches!(
collect_link_data(&mut event_iter).map_or(String::new(), CowStr::into_string); link_type,
LinkType::Inline
| LinkType::ReferenceUnknown
| LinkType::Reference
| LinkType::Shortcut
| LinkType::ShortcutUnknown
) {
collect_link_data(&mut event_iter)
} else {
None
};
if let Some(link) = preprocess_link(MarkdownLink { if let Some(link) = preprocess_link(MarkdownLink {
kind: link_type, kind: link_type,
display_text,
link: dest.into_string(), link: dest.into_string(),
display_text,
range, range,
}) { }) {
links.push(link); links.push(link);
@ -1424,16 +1434,23 @@ pub(crate) fn markdown_links<'md, R>(
/// Collects additional data of link. /// Collects additional data of link.
fn collect_link_data<'input, 'callback>( fn collect_link_data<'input, 'callback>(
event_iter: &mut OffsetIter<'input, 'callback>, event_iter: &mut OffsetIter<'input, 'callback>,
) -> Option<CowStr<'input>> { ) -> Option<String> {
let mut display_text = None; 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, _span)) = event_iter.next() { while let Some((event, _span)) = event_iter.next() {
match event { match event {
Event::Text(code) => { Event::Text(text) => {
display_text = Some(code); append_text(text);
} }
Event::Code(code) => { Event::Code(code) => {
display_text = Some(code); append_text(code);
} }
Event::End(_) => { Event::End(_) => {
break; break;

View file

@ -1041,18 +1041,20 @@ impl LinkCollector<'_, '_> {
false, false,
)?; )?;
self.resolve_display_text( if ori_link.display_text.is_some() {
path_str, self.resolve_display_text(
ResolutionInfo { path_str,
item_id, ResolutionInfo {
module_id, item_id,
dis: disambiguator, module_id,
path_str: ori_link.display_text.clone().into_boxed_str(), dis: disambiguator,
extra_fragment: extra_fragment.clone(), path_str: ori_link.display_text.clone()?.into_boxed_str(),
}, extra_fragment: extra_fragment.clone(),
&ori_link, },
&diag_info, &ori_link,
); &diag_info,
);
}
// Check for a primitive which might conflict with a module // Check for a primitive which might conflict with a module
// Report the ambiguity and require that the user specify which one they meant. // Report the ambiguity and require that the user specify which one they meant.
@ -1429,7 +1431,7 @@ impl LinkCollector<'_, '_> {
// //
// Notice that this algorithm is passive, might possibly miss actual redudant cases. // Notice that this algorithm is passive, might possibly miss actual redudant cases.
let explicit_link = &explicit_link.to_string(); let explicit_link = &explicit_link.to_string();
let display_text = &ori_link.display_text; let display_text = ori_link.display_text.as_ref().unwrap();
let display_len = display_text.len(); let display_len = display_text.len();
let explicit_len = explicit_link.len(); let explicit_len = explicit_link.len();

View file

@ -67,6 +67,16 @@ fn check_redundant_explicit_link<'md>(
Event::Start(Tag::Link(link_type, dest, _)) => { Event::Start(Tag::Link(link_type, dest, _)) => {
let link_data = collect_link_data(&mut offset_iter); let link_data = collect_link_data(&mut offset_iter);
if let Some(resolvable_link) = link_data.resolvable_link.as_ref() {
if &link_data.display_link != resolvable_link {
// Skips if display link does not match to actual
// resolvable link, usually happens if display link
// has several segments, e.g.
// [this is just an `Option`](Option)
continue;
}
}
let explicit_link = dest.to_string(); let explicit_link = dest.to_string();
let display_link = link_data.resolvable_link.clone()?; let display_link = link_data.resolvable_link.clone()?;
let explicit_len = explicit_link.len(); let explicit_len = explicit_link.len();

View file

@ -3,4 +3,5 @@
#![deny(rustdoc::redundant_explicit_links)] #![deny(rustdoc::redundant_explicit_links)]
/// [Vec][std::vec::Vec#examples] should not warn, because it's not actually redundant! /// [Vec][std::vec::Vec#examples] should not warn, because it's not actually redundant!
/// [This is just an `Option`][std::option::Option] has different display content to actual link!
pub fn func() {} pub fn func() {}