narrow down the lint trigger constraint
This commit is contained in:
parent
78c85f439f
commit
ecb26376e5
5 changed files with 65 additions and 28 deletions
|
@ -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;
|
||||
|
@ -436,15 +436,22 @@ fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> {
|
|||
fn collect_link_data<'input, 'callback>(
|
||||
event_iter: &mut Parser<'input, 'callback>,
|
||||
) -> 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() {
|
||||
match event {
|
||||
Event::Text(code) => {
|
||||
display_text = Some(code.to_string().into_boxed_str());
|
||||
Event::Text(text) => {
|
||||
append_text(text);
|
||||
}
|
||||
Event::Code(code) => {
|
||||
display_text = Some(code.to_string().into_boxed_str());
|
||||
append_text(code);
|
||||
}
|
||||
Event::End(_) => {
|
||||
break;
|
||||
|
@ -453,5 +460,5 @@ fn collect_link_data<'input, 'callback>(
|
|||
}
|
||||
}
|
||||
|
||||
display_text
|
||||
display_text.map(String::into_boxed_str)
|
||||
}
|
||||
|
|
|
@ -1240,7 +1240,7 @@ pub(crate) fn plain_text_summary(md: &str, link_names: &[RenderedLink]) -> Strin
|
|||
pub(crate) struct MarkdownLink {
|
||||
pub kind: LinkType,
|
||||
pub link: String,
|
||||
pub display_text: String,
|
||||
pub display_text: Option<String>,
|
||||
pub range: MarkdownLinkRange,
|
||||
}
|
||||
|
||||
|
@ -1402,13 +1402,23 @@ pub(crate) fn markdown_links<'md, R>(
|
|||
LinkType::Autolink | LinkType::Email => unreachable!(),
|
||||
};
|
||||
|
||||
let display_text =
|
||||
collect_link_data(&mut event_iter).map_or(String::new(), CowStr::into_string);
|
||||
let display_text = if matches!(
|
||||
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 {
|
||||
kind: link_type,
|
||||
display_text,
|
||||
link: dest.into_string(),
|
||||
display_text,
|
||||
range,
|
||||
}) {
|
||||
links.push(link);
|
||||
|
@ -1424,16 +1434,23 @@ pub(crate) fn markdown_links<'md, R>(
|
|||
/// Collects additional data of link.
|
||||
fn collect_link_data<'input, 'callback>(
|
||||
event_iter: &mut OffsetIter<'input, 'callback>,
|
||||
) -> Option<CowStr<'input>> {
|
||||
let mut display_text = None;
|
||||
) -> Option<String> {
|
||||
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() {
|
||||
match event {
|
||||
Event::Text(code) => {
|
||||
display_text = Some(code);
|
||||
Event::Text(text) => {
|
||||
append_text(text);
|
||||
}
|
||||
Event::Code(code) => {
|
||||
display_text = Some(code);
|
||||
append_text(code);
|
||||
}
|
||||
Event::End(_) => {
|
||||
break;
|
||||
|
|
|
@ -1041,18 +1041,20 @@ impl LinkCollector<'_, '_> {
|
|||
false,
|
||||
)?;
|
||||
|
||||
self.resolve_display_text(
|
||||
path_str,
|
||||
ResolutionInfo {
|
||||
item_id,
|
||||
module_id,
|
||||
dis: disambiguator,
|
||||
path_str: ori_link.display_text.clone().into_boxed_str(),
|
||||
extra_fragment: extra_fragment.clone(),
|
||||
},
|
||||
&ori_link,
|
||||
&diag_info,
|
||||
);
|
||||
if ori_link.display_text.is_some() {
|
||||
self.resolve_display_text(
|
||||
path_str,
|
||||
ResolutionInfo {
|
||||
item_id,
|
||||
module_id,
|
||||
dis: disambiguator,
|
||||
path_str: ori_link.display_text.clone()?.into_boxed_str(),
|
||||
extra_fragment: extra_fragment.clone(),
|
||||
},
|
||||
&ori_link,
|
||||
&diag_info,
|
||||
);
|
||||
}
|
||||
|
||||
// Check for a primitive which might conflict with a module
|
||||
// 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.
|
||||
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 explicit_len = explicit_link.len();
|
||||
|
||||
|
|
|
@ -67,6 +67,16 @@ fn check_redundant_explicit_link<'md>(
|
|||
Event::Start(Tag::Link(link_type, dest, _)) => {
|
||||
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 display_link = link_data.resolvable_link.clone()?;
|
||||
let explicit_len = explicit_link.len();
|
||||
|
|
|
@ -3,4 +3,5 @@
|
|||
#![deny(rustdoc::redundant_explicit_links)]
|
||||
|
||||
/// [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() {}
|
||||
|
|
Loading…
Add table
Reference in a new issue