Description
I tried to refer to the core Clone
derive macro (rather than the core Clone
trait) in a rustdoc intra-doc link, but was not able to find a way that works. Along the way I found broken generated links and a broken error message.
Environment
I am using a rust-toolchain.toml
with toolchain.channel
set to "nightly-2023-04-07"
. Rustdoc identifies itself as:
$ rustdoc --version --verbose
rustdoc 1.70.0-nightly (28a29282f 2023-04-06)
binary: rustdoc
commit-hash: unknown
commit-date: unknown
host: x86_64-unknown-linux-gnu
release: 1.70.0-nightly
LLVM version: 16.0.2
I happen to be working on a no_std
crate, so all of my generated links will point to the core
variants of these items.
Correct behavior
First, what works:
/// [`Clone`]
Generated link: https://doc.rust-lang.org/nightly/core/clone/trait.Clone.html
This links to the Clone
trait and does not issue an ambiguity warning, apparently due to an intentional disambiguation rule that serves the common case: #82478 (comment). Great! I have benefited from this tens if not hundreds of times. But I'm on the unusual path and want to link to the derive macro.
Incomplete documentation
I did a search and found the Namespaces and Disambiguators section of the rustdoc book. It says, "Paths in Rust have three namespaces: type, value, and macro." This implies to me that type@
, value@
, and macro@
would be the only valid disambiguators. But then the only examples use struct@
and fn@
.
I also found RFC 1946, which provides a more exhaustive (though potentially outdated) list of disambiguators.
The book says there's a macro namespace and the RFC mentions the macro@
disambiguator, so I tried that one. I also found that a derive@
disambiguator is accepted and has the same effect, though neither doc mentions it. It would be nice if there was an exhaustive list of these disambiguators and their behaviors.
Broken links
I tried using the macro@
and derive@
disambiguators in my doc links:
/// [`macro@Clone`]
/// [`derive@Clone`]
Generated links:
- https://doc.rust-lang.org/nightly/core/clone/derive.Clone.html
- https://doc.rust-lang.org/nightly/core/clone/derive.Clone.html
Those are 404s! And rustdoc does not issue any warnings or errors. Navigating the official docs, this is the link I want:
https://doc.rust-lang.org/nightly/core/clone/macro.Clone.html
So the official docs and and rustdoc disagree on how to refer to this item.
Third-party derive macros work
Does this happen with user-defined derive macros? I was surprised to see I was unable to link to the derive_more::Add
or clap::Parser
derive macros (no idea why and #[doc(hidden)]
, respectively). But here's serde
1.0.151 with the derive
feature enabled:
/// [`serde::Serialize`]
/// [`macro@serde::Serialize`]
/// [`derive@serde::Serialize`]
Generated links:
- https://docs.rs/serde/1.0.151/serde/ser/trait.Serialize.html
- https://docs.rs/serde_derive/1.0.151/serde_derive/derive.Serialize.html
- https://docs.rs/serde_derive/1.0.151/serde_derive/derive.Serialize.html
Those links all work!
So I'm led to believe the std/core docs are doing something unusual with the naming of their derive macro pages.
Sliced error message
For fun, I tried specifying an incorrect disambiguator:
/// For bug report: [`struct@Clone`]
warning: incompatible link kind for `Clone`
--> my_crate/src/lib.rs:175:23
|
175 | /// For bug report: [`struct@Clone`]
| ^^^^^^^^^^^^ this link resolved to a trait, which is not a struct
|
= note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
help: to link to the trait, prefix with `trait@`
|
175 | /// For bug report: [`trait@lone`]
| ~~~~~~
The suggestion replaced struct
with trait
, which is reasonable, but it removed the C
from Clone
in the process.
The error message seems to do the right thing if I omit the backticks:
warning: incompatible link kind for `Clone`
--> my_crate/src/lib.rs:175:19
|
175 | /// Bug attempt: [struct@Clone]
| ^^^^^^^^^^^^ this link resolved to a trait, which is not a struct
|
= note: `#[warn(rustdoc::broken_intra_doc_links)]` on by default
help: to link to the trait, prefix with `trait@`
|
175 | /// Bug attempt: [trait@Clone]
| ~~~~~~