about summary refs log tree commit diff
path: root/src/librustdoc/passes
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-29 12:11:17 +0000
committerbors <bors@rust-lang.org>2020-09-29 12:11:17 +0000
commit9e34b729647f44bfbbc361949b14b5bea65e4996 (patch)
tree5a96bb441ab40aaa69818812e418898c805456bf /src/librustdoc/passes
parent26373fb4baa9c5b8a7a1e2821fcfa930a85d327d (diff)
parent406584621a4e2d3752b2444c5bed2218447f0bfe (diff)
downloadrust-9e34b729647f44bfbbc361949b14b5bea65e4996.tar.gz
rust-9e34b729647f44bfbbc361949b14b5bea65e4996.zip
Auto merge of #77253 - jyn514:crate-link, r=Manishearth
Resolve `crate` in intra-doc links properly across crates

Closes https://github.com/rust-lang/rust/issues/77193; see https://github.com/rust-lang/rust/issues/77193#issuecomment-699065946 for an explanation of what's going on here.
~~This also fixes the BTreeMap docs that have been broken for a while; see the description on the second commit for why and how.~~ Nope, see the second commit for why the link had to be changed.

r? `@Manishearth`
cc `@dylni`

`@dylni` note that this doesn't solve your original problem - now _both_ `with_code` and `crate::with_code` will be broken links. However this will fix a lot of other broken links (in particular I think https://docs.rs/sqlx/0.4.0-beta.1/sqlx/query/struct.Query.html is because of this bug). I'll open another issue for resolving additional docs in the new scope.
Diffstat (limited to 'src/librustdoc/passes')
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs13
1 files changed, 12 insertions, 1 deletions
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index cd6a7feb180..cf94ea384fd 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -914,7 +914,7 @@ impl LinkCollector<'_, '_> {
                 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);
@@ -937,6 +937,17 @@ impl LinkCollector<'_, '_> {
                     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(