diff options
| author | Kyle Lin <minecraft.kyle.train@gmail.com> | 2023-07-01 00:55:37 +0800 |
|---|---|---|
| committer | Kyle Lin <minecraft.kyle.train@gmail.com> | 2023-08-18 15:19:17 +0800 |
| commit | 5ce6cc7df3175519219c091059dd663313438c97 (patch) | |
| tree | fb8423c2d39df2cf1a21cf1526a287e73279c1ae | |
| parent | 46df95817d2f9700f0c5a69ea8b05b1c83d9ee35 (diff) | |
| download | rust-5ce6cc7df3175519219c091059dd663313438c97.tar.gz rust-5ce6cc7df3175519219c091059dd663313438c97.zip | |
Still resolving rustdoc resolution panicking
| -rw-r--r-- | compiler/rustc_resolve/src/rustdoc.rs | 6 | ||||
| -rw-r--r-- | src/librustdoc/passes/collect_intra_doc_links.rs | 69 | ||||
| -rw-r--r-- | src/librustdoc/passes/lint/redundant_explicit_links.rs | 76 | ||||
| -rw-r--r-- | tests/rustdoc-ui/lints/redundant_explicit_links.fixed | 6 | ||||
| -rw-r--r-- | tests/rustdoc-ui/lints/redundant_explicit_links.rs | 6 | ||||
| -rw-r--r-- | tests/rustdoc-ui/unescaped_backticks.rs | 1 | ||||
| -rw-r--r-- | tests/rustdoc/description.rs | 2 | ||||
| -rw-r--r-- | tests/rustdoc/intra-doc/basic.rs | 2 | ||||
| -rw-r--r-- | tests/rustdoc/intra-doc/generic-params.rs | 1 | ||||
| -rw-r--r-- | tests/rustdoc/intra-doc/issue-108459.rs | 1 |
10 files changed, 90 insertions, 80 deletions
diff --git a/compiler/rustc_resolve/src/rustdoc.rs b/compiler/rustc_resolve/src/rustdoc.rs index 083d16d3b04..f7275bed59c 100644 --- a/compiler/rustc_resolve/src/rustdoc.rs +++ b/compiler/rustc_resolve/src/rustdoc.rs @@ -410,8 +410,10 @@ fn parse_links<'md>(doc: &'md str) -> Vec<Box<str>> { while let Some(event) = event_iter.next() { match event { Event::Start(Tag::Link(link_type, dest, _)) if may_be_doc_link(link_type) => { - if let Some(display_text) = collect_link_data(&mut event_iter) { - links.push(display_text); + if matches!(link_type, LinkType::Inline | LinkType::ReferenceUnknown | LinkType::Reference) { + if let Some(display_text) = collect_link_data(&mut event_iter) { + links.push(display_text); + } } links.push(preprocess_link(&dest)); diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 0a0ffcb5b1e..4c40363ac1d 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1038,6 +1038,7 @@ impl LinkCollector<'_, '_> { // resolutions are cached, for other links we want to report an error every // time so they are not cached. matches!(ori_link.kind, LinkType::Reference | LinkType::Shortcut), + false, )?; self.resolve_display_text( @@ -1232,6 +1233,9 @@ impl LinkCollector<'_, '_> { // If errors are cached then they are only reported on first occurrence // which we want in some cases but not in others. cache_errors: bool, + // If this call is intended to be recoverable, then pass true to silence. + // This is only recoverable when path is failed to resolved. + recoverable: bool, ) -> Option<(Res, Option<UrlFragment>)> { if let Some(res) = self.visited_links.get(&key) { if res.is_some() || cache_errors { @@ -1239,7 +1243,7 @@ impl LinkCollector<'_, '_> { } } - let mut candidates = self.resolve_with_disambiguator(&key, diag.clone()); + let mut candidates = self.resolve_with_disambiguator(&key, diag.clone(), recoverable); // FIXME: it would be nice to check that the feature gate was enabled in the original crate, not just ignore it altogether. // However I'm not sure how to check that across crates. @@ -1290,6 +1294,9 @@ impl LinkCollector<'_, '_> { &mut self, key: &ResolutionInfo, diag: DiagnosticInfo<'_>, + // If this call is intended to be recoverable, then pass true to silence. + // This is only recoverable when path is failed to resolved. + recoverable: bool, ) -> Vec<(Res, Option<DefId>)> { let disambiguator = key.dis; let path_str = &key.path_str; @@ -1319,7 +1326,9 @@ impl LinkCollector<'_, '_> { } } } - resolution_failure(self, diag, path_str, disambiguator, smallvec![err]); + if !recoverable { + resolution_failure(self, diag, path_str, disambiguator, smallvec![err]); + } return vec![]; } } @@ -1356,13 +1365,15 @@ impl LinkCollector<'_, '_> { .fold(0, |acc, res| if let Ok(res) = res { acc + res.len() } else { acc }); if len == 0 { - resolution_failure( - self, - diag, - path_str, - disambiguator, - candidates.into_iter().filter_map(|res| res.err()).collect(), - ); + if !recoverable { + resolution_failure( + self, + diag, + path_str, + disambiguator, + candidates.into_iter().filter_map(|res| res.err()).collect(), + ); + } return vec![]; } else if len == 1 { candidates.into_iter().filter_map(|res| res.ok()).flatten().collect::<Vec<_>>() @@ -1396,43 +1407,8 @@ impl LinkCollector<'_, '_> { ori_link: &MarkdownLink, diag_info: &DiagnosticInfo<'_>, ) { - // Check if explicit resolution's path is same as resolution of original link's display text path, e.g. - // - // LinkType::Inline: - // - // [target](target) - // [`target`](target) - // [target](path::to::target) - // [`target`](path::to::target) - // [path::to::target](target) - // [`path::to::target`](target) - // [path::to::target](path::to::target) - // [`path::to::target`](path::to::target) - // - // LinkType::ReferenceUnknown - // - // [target][target] - // [`target`][target] - // [target][path::to::target] - // [`target`][path::to::target] - // [path::to::target][target] - // [`path::to::target`][target] - // [path::to::target][path::to::target] - // [`path::to::target`][path::to::target] - // - // LinkType::Reference - // - // [target][target] - // [`target`][target] - // [target][path::to::target] - // [`target`][path::to::target] - // [path::to::target][target] - // [`path::to::target`][target] - // [path::to::target][path::to::target] - // [`path::to::target`][path::to::target] - // - // [target]: target // or [target]: path::to::target - // [path::to::target]: path::to::target // or [path::to::target]: target + // Check if explicit resolution's path is same as resolution of original link's display text path, see + // tests/rustdoc-ui/lint/redundant_explicit_links.rs for more cases. // // To avoid disambiguator from panicking, we check if display text path is possible to be disambiguated // into explicit path. @@ -1471,6 +1447,7 @@ impl LinkCollector<'_, '_> { display_res_info, diag_info.clone(), // this struct should really be Copy, but Range is not :( false, + true, ); } } diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs index 722088eb79a..da8a73be60b 100644 --- a/src/librustdoc/passes/lint/redundant_explicit_links.rs +++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs @@ -32,6 +32,13 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) { return; } + if item.link_names(&cx.cache).is_empty() { + // If there's no link names in this item, + // then we skip resolution querying to + // avoid from panicking. + return; + } + check_redundant_explicit_link(cx, item, hir_id, &doc); } @@ -57,33 +64,52 @@ fn check_redundant_explicit_link<'md>( while let Some((event, link_range)) = offset_iter.next() { match event { - Event::Start(Tag::Link(link_type, dest, _)) => match link_type { - LinkType::Inline | LinkType::ReferenceUnknown => { - check_inline_or_reference_unknown_redundancy( - cx, - item, - hir_id, - doc, - resolutions, - link_range, - dest.to_string(), - collect_link_data(&mut offset_iter), - if link_type == LinkType::Inline { (b'(', b')') } else { (b'[', b']') }, - ); + Event::Start(Tag::Link(link_type, dest, _)) => { + let link_data = collect_link_data(&mut offset_iter); + + let explicit_link = dest.to_string(); + let display_link = link_data.resolvable_link.clone()?; + let explicit_len = explicit_link.len(); + let display_len = display_link.len(); + + if explicit_len == display_len && explicit_link != display_link { + // Skips if they possibly have no relativity. + continue; } - LinkType::Reference => { - check_reference_redundancy( - cx, - item, - hir_id, - doc, - resolutions, - link_range, - &dest, - collect_link_data(&mut offset_iter), - ); + + if (explicit_len >= display_len + && &explicit_link[(explicit_len - display_len)..] == display_link) + || (display_len >= explicit_len + && &display_link[(display_len - explicit_len)..] == explicit_link) { + match link_type { + LinkType::Inline | LinkType::ReferenceUnknown => { + check_inline_or_reference_unknown_redundancy( + cx, + item, + hir_id, + doc, + resolutions, + link_range, + dest.to_string(), + link_data, + if link_type == LinkType::Inline { (b'(', b')') } else { (b'[', b']') }, + ); + } + LinkType::Reference => { + check_reference_redundancy( + cx, + item, + hir_id, + doc, + resolutions, + link_range, + &dest, + link_data, + ); + } + _ => {} + } } - _ => {} }, _ => {} } diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links.fixed b/tests/rustdoc-ui/lints/redundant_explicit_links.fixed index 4745da879a3..900234e31e9 100644 --- a/tests/rustdoc-ui/lints/redundant_explicit_links.fixed +++ b/tests/rustdoc-ui/lints/redundant_explicit_links.fixed @@ -42,7 +42,7 @@ pub fn dummy_target() {} //~^ ERROR redundant explicit link target /// [`std::primitive::usize`] //~^ ERROR redundant explicit link target -/// +/// /// [dummy_target] TEXT //~^ ERROR redundant explicit link target /// [`dummy_target`] TEXT @@ -91,7 +91,7 @@ pub fn should_not_warn_inline() {} //~^ ERROR redundant explicit link target /// [`std::primitive::usize`] //~^ ERROR redundant explicit link target -/// +/// /// [dummy_target] TEXT //~^ ERROR redundant explicit link target /// [`dummy_target`] TEXT @@ -140,7 +140,7 @@ pub fn should_not_warn_reference_unknown() {} //~^ ERROR redundant explicit link target /// [`std::primitive::usize`] //~^ ERROR redundant explicit link target -/// +/// /// [dummy_target] TEXT //~^ ERROR redundant explicit link target /// [`dummy_target`] TEXT diff --git a/tests/rustdoc-ui/lints/redundant_explicit_links.rs b/tests/rustdoc-ui/lints/redundant_explicit_links.rs index 7dd8eba5a5e..13feb85e051 100644 --- a/tests/rustdoc-ui/lints/redundant_explicit_links.rs +++ b/tests/rustdoc-ui/lints/redundant_explicit_links.rs @@ -42,7 +42,7 @@ pub fn dummy_target() {} //~^ ERROR redundant explicit link target /// [`std::primitive::usize`](std::primitive::usize) //~^ ERROR redundant explicit link target -/// +/// /// [dummy_target](dummy_target) TEXT //~^ ERROR redundant explicit link target /// [`dummy_target`](dummy_target) TEXT @@ -91,7 +91,7 @@ pub fn should_not_warn_inline() {} //~^ ERROR redundant explicit link target /// [`std::primitive::usize`][std::primitive::usize] //~^ ERROR redundant explicit link target -/// +/// /// [dummy_target][dummy_target] TEXT //~^ ERROR redundant explicit link target /// [`dummy_target`][dummy_target] TEXT @@ -140,7 +140,7 @@ pub fn should_not_warn_reference_unknown() {} //~^ ERROR redundant explicit link target /// [`std::primitive::usize`][std::primitive::usize] //~^ ERROR redundant explicit link target -/// +/// /// [dummy_target][dummy_target] TEXT //~^ ERROR redundant explicit link target /// [`dummy_target`][dummy_target] TEXT diff --git a/tests/rustdoc-ui/unescaped_backticks.rs b/tests/rustdoc-ui/unescaped_backticks.rs index e99cd1f3d58..e960e9f59e9 100644 --- a/tests/rustdoc-ui/unescaped_backticks.rs +++ b/tests/rustdoc-ui/unescaped_backticks.rs @@ -1,6 +1,7 @@ #![deny(rustdoc::unescaped_backticks)] #![allow(rustdoc::broken_intra_doc_links)] #![allow(rustdoc::invalid_html_tags)] +#![allow(rustdoc::redundant_explicit_links)] /// pub fn empty() {} diff --git a/tests/rustdoc/description.rs b/tests/rustdoc/description.rs index 43cd59ebd09..918ccd63968 100644 --- a/tests/rustdoc/description.rs +++ b/tests/rustdoc/description.rs @@ -26,5 +26,5 @@ pub fn foo_fn() {} // @has 'foo/fn.bar_fn.html' '//meta[@name="description"]/@content' \ // 'Description with intra-doc link to foo_fn and [nonexistent_item] and foo_fn.' #[allow(rustdoc::broken_intra_doc_links)] -/// Description with intra-doc link to [foo_fn] and [nonexistent_item] and [foo_fn](self::foo_fn). +/// Description with intra-doc link to [foo_fn] and [nonexistent_item] and [foo_fn]. pub fn bar_fn() {} diff --git a/tests/rustdoc/intra-doc/basic.rs b/tests/rustdoc/intra-doc/basic.rs index 96e21137b2d..c88a7887f11 100644 --- a/tests/rustdoc/intra-doc/basic.rs +++ b/tests/rustdoc/intra-doc/basic.rs @@ -1,3 +1,5 @@ +#![allow(rustdoc::redundant_explicit_links)] + // @has basic/index.html // @has - '//a/@href' 'struct.ThisType.html' // @has - '//a/@title' 'struct basic::ThisType' diff --git a/tests/rustdoc/intra-doc/generic-params.rs b/tests/rustdoc/intra-doc/generic-params.rs index fbc9fc6a9bc..359f775f97f 100644 --- a/tests/rustdoc/intra-doc/generic-params.rs +++ b/tests/rustdoc/intra-doc/generic-params.rs @@ -1,6 +1,7 @@ // ignore-tidy-linelength #![crate_name = "foo"] +#![allow(rustdoc::redundant_explicit_links)] //! Here's a link to [`Vec<T>`] and one to [`Box<Vec<Option<T>>>`]. //! Here's a link to [`Iterator<Box<T>>::Item`]. diff --git a/tests/rustdoc/intra-doc/issue-108459.rs b/tests/rustdoc/intra-doc/issue-108459.rs index eb1c7a05e54..b8cd478b4df 100644 --- a/tests/rustdoc/intra-doc/issue-108459.rs +++ b/tests/rustdoc/intra-doc/issue-108459.rs @@ -1,4 +1,5 @@ #![deny(rustdoc::broken_intra_doc_links)] +#![allow(rustdoc::redundant_explicit_links)] pub struct S; pub mod char {} |
