]> git.lizzy.rs Git - rust.git/commitdiff
Resolve `crate` properly across crates
authorJoshua Nelson <jyn514@gmail.com>
Sun, 27 Sep 2020 02:32:20 +0000 (22:32 -0400)
committerJoshua Nelson <jyn514@gmail.com>
Sun, 27 Sep 2020 14:13:59 +0000 (10:13 -0400)
src/librustdoc/passes/collect_intra_doc_links.rs
src/test/rustdoc/auxiliary/intra-link-cross-crate-crate.rs [new file with mode: 0644]
src/test/rustdoc/intra-link-cross-crate-crate.rs [new file with mode: 0644]

index 5d74a3da9a2050f1ba80020407b89d85af10f3c4..a463c0a3c9cda1b8a45fa50897c06c1bbeb3c9f3 100644 (file)
@@ -911,7 +911,7 @@ fn resolve_link(
                 parent_node
             };
 
-            let module_id = if let Some(id) = base_node {
+            let mut module_id = if let Some(id) = base_node {
                 id
             } else {
                 debug!("attempting to resolve item without parent module: {}", path_str);
@@ -934,6 +934,17 @@ fn resolve_link(
                     resolved_self = format!("{}::{}", name, &path_str[6..]);
                     path_str = &resolved_self;
                 }
+            } else if path_str.starts_with("crate::") {
+                use rustc_span::def_id::CRATE_DEF_INDEX;
+
+                // HACK(jynelson): rustc_resolve thinks that `crate` is the crate currently being documented.
+                // But rustdoc wants it to mean the crate this item was originally present in.
+                // To work around this, remove it and resolve relative to the crate root instead.
+                // 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.
+                resolved_self = format!("self::{}", &path_str["crate::".len()..]);
+                path_str = &resolved_self;
+                module_id = DefId { krate: item.def_id.krate, index: CRATE_DEF_INDEX };
             }
 
             match self.resolve_with_disambiguator(
diff --git a/src/test/rustdoc/auxiliary/intra-link-cross-crate-crate.rs b/src/test/rustdoc/auxiliary/intra-link-cross-crate-crate.rs
new file mode 100644 (file)
index 0000000..a37848e
--- /dev/null
@@ -0,0 +1,5 @@
+#![crate_name = "inner"]
+
+/// Links to [crate::g]
+pub fn f() {}
+pub fn g() {}
diff --git a/src/test/rustdoc/intra-link-cross-crate-crate.rs b/src/test/rustdoc/intra-link-cross-crate-crate.rs
new file mode 100644 (file)
index 0000000..edf5447
--- /dev/null
@@ -0,0 +1,6 @@
+// aux-build:intra-link-cross-crate-crate.rs
+// build-aux-docs
+#![crate_name = "outer"]
+extern crate inner;
+// @has outer/fn.f.html '//a[@href="../inner/fn.g.html"]' "crate::g"
+pub use inner::f;