]>
Commit | Line | Data |
---|---|---|
532ac7d7 XL |
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 | This example shows how one can use `allow` and `warn` to toggle a particular | |
43 | check on and off: | |
44 | ||
45 | ```rust | |
46 | #[warn(missing_docs)] | |
47 | pub mod m2{ | |
48 | #[allow(missing_docs)] | |
49 | pub mod nested { | |
50 | // Missing documentation is ignored here | |
51 | pub fn undocumented_one() -> i32 { 1 } | |
52 | ||
53 | // Missing documentation signals a warning here, | |
54 | // despite the allow above. | |
55 | #[warn(missing_docs)] | |
56 | pub fn undocumented_two() -> i32 { 2 } | |
57 | } | |
58 | ||
59 | // Missing documentation signals a warning here | |
60 | pub fn undocumented_too() -> i32 { 3 } | |
61 | } | |
62 | ``` | |
63 | ||
64 | This example shows how one can use `forbid` to disallow uses of `allow` for | |
65 | that lint check: | |
66 | ||
67 | ```rust,compile_fail | |
68 | #[forbid(missing_docs)] | |
69 | pub mod m3 { | |
70 | // Attempting to toggle warning signals an error here | |
71 | #[allow(missing_docs)] | |
72 | /// Returns 2. | |
73 | pub fn undocumented_too() -> i32 { 2 } | |
74 | } | |
75 | ``` | |
76 | ||
77 | ### Tool lint attributes | |
78 | ||
79 | Tool lints allows using scoped lints, to `allow`, `warn`, `deny` or `forbid` | |
80 | lints of certain tools. | |
81 | ||
82 | Currently `clippy` is the only available lint tool. | |
83 | ||
84 | Tool lints only get checked when the associated tool is active. If a lint | |
85 | attribute, such as `allow`, references a nonexistent tool lint, the compiler | |
86 | will not warn about the nonexistent lint until you use the tool. | |
87 | ||
88 | Otherwise, they work just like regular lint attributes: | |
89 | ||
90 | ```rust | |
91 | // set the entire `pedantic` clippy lint group to warn | |
92 | #![warn(clippy::pedantic)] | |
93 | // silence warnings from the `filter_map` clippy lint | |
94 | #![allow(clippy::filter_map)] | |
95 | ||
96 | fn main() { | |
97 | // ... | |
98 | } | |
99 | ||
100 | // silence the `cmp_nan` clippy lint just for this function | |
101 | #[allow(clippy::cmp_nan)] | |
102 | fn foo() { | |
103 | // ... | |
104 | } | |
105 | ``` | |
106 | ||
107 | ## The `deprecated` attribute | |
108 | ||
109 | The *`deprecated` attribute* marks an item as deprecated. `rustc` will issue | |
110 | warnings on usage of `#[deprecated]` items. `rustdoc` will show item | |
111 | deprecation, including the `since` version and `note`, if available. | |
112 | ||
113 | The `deprecated` attribute has several forms: | |
114 | ||
115 | - `deprecated` — Issues a generic message. | |
116 | - `deprecated = "message"` — Includes the given string in the deprecation | |
117 | message. | |
118 | - [_MetaListNameValueStr_] syntax with two optional fields: | |
119 | - `since` — Specifies a version number when the item was deprecated. `rustc` | |
120 | does not currently interpret the string, but external tools like [Clippy] | |
121 | may check the validity of the value. | |
122 | - `note` — Specifies a string that should be included in the deprecation | |
123 | message. This is typically used to provide an explanation about the | |
124 | deprecation and preferred alternatives. | |
125 | ||
126 | The `deprecated` attribute may be applied to any [item], [trait item], [enum | |
127 | variant], [struct field], or [external block item]. It cannot be applied to [trait | |
128 | implementation items]. When applied to an item containing other items, such as | |
129 | a [module] or [implementation], all child items inherit the deprecation attribute. | |
130 | <!-- NOTE: Currently broken for macros, see https://github.com/rust-lang/rust/issues/49912 | |
131 | Also, it is only rejected for trait impl items (AnnotationKind::Prohibited). In all | |
132 | other locations, it is silently ignored. Tuple struct fields are ignored. | |
133 | --> | |
134 | ||
135 | Here is an example: | |
136 | ||
137 | ```rust | |
138 | #[deprecated(since = "5.2", note = "foo was rarely used. Users should instead use bar")] | |
139 | pub fn foo() {} | |
140 | ||
141 | pub fn bar() {} | |
142 | ``` | |
143 | ||
144 | The [RFC][1270-deprecation.md] contains motivations and more details. | |
145 | ||
146 | [1270-deprecation.md]: https://github.com/rust-lang/rfcs/blob/master/text/1270-deprecation.md | |
147 | ||
148 | ## The `must_use` attribute | |
149 | ||
150 | The *`must_use` attribute* is used to issue a diagnostic warning when a value | |
151 | is not "used". It can be applied to user-defined composite types | |
152 | ([`struct`s][struct], [`enum`s][enum], and [`union`s][union]), [functions], | |
153 | and [traits]. | |
154 | ||
155 | The `must_use` attribute may include a message by using the | |
156 | [_MetaNameValueStr_] syntax such as `#[must_use = "example message"]`. The | |
157 | message will be given alongside the warning. | |
158 | ||
159 | When used on user-defined composite types, if the [expression] of an | |
160 | [expression statement] has that type, then the `unused_must_use` lint is | |
161 | violated. | |
162 | ||
163 | ```rust | |
164 | #[must_use] | |
165 | struct MustUse { | |
166 | // some fields | |
167 | } | |
168 | ||
169 | # impl MustUse { | |
170 | # fn new() -> MustUse { MustUse {} } | |
171 | # } | |
172 | # | |
173 | // Violates the `unused_must_use` lint. | |
174 | MustUse::new(); | |
175 | ``` | |
176 | ||
177 | When used on a function, if the [expression] of an [expression statement] is a | |
178 | [call expression] to that function, then the `unused_must_use` lint is | |
179 | violated. | |
180 | ||
181 | ```rust | |
182 | #[must_use] | |
183 | fn five() -> i32 { 5i32 } | |
184 | ||
185 | // Violates the unused_must_use lint. | |
186 | five(); | |
187 | ``` | |
188 | ||
189 | When used on a [trait declaration], a [call expression] of an [expression | |
190 | statement] to a function that returns an [impl trait] of that trait violates | |
dc9dc135 | 191 | the `unused_must_use` lint. |
532ac7d7 XL |
192 | |
193 | ```rust | |
194 | #[must_use] | |
195 | trait Critical {} | |
196 | impl Critical for i32 {} | |
197 | ||
198 | fn get_critical() -> impl Critical { | |
199 | 4i32 | |
200 | } | |
201 | ||
202 | // Violates the `unused_must_use` lint. | |
203 | get_critical(); | |
204 | ``` | |
205 | ||
206 | When used on a function in a trait declaration, then the behavior also applies | |
207 | when the call expression is a function from an implementation of the trait. | |
208 | ||
209 | ```rust | |
210 | trait Trait { | |
211 | #[must_use] | |
212 | fn use_me(&self) -> i32; | |
213 | } | |
214 | ||
215 | impl Trait for i32 { | |
216 | fn use_me(&self) -> i32 { 0i32 } | |
217 | } | |
218 | ||
219 | // Violates the `unused_must_use` lint. | |
220 | 5i32.use_me(); | |
221 | ``` | |
222 | ||
223 | When used on a function in a trait implementation, the attribute does nothing. | |
224 | ||
225 | > Note: Trivial no-op expressions containing the value will not violate the | |
226 | > lint. Examples include wrapping the value in a type that does not implement | |
227 | > [`Drop`] and then not using that type and being the final expression of a | |
228 | > [block expression] that is not used. | |
229 | > | |
230 | > ```rust | |
231 | > #[must_use] | |
232 | > fn five() -> i32 { 5i32 } | |
233 | > | |
234 | > // None of these violate the unused_must_use lint. | |
235 | > (five(),); | |
236 | > Some(five()); | |
237 | > { five() }; | |
238 | > if true { five() } else { 0i32 }; | |
239 | > match true { | |
240 | > _ => five() | |
241 | > }; | |
242 | > ``` | |
243 | ||
244 | > Note: It is idiomatic to use a [let statement] with a pattern of `_` | |
245 | > when a must-used value is purposely discarded. | |
246 | > | |
247 | > ```rust | |
248 | > #[must_use] | |
249 | > fn five() -> i32 { 5i32 } | |
250 | > | |
251 | > // Does not violate the unused_must_use lint. | |
252 | > let _ = five(); | |
253 | > ``` | |
254 | ||
255 | [Clippy]: https://github.com/rust-lang/rust-clippy | |
416331ca XL |
256 | [_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax |
257 | [_MetaListPaths_]: ../attributes.md#meta-item-attribute-syntax | |
258 | [_MetaNameValueStr_]: ../attributes.md#meta-item-attribute-syntax | |
259 | [`Drop`]: ../special-types-and-traits.md#drop | |
260 | [attributes]: ../attributes.md | |
261 | [block expression]: ../expressions/block-expr.md | |
262 | [call expression]: ../expressions/call-expr.md | |
263 | [enum variant]: ../items/enumerations.md | |
264 | [enum]: ../items/enumerations.md | |
265 | [expression statement]: ../statements.md#expression-statements | |
266 | [expression]: ../expressions.md | |
267 | [external block item]: ../items/external-blocks.md | |
268 | [functions]: ../items/functions.md | |
269 | [impl trait]: ../types/impl-trait.md | |
270 | [implementation]: ../items/implementations.md | |
271 | [item]: ../items.md | |
272 | [let statement]: ../statements.md#let-statements | |
273 | [module]: ../items/modules.md | |
274 | [rustc book]: ../../rustc/lints/index.html | |
275 | [struct field]: ../items/structs.md | |
276 | [struct]: ../items/structs.md | |
277 | [trait declaration]: ../items/traits.md | |
278 | [trait implementation items]: ../items/implementations.md#trait-implementations | |
279 | [trait item]: ../items/traits.md | |
280 | [traits]: ../items/traits.md | |
281 | [union]: ../items/unions.md |