diff options
| author | max-heller <max.a.heller@gmail.com> | 2021-01-03 20:35:18 -0500 |
|---|---|---|
| committer | max-heller <max.a.heller@gmail.com> | 2021-01-03 20:45:08 -0500 |
| commit | fc3a4058cefc09bebe98039c7fb8d74d1be9c6e6 (patch) | |
| tree | 4b01a2ff50cd2929401bc9227b609041585f4d27 | |
| parent | e33a205bdfb0fbbbad80f49e4d39180dc78087bf (diff) | |
| download | rust-fc3a4058cefc09bebe98039c7fb8d74d1be9c6e6.tar.gz rust-fc3a4058cefc09bebe98039c7fb8d74d1be9c6e6.zip | |
still verify disambiguators for primitives
| -rw-r--r-- | src/librustdoc/passes/collect_intra_doc_links.rs | 104 |
1 files changed, 57 insertions, 47 deletions
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index fd63d5eb5c9..090c45b30ff 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1146,60 +1146,70 @@ impl LinkCollector<'_, '_> { callback, ); }; - match res { - Res::Primitive(_) if self.kind_side_channel.get().is_none() => match disambiguator { - Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => { - Some(ItemLink { link: ori_link.link, link_text, did: None, fragment }) - } - Some(other) => { - report_mismatch(other, Disambiguator::Primitive); - None - } - }, - Res::Primitive(_) => Some(ItemLink { link: ori_link, link_text, did: None, fragment }), - Res::Def(kind, id) => { - debug!("intra-doc link to {} resolved to {:?}", path_str, res); - - // Disallow e.g. linking to enums with `struct@` - debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator); - match (self.kind_side_channel.take().map(|(kind, _)| kind).unwrap_or(kind), disambiguator) { - | (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const))) - // NOTE: this allows 'method' to mean both normal functions and associated functions - // This can't cause ambiguity because both are in the same namespace. - | (DefKind::Fn | DefKind::AssocFn, Some(Disambiguator::Kind(DefKind::Fn))) - // These are namespaces; allow anything in the namespace to match - | (_, Some(Disambiguator::Namespace(_))) - // If no disambiguator given, allow anything - | (_, None) - // All of these are valid, so do nothing - => {} - (actual, Some(Disambiguator::Kind(expected))) if actual == expected => {} - (_, Some(specified @ Disambiguator::Kind(_) | specified @ Disambiguator::Primitive)) => { - report_mismatch(specified, Disambiguator::Kind(kind)); - return None; + + let (kind, id) = match res { + Res::Primitive(_) => { + if let Some((kind, id)) = self.kind_side_channel.take() { + (kind, id) + } else { + match disambiguator { + Some(Disambiguator::Primitive | Disambiguator::Namespace(_)) | None => { + return Some(ItemLink { + link: ori_link.link, + link_text, + did: None, + fragment, + }); + } + Some(other) => { + report_mismatch(other, Disambiguator::Primitive); + return None; + } } } + } + Res::Def(kind, id) => (kind, id), + }; - // item can be non-local e.g. when using #[doc(primitive = "pointer")] - if let Some((src_id, dst_id)) = id - .as_local() - .and_then(|dst_id| item.def_id.as_local().map(|src_id| (src_id, dst_id))) - { - use rustc_hir::def_id::LOCAL_CRATE; + debug!("intra-doc link to {} resolved to {:?}", path_str, res); + + // Disallow e.g. linking to enums with `struct@` + debug!("saw kind {:?} with disambiguator {:?}", kind, disambiguator); + match (self.kind_side_channel.take().map(|(kind, _)| kind).unwrap_or(kind), disambiguator) { + | (DefKind::Const | DefKind::ConstParam | DefKind::AssocConst | DefKind::AnonConst, Some(Disambiguator::Kind(DefKind::Const))) + // NOTE: this allows 'method' to mean both normal functions and associated functions + // This can't cause ambiguity because both are in the same namespace. + | (DefKind::Fn | DefKind::AssocFn, Some(Disambiguator::Kind(DefKind::Fn))) + // These are namespaces; allow anything in the namespace to match + | (_, Some(Disambiguator::Namespace(_))) + // If no disambiguator given, allow anything + | (_, None) + // All of these are valid, so do nothing + => {} + (actual, Some(Disambiguator::Kind(expected))) if actual == expected => {} + (_, Some(specified @ Disambiguator::Kind(_) | specified @ Disambiguator::Primitive)) => { + report_mismatch(specified, Disambiguator::Kind(kind)); + return None; + } + } - let hir_src = self.cx.tcx.hir().local_def_id_to_hir_id(src_id); - let hir_dst = self.cx.tcx.hir().local_def_id_to_hir_id(dst_id); + // item can be non-local e.g. when using #[doc(primitive = "pointer")] + if let Some((src_id, dst_id)) = + id.as_local().and_then(|dst_id| item.def_id.as_local().map(|src_id| (src_id, dst_id))) + { + use rustc_hir::def_id::LOCAL_CRATE; - if self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_src) - && !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_dst) - { - privacy_error(cx, &item, &path_str, dox, &ori_link); - } - } - let id = clean::register_res(cx, rustc_hir::def::Res::Def(kind, id)); - Some(ItemLink { link: ori_link.link, link_text, did: Some(id), fragment }) + let hir_src = self.cx.tcx.hir().local_def_id_to_hir_id(src_id); + let hir_dst = self.cx.tcx.hir().local_def_id_to_hir_id(dst_id); + + if self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_src) + && !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_dst) + { + privacy_error(cx, &item, &path_str, dox, &ori_link); } } + let id = clean::register_res(cx, rustc_hir::def::Res::Def(kind, id)); + Some(ItemLink { link: ori_link.link, link_text, did: Some(id), fragment }) } fn resolve_with_disambiguator_cached( |
