Skip to content

Issues with intra-doc links to core/std derive macros #110111

Closed
@mvanbem

Description

@mvanbem

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:

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:

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]
    |                   ~~~~~~

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-diagnosticsArea: Messages for errors, warnings, and lintsA-intra-doc-linksArea: Intra-doc links, the ability to link to items in docs by nameA-macrosArea: All kinds of macros (custom derive, macro_rules!, proc macros, ..)C-bugCategory: This is a bug.D-invalid-suggestionDiagnostics: A structured suggestion resulting in incorrect code.T-rustdocRelevant to the rustdoc team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions