@@ -33,6 +33,204 @@ pub struct UnixToken;
33
33
Here, the respective tokens can only be used by dependent crates on their respective platforms, but
34
34
they will both appear in documentation.
35
35
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
+
36
234
### Interactions between platform-specific docs
37
235
38
236
Rustdoc does not have a magic way to compile documentation 'as-if' you'd run it once for each
0 commit comments