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;