How do intra-doc links work?

I have already read the mdbook page on links.

I am attempting to create intra-doc links for external libraries that I've gotten from crates.io in my project documentation. Links to items in my own project, and links to the standard library work fine, but links to external libraries aren't working.

I have the example code:

/// All of these are in my cargo.toml
/// 1. [`std::net::SocketAddr`]
/// 2. [`serde::Serialize`]
/// 3. [`syn::File`]
/// 4. [`rcgen::Attribute`]
/// 5. [`http::response::Builder`]
/// 6. [`tokio::task`]
/// 7. [`rustls::RootCertStore`]
/// 8. [`axum_server::Server`]
/// 9. [`tower_service::Service`]
struct thing;

I generate the docs using cargo doc --open --no-deps --document-private-items --all-features and get this:

Why does only the link for serde work? The link to syn::File gives me an unresolved link warning, even though it exists here, and none of the other links even give me a warning. What am I doing wrong?

Only links to crates you’ve imported will work that way. They are visible as items in that scope of your crate. There’s no special case for types within your own library or the standard library; it uses the same visibility rules as normal Rust code AFAIK.

Are you absolutely certain that you’ve imported them in the Cargo.toml of that crate? Not just a workspace Cargo.toml?

So, I can tell that your crate uses serde but not syn. As for why the following links don’t print an error… maybe it only reports at most one error of that kind per doc comment, or something?

For truly external libraries (that you’re not importing), you’ll need to handle them as normal links, something like

[`path::to::Foo`]: https://docs.rs/crate-name/latest/crate_name/path/to/struct.Foo.html

Ahhhh I just realized another possibility. Maybe you’ve generated the docs for serde before, but never generated the docs for the other dependencies, leading to --no-deps preventing the links from working?

1 Like

This is the answer! Linked libraries need to have their documentation compiled locally!

I assumed that documenting just my project somehow generated a URL to the doc.rust-lang.org website, but it actually links to the local documentation file with that name.

Thank you!

1 Like

It is possible to configure rustdoc to generate specific links for extern crates (that’s how docs.rs generates documentation independently for each package), but that is not the behavior of cargo doc.

There are some benefits to the always-local approach — besides the obvious advantage of being able to keep working offline, also, the search works across all crates in your project, and trait documentation will show implementations from all crates, not only the crate defining the trait.

2 Likes