From e6b88c1f4d10df2912bdba02b18250b561277e0e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 7 Dec 2022 18:28:24 +0100 Subject: [PATCH 01/12] Start RFC for doc cfg feature MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: León Orell Valerian Liehr Co-authored-by: Michael Howell --- text/000-rustdoc-cfgs-handling.md | 283 ++++++++++++++++++++++++++++++ 1 file changed, 283 insertions(+) create mode 100644 text/000-rustdoc-cfgs-handling.md diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md new file mode 100644 index 00000000000..51f25e802d9 --- /dev/null +++ b/text/000-rustdoc-cfgs-handling.md @@ -0,0 +1,283 @@ +Rustdoc: stabilization of the `doc(cfg*)` attributes + +- Features Name: `doc_cfg` +- Start Date: 2022-12-07 +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- Rust Issue: [rust-lang/rust#43781](https://github.com/rust-lang/rust/issues/43781) + + +# Summary +[summary]: #summary + +This RFC aims at providing rustdoc users the possibility to add visual markers to the rendered documentation to know under which conditions an item is available (currently possible through the following unstable features: `doc_cfg`, `doc_auto_cfg` and `doc_cfg_hide`). + +It does not aim to allow having a same item with different `cfg`s to appear more than once in the generated documentation. + +It does not aim to document items which are *inactive* under the current configuration (i.e., “`cfg`'ed out”). + +# Motivation +[motivation]: #motivation + +The goal of this RFC is to stabilize the possibility to add visual markers to the rendered documentation to know under which conditions an item is available. + +Providing this information to users will solve a common issue: “Why can I see this item in the documentation and yet can't use it in my code?”. +The end goal being to provide this information automatically so that the documentation maintenance cost won't increase. + + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +This RFC proposes to add the following attributes: + + * `#[doc(cfg(...))]` + + This attribute is used to document the operating systems, feature flags, and build profiles where an item is available. For example, `#[doc(cfg(unix))` will add a tag that says "this is supported on **unix** only" to the item. + + The syntax of this attribute is the same as the syntax of the [`#[cfg(unix)]` attribute][cfg attribute] used for conditional compilation. + + * `#[doc(auto_cfg)]`/`#[doc(no_auto_cfg)]` + + When this is turned on, `#[cfg]` attributes are shown in documentation just like `#[doc(cfg)]` attributes are. + + * `#[doc(cfg_hide(...))]` / `#[doc(cfg_show(...))]` + + These attributes suppress or un-suppress the `auto_cfg` behavior for a particular configuration predicate. + + For example, `#[doc(cfg_hide(windows))]` shall be used in newer versions of the [`windows` crate] to prevent the "this is supported on **windows** only" tag from being shown on every single item. + +[cfg attribute]: https://doc.rust-lang.org/reference/conditional-compilation.html +[`windows` crate]: https://docs.rs/windows/latest/windows/ + +All of these attributes can be added to a module or to the crate root, and they will be inherited by the child items unless another attribute overrides it (except that `doc(cfg)` cannot be added to the crate root). This is why "opposite" attributes like `cfg_hide` and `cfg_show` are provided: they allow a child item to override its parent. + + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +## The attributes + +### `#[doc(cfg(...))]` + +This attribute provides a standardized format to document conditionally available items. Example: + +```rust +// the "real" cfg condition +#[cfg(feature = "futures-io")] +// the `doc(cfg())` so it's displayed to the readers +#[doc(cfg(feature = "futures-io"))] +pub mod futures {} +``` + +It will display in the documentation for this module: + +![This is supported on feature="futures-io" only.](https://user-images.githubusercontent.com/81079/89731116-d7b7ce00-da44-11ea-87c6-022d192d6eca.png) + +This attribute has the same syntax as conditional compilation, but it only causes documentation to be added. This means `#[doc(cfg(false))` will not cause your docs to be hidden, even though `#[cfg(false)]` does do that. + +This attribute works on modules and on items but cannot be used at the crate root level. + +### `#[doc(auto_cfg)]`/`#[doc(no_auto_cfg)]` + +By default, `#[doc(auto_cfg)]` is enabled at the crate-level. When it's enabled, Rustdoc will automatically display `cfg(...)` compatibility information as-if the same `#[doc(cfg(...))]` had been specified. + +So if we take back the previous example: + +```rust +#[cfg(feature = "futures-io")] +pub mod futures {} +``` + +There's no need to "duplicate" the `cfg` into a `doc(cfg())` to make Rustdoc display it. + +In some situations, the detailed conditional compilation rules used to implement the feature might not serve as good documentation (for example, the list of supported platforms might be very long, and it might be better to document them in one place). To turn it off, add the `#[doc(no_auto_cfg)]` attribute. + +Both `#[doc(auto_cfg)]` and `#[doc(no_auto_cfg)]` attributes impact all there descendants. You can then enable/disable them by using the opposite attribute on a given item. They can be used as follows: + +```rust +// As an inner attribute, all this module's descendants will have this feature +// enabled. +#![doc(auto_cfg)] + +// As an outer attribute. So in this case, `foo` and all its +// descendants won't have the `auto_cfg` feature enabled. +#[doc(no_auto_cfg)] +pub mod foo { + // We re-enable the feature on `Bar` and on all its descendants. + #[doc(auto_cfg)] + pub struct Bar { + pub f: u32, + } +} +``` + +As mentioned, both attributes can be used on modules, items and crate root level. + +### `#[doc(cfg_hide(...))]` + +This attribute is used to prevent some `cfg` to be generated in the visual markers. So in the previous example: + +```rust +#[cfg(any(doc, feature = "futures-io"))] +pub mod futures {} +``` + +It currently displays both `doc` and `feature = "futures-io"` into the documentation, which is not great. To prevent the `doc` cfg to ever be displayed, you can use this attribute at the crate root level: + +```rust +#![doc(cfg_hide(doc))] +``` + +Or directly on a given item/module as it covers any of the item's descendants: + +```rust +#[doc(cfg_hide(doc))] +#[cfg(any(doc, feature = "futures-io"))] +pub mod futures { + // `futures` and all its descendants won't display "doc" in their cfgs. +} +``` + +Then, the `doc` cfg will never be displayed into the documentation. + +Rustdoc currently hides `doc` and `doctest` attributes by default and reserves the right to change the list of "hidden by default" attributes. + +The attribute accepts only a list of identifiers or key/value items. So you can write: + +```rust +#[doc(cfg_hide(doc, doctest, feature = "something"))] +#[doc(cfg_hide())] +``` + +But you cannot write: + +```rust +#[doc(cfg_hide(not(doc)))] +``` + +### `#[doc(cfg_show(...))]` + +This attribute does the opposite of `#[doc(cfg_hide(...))]`: if you used `#[doc(cfg_hide(...))]` and want to revert its effect on an item and its descendants, you can use `#[doc(cfg_show(...))]`: + +```rust +#[doc(cfg_hide(doc))] +#[cfg(any(doc, feature = "futures-io"))] +pub mod futures { + // `futures` and all its descendants won't display "doc" in their cfgs. + #[doc(cfg_show(doc))] + pub mod child { + // `child` and all its descendants will display "doc" in their cfgs. + } +} +``` + +The attribute accepts only a list of identifiers or key/value items. So you can write: + +```rust +#[doc(cfg_show(doc, doctest, feature = "something"))] +#[doc(cfg_show())] +``` + +But you cannot write: + +```rust +#[doc(cfg_show(not(doc)))] +``` + +## Inheritance + +Rustdoc merges `cfg` attributes from parent modules to its children. For example, in this case, the module `non_unix` will describe the entire compatibility matrix for the module, and not just its directly attached information: + +```rust +#[doc(cfg(any(windows, unix)))] +pub mod desktop { + #[doc(cfg(not(unix)))] + pub mod non_unix { + // + } +} +``` + +> ![Available on (Windows or Unix) and non-Unix only.](https://hackmd.io/_uploads/SJrmwYeF2.png) + +[Future versions of rustdoc][boolean simplification] may simplify this display down to "available on **Windows** only." + +### Re-exports and inlining + +`cfg` attributes of a re-export are never merged the re-exported item(s). If `#[doc(inline)]` attribute is used on a re-export, the `cfg` of the re-exported item will be merged with the re-export's. + +```rust +#[doc(cfg(any(windows, unix)))] +pub mod desktop { + #[doc(cfg(not(unix)))] + pub mod non_unix { + // + } +} + +#[doc(cfg(target_os = "freebsd"))] +pub use desktop::non_unix as non_unix_desktop; +#[doc(cfg(target_os = "macos"))] +#[doc(inline)] +pub use desktop::non_unix as inlined_non_unix_desktop; +``` + +In this example, `non_unix_desktop` will only display `cfg(target_os = "freeebsd")` and not display any `cfg` from `desktop::non_unix`. + +On the contrary, `inlined_non_unix_desktop` will have cfgs from both the re-export and the re-exported item. + +# Drawbacks +[drawbacks]: #drawbacks + +A potential drawback is that it adds more attributes, making documentation more complex. + + +# Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +## Why not merging cfg and doc(cfg) attributes by default? + +It was debated and implemented in [rust-lang/rust#113091](https://github.com/rust-lang/rust/pull/113091). + +When re-exporting items with different cfgs there are two things that can happen: + + 1. The re-export uses a subset of cfgs, this subset is sufficient so that the item will appear exactly with the subset + 2. The re-export uses a non-subset of cfgs like in this code: + ```rust + #![feature(doc_auto_cfg)] + + #[cfg(target_os = "linux")] + mod impl_ { + pub fn foo() { /* impl for linux */ } + } + + #[cfg(target_os = "macos")] + mod impl_ { + pub fn foo() { /* impl for darwin */ } + } + + pub use impl_::foo; + ``` + If the non-subset cfgs are active (e.g. compiling this example on windows), then this will be a compile error as the item doesn't exist to re-export. If the subset cfgs are active it behaves like described in 1. + + +# Unresolved questions +[unresolved-questions]: #unresolved-questions + + +# Future possibilities +[future possibilities]: #future-possibilities + +## Boolean simplification +[boolean simplification]: #boolean-simplification + +> ![Available on (Windows or Unix) and non-Unix only.](https://hackmd.io/_uploads/SJrmwYeF2.png) + +Of course, the above example is equivalent to "available on **Windows** only." + +Making this actually work all the time is equivalent to a [boolean satisfiability] check, coliquially called a "SAT problem," and can take exponential time. + +[boolean satisfiability]: https://en.wikipedia.org/wiki/Boolean_satisfiability_problem + +We probably don't want to make promises one way or the other about whether rustdoc does this, but for compatibility's sake, Rustdoc does promise that `#[doc(cfg(false))` will not hide the documentation. This means simplification can be added, and it won't cause docs to mysteriously vanish. + +This is tracked in issue [rust-lang/rust#104991](https://github.com/rust-lang/rust/issues/104991). From e5d1eeb4bcc16b31bcb0634835dbabef4a0db7a9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 13 May 2024 14:39:16 +0200 Subject: [PATCH 02/12] Apply first round of review comments --- text/000-rustdoc-cfgs-handling.md | 130 +++++++++++++++--------------- 1 file changed, 64 insertions(+), 66 deletions(-) diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md index 51f25e802d9..659ab3fb2d3 100644 --- a/text/000-rustdoc-cfgs-handling.md +++ b/text/000-rustdoc-cfgs-handling.md @@ -29,21 +29,21 @@ The end goal being to provide this information automatically so that the documen This RFC proposes to add the following attributes: + * `#![doc(auto_cfg(enable))]`/`#[doc(auto_cfg(disable))]` + + When this is turned on, `#[cfg]` attributes are shown in documentation just like `#[doc(cfg)]` attributes are. By default, `auto_cfg` will be enabled. + * `#[doc(cfg(...))]` This attribute is used to document the operating systems, feature flags, and build profiles where an item is available. For example, `#[doc(cfg(unix))` will add a tag that says "this is supported on **unix** only" to the item. The syntax of this attribute is the same as the syntax of the [`#[cfg(unix)]` attribute][cfg attribute] used for conditional compilation. - * `#[doc(auto_cfg)]`/`#[doc(no_auto_cfg)]` - - When this is turned on, `#[cfg]` attributes are shown in documentation just like `#[doc(cfg)]` attributes are. - - * `#[doc(cfg_hide(...))]` / `#[doc(cfg_show(...))]` + * `#![doc(cfg_hide(...))]` / `#[doc(cfg_show(...))]` These attributes suppress or un-suppress the `auto_cfg` behavior for a particular configuration predicate. - For example, `#[doc(cfg_hide(windows))]` shall be used in newer versions of the [`windows` crate] to prevent the "this is supported on **windows** only" tag from being shown on every single item. + For example, `#[doc(cfg_hide(windows))]` could be used in newer versions of the [`windows` crate] to prevent the "this is supported on **windows** only" tag from being shown on every single item. [cfg attribute]: https://doc.rust-lang.org/reference/conditional-compilation.html [`windows` crate]: https://docs.rs/windows/latest/windows/ @@ -56,116 +56,106 @@ All of these attributes can be added to a module or to the crate root, and they ## The attributes -### `#[doc(cfg(...))]` +### `#[doc(auto_cfg(enable))]`/`#[doc(auto_cfg(disable))]` -This attribute provides a standardized format to document conditionally available items. Example: +This is a crate-level attribute. By default, `#[doc(auto_cfg)]` is enabled at the crate-level. When it's enabled, Rustdoc will automatically display `cfg(...)` compatibility information as-if the same `#[doc(cfg(...))]` had been specified. + +So if we take back the previous example: ```rust -// the "real" cfg condition #[cfg(feature = "futures-io")] -// the `doc(cfg())` so it's displayed to the readers -#[doc(cfg(feature = "futures-io"))] pub mod futures {} ``` -It will display in the documentation for this module: - -![This is supported on feature="futures-io" only.](https://user-images.githubusercontent.com/81079/89731116-d7b7ce00-da44-11ea-87c6-022d192d6eca.png) - -This attribute has the same syntax as conditional compilation, but it only causes documentation to be added. This means `#[doc(cfg(false))` will not cause your docs to be hidden, even though `#[cfg(false)]` does do that. - -This attribute works on modules and on items but cannot be used at the crate root level. +There's no need to "duplicate" the `cfg` into a `doc(cfg())` to make Rustdoc display it. -### `#[doc(auto_cfg)]`/`#[doc(no_auto_cfg)]` +In some situations, the detailed conditional compilation rules used to implement the feature might not serve as good documentation (for example, the list of supported platforms might be very long, and it might be better to document them in one place). To turn it off, add the `#[doc(auto_cfg(disable))]` attribute at the crate-level. -By default, `#[doc(auto_cfg)]` is enabled at the crate-level. When it's enabled, Rustdoc will automatically display `cfg(...)` compatibility information as-if the same `#[doc(cfg(...))]` had been specified. +### `#[doc(cfg(...))]` -So if we take back the previous example: +This attribute provides a standardized format to override `#[cfg()]` attributes to document conditionally available items. Example: ```rust +// the "real" cfg condition #[cfg(feature = "futures-io")] +// the `doc(cfg())` so it's displayed to the readers +#[doc(cfg(feature = "futures-io"))] pub mod futures {} ``` -There's no need to "duplicate" the `cfg` into a `doc(cfg())` to make Rustdoc display it. +It will display in the documentation for this module: -In some situations, the detailed conditional compilation rules used to implement the feature might not serve as good documentation (for example, the list of supported platforms might be very long, and it might be better to document them in one place). To turn it off, add the `#[doc(no_auto_cfg)]` attribute. +![This is supported on feature="futures-io" only.](https://user-images.githubusercontent.com/81079/89731116-d7b7ce00-da44-11ea-87c6-022d192d6eca.png) -Both `#[doc(auto_cfg)]` and `#[doc(no_auto_cfg)]` attributes impact all there descendants. You can then enable/disable them by using the opposite attribute on a given item. They can be used as follows: +This attribute has the same syntax as conditional compilation, but it only causes documentation to be added. This means `#[doc(cfg(not(windows)))]` will not cause your docs to be hidden on non-windows targets, even though `#[cfg(not(windows))]` does do that. -```rust -// As an inner attribute, all this module's descendants will have this feature -// enabled. -#![doc(auto_cfg)] - -// As an outer attribute. So in this case, `foo` and all its -// descendants won't have the `auto_cfg` feature enabled. -#[doc(no_auto_cfg)] -pub mod foo { - // We re-enable the feature on `Bar` and on all its descendants. - #[doc(auto_cfg)] - pub struct Bar { - pub f: u32, - } -} -``` - -As mentioned, both attributes can be used on modules, items and crate root level. +This attribute works on modules and on items but cannot be used at the crate root level. ### `#[doc(cfg_hide(...))]` -This attribute is used to prevent some `cfg` to be generated in the visual markers. So in the previous example: +This attribute is used to prevent some `cfg` to be generated in the visual markers. It only applies to `#[doc(auto_cfg(enable))]`, not to `#[doc(cfg(...))]`. So in the previous example: ```rust -#[cfg(any(doc, feature = "futures-io"))] +#[cfg(any(unix, feature = "futures-io"))] pub mod futures {} ``` -It currently displays both `doc` and `feature = "futures-io"` into the documentation, which is not great. To prevent the `doc` cfg to ever be displayed, you can use this attribute at the crate root level: +It currently displays both `unix` and `feature = "futures-io"` into the documentation, which is not great. To prevent the `unix` cfg to ever be displayed, you can use this attribute at the crate root level: ```rust -#![doc(cfg_hide(doc))] +#![doc(cfg_hide(unix))] ``` Or directly on a given item/module as it covers any of the item's descendants: ```rust -#[doc(cfg_hide(doc))] -#[cfg(any(doc, feature = "futures-io"))] +#[doc(cfg_hide(unix))] +#[cfg(any(unix, feature = "futures-io"))] pub mod futures { - // `futures` and all its descendants won't display "doc" in their cfgs. + // `futures` and all its descendants won't display "unix" in their cfgs. } ``` -Then, the `doc` cfg will never be displayed into the documentation. +Then, the `unix` cfg will never be displayed into the documentation. Rustdoc currently hides `doc` and `doctest` attributes by default and reserves the right to change the list of "hidden by default" attributes. The attribute accepts only a list of identifiers or key/value items. So you can write: ```rust -#[doc(cfg_hide(doc, doctest, feature = "something"))] +#[doc(cfg_hide(unix, doctest, feature = "something"))] #[doc(cfg_hide())] ``` But you cannot write: ```rust -#[doc(cfg_hide(not(doc)))] +#[doc(cfg_hide(not(unix)))] +``` + +If `cfg_show` and `cfg_hide` are used to show/hide a same `cfg` on a same item, it'll emit an error. Example: + +```rust +#[doc(cfg_hide(unix))] +#[doc(cfg_show(unix))] // Error! +pub fn foo() {} ``` ### `#[doc(cfg_show(...))]` -This attribute does the opposite of `#[doc(cfg_hide(...))]`: if you used `#[doc(cfg_hide(...))]` and want to revert its effect on an item and its descendants, you can use `#[doc(cfg_show(...))]`: +This attribute does the opposite of `#[doc(cfg_hide(...))]`: if you used `#[doc(cfg_hide(...))]` and want to revert its effect on an item and its descendants, you can use `#[doc(cfg_show(...))]`. +It only applies to `#[doc(auto_cfg(enable))]`, not to `#[doc(cfg(...))]`. + +For example: ```rust -#[doc(cfg_hide(doc))] -#[cfg(any(doc, feature = "futures-io"))] +#[doc(cfg_hide(unix))] +#[cfg(any(unix, feature = "futures-io"))] pub mod futures { - // `futures` and all its descendants won't display "doc" in their cfgs. - #[doc(cfg_show(doc))] + // `futures` and all its descendants won't display "unix" in their cfgs. + #[doc(cfg_show(unix))] pub mod child { - // `child` and all its descendants will display "doc" in their cfgs. + // `child` and all its descendants will display "unix" in their cfgs. } } ``` @@ -173,14 +163,22 @@ pub mod futures { The attribute accepts only a list of identifiers or key/value items. So you can write: ```rust -#[doc(cfg_show(doc, doctest, feature = "something"))] +#[doc(cfg_show(unix, doctest, feature = "something"))] #[doc(cfg_show())] ``` But you cannot write: ```rust -#[doc(cfg_show(not(doc)))] +#[doc(cfg_show(not(unix)))] +``` + +If `cfg_show` and `cfg_hide` are used to show/hide a same `cfg` on a same item, it'll emit an error. Example: + +```rust +#[doc(cfg_hide(unix))] +#[doc(cfg_show(unix))] // Error! +pub fn foo() {} ``` ## Inheritance @@ -203,7 +201,11 @@ pub mod desktop { ### Re-exports and inlining -`cfg` attributes of a re-export are never merged the re-exported item(s). If `#[doc(inline)]` attribute is used on a re-export, the `cfg` of the re-exported item will be merged with the re-export's. +`cfg` attributes of a re-export are never merged with the re-exported item(s) attributes except if the re-export has the `#[doc(inline)]` attribute. In this case, the `cfg` of the re-exported item will be merged with the re-export's. + +When talking about "attributes merge", we mean that if the re-export has `#[cfg(unix)]` and the re-exported item has `#[cfg(feature = "foo")]`, you will only see `cfg(unix)` on the re-export and only `cfg(feature = "foo")` on the re-exported item, unless the re-export has `#[doc(inline)]`, then you will only see the re-exported item with both `cfg(unix)` and `cfg(feature = "foo")`. + +Example: ```rust #[doc(cfg(any(windows, unix)))] @@ -274,10 +276,6 @@ When re-exporting items with different cfgs there are two things that can happen Of course, the above example is equivalent to "available on **Windows** only." -Making this actually work all the time is equivalent to a [boolean satisfiability] check, coliquially called a "SAT problem," and can take exponential time. - -[boolean satisfiability]: https://en.wikipedia.org/wiki/Boolean_satisfiability_problem - -We probably don't want to make promises one way or the other about whether rustdoc does this, but for compatibility's sake, Rustdoc does promise that `#[doc(cfg(false))` will not hide the documentation. This means simplification can be added, and it won't cause docs to mysteriously vanish. +We probably don't want to make promises one way or the other about whether rustdoc does this, but for compatibility's sake, Rustdoc does promise that `#[doc(cfg(false))]` will not hide the documentation. This means simplification can be added, and it won't cause docs to mysteriously vanish. This is tracked in issue [rust-lang/rust#104991](https://github.com/rust-lang/rust/issues/104991). From 3978a1ceb24750424b91c265679b7b46043d42ba Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 13 May 2024 23:31:30 +0200 Subject: [PATCH 03/12] Add entry to "future possibilities" about making `doc(cfg_auto())` attribute not limited to crate-level --- text/000-rustdoc-cfgs-handling.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md index 659ab3fb2d3..803261f2f49 100644 --- a/text/000-rustdoc-cfgs-handling.md +++ b/text/000-rustdoc-cfgs-handling.md @@ -269,6 +269,8 @@ When re-exporting items with different cfgs there are two things that can happen # Future possibilities [future possibilities]: #future-possibilities +The `#[cfg(cfg_auto(enable))]`/`#[cfg(cfg_auto(disable))]` attribute is crate-level only for now as it doesn't really seem useful to be used on a specific item at the moment. However, if needed, this restriction could be lifted in the future if new needs come to appear. + ## Boolean simplification [boolean simplification]: #boolean-simplification From cae5f57cbc96797e9b0786680e3bf2384cf97589 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 21 May 2024 14:52:46 +0200 Subject: [PATCH 04/12] Improve auto_cfg attribute syntax and remove `doc(cfg())` restriction about not being able to be used at crate-level --- text/000-rustdoc-cfgs-handling.md | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md index 803261f2f49..ed3b5d91814 100644 --- a/text/000-rustdoc-cfgs-handling.md +++ b/text/000-rustdoc-cfgs-handling.md @@ -29,9 +29,9 @@ The end goal being to provide this information automatically so that the documen This RFC proposes to add the following attributes: - * `#![doc(auto_cfg(enable))]`/`#[doc(auto_cfg(disable))]` + * `#![doc(auto_cfg = true)]`/`#[doc(auto_cfg = false)]` - When this is turned on, `#[cfg]` attributes are shown in documentation just like `#[doc(cfg)]` attributes are. By default, `auto_cfg` will be enabled. + When this is turned on (with `doc(auto_cfg = true)`, `#[cfg]` attributes are shown in documentation just like `#[doc(cfg)]` attributes are. By default, `auto_cfg` will be enabled. * `#[doc(cfg(...))]` @@ -48,15 +48,14 @@ This RFC proposes to add the following attributes: [cfg attribute]: https://doc.rust-lang.org/reference/conditional-compilation.html [`windows` crate]: https://docs.rs/windows/latest/windows/ -All of these attributes can be added to a module or to the crate root, and they will be inherited by the child items unless another attribute overrides it (except that `doc(cfg)` cannot be added to the crate root). This is why "opposite" attributes like `cfg_hide` and `cfg_show` are provided: they allow a child item to override its parent. - +All of these attributes can be added to a module or to the crate root, and they will be inherited by the child items unless another attribute overrides it. This is why "opposite" attributes like `cfg_hide` and `cfg_show` are provided: they allow a child item to override its parent. # Reference-level explanation [reference-level-explanation]: #reference-level-explanation ## The attributes -### `#[doc(auto_cfg(enable))]`/`#[doc(auto_cfg(disable))]` +### `#[doc(auto_cfg = true)]`/`#[doc(auto_cfg = false)]` This is a crate-level attribute. By default, `#[doc(auto_cfg)]` is enabled at the crate-level. When it's enabled, Rustdoc will automatically display `cfg(...)` compatibility information as-if the same `#[doc(cfg(...))]` had been specified. @@ -89,11 +88,11 @@ It will display in the documentation for this module: This attribute has the same syntax as conditional compilation, but it only causes documentation to be added. This means `#[doc(cfg(not(windows)))]` will not cause your docs to be hidden on non-windows targets, even though `#[cfg(not(windows))]` does do that. -This attribute works on modules and on items but cannot be used at the crate root level. +This attribute works on modules and on items. ### `#[doc(cfg_hide(...))]` -This attribute is used to prevent some `cfg` to be generated in the visual markers. It only applies to `#[doc(auto_cfg(enable))]`, not to `#[doc(cfg(...))]`. So in the previous example: +This attribute is used to prevent some `cfg` to be generated in the visual markers. It only applies to `#[doc(auto_cfg = true)]`, not to `#[doc(cfg(...))]`. So in the previous example: ```rust #[cfg(any(unix, feature = "futures-io"))] @@ -144,7 +143,7 @@ pub fn foo() {} ### `#[doc(cfg_show(...))]` This attribute does the opposite of `#[doc(cfg_hide(...))]`: if you used `#[doc(cfg_hide(...))]` and want to revert its effect on an item and its descendants, you can use `#[doc(cfg_show(...))]`. -It only applies to `#[doc(auto_cfg(enable))]`, not to `#[doc(cfg(...))]`. +It only applies to `#[doc(auto_cfg = true)]`, not to `#[doc(cfg(...))]`. For example: @@ -269,7 +268,7 @@ When re-exporting items with different cfgs there are two things that can happen # Future possibilities [future possibilities]: #future-possibilities -The `#[cfg(cfg_auto(enable))]`/`#[cfg(cfg_auto(disable))]` attribute is crate-level only for now as it doesn't really seem useful to be used on a specific item at the moment. However, if needed, this restriction could be lifted in the future if new needs come to appear. +The `#[cfg(cfg_auto = true)]`/`#[cfg(cfg_auto = false)]` attribute is crate-level only for now as it doesn't really seem useful to be used on a specific item at the moment. However, if needed, this restriction could be lifted in the future if new needs come to appear. ## Boolean simplification [boolean simplification]: #boolean-simplification From 08f47cec2d37f4310ee07264e3eb053414bbb893 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 28 May 2024 21:25:05 +0200 Subject: [PATCH 05/12] Clarify `doc(cfg())` working without `cfg()` and lift `doc(auto_cfg)` crate-level only restriction --- text/000-rustdoc-cfgs-handling.md | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md index ed3b5d91814..a5080bcbfa2 100644 --- a/text/000-rustdoc-cfgs-handling.md +++ b/text/000-rustdoc-cfgs-handling.md @@ -37,7 +37,7 @@ This RFC proposes to add the following attributes: This attribute is used to document the operating systems, feature flags, and build profiles where an item is available. For example, `#[doc(cfg(unix))` will add a tag that says "this is supported on **unix** only" to the item. - The syntax of this attribute is the same as the syntax of the [`#[cfg(unix)]` attribute][cfg attribute] used for conditional compilation. + The syntax of this attribute is the same as the syntax of the [`#[cfg()]` attribute][cfg attribute] used for conditional compilation. * `#![doc(cfg_hide(...))]` / `#[doc(cfg_show(...))]` @@ -57,7 +57,9 @@ All of these attributes can be added to a module or to the crate root, and they ### `#[doc(auto_cfg = true)]`/`#[doc(auto_cfg = false)]` -This is a crate-level attribute. By default, `#[doc(auto_cfg)]` is enabled at the crate-level. When it's enabled, Rustdoc will automatically display `cfg(...)` compatibility information as-if the same `#[doc(cfg(...))]` had been specified. +By default, `#[doc(auto_cfg)]` is enabled at the crate-level. When it's enabled, Rustdoc will automatically display `cfg(...)` compatibility information as-if the same `#[doc(cfg(...))]` had been specified. + +This attribute impacts the item on which it is used and its descendants. So if we take back the previous example: @@ -68,7 +70,7 @@ pub mod futures {} There's no need to "duplicate" the `cfg` into a `doc(cfg())` to make Rustdoc display it. -In some situations, the detailed conditional compilation rules used to implement the feature might not serve as good documentation (for example, the list of supported platforms might be very long, and it might be better to document them in one place). To turn it off, add the `#[doc(auto_cfg(disable))]` attribute at the crate-level. +In some situations, the detailed conditional compilation rules used to implement the feature might not serve as good documentation (for example, the list of supported platforms might be very long, and it might be better to document them in one place). To turn it off, add the `#[doc(auto_cfg = false)]` attribute on the item. ### `#[doc(cfg(...))]` @@ -86,6 +88,15 @@ It will display in the documentation for this module: ![This is supported on feature="futures-io" only.](https://user-images.githubusercontent.com/81079/89731116-d7b7ce00-da44-11ea-87c6-022d192d6eca.png) +You can use it to display information in generated documentation, whether or not there is a `#[cfg()]` attribute: + +```rust +#[doc(cfg(feature = "futures-io"))] +pub mod futures {} +``` + +It will be displayed exactly the same as the previous code. + This attribute has the same syntax as conditional compilation, but it only causes documentation to be added. This means `#[doc(cfg(not(windows)))]` will not cause your docs to be hidden on non-windows targets, even though `#[cfg(not(windows))]` does do that. This attribute works on modules and on items. @@ -268,7 +279,6 @@ When re-exporting items with different cfgs there are two things that can happen # Future possibilities [future possibilities]: #future-possibilities -The `#[cfg(cfg_auto = true)]`/`#[cfg(cfg_auto = false)]` attribute is crate-level only for now as it doesn't really seem useful to be used on a specific item at the moment. However, if needed, this restriction could be lifted in the future if new needs come to appear. ## Boolean simplification [boolean simplification]: #boolean-simplification From 686c7e97220f6582782acf52c77f85f92a385e23 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 28 Jun 2024 16:38:24 +0200 Subject: [PATCH 06/12] Add some precisions for reexports --- text/000-rustdoc-cfgs-handling.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md index a5080bcbfa2..47fef1f40f0 100644 --- a/text/000-rustdoc-cfgs-handling.md +++ b/text/000-rustdoc-cfgs-handling.md @@ -222,7 +222,7 @@ Example: pub mod desktop { #[doc(cfg(not(unix)))] pub mod non_unix { - // + // code } } @@ -237,6 +237,19 @@ In this example, `non_unix_desktop` will only display `cfg(target_os = "freeebsd On the contrary, `inlined_non_unix_desktop` will have cfgs from both the re-export and the re-exported item. +So that also means that if a crate re-exports a foreign item, unless it has `#[doc(inline)]`, the `cfg` and `doc(cfg)` attributes will not be visible: + +```rust +// dep: +#[cfg(feature = "a")] +pub struct S; + +// crate using dep: + +// There will be no mention of `feature = "a"` in the documentation. +pub use dep::S as Y; +``` + # Drawbacks [drawbacks]: #drawbacks From d2ee5df12c4a606cf2f13353f9bc3bcb3dd94727 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 27 Nov 2024 17:23:11 +0100 Subject: [PATCH 07/12] Rename `cfg_hide` into `auto_cfg(hide(...))` and `cfg_show` into `auto_cfg(show(...))` --- text/000-rustdoc-cfgs-handling.md | 44 +++++++++++++++---------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md index 47fef1f40f0..0cf9cfc8a02 100644 --- a/text/000-rustdoc-cfgs-handling.md +++ b/text/000-rustdoc-cfgs-handling.md @@ -39,16 +39,16 @@ This RFC proposes to add the following attributes: The syntax of this attribute is the same as the syntax of the [`#[cfg()]` attribute][cfg attribute] used for conditional compilation. - * `#![doc(cfg_hide(...))]` / `#[doc(cfg_show(...))]` + * `#![doc(auto_cfg(hide(...)))]` / `#[doc(auto_cfg(show(...)))]` These attributes suppress or un-suppress the `auto_cfg` behavior for a particular configuration predicate. - For example, `#[doc(cfg_hide(windows))]` could be used in newer versions of the [`windows` crate] to prevent the "this is supported on **windows** only" tag from being shown on every single item. + For example, `#[doc(auto_cfg(hide(windows)))]` could be used in newer versions of the [`windows` crate] to prevent the "this is supported on **windows** only" tag from being shown on every single item. [cfg attribute]: https://doc.rust-lang.org/reference/conditional-compilation.html [`windows` crate]: https://docs.rs/windows/latest/windows/ -All of these attributes can be added to a module or to the crate root, and they will be inherited by the child items unless another attribute overrides it. This is why "opposite" attributes like `cfg_hide` and `cfg_show` are provided: they allow a child item to override its parent. +All of these attributes can be added to a module or to the crate root, and they will be inherited by the child items unless another attribute overrides it. This is why "opposite" attributes like `auto_cfg(hide(...))` and `auto_cfg(show(...))` are provided: they allow a child item to override its parent. # Reference-level explanation [reference-level-explanation]: #reference-level-explanation @@ -101,7 +101,7 @@ This attribute has the same syntax as conditional compilation, but it only cause This attribute works on modules and on items. -### `#[doc(cfg_hide(...))]` +### `#[doc(auto_cfg(hide(...)))]` This attribute is used to prevent some `cfg` to be generated in the visual markers. It only applies to `#[doc(auto_cfg = true)]`, not to `#[doc(cfg(...))]`. So in the previous example: @@ -113,13 +113,13 @@ pub mod futures {} It currently displays both `unix` and `feature = "futures-io"` into the documentation, which is not great. To prevent the `unix` cfg to ever be displayed, you can use this attribute at the crate root level: ```rust -#![doc(cfg_hide(unix))] +#![doc(auto_cfg(hide(unix)))] ``` Or directly on a given item/module as it covers any of the item's descendants: ```rust -#[doc(cfg_hide(unix))] +#[doc(auto_cfg(hide(unix)))] #[cfg(any(unix, feature = "futures-io"))] pub mod futures { // `futures` and all its descendants won't display "unix" in their cfgs. @@ -133,37 +133,37 @@ Rustdoc currently hides `doc` and `doctest` attributes by default and reserves t The attribute accepts only a list of identifiers or key/value items. So you can write: ```rust -#[doc(cfg_hide(unix, doctest, feature = "something"))] -#[doc(cfg_hide())] +#[doc(auto_cfg(hide(unix, doctest, feature = "something")))] +#[doc(auto_cfg(hide()))] ``` But you cannot write: ```rust -#[doc(cfg_hide(not(unix)))] +#[doc(auto_cfg(hide(not(unix))))] ``` -If `cfg_show` and `cfg_hide` are used to show/hide a same `cfg` on a same item, it'll emit an error. Example: +If `cfg_auto(show(...))` and `cfg_auto(hide(...))` are used to show/hide a same `cfg` on a same item, it'll emit an error. Example: ```rust -#[doc(cfg_hide(unix))] -#[doc(cfg_show(unix))] // Error! +#[doc(auto_cfg(hide(unix)))] +#[doc(auto_cfg(show(unix)))] // Error! pub fn foo() {} ``` -### `#[doc(cfg_show(...))]` +### `#[doc(auto_cfg(show(...)))]` -This attribute does the opposite of `#[doc(cfg_hide(...))]`: if you used `#[doc(cfg_hide(...))]` and want to revert its effect on an item and its descendants, you can use `#[doc(cfg_show(...))]`. +This attribute does the opposite of `#[doc(auto_cfg(hide(...)))]`: if you used `#[doc(auto_cfg(hide(...)))]` and want to revert its effect on an item and its descendants, you can use `#[doc(auto_cfg(show(...)))]`. It only applies to `#[doc(auto_cfg = true)]`, not to `#[doc(cfg(...))]`. For example: ```rust -#[doc(cfg_hide(unix))] +#[doc(auto_cfg(hide(unix)))] #[cfg(any(unix, feature = "futures-io"))] pub mod futures { // `futures` and all its descendants won't display "unix" in their cfgs. - #[doc(cfg_show(unix))] + #[doc(auto_cfg(show(unix)))] pub mod child { // `child` and all its descendants will display "unix" in their cfgs. } @@ -173,21 +173,21 @@ pub mod futures { The attribute accepts only a list of identifiers or key/value items. So you can write: ```rust -#[doc(cfg_show(unix, doctest, feature = "something"))] -#[doc(cfg_show())] +#[doc(auto_cfg(show(unix, doctest, feature = "something")))] +#[doc(auto_cfg(show()))] ``` But you cannot write: ```rust -#[doc(cfg_show(not(unix)))] +#[doc(auto_cfg(show(not(unix))))] ``` -If `cfg_show` and `cfg_hide` are used to show/hide a same `cfg` on a same item, it'll emit an error. Example: +If `auto_cfg(show(...))` and `auto_cfg(hide(...))` are used to show/hide a same `cfg` on a same item, it'll emit an error. Example: ```rust -#[doc(cfg_hide(unix))] -#[doc(cfg_show(unix))] // Error! +#[doc(auto_cfg(hide(unix)))] +#[doc(auto_cfg(show(unix)))] // Error! pub fn foo() {} ``` From aad1fbd7c1378025f2f73f6f8fa4d8a76c47453e Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 27 Nov 2024 17:32:49 +0100 Subject: [PATCH 08/12] Add some explanations on `cfg`ed out items --- text/000-rustdoc-cfgs-handling.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md index 0cf9cfc8a02..349e071b041 100644 --- a/text/000-rustdoc-cfgs-handling.md +++ b/text/000-rustdoc-cfgs-handling.md @@ -13,7 +13,7 @@ This RFC aims at providing rustdoc users the possibility to add visual markers t It does not aim to allow having a same item with different `cfg`s to appear more than once in the generated documentation. -It does not aim to document items which are *inactive* under the current configuration (i.e., “`cfg`'ed out”). +It does not aim to document items which are *inactive* under the current configuration (i.e., “`cfg`ed out”). More details in the [Unresolved questions section](#unresolved-questions). # Motivation [motivation]: #motivation @@ -288,6 +288,25 @@ When re-exporting items with different cfgs there are two things that can happen # Unresolved questions [unresolved-questions]: #unresolved-questions +## `cfg`ed out items + +Rustdoc doesn't take into account `cfg`ed out items. The reason for this limitation is that Rustdoc has only access to rustc's information: `cfg`ed out items, although still present, don't have enough information to be useful to rustdoc when generating documentation, hence why they are not treated. + +So for the following crate, `function` wouldn't show up in the generated docs unless you actually passed `--cfg special` to Rustdoc: + +```rust +#[cfg(special)] +pub fn function() {} +``` + +Therefore, the common and offical workaround is the use of the semi-special cfg `doc`: + +```rust +#[cfg(any(doc, special))] +pub fn function() {} +``` + +There are a few leads on how Rustdoc could solve this issue, but they all come with big drawbacks, so this problem is not addressed in this RFC but will (hopefully) be in the future. # Future possibilities [future possibilities]: #future-possibilities From 4746afc08240aa7347f1e280d364de865ec56b65 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 28 Nov 2024 00:41:07 +0100 Subject: [PATCH 09/12] Allow auto_cfg to take no argument and also make `hide` and `show` to re-enable `auto_cfg` if it was disabled --- text/000-rustdoc-cfgs-handling.md | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md index 349e071b041..aa441962c14 100644 --- a/text/000-rustdoc-cfgs-handling.md +++ b/text/000-rustdoc-cfgs-handling.md @@ -29,9 +29,9 @@ The end goal being to provide this information automatically so that the documen This RFC proposes to add the following attributes: - * `#![doc(auto_cfg = true)]`/`#[doc(auto_cfg = false)]` + * `#[doc(auto_cfg)]`/`#[doc(auto_cfg = true)]`/`#[doc(auto_cfg = false)]` - When this is turned on (with `doc(auto_cfg = true)`, `#[cfg]` attributes are shown in documentation just like `#[doc(cfg)]` attributes are. By default, `auto_cfg` will be enabled. + When this is turned on (with `doc(auto_cfg)` or `doc(auto_cfg = true)`), `#[cfg]` attributes are shown in documentation just like `#[doc(cfg)]` attributes are. By default, `auto_cfg` will be enabled. * `#[doc(cfg(...))]` @@ -43,7 +43,7 @@ This RFC proposes to add the following attributes: These attributes suppress or un-suppress the `auto_cfg` behavior for a particular configuration predicate. - For example, `#[doc(auto_cfg(hide(windows)))]` could be used in newer versions of the [`windows` crate] to prevent the "this is supported on **windows** only" tag from being shown on every single item. + For example, `#[doc(auto_cfg(hide(windows)))]` could be used in newer versions of the [`windows` crate] to prevent the "this is supported on **windows** only" tag from being shown on every single item. Using these attributes will also re-enable `doc(auto_cfg)` if it was disabled at this location. [cfg attribute]: https://doc.rust-lang.org/reference/conditional-compilation.html [`windows` crate]: https://docs.rs/windows/latest/windows/ @@ -55,7 +55,7 @@ All of these attributes can be added to a module or to the crate root, and they ## The attributes -### `#[doc(auto_cfg = true)]`/`#[doc(auto_cfg = false)]` +### `#[doc(auto_cfg)`/`#[doc(auto_cfg = true)]`/`#[doc(auto_cfg = false)]` By default, `#[doc(auto_cfg)]` is enabled at the crate-level. When it's enabled, Rustdoc will automatically display `cfg(...)` compatibility information as-if the same `#[doc(cfg(...))]` had been specified. @@ -72,6 +72,8 @@ There's no need to "duplicate" the `cfg` into a `doc(cfg())` to make Rustdoc dis In some situations, the detailed conditional compilation rules used to implement the feature might not serve as good documentation (for example, the list of supported platforms might be very long, and it might be better to document them in one place). To turn it off, add the `#[doc(auto_cfg = false)]` attribute on the item. +If no argument is specified (ie `#[doc(auto_cfg)]`), it's the same as writing `#[doc(auto_cfg = true)]`. + ### `#[doc(cfg(...))]` This attribute provides a standardized format to override `#[cfg()]` attributes to document conditionally available items. Example: @@ -151,6 +153,14 @@ If `cfg_auto(show(...))` and `cfg_auto(hide(...))` are used to show/hide a same pub fn foo() {} ``` +Using this attribute will re-enable `auto_cfg` if it was disabled at this location: + +```rust +#[doc(auto_cfg = false)] // Disabling `auto_cfg` +#[doc(auto_cfg(hide(unix)))] // `auto_cfg` is re-enabled. +pub fn foo() {} +``` + ### `#[doc(auto_cfg(show(...)))]` This attribute does the opposite of `#[doc(auto_cfg(hide(...)))]`: if you used `#[doc(auto_cfg(hide(...)))]` and want to revert its effect on an item and its descendants, you can use `#[doc(auto_cfg(show(...)))]`. @@ -186,8 +196,16 @@ But you cannot write: If `auto_cfg(show(...))` and `auto_cfg(hide(...))` are used to show/hide a same `cfg` on a same item, it'll emit an error. Example: ```rust -#[doc(auto_cfg(hide(unix)))] -#[doc(auto_cfg(show(unix)))] // Error! +#[doc(auto_cfg(show(unix)))] +#[doc(auto_cfg(hide(unix)))] // Error! +pub fn foo() {} +``` + +Using this attribute will re-enable `auto_cfg` if it was disabled at this location: + +```rust +#[doc(auto_cfg = false)] // Disabling `auto_cfg` +#[doc(auto_cfg(show(unix)))] // `auto_cfg` is re-enabled. pub fn foo() {} ``` From 8187fe0ed8d6292b7e3b45476a37998e71ffdb47 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 13 Jan 2025 00:18:01 +0100 Subject: [PATCH 10/12] Explain how `doc(cfg)` and `doc(auto_cfg)` interacts --- text/000-rustdoc-cfgs-handling.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md index aa441962c14..8e6dcb264aa 100644 --- a/text/000-rustdoc-cfgs-handling.md +++ b/text/000-rustdoc-cfgs-handling.md @@ -101,6 +101,8 @@ It will be displayed exactly the same as the previous code. This attribute has the same syntax as conditional compilation, but it only causes documentation to be added. This means `#[doc(cfg(not(windows)))]` will not cause your docs to be hidden on non-windows targets, even though `#[cfg(not(windows))]` does do that. +If `doc(auto_cfg)` is enabled on the item, `doc(cfg)` will override it anyway so in the two previous examples, even if the `doc(auto_cfg)` feature was enabled, it would still display the same thing. + This attribute works on modules and on items. ### `#[doc(auto_cfg(hide(...)))]` From a295af1c7868db32eb93c179700a145dab400cfc Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 13 Jan 2025 00:35:56 +0100 Subject: [PATCH 11/12] Clarify how `doc(auto_cfg(hide())` works --- text/000-rustdoc-cfgs-handling.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md index 8e6dcb264aa..f70a217152b 100644 --- a/text/000-rustdoc-cfgs-handling.md +++ b/text/000-rustdoc-cfgs-handling.md @@ -147,6 +147,20 @@ But you cannot write: #[doc(auto_cfg(hide(not(unix))))] ``` +So if we use `doc(auto_cfg(hide(unix)))`, it means it will hide all mentions of `unix`: + +```rust +#[cfg(unix)] // nothing displayed +#[cfg(any(unix))] // nothing displayed +#[cfg(any(unix, windows))] // only `windows` displayed +``` + +However, it only impacts the `unix` cfg, not the feature: + +```rust +#[cfg(feature = "unix")] // `feature = "unix"` is displayed +``` + If `cfg_auto(show(...))` and `cfg_auto(hide(...))` are used to show/hide a same `cfg` on a same item, it'll emit an error. Example: ```rust From e5338b6c142b56a790727b4c3cd846fc75837b25 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 18 Jan 2025 15:56:22 +0100 Subject: [PATCH 12/12] Change behaviour in case `doc(auto_cfg = ...)` and `doc(auto_cfg(...))` are used on the same attribute --- text/000-rustdoc-cfgs-handling.md | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/text/000-rustdoc-cfgs-handling.md b/text/000-rustdoc-cfgs-handling.md index f70a217152b..728393e96e8 100644 --- a/text/000-rustdoc-cfgs-handling.md +++ b/text/000-rustdoc-cfgs-handling.md @@ -173,10 +173,29 @@ Using this attribute will re-enable `auto_cfg` if it was disabled at this locati ```rust #[doc(auto_cfg = false)] // Disabling `auto_cfg` -#[doc(auto_cfg(hide(unix)))] // `auto_cfg` is re-enabled. pub fn foo() {} ``` +And using `doc(auto_cfg)` will re-enable it: + +```rust +#[doc(auto_cfg = false)] // Disabling `auto_cfg` +pub mod module { + #[doc(auto_cfg(hide(unix)))] // `auto_cfg` is re-enabled. + pub fn foo() {} +} +``` + +However, using `doc(auto_cfg = ...)` and `doc(auto_cfg(...))` on the same item will emit an error: + +```rust +#[doc(auto_cfg = false)] +#[doc(auto_cfg(hide(unix)))] // error +pub fn foo() {} +``` + +The reason behind this is that `doc(auto_cfg = ...)` enables or disables the feature, whereas `doc(auto_cfg(...))` enables it unconditionally, making the first attribute to appear useless as it will be overidden by the next `doc(auto_cfg)` attribute. + ### `#[doc(auto_cfg(show(...)))]` This attribute does the opposite of `#[doc(auto_cfg(hide(...)))]`: if you used `#[doc(auto_cfg(hide(...)))]` and want to revert its effect on an item and its descendants, you can use `#[doc(auto_cfg(show(...)))]`.