Cross-crate documentation links in a workspace

I have a workspace with two crates in it. One crate contains procedural macros and another contains most of the (library) code.

In the documentation, I'd like to embed links between the crates; e.g. a macro might refer to related library functions or vice-versa.

The library crate depends on the macros crate, so I can embed links to [macros_crate::Symbol] and they work as expected.

However, the macros crate does not depend on the library crate, so trying to write [lib_crate::module::Symbol] in the macros crate fails, complaining that the library crate is not known.

When looking at this one crate a a time, this makes sense; however, since I'm running cargo doc --workspace I was hoping that all the workspace crates would be able to link to each other.

Is there some workaround for this?

If it matters - the physical layout is that the library crate is at the top level and the macros crate is in a sub-directory.

1 Like

Looking at tokio and tokio_macros, they seem to be using [link_text](../crate_name/path/…). E.g. look here. If you don’t know how the struct/trait/function name translates into the precise path to the html, take inspiration from the URL of the relevant documentation page and/or the links generated for crate-internal links. This approach should work locally in the workspace, it also works well for the documentation reproduced in a re-export, e.g. clicking the link here on docs.rs, but the docs.rs page of the tokio_macros crate has links that don’t work. But it does again work properly for the docs you get when locally running cargo doc in a crate that depends on tokio (even in the generated tokio_macros docs).

I don’t think that workspace layout will matter, as the generated docs should all land together in the same target directory anyways.

(To be clear, you might need multiple ../../../…s if you’re linking from with in a module, or a module inside of a module, etc.)

1 Like

This is the frontend / backend crate patterns, and the trick is for the frontend crate to be the one providing the documentation for the backend items, at the moment where they are imported.

Thanks!

It didn't occur to me that one can re-export procedural macros from a regular library crates. I was thrown off by the fact that one can't have a crate that exports both locally-defined procedural macros and also other symbols.

This is a better user experience for the users as the just need to import one crate, and the documentation is centralized. It raises the question of why the compiler can't automatically package all procedural macros defined in a library crate "as if" they were defined in a separate sub-crate which was imported and its symbols re-exported in the containing library crate.

At any rate, I'll give this a try. I prefer this to hard-wiring generated URLs into the links, which would be fragile if these paths do not match the actually generated URLs for any reason - AFAIK there's no strong commitment of cargo doc as to the exact format of these URLs, is that right?

This seems to be one of the reasons for why Rust supports the links by-name in the first place.

1946-intra-rustdoc-links - The Rust RFC Book

(under "Motivation")

Should Rustdoc's file name scheme ever change (it has change [sic] before, cf. Rust issue #35236), all manually created links need to be updated.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.