From 0acaa5af6bd11f425245743b59530e40b8e0d193 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 10 Jan 2021 10:00:17 -0500 Subject: [PATCH 1/2] Fix intra-doc links to `Self` and `crate` --- .../passes/collect_intra_doc_links.rs | 22 ++++++++++++++----- .../rustdoc/intra-doc-crate/auxiliary/self.rs | 3 +++ src/test/rustdoc/intra-doc-crate/self.rs | 3 +++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 11ee59b2401c8..c84726312f5db 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -1024,12 +1024,18 @@ impl LinkCollector<'_, '_> { let resolved_self; // replace `Self` with suitable item's parent name - if path_str.starts_with("Self::") { + let is_lone_self = path_str == "Self"; + let is_lone_crate = path_str == "crate"; + if path_str.starts_with("Self::") || is_lone_self { if let Some(ref name) = self_name { - resolved_self = format!("{}::{}", name, &path_str[6..]); - path_str = &resolved_self; + if is_lone_self { + path_str = name; + } else { + resolved_self = format!("{}::{}", name, &path_str[6..]); + path_str = &resolved_self; + } } - } else if path_str.starts_with("crate::") { + } else if path_str.starts_with("crate::") || is_lone_crate { use rustc_span::def_id::CRATE_DEF_INDEX; // HACK(jynelson): rustc_resolve thinks that `crate` is the crate currently being documented. @@ -1038,8 +1044,12 @@ impl LinkCollector<'_, '_> { // HACK(jynelson)(2): If we just strip `crate::` then suddenly primitives become ambiguous // (consider `crate::char`). Instead, change it to `self::`. This works because 'self' is now the crate root. // FIXME(#78696): This doesn't always work. - resolved_self = format!("self::{}", &path_str["crate::".len()..]); - path_str = &resolved_self; + if is_lone_crate { + path_str = "self"; + } else { + resolved_self = format!("self::{}", &path_str["crate::".len()..]); + path_str = &resolved_self; + } module_id = DefId { krate, index: CRATE_DEF_INDEX }; } diff --git a/src/test/rustdoc/intra-doc-crate/auxiliary/self.rs b/src/test/rustdoc/intra-doc-crate/auxiliary/self.rs index cdfe842f3ccbb..54902f12eb18c 100644 --- a/src/test/rustdoc/intra-doc-crate/auxiliary/self.rs +++ b/src/test/rustdoc/intra-doc-crate/auxiliary/self.rs @@ -1,4 +1,7 @@ #![crate_name = "cross_crate_self"] + +/// Link to [Self] +/// Link to [crate] pub struct S; impl S { diff --git a/src/test/rustdoc/intra-doc-crate/self.rs b/src/test/rustdoc/intra-doc-crate/self.rs index 62aef8e85afc9..4db63b12b6bb7 100644 --- a/src/test/rustdoc/intra-doc-crate/self.rs +++ b/src/test/rustdoc/intra-doc-crate/self.rs @@ -1,6 +1,9 @@ // aux-build:self.rs +// build-aux-docs extern crate cross_crate_self; // @has self/struct.S.html '//a[@href="../self/struct.S.html#method.f"]' "Self::f" +// @has self/struct.S.html '//a[@href="../self/struct.S.html"]' "Self" +// @has self/struct.S.html '//a[@href="../cross_crate_self/index.html"]' "crate" pub use cross_crate_self::S; From a52341d784b3b7a6acacae4c2f461de735651fee Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Sun, 10 Jan 2021 10:00:41 -0500 Subject: [PATCH 2/2] Small cleanups --- .../passes/collect_intra_doc_links.rs | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c84726312f5db..9252ed2e831e3 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -504,15 +504,9 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { match res { // FIXME(#76467): make this fallthrough to lookup the associated // item a separate function. - Res::Def(DefKind::AssocFn | DefKind::AssocConst, _) => { - assert_eq!(ns, ValueNS); - } - Res::Def(DefKind::AssocTy, _) => { - assert_eq!(ns, TypeNS); - } - Res::Def(DefKind::Variant, _) => { - return handle_variant(cx, res, extra_fragment); - } + Res::Def(DefKind::AssocFn | DefKind::AssocConst, _) => assert_eq!(ns, ValueNS), + Res::Def(DefKind::AssocTy, _) => assert_eq!(ns, TypeNS), + Res::Def(DefKind::Variant, _) => return handle_variant(cx, res, extra_fragment), // Not a trait item; just return what we found. Res::Primitive(ty) => { if extra_fragment.is_some() { @@ -522,12 +516,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { } return Ok((res, Some(ty.as_str().to_owned()))); } - Res::Def(DefKind::Mod, _) => { - return Ok((res, extra_fragment.clone())); - } - _ => { - return Ok((res, extra_fragment.clone())); - } + _ => return Ok((res, extra_fragment.clone())), } }