diff --git a/src/doc/rustdoc/src/advanced-features.md b/src/doc/rustdoc/src/advanced-features.md index c9a0dff5ab3..cad5648be48 100644 --- a/src/doc/rustdoc/src/advanced-features.md +++ b/src/doc/rustdoc/src/advanced-features.md @@ -2,7 +2,7 @@ The features listed on this page fall outside the rest of the main categories. -## `#[cfg(doc)]`: Documenting platform-/feature-specific information +## `#[cfg(doc)]`: Documenting platform-specific or feature-specific information For conditional compilation, Rustdoc treats your crate the same way the compiler does. Only things from the host target are available (or from the given `--target` if present), and everything else is @@ -17,7 +17,7 @@ with other `#[cfg]` filters on it, you can write something like `#[cfg(any(windo This will preserve the item either when built normally on Windows, or when being documented anywhere. -Please note that this feature is not passed to doctests. +Please note that this `cfg` is not passed to doctests. Example: @@ -33,6 +33,40 @@ pub struct UnixToken; Here, the respective tokens can only be used by dependent crates on their respective platforms, but they will both appear in documentation. +### Interactions between platform-specific docs + +Rustdoc does not have a magic way to compile documentation 'as-if' you'd run it once for each +platform (such a magic wand has been called the ['holy grail of rustdoc'][#1998]). Instead, +it sees *all* of your code at once, the same way the Rust compiler would if you passed it +`--cfg doc`. However, Rustdoc has a trick up its sleeve to handle platform-specific code if it +*does* receive it. + +To document your crate, Rustdoc only needs to know the public signature of your functions. +In particular, it doesn't have to know how any of your functions are implemented, so it ignores +all type errors and name resolution errors with function bodies. Note that this does *not* +work for anything outside a function body: since Rustdoc documents your types, it has to +know what those types are! For example, this code will work regardless of the platform: + + +```ignore +pub fn f() { + use std::os::windows::ffi::OsStrExt; +} +``` + +but this will not, because the unknown type is part of the function signature: + +```ignore +pub fn f() -> std::os::windows::ffi::EncodeWide<'static> { + unimplemented!() +} +``` + +For a more realistic example of code this allows, see [the rustdoc test suite][realistic-async]. + +[#1998]: https://github.com/rust-lang/rust/issues/1998 +[realistic-async]: https://github.com/rust-lang/rust/blob/b146000e910ccd60bdcde89363cb6aa14ecc0d95/src/test/rustdoc-ui/error-in-impl-trait/realistic-async.rs + ## Add aliases for an item in documentation search This feature allows you to add alias(es) to an item when using the `rustdoc` search through the diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md index e4d8818b56c..16157a4b080 100644 --- a/src/doc/rustdoc/src/unstable-features.md +++ b/src/doc/rustdoc/src/unstable-features.md @@ -43,28 +43,16 @@ plain text. These features operate by extending the `#[doc]` attribute, and thus can be caught by the compiler and enabled with a `#![feature(...)]` attribute in your crate. -### Documenting platform-/feature-specific information +### `#[doc(cfg)]`: Recording what platforms or features are required for code to be present -Because of the way Rustdoc documents a crate, the documentation it creates is specific to the target -rustc compiles for. Anything that's specific to any other target is dropped via `#[cfg]` attribute -processing early in the compilation process. However, Rustdoc has a trick up its sleeve to handle -platform-specific code if it *does* receive it. +You can use `#[doc(cfg(...))]` to tell Rustdoc exactly which platform items appear on. +This has two effects: -Because Rustdoc doesn't need to fully compile a crate to binary, it replaces function bodies with -`loop {}` to prevent having to process more than necessary. This means that any code within a -function that requires platform-specific pieces is ignored. Combined with a special attribute, -`#[doc(cfg(...))]`, you can tell Rustdoc exactly which platform something is supposed to run on, -ensuring that doctests are only run on the appropriate platforms. - -The `#[doc(cfg(...))]` attribute has another effect: When Rustdoc renders documentation for that -item, it will be accompanied by a banner explaining that the item is only available on certain -platforms. - -For Rustdoc to document an item, it needs to see it, regardless of what platform it's currently -running on. To aid this, Rustdoc sets the flag `#[cfg(doc)]` when running on your crate. -Combining this with the target platform of a given item allows it to appear when building your crate -normally on that platform, as well as when building documentation anywhere. +1. doctests will only run on the appropriate platforms, and +2. When Rustdoc renders documentation for that item, it will be accompanied by a banner explaining + that the item is only available on certain platforms. +`#[doc(cfg)]` is intended to be used alongside [`#[cfg(doc)]`][cfg-doc]. For example, `#[cfg(any(windows, doc))]` will preserve the item either on Windows or during the documentation process. Then, adding a new attribute `#[doc(cfg(windows))]` will tell Rustdoc that the item is supposed to be used on Windows. For example: @@ -81,6 +69,12 @@ pub struct WindowsToken; #[cfg(any(unix, doc))] #[doc(cfg(unix))] pub struct UnixToken; + +/// Token struct that is only available with the `serde` feature +#[cfg(feature = "serde")] +#[doc(cfg(feature = "serde"))] +#[derive(serde::Deserialize)] +pub struct SerdeToken; ``` In this sample, the tokens will only appear on their respective platforms, but they will both appear @@ -90,6 +84,7 @@ in documentation. `#![feature(doc_cfg)]` feature gate. For more information, see [its chapter in the Unstable Book][unstable-doc-cfg] and [its tracking issue][issue-doc-cfg]. +[cfg-doc]: ./advanced-features.md [unstable-doc-cfg]: ../unstable-book/language-features/doc-cfg.html [issue-doc-cfg]: https://github.com/rust-lang/rust/issues/43781