]> git.proxmox.com Git - rustc.git/blob - src/doc/reference/src/attributes/diagnostics.md
New upstream version 1.66.0+dfsg1
[rustc.git] / src / doc / reference / src / attributes / diagnostics.md
1 # Diagnostic attributes
2
3 The following [attributes] are used for controlling or generating diagnostic
4 messages during compilation.
5
6 ## Lint check attributes
7
8 A lint check names a potentially undesirable coding pattern, such as
9 unreachable code or omitted documentation. The lint attributes `allow`,
10 `warn`, `deny`, and `forbid` use the [_MetaListPaths_] syntax to specify a
11 list of lint names to change the lint level for the entity to which the
12 attribute applies.
13
14 For any lint check `C`:
15
16 * `allow(C)` overrides the check for `C` so that violations will go
17 unreported,
18 * `warn(C)` warns about violations of `C` but continues compilation.
19 * `deny(C)` signals an error after encountering a violation of `C`,
20 * `forbid(C)` is the same as `deny(C)`, but also forbids changing the lint
21 level afterwards,
22
23 > Note: The lint checks supported by `rustc` can be found via `rustc -W help`,
24 > along with their default settings and are documented in the [rustc book].
25
26 ```rust
27 pub mod m1 {
28 // Missing documentation is ignored here
29 #[allow(missing_docs)]
30 pub fn undocumented_one() -> i32 { 1 }
31
32 // Missing documentation signals a warning here
33 #[warn(missing_docs)]
34 pub fn undocumented_too() -> i32 { 2 }
35
36 // Missing documentation signals an error here
37 #[deny(missing_docs)]
38 pub fn undocumented_end() -> i32 { 3 }
39 }
40 ```
41
42 Lint attributes can override the level specified from a previous attribute, as
43 long as the level does not attempt to change a forbidden lint. Previous
44 attributes are those from a higher level in the syntax tree, or from a
45 previous attribute on the same entity as listed in left-to-right source order.
46
47 This example shows how one can use `allow` and `warn` to toggle a particular
48 check on and off:
49
50 ```rust
51 #[warn(missing_docs)]
52 pub mod m2{
53 #[allow(missing_docs)]
54 pub mod nested {
55 // Missing documentation is ignored here
56 pub fn undocumented_one() -> i32 { 1 }
57
58 // Missing documentation signals a warning here,
59 // despite the allow above.
60 #[warn(missing_docs)]
61 pub fn undocumented_two() -> i32 { 2 }
62 }
63
64 // Missing documentation signals a warning here
65 pub fn undocumented_too() -> i32 { 3 }
66 }
67 ```
68
69 This example shows how one can use `forbid` to disallow uses of `allow` for
70 that lint check:
71
72 ```rust,compile_fail
73 #[forbid(missing_docs)]
74 pub mod m3 {
75 // Attempting to toggle warning signals an error here
76 #[allow(missing_docs)]
77 /// Returns 2.
78 pub fn undocumented_too() -> i32 { 2 }
79 }
80 ```
81
82 > Note: `rustc` allows setting lint levels on the
83 > [command-line][rustc-lint-cli], and also supports [setting
84 > caps][rustc-lint-caps] on the lints that are reported.
85
86 ### Lint groups
87
88 Lints may be organized into named groups so that the level of related lints
89 can be adjusted together. Using a named group is equivalent to listing out the
90 lints within that group.
91
92 ```rust,compile_fail
93 // This allows all lints in the "unused" group.
94 #[allow(unused)]
95 // This overrides the "unused_must_use" lint from the "unused"
96 // group to deny.
97 #[deny(unused_must_use)]
98 fn example() {
99 // This does not generate a warning because the "unused_variables"
100 // lint is in the "unused" group.
101 let x = 1;
102 // This generates an error because the result is unused and
103 // "unused_must_use" is marked as "deny".
104 std::fs::remove_file("some_file"); // ERROR: unused `Result` that must be used
105 }
106 ```
107
108 There is a special group named "warnings" which includes all lints at the
109 "warn" level. The "warnings" group ignores attribute order and applies to all
110 lints that would otherwise warn within the entity.
111
112 ```rust,compile_fail
113 # unsafe fn an_unsafe_fn() {}
114 // The order of these two attributes does not matter.
115 #[deny(warnings)]
116 // The unsafe_code lint is normally "allow" by default.
117 #[warn(unsafe_code)]
118 fn example_err() {
119 // This is an error because the `unsafe_code` warning has
120 // been lifted to "deny".
121 unsafe { an_unsafe_fn() } // ERROR: usage of `unsafe` block
122 }
123 ```
124
125 ### Tool lint attributes
126
127 Tool lints allows using scoped lints, to `allow`, `warn`, `deny` or `forbid`
128 lints of certain tools.
129
130 Tool lints only get checked when the associated tool is active. If a lint
131 attribute, such as `allow`, references a nonexistent tool lint, the compiler
132 will not warn about the nonexistent lint until you use the tool.
133
134 Otherwise, they work just like regular lint attributes:
135
136 ```rust
137 // set the entire `pedantic` clippy lint group to warn
138 #![warn(clippy::pedantic)]
139 // silence warnings from the `filter_map` clippy lint
140 #![allow(clippy::filter_map)]
141
142 fn main() {
143 // ...
144 }
145
146 // silence the `cmp_nan` clippy lint just for this function
147 #[allow(clippy::cmp_nan)]
148 fn foo() {
149 // ...
150 }
151 ```
152
153 > Note: `rustc` currently recognizes the tool lints for "[clippy]" and "[rustdoc]".
154
155 ## The `deprecated` attribute
156
157 The *`deprecated` attribute* marks an item as deprecated. `rustc` will issue
158 warnings on usage of `#[deprecated]` items. `rustdoc` will show item
159 deprecation, including the `since` version and `note`, if available.
160
161 The `deprecated` attribute has several forms:
162
163 - `deprecated` — Issues a generic message.
164 - `deprecated = "message"` — Includes the given string in the deprecation
165 message.
166 - [_MetaListNameValueStr_] syntax with two optional fields:
167 - `since` — Specifies a version number when the item was deprecated. `rustc`
168 does not currently interpret the string, but external tools like [Clippy]
169 may check the validity of the value.
170 - `note` — Specifies a string that should be included in the deprecation
171 message. This is typically used to provide an explanation about the
172 deprecation and preferred alternatives.
173
174 The `deprecated` attribute may be applied to any [item], [trait item], [enum
175 variant], [struct field], [external block item], or [macro definition]. It
176 cannot be applied to [trait implementation items]. When applied to an item
177 containing other items, such as a [module] or [implementation], all child
178 items inherit the deprecation attribute.
179 <!-- NOTE: It is only rejected for trait impl items
180 (AnnotationKind::Prohibited). In all other locations, it is silently ignored.
181 Tuple struct fields are ignored.
182 -->
183
184 Here is an example:
185
186 ```rust
187 #[deprecated(since = "5.2.0", note = "foo was rarely used. Users should instead use bar")]
188 pub fn foo() {}
189
190 pub fn bar() {}
191 ```
192
193 The [RFC][1270-deprecation.md] contains motivations and more details.
194
195 [1270-deprecation.md]: https://github.com/rust-lang/rfcs/blob/master/text/1270-deprecation.md
196
197 ## The `must_use` attribute
198
199 The *`must_use` attribute* is used to issue a diagnostic warning when a value
200 is not "used". It can be applied to user-defined composite types
201 ([`struct`s][struct], [`enum`s][enum], and [`union`s][union]), [functions],
202 and [traits].
203
204 The `must_use` attribute may include a message by using the
205 [_MetaNameValueStr_] syntax such as `#[must_use = "example message"]`. The
206 message will be given alongside the warning.
207
208 When used on user-defined composite types, if the [expression] of an
209 [expression statement] has that type, then the `unused_must_use` lint is
210 violated.
211
212 ```rust
213 #[must_use]
214 struct MustUse {
215 // some fields
216 }
217
218 # impl MustUse {
219 # fn new() -> MustUse { MustUse {} }
220 # }
221 #
222 // Violates the `unused_must_use` lint.
223 MustUse::new();
224 ```
225
226 When used on a function, if the [expression] of an [expression statement] is a
227 [call expression] to that function, then the `unused_must_use` lint is
228 violated.
229
230 ```rust
231 #[must_use]
232 fn five() -> i32 { 5i32 }
233
234 // Violates the unused_must_use lint.
235 five();
236 ```
237
238 When used on a [trait declaration], a [call expression] of an [expression
239 statement] to a function that returns an [impl trait] or a [dyn trait] of that trait violates
240 the `unused_must_use` lint.
241
242 ```rust
243 #[must_use]
244 trait Critical {}
245 impl Critical for i32 {}
246
247 fn get_critical() -> impl Critical {
248 4i32
249 }
250
251 // Violates the `unused_must_use` lint.
252 get_critical();
253 ```
254
255 When used on a function in a trait declaration, then the behavior also applies
256 when the call expression is a function from an implementation of the trait.
257
258 ```rust
259 trait Trait {
260 #[must_use]
261 fn use_me(&self) -> i32;
262 }
263
264 impl Trait for i32 {
265 fn use_me(&self) -> i32 { 0i32 }
266 }
267
268 // Violates the `unused_must_use` lint.
269 5i32.use_me();
270 ```
271
272 When used on a function in a trait implementation, the attribute does nothing.
273
274 > Note: Trivial no-op expressions containing the value will not violate the
275 > lint. Examples include wrapping the value in a type that does not implement
276 > [`Drop`] and then not using that type and being the final expression of a
277 > [block expression] that is not used.
278 >
279 > ```rust
280 > #[must_use]
281 > fn five() -> i32 { 5i32 }
282 >
283 > // None of these violate the unused_must_use lint.
284 > (five(),);
285 > Some(five());
286 > { five() };
287 > if true { five() } else { 0i32 };
288 > match true {
289 > _ => five()
290 > };
291 > ```
292
293 > Note: It is idiomatic to use a [let statement] with a pattern of `_`
294 > when a must-used value is purposely discarded.
295 >
296 > ```rust
297 > #[must_use]
298 > fn five() -> i32 { 5i32 }
299 >
300 > // Does not violate the unused_must_use lint.
301 > let _ = five();
302 > ```
303
304 [Clippy]: https://github.com/rust-lang/rust-clippy
305 [_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
306 [_MetaListPaths_]: ../attributes.md#meta-item-attribute-syntax
307 [_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
308 [`Drop`]: ../special-types-and-traits.md#drop
309 [attributes]: ../attributes.md
310 [block expression]: ../expressions/block-expr.md
311 [call expression]: ../expressions/call-expr.md
312 [dyn trait]: ../types/trait-object.md
313 [enum variant]: ../items/enumerations.md
314 [enum]: ../items/enumerations.md
315 [expression statement]: ../statements.md#expression-statements
316 [expression]: ../expressions.md
317 [external block item]: ../items/external-blocks.md
318 [functions]: ../items/functions.md
319 [impl trait]: ../types/impl-trait.md
320 [implementation]: ../items/implementations.md
321 [item]: ../items.md
322 [let statement]: ../statements.md#let-statements
323 [macro definition]: ../macros-by-example.md
324 [module]: ../items/modules.md
325 [rustc book]: ../../rustc/lints/index.html
326 [rustc-lint-caps]: ../../rustc/lints/levels.html#capping-lints
327 [rustc-lint-cli]: ../../rustc/lints/levels.html#via-compiler-flag
328 [rustdoc]: ../../rustdoc/lints.html
329 [struct field]: ../items/structs.md
330 [struct]: ../items/structs.md
331 [trait declaration]: ../items/traits.md
332 [trait implementation items]: ../items/implementations.md#trait-implementations
333 [trait item]: ../items/traits.md
334 [traits]: ../items/traits.md
335 [union]: ../items/unions.md