about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJoshua Nelson <jyn514@gmail.com>2021-01-10 10:00:17 -0500
committerJoshua Nelson <jyn514@gmail.com>2021-01-10 10:00:17 -0500
commit0acaa5af6bd11f425245743b59530e40b8e0d193 (patch)
tree681fc3c280806128ca18b4815ee91db3011d643a
parentc8915eebeaaef9f7cc1cff6ffd97f578b03c2ac9 (diff)
downloadrust-0acaa5af6bd11f425245743b59530e40b8e0d193.tar.gz
rust-0acaa5af6bd11f425245743b59530e40b8e0d193.zip
Fix intra-doc links to `Self` and `crate`
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs22
-rw-r--r--src/test/rustdoc/intra-doc-crate/auxiliary/self.rs3
-rw-r--r--src/test/rustdoc/intra-doc-crate/self.rs3
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 11ee59b2401..c84726312f5 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 cdfe842f3cc..54902f12eb1 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 62aef8e85af..4db63b12b6b 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;