about summary refs log tree commit diff
diff options
context:
space:
mode:
authormax-heller <max.a.heller@gmail.com>2021-01-03 20:35:18 -0500
committermax-heller <max.a.heller@gmail.com>2021-01-03 20:45:08 -0500
commitfc3a4058cefc09bebe98039c7fb8d74d1be9c6e6 (patch)
tree4b01a2ff50cd2929401bc9227b609041585f4d27
parente33a205bdfb0fbbbad80f49e4d39180dc78087bf (diff)
downloadrust-fc3a4058cefc09bebe98039c7fb8d74d1be9c6e6.tar.gz
rust-fc3a4058cefc09bebe98039c7fb8d74d1be9c6e6.zip
still verify disambiguators for primitives
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs104
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(