From ecb26376e5d4a03bc5f536b315161d5450bd914e Mon Sep 17 00:00:00 2001 From: Kyle Lin Date: Sun, 2 Jul 2023 23:32:46 +0800 Subject: [PATCH] narrow down the lint trigger constraint --- compiler/rustc_resolve/src/rustdoc.rs | 19 ++++++---- src/librustdoc/html/markdown.rs | 35 ++++++++++++++----- .../passes/collect_intra_doc_links.rs | 28 ++++++++------- .../passes/lint/redundant_explicit_links.rs | 10 ++++++ tests/rustdoc-ui/lints/no-redundancy.rs | 1 + 5 files changed, 65 insertions(+), 28 deletions(-) diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index cbda0535c89..ba7417b6dda 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -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> { fn collect_link_data<'input, 'callback>( event_iter: &mut Parser<'input, 'callback>, ) -> Option> { - let mut display_text = None; + let mut display_text: Option = 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) } diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 2fe052283a9..98cc38a10d4 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -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, 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> { - let mut display_text = None; +) -> Option { + let mut display_text: Option = 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; diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 4c40363ac1d..36872266ee1 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -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(); diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index a41e278fd81..da71e537f68 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -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(); diff --git a/tests/rustdoc-ui/lints/no-redundancy.rs b/tests/rustdoc-ui/lints/no-redundancy.rs index f9c5e17a5f3..e3358728b1b 100644 --- a/tests/rustdoc-ui/lints/no-redundancy.rs +++ b/tests/rustdoc-ui/lints/no-redundancy.rs @@ -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() {}