Docs.rs - build on multiple toolchains

I know there are options to define which targets are built for docs.rs and for multiple targets to be combined into a single documentation.

Is it also possible to have docs.rs build stable & nightly then combine the documentation?

Background: I have a crate which provides a consistent stable interface and leverages experimental features where available. Currently the docs only show the implementation details for the toolchain defined in rust-toolchain.toml (nightly) and are therefore missing the stable alternatives. This makes it look like a chunk of the API surface is nightly-only.

docs.rs uses nightly features of rustdoc, so it always uses the nightly toolchain and can't be configured otherwise.

That said, if your automatic use of nightly features is visible in the documentation, that seems likely to be something that will cause trouble by itself, and you should likely reconsider it (but I don't have the details).

docs.rs only supports building using the latest nightly. Would it be possible to instead of detect if you are running on stable or nightly rather add a nightly cargo feature to allow the user to opt-in to unstable features? This avoids breakage when unstable features in rustc change when the user didn't need them but is using nightly for unrelated reasons. And rustdoc would show a badge for every item that is only usable when the nightly feature is enabled.

It's a bit of an edge case: the crate provides an ergonomic wrapper around the nightly feature proc_macro_diagnostic in a way which works (definition below) today on both nightly and stable. It also leverages additional nightly features (related to trait Try) where available and will continue to work as features are stabilised (in any order - testing this was a nice challenge).

"Crate goal: it just works":

  • same code compiles on nightly & stable
  • all key functionality is available on nightly & stable
  • where (nice-to-have) functionality cannot be provided on stable, the API is designed in a way that this will not affect the overall result
  • some ergonomic benefits are missing on stable
  • code continues to compile as features are stabilised (in any order) & takes advantage of stable features without downstream crates needing to change anything
  • it is not possible to write code on nightly which will fail on stable (reciprocal goal missed in one specific, documented & hopefully unlikely case)

The above precludes using opt-in features in a meaningful way for the next-downstream to decide what to support.

To achieve this:

  1. I am automatically generating cfg flag pairs for each feature:
    • unstable_proc_macro_diagnostic
    • has_proc_macro_diagnostic
  2. I prefix lib.rs with !#[cfg_attr(unstable_proc_macro_diagnostic, feature(proc_macro_diagnostic))]
  3. I have paired code segments gated #[cfg(has_proc_macro_diagnostic)] / #[cfg(not(has_proc_macro_diagnostic))]

Where a public function or type is gated, the nightly version shows on docs.rs, with a note "Available on has_proc_macro_diagnostic only" and the stable version is not shown.

For those interested in helping spot what I did wrong:

You can override the displayed badges with #[doc(cfg(...))].

#![cfg_attr(docsrs, feature(doc_cfg))]

#[cfg(has_proc_macro_diagnostic)]
#[cfg_attr(docsrs, doc(cfg(true)))]
pub fn example() {}