@@ -33,6 +33,204 @@ pub struct UnixToken;
3333Here, the respective tokens can only be used by dependent crates on their respective platforms, but
3434they will both appear in documentation.
3535
36+ ## Recording what platforms or features are required for code to be present
37+
38+ By default, rustdoc will pick the ` cfg ` attributes present on each item and render them in the
39+ generated documentation. However, if you want to tweak or completely overload this behaviour, it's
40+ possible with the ` #[doc(auto_cfg)] ` and ` #[doc(cfg(...)] ` attributes.
41+
42+ ### ` #[doc(auto_cfg)] `
43+
44+ This attribute can have the following forms:
45+
46+ * ` #[doc(auto_cfg)] `
47+ * ` #[doc(auto_cfg = ...)] `
48+ * ` #[doc(auto_cfg(show(...)))] `
49+ * ` #[doc(auto_cfg(hide(...)))] `
50+
51+ ` #[doc(auto_cfg)] ` enables the feature and is the shorter form of ` #[doc(auto_cfg = true)] ` .
52+ Enabling the feature means that the ` cfg ` attributes will be picked automatically by rustdoc. To be
53+ noted: using any form of ` #[doc(auto_cfg)] ` will (re-)enable the feature.
54+
55+ If you want to disable it, you can use ` #[doc(auto_cfg = false)] ` .
56+
57+ The state of the feature (whether it's enabled or disabled) is inherited by the item's children. So
58+ if you disable the feature on module, non of the module items will get their ` cfg ` picked
59+ automatically, unless you re-enable the feature on the items.
60+
61+ Now about ` #[doc(auto_cfg(show(...)))] ` and ` #[doc(auto_cfg(hide(...)))] ` , they allow you to
62+ show/hide ` cfg ` s you don't want to appear in the documentation. By default, rustdoc hides the
63+ following ` cfg ` attributes: ` test ` , ` doc ` and ` doctest ` .
64+
65+ You can use it as follows:
66+
67+ ``` rust
68+ #[doc(auto_cfg(hide(unix)))]
69+ #[cfg(any(unix, feature = " futures-io" ))]
70+ pub mod futures {
71+ // `futures` and all its descendants won't display "unix" in their cfgs.
72+ }
73+ ```
74+
75+ And if you want to revert the hidden attributes, you can use ` doc(auto_cfg(show(...))) ` :
76+
77+ ``` rust
78+ #[doc(auto_cfg(hide(unix)))]
79+ #[cfg(any(unix, feature = " futures-io" ))]
80+ pub mod futures {
81+ // `futures` and all its descendants won't display "unix" in their cfgs.
82+ #[doc(auto_cfg(show(unix)))]
83+ #[cfg(unix)] // It will be displayed for `bar`.
84+ pub fn bar () {}
85+
86+ #[cfg(unix)] // It will not be displayed for `bar`.
87+ pub fn foo () {}
88+ }
89+ ```
90+
91+ The attribute accepts only a list of identifiers or key/value items. So you can write:
92+
93+ ``` rust
94+ #[doc(auto_cfg(hide(unix, doctest, feature = " something" )))]
95+ #[doc(auto_cfg(hide()))]
96+ ```
97+
98+ But you cannot write:
99+
100+ ``` rust
101+ #[doc(auto_cfg(hide(not(unix))))]
102+ ```
103+
104+ So if we use ` doc(auto_cfg(hide(unix))) ` , it means it will hide all mentions of ` unix ` :
105+
106+ ``` rust
107+ #[cfg(unix)] // nothing displayed
108+ #[cfg(any(unix))] // nothing displayed
109+ #[cfg(any(unix, windows))] // only `windows` displayed
110+ ```
111+
112+ However, it only impacts the ` unix ` cfg, not the feature:
113+
114+ ``` rust
115+ #[cfg(feature = " unix" )] // `feature = "unix"` is displayed
116+ ```
117+
118+ If ` cfg_auto(show(...)) ` and ` cfg_auto(hide(...)) ` are used to show/hide a same cfg on a same item,
119+ it'll emit an error. Example:
120+
121+ ``` rust
122+ #[doc(auto_cfg(hide(unix)))]
123+ #[doc(auto_cfg(show(unix)))] // Error!
124+ pub fn foo () {}
125+ ```
126+
127+ ### ` #[doc(cfg(...))] `
128+
129+ This attribute provides a standardized format to override ` #[cfg()] ` attributes to document
130+ conditionally available items. Example:
131+
132+ ``` rust
133+ // the "real" cfg condition
134+ #[cfg(feature = " futures-io" )]
135+ // the `doc(cfg())` so it's displayed to the readers
136+ #[doc(cfg(feature = " futures-io" ))]
137+ pub mod futures {}
138+ ```
139+
140+ It will display in the documentation for this module:
141+
142+ ``` text
143+ This is supported on feature="futures-io" only.
144+ ```
145+
146+ You can use it to display information in generated documentation, whether or not there is a
147+ ` #[cfg()] ` attribute:
148+
149+ ``` rust
150+ #[doc(cfg(feature = " futures-io" ))]
151+ pub mod futures {}
152+ ```
153+
154+ It will be displayed exactly the same as the previous code.
155+
156+ This attribute has the same syntax as conditional compilation, but it only causes documentation to
157+ be added. This means ` #[doc(cfg(not(windows)))] ` will not cause your docs to be hidden on
158+ non-windows targets, even though ` #[cfg(not(windows))] ` does do that.
159+
160+ If ` doc(auto_cfg) ` is enabled on the item, ` doc(cfg) ` will override it anyway so in the two previous
161+ examples, even if the ` doc(auto_cfg) ` feature was enabled, it would still display the same thing.
162+
163+ ### (doc) cfg inheritance
164+
165+ Rustdoc merges ` cfg ` attributes from parent modules to its children. For example, in this case, the
166+ module ` non_unix ` will describe the entire compatibility matrix for the module, and not just its
167+ directly attached information:
168+
169+ ``` rust
170+ #[doc(cfg(any(windows, unix)))]
171+ pub mod desktop {
172+ #[doc(cfg(not(unix)))]
173+ pub mod non_unix {
174+ //
175+ }
176+ }
177+ ```
178+
179+ will display:
180+
181+ ```
182+ Available on (Windows or Unix) and non-Unix only.
183+ ```
184+
185+ ### Re-exports and inlining
186+
187+ ` cfg ` attributes of a re-export are never merged with the re-exported item(s) attributes except if
188+ the re-export has the ` #[doc(inline)] ` attribute. In this case, the ` cfg ` of the re-exported item
189+ will be merged with the re-export's.
190+
191+ When talking about "attributes merge", we mean that if the re-export has ` #[cfg(unix)] ` and the
192+ re-exported item has ` #[cfg(feature = "foo")] ` , you will only see ` cfg(unix) ` on the re-export and
193+ only ` cfg(feature = "foo") ` on the re-exported item, unless the re-export has ` #[doc(inline)] ` , then
194+ you will only see the re-exported item with both ` cfg(unix) ` and ` cfg(feature = "foo") ` .
195+
196+ Example:
197+
198+ ``` rust
199+ #[doc(cfg(any(windows, unix)))]
200+ pub mod desktop {
201+ #[doc(cfg(not(unix)))]
202+ pub mod non_unix {
203+ // code
204+ }
205+ }
206+
207+ #[doc(cfg(target_os = " freebsd" ))]
208+ pub use desktop :: non_unix as non_unix_desktop;
209+ #[doc(cfg(target_os = " macos" ))]
210+ #[doc(inline)]
211+ pub use desktop :: non_unix as inlined_non_unix_desktop;
212+ ```
213+
214+ In this example, ` non_unix_desktop ` will only display ` cfg(target_os = "freeebsd") ` and not display
215+ any ` cfg ` from ` desktop::non_unix ` .
216+
217+ On the contrary, ` inlined_non_unix_desktop ` will have cfgs from both the re-export and the
218+ re-exported item.
219+
220+ So that also means that if a crate re-exports a foreign item, unless it has ` #[doc(inline)] ` , the
221+ ` cfg ` and ` doc(cfg) ` attributes will not be visible:
222+
223+ ``` rust
224+ // dep:
225+ #[cfg(feature = " a" )]
226+ pub struct S ;
227+
228+ // crate using dep:
229+
230+ // There will be no mention of `feature = "a"` in the documentation.
231+ pub use dep :: S as Y ;
232+ ```
233+
36234### Interactions between platform-specific docs
37235
38236Rustdoc does not have a magic way to compile documentation 'as-if' you'd run it once for each
0 commit comments