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.)
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?