diff options
| author | Guillaume Gomez <guillaume.gomez@huawei.com> | 2023-03-24 16:10:31 +0100 |
|---|---|---|
| committer | Guillaume Gomez <guillaume.gomez@huawei.com> | 2023-03-24 16:10:31 +0100 |
| commit | 415a3ca909084e83441306b21db5232ee8952fc4 (patch) | |
| tree | bbcb5585f9b6fb746efc2b05bdfd9e63e7e79821 | |
| parent | 537fdbd75b13d278645fa223b0e4bee1c0e5dc19 (diff) | |
| download | rust-415a3ca909084e83441306b21db5232ee8952fc4.tar.gz rust-415a3ca909084e83441306b21db5232ee8952fc4.zip | |
Put back `is_derive_trait_collision` check
| -rw-r--r-- | src/librustdoc/passes/collect_intra_doc_links.rs | 31 | ||||
| -rw-r--r-- | tests/rustdoc-ui/intra-doc/issue-108653-associated-items-10.rs | 22 |
2 files changed, 51 insertions, 2 deletions
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 80895893ae8..0da56e70ed5 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -806,6 +806,20 @@ fn trait_impls_for<'a>( iter.collect() } +/// Check for resolve collisions between a trait and its derive. +/// +/// These are common and we should just resolve to the trait in that case. +fn is_derive_trait_collision<T>(ns: &PerNS<Result<Vec<(Res, T)>, ResolutionFailure<'_>>>) -> bool { + if let (&Ok(ref type_ns), &Ok(ref macro_ns)) = (&ns.type_ns, &ns.macro_ns) { + type_ns.iter().any(|(res, _)| matches!(res, Res::Def(DefKind::Trait, _))) + && macro_ns + .iter() + .any(|(res, _)| matches!(res, Res::Def(DefKind::Macro(MacroKind::Derive), _))) + } else { + false + } +} + impl<'a, 'tcx> DocVisitor for LinkCollector<'a, 'tcx> { fn visit_item(&mut self, item: &Item) { self.resolve_links(item); @@ -1313,9 +1327,22 @@ impl LinkCollector<'_, '_> { disambiguator, candidates.into_iter().filter_map(|res| res.err()).collect(), ); + } else if len == 1 { + candidates.into_iter().filter_map(|res| res.ok()).flatten().collect::<Vec<_>>() + } else { + let has_derive_trait_collision = is_derive_trait_collision(&candidates); + if len == 2 && has_derive_trait_collision { + candidates.type_ns.unwrap() + } else { + // If we're reporting an ambiguity, don't mention the namespaces that failed + let mut candidates = candidates.map(|candidate| candidate.ok()); + // If there a collision between a trait and a derive, we ignore the derive. + if has_derive_trait_collision { + candidates.macro_ns = None; + } + candidates.into_iter().filter_map(|res| res).flatten().collect::<Vec<_>>() + } } - - candidates.into_iter().filter_map(|res| res.ok()).flatten().collect::<Vec<_>>() } } } diff --git a/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-10.rs b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-10.rs new file mode 100644 index 00000000000..464c5f0d543 --- /dev/null +++ b/tests/rustdoc-ui/intra-doc/issue-108653-associated-items-10.rs @@ -0,0 +1,22 @@ +// This test ensures that this warning doesn't show up: +// warning: `PartialEq` is both a trait and a derive macro +// --> tests/rustdoc-ui/intra-doc/issue-108653-associated-items-10.rs:1:7 +// | +// 1 | //! [`PartialEq`] +// | ^^^^^^^^^ ambiguous link +// | +// = note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default +// help: to link to the trait, prefix with `trait@` +// | +// 1 | //! [`trait@PartialEq`] +// | ++++++ +// help: to link to the derive macro, prefix with `derive@` +// | +// 1 | //! [`derive@PartialEq`] +// | +++++++ + +// check-pass + +#![deny(rustdoc::broken_intra_doc_links)] + +//! [`PartialEq`] |
