]>
Commit | Line | Data |
---|---|---|
5869c6ff | 1 | // ignore-tidy-filelength |
6a06907d | 2 | |
1b1a35ee XL |
3 | //! Some lints that are built in to the compiler. |
4 | //! | |
5 | //! These are the built-in lints that are emitted direct in the main | |
6 | //! compiler code, rather than using their own custom pass. Those | |
7 | //! lints are all available in `rustc_lint::builtin`. | |
8 | ||
6a06907d | 9 | use crate::{declare_lint, declare_lint_pass, FutureBreakage}; |
1b1a35ee | 10 | use rustc_span::edition::Edition; |
1b1a35ee | 11 | |
fc512014 XL |
12 | declare_lint! { |
13 | /// The `forbidden_lint_groups` lint detects violations of | |
14 | /// `forbid` applied to a lint group. Due to a bug in the compiler, | |
15 | /// these used to be overlooked entirely. They now generate a warning. | |
16 | /// | |
17 | /// ### Example | |
18 | /// | |
19 | /// ```rust | |
20 | /// #![forbid(warnings)] | |
21 | /// #![deny(bad_style)] | |
22 | /// | |
23 | /// fn main() {} | |
24 | /// ``` | |
25 | /// | |
26 | /// {{produces}} | |
27 | /// | |
28 | /// ### Recommended fix | |
29 | /// | |
30 | /// If your crate is using `#![forbid(warnings)]`, | |
31 | /// we recommend that you change to `#![deny(warnings)]`. | |
32 | /// | |
33 | /// ### Explanation | |
34 | /// | |
35 | /// Due to a compiler bug, applying `forbid` to lint groups | |
36 | /// previously had no effect. The bug is now fixed but instead of | |
37 | /// enforcing `forbid` we issue this future-compatibility warning | |
38 | /// to avoid breaking existing crates. | |
39 | pub FORBIDDEN_LINT_GROUPS, | |
40 | Warn, | |
41 | "applying forbid to lint-groups", | |
42 | @future_incompatible = FutureIncompatibleInfo { | |
43 | reference: "issue #81670 <https://github.com/rust-lang/rust/issues/81670>", | |
44 | edition: None, | |
45 | }; | |
46 | } | |
47 | ||
1b1a35ee XL |
48 | declare_lint! { |
49 | /// The `ill_formed_attribute_input` lint detects ill-formed attribute | |
50 | /// inputs that were previously accepted and used in practice. | |
51 | /// | |
52 | /// ### Example | |
53 | /// | |
54 | /// ```rust,compile_fail | |
55 | /// #[inline = "this is not valid"] | |
56 | /// fn foo() {} | |
57 | /// ``` | |
58 | /// | |
59 | /// {{produces}} | |
60 | /// | |
61 | /// ### Explanation | |
62 | /// | |
63 | /// Previously, inputs for many built-in attributes weren't validated and | |
64 | /// nonsensical attribute inputs were accepted. After validation was | |
65 | /// added, it was determined that some existing projects made use of these | |
66 | /// invalid forms. This is a [future-incompatible] lint to transition this | |
67 | /// to a hard error in the future. See [issue #57571] for more details. | |
68 | /// | |
69 | /// Check the [attribute reference] for details on the valid inputs for | |
70 | /// attributes. | |
71 | /// | |
72 | /// [issue #57571]: https://github.com/rust-lang/rust/issues/57571 | |
73 | /// [attribute reference]: https://doc.rust-lang.org/nightly/reference/attributes.html | |
74 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
75 | pub ILL_FORMED_ATTRIBUTE_INPUT, | |
76 | Deny, | |
77 | "ill-formed attribute inputs that were previously accepted and used in practice", | |
78 | @future_incompatible = FutureIncompatibleInfo { | |
79 | reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>", | |
80 | edition: None, | |
81 | }; | |
82 | crate_level_only | |
83 | } | |
84 | ||
85 | declare_lint! { | |
86 | /// The `conflicting_repr_hints` lint detects [`repr` attributes] with | |
87 | /// conflicting hints. | |
88 | /// | |
89 | /// [`repr` attributes]: https://doc.rust-lang.org/reference/type-layout.html#representations | |
90 | /// | |
91 | /// ### Example | |
92 | /// | |
93 | /// ```rust,compile_fail | |
94 | /// #[repr(u32, u64)] | |
95 | /// enum Foo { | |
96 | /// Variant1, | |
97 | /// } | |
98 | /// ``` | |
99 | /// | |
100 | /// {{produces}} | |
101 | /// | |
102 | /// ### Explanation | |
103 | /// | |
104 | /// The compiler incorrectly accepted these conflicting representations in | |
105 | /// the past. This is a [future-incompatible] lint to transition this to a | |
106 | /// hard error in the future. See [issue #68585] for more details. | |
107 | /// | |
108 | /// To correct the issue, remove one of the conflicting hints. | |
109 | /// | |
110 | /// [issue #68585]: https://github.com/rust-lang/rust/issues/68585 | |
111 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
112 | pub CONFLICTING_REPR_HINTS, | |
113 | Deny, | |
114 | "conflicts between `#[repr(..)]` hints that were previously accepted and used in practice", | |
115 | @future_incompatible = FutureIncompatibleInfo { | |
116 | reference: "issue #68585 <https://github.com/rust-lang/rust/issues/68585>", | |
117 | edition: None, | |
118 | }; | |
119 | } | |
120 | ||
121 | declare_lint! { | |
122 | /// The `meta_variable_misuse` lint detects possible meta-variable misuse | |
123 | /// in macro definitions. | |
124 | /// | |
125 | /// ### Example | |
126 | /// | |
127 | /// ```rust,compile_fail | |
128 | /// #![deny(meta_variable_misuse)] | |
129 | /// | |
130 | /// macro_rules! foo { | |
131 | /// () => {}; | |
132 | /// ($( $i:ident = $($j:ident),+ );*) => { $( $( $i = $k; )+ )* }; | |
133 | /// } | |
134 | /// | |
135 | /// fn main() { | |
136 | /// foo!(); | |
137 | /// } | |
138 | /// ``` | |
139 | /// | |
140 | /// {{produces}} | |
141 | /// | |
142 | /// ### Explanation | |
143 | /// | |
144 | /// There are quite a few different ways a [`macro_rules`] macro can be | |
145 | /// improperly defined. Many of these errors were previously only detected | |
146 | /// when the macro was expanded or not at all. This lint is an attempt to | |
147 | /// catch some of these problems when the macro is *defined*. | |
148 | /// | |
149 | /// This lint is "allow" by default because it may have false positives | |
150 | /// and other issues. See [issue #61053] for more details. | |
151 | /// | |
152 | /// [`macro_rules`]: https://doc.rust-lang.org/reference/macros-by-example.html | |
153 | /// [issue #61053]: https://github.com/rust-lang/rust/issues/61053 | |
154 | pub META_VARIABLE_MISUSE, | |
155 | Allow, | |
156 | "possible meta-variable misuse at macro definition" | |
157 | } | |
158 | ||
159 | declare_lint! { | |
160 | /// The `incomplete_include` lint detects the use of the [`include!`] | |
161 | /// macro with a file that contains more than one expression. | |
162 | /// | |
163 | /// [`include!`]: https://doc.rust-lang.org/std/macro.include.html | |
164 | /// | |
165 | /// ### Example | |
166 | /// | |
167 | /// ```rust,ignore (needs separate file) | |
168 | /// fn main() { | |
169 | /// include!("foo.txt"); | |
170 | /// } | |
171 | /// ``` | |
172 | /// | |
173 | /// where the file `foo.txt` contains: | |
174 | /// | |
175 | /// ```text | |
176 | /// println!("hi!"); | |
177 | /// ``` | |
178 | /// | |
179 | /// produces: | |
180 | /// | |
181 | /// ```text | |
182 | /// error: include macro expected single expression in source | |
183 | /// --> foo.txt:1:14 | |
184 | /// | | |
185 | /// 1 | println!("1"); | |
186 | /// | ^ | |
187 | /// | | |
188 | /// = note: `#[deny(incomplete_include)]` on by default | |
189 | /// ``` | |
190 | /// | |
191 | /// ### Explanation | |
192 | /// | |
193 | /// The [`include!`] macro is currently only intended to be used to | |
194 | /// include a single [expression] or multiple [items]. Historically it | |
195 | /// would ignore any contents after the first expression, but that can be | |
196 | /// confusing. In the example above, the `println!` expression ends just | |
197 | /// before the semicolon, making the semicolon "extra" information that is | |
198 | /// ignored. Perhaps even more surprising, if the included file had | |
199 | /// multiple print statements, the subsequent ones would be ignored! | |
200 | /// | |
201 | /// One workaround is to place the contents in braces to create a [block | |
202 | /// expression]. Also consider alternatives, like using functions to | |
203 | /// encapsulate the expressions, or use [proc-macros]. | |
204 | /// | |
205 | /// This is a lint instead of a hard error because existing projects were | |
206 | /// found to hit this error. To be cautious, it is a lint for now. The | |
207 | /// future semantics of the `include!` macro are also uncertain, see | |
208 | /// [issue #35560]. | |
209 | /// | |
210 | /// [items]: https://doc.rust-lang.org/reference/items.html | |
211 | /// [expression]: https://doc.rust-lang.org/reference/expressions.html | |
212 | /// [block expression]: https://doc.rust-lang.org/reference/expressions/block-expr.html | |
213 | /// [proc-macros]: https://doc.rust-lang.org/reference/procedural-macros.html | |
214 | /// [issue #35560]: https://github.com/rust-lang/rust/issues/35560 | |
215 | pub INCOMPLETE_INCLUDE, | |
216 | Deny, | |
217 | "trailing content in included file" | |
218 | } | |
219 | ||
220 | declare_lint! { | |
221 | /// The `arithmetic_overflow` lint detects that an arithmetic operation | |
222 | /// will [overflow]. | |
223 | /// | |
224 | /// [overflow]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow | |
225 | /// | |
226 | /// ### Example | |
227 | /// | |
228 | /// ```rust,compile_fail | |
229 | /// 1_i32 << 32; | |
230 | /// ``` | |
231 | /// | |
232 | /// {{produces}} | |
233 | /// | |
234 | /// ### Explanation | |
235 | /// | |
236 | /// It is very likely a mistake to perform an arithmetic operation that | |
237 | /// overflows its value. If the compiler is able to detect these kinds of | |
238 | /// overflows at compile-time, it will trigger this lint. Consider | |
239 | /// adjusting the expression to avoid overflow, or use a data type that | |
240 | /// will not overflow. | |
241 | pub ARITHMETIC_OVERFLOW, | |
242 | Deny, | |
243 | "arithmetic operation overflows" | |
244 | } | |
245 | ||
246 | declare_lint! { | |
247 | /// The `unconditional_panic` lint detects an operation that will cause a | |
248 | /// panic at runtime. | |
249 | /// | |
250 | /// ### Example | |
251 | /// | |
252 | /// ```rust,compile_fail | |
253 | /// # #![allow(unused)] | |
254 | /// let x = 1 / 0; | |
255 | /// ``` | |
256 | /// | |
257 | /// {{produces}} | |
258 | /// | |
259 | /// ### Explanation | |
260 | /// | |
5869c6ff XL |
261 | /// This lint detects code that is very likely incorrect because it will |
262 | /// always panic, such as division by zero and out-of-bounds array | |
263 | /// accesses. Consider adjusting your code if this is a bug, or using the | |
264 | /// `panic!` or `unreachable!` macro instead in case the panic is intended. | |
1b1a35ee XL |
265 | pub UNCONDITIONAL_PANIC, |
266 | Deny, | |
267 | "operation will cause a panic at runtime" | |
268 | } | |
269 | ||
270 | declare_lint! { | |
271 | /// The `const_err` lint detects an erroneous expression while doing | |
272 | /// constant evaluation. | |
273 | /// | |
274 | /// ### Example | |
275 | /// | |
276 | /// ```rust,compile_fail | |
277 | /// #![allow(unconditional_panic)] | |
5869c6ff | 278 | /// const C: i32 = 1/0; |
1b1a35ee XL |
279 | /// ``` |
280 | /// | |
281 | /// {{produces}} | |
282 | /// | |
283 | /// ### Explanation | |
284 | /// | |
5869c6ff XL |
285 | /// This lint detects constants that fail to evaluate. Allowing the lint will accept the |
286 | /// constant declaration, but any use of this constant will still lead to a hard error. This is | |
287 | /// a future incompatibility lint; the plan is to eventually entirely forbid even declaring | |
288 | /// constants that cannot be evaluated. See [issue #71800] for more details. | |
1b1a35ee | 289 | /// |
5869c6ff | 290 | /// [issue #71800]: https://github.com/rust-lang/rust/issues/71800 |
1b1a35ee XL |
291 | pub CONST_ERR, |
292 | Deny, | |
5869c6ff XL |
293 | "constant evaluation encountered erroneous expression", |
294 | @future_incompatible = FutureIncompatibleInfo { | |
295 | reference: "issue #71800 <https://github.com/rust-lang/rust/issues/71800>", | |
296 | edition: None, | |
297 | }; | |
1b1a35ee XL |
298 | report_in_external_macro |
299 | } | |
300 | ||
301 | declare_lint! { | |
302 | /// The `unused_imports` lint detects imports that are never used. | |
303 | /// | |
304 | /// ### Example | |
305 | /// | |
306 | /// ```rust | |
307 | /// use std::collections::HashMap; | |
308 | /// ``` | |
309 | /// | |
310 | /// {{produces}} | |
311 | /// | |
312 | /// ### Explanation | |
313 | /// | |
314 | /// Unused imports may signal a mistake or unfinished code, and clutter | |
315 | /// the code, and should be removed. If you intended to re-export the item | |
316 | /// to make it available outside of the module, add a visibility modifier | |
317 | /// like `pub`. | |
318 | pub UNUSED_IMPORTS, | |
319 | Warn, | |
320 | "imports that are never used" | |
321 | } | |
322 | ||
323 | declare_lint! { | |
324 | /// The `unused_extern_crates` lint guards against `extern crate` items | |
325 | /// that are never used. | |
326 | /// | |
327 | /// ### Example | |
328 | /// | |
329 | /// ```rust,compile_fail | |
330 | /// #![deny(unused_extern_crates)] | |
331 | /// extern crate proc_macro; | |
332 | /// ``` | |
333 | /// | |
334 | /// {{produces}} | |
335 | /// | |
336 | /// ### Explanation | |
337 | /// | |
338 | /// `extern crate` items that are unused have no effect and should be | |
339 | /// removed. Note that there are some cases where specifying an `extern | |
340 | /// crate` is desired for the side effect of ensuring the given crate is | |
341 | /// linked, even though it is not otherwise directly referenced. The lint | |
342 | /// can be silenced by aliasing the crate to an underscore, such as | |
343 | /// `extern crate foo as _`. Also note that it is no longer idiomatic to | |
344 | /// use `extern crate` in the [2018 edition], as extern crates are now | |
345 | /// automatically added in scope. | |
346 | /// | |
347 | /// This lint is "allow" by default because it can be noisy, and produce | |
348 | /// false-positives. If a dependency is being removed from a project, it | |
349 | /// is recommended to remove it from the build configuration (such as | |
350 | /// `Cargo.toml`) to ensure stale build entries aren't left behind. | |
351 | /// | |
352 | /// [2018 edition]: https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-clarity.html#no-more-extern-crate | |
353 | pub UNUSED_EXTERN_CRATES, | |
354 | Allow, | |
355 | "extern crates that are never used" | |
356 | } | |
357 | ||
358 | declare_lint! { | |
359 | /// The `unused_crate_dependencies` lint detects crate dependencies that | |
360 | /// are never used. | |
361 | /// | |
362 | /// ### Example | |
363 | /// | |
364 | /// ```rust,ignore (needs extern crate) | |
365 | /// #![deny(unused_crate_dependencies)] | |
366 | /// ``` | |
367 | /// | |
368 | /// This will produce: | |
369 | /// | |
370 | /// ```text | |
371 | /// error: external crate `regex` unused in `lint_example`: remove the dependency or add `use regex as _;` | |
372 | /// | | |
373 | /// note: the lint level is defined here | |
374 | /// --> src/lib.rs:1:9 | |
375 | /// | | |
376 | /// 1 | #![deny(unused_crate_dependencies)] | |
377 | /// | ^^^^^^^^^^^^^^^^^^^^^^^^^ | |
378 | /// ``` | |
379 | /// | |
380 | /// ### Explanation | |
381 | /// | |
382 | /// After removing the code that uses a dependency, this usually also | |
383 | /// requires removing the dependency from the build configuration. | |
384 | /// However, sometimes that step can be missed, which leads to time wasted | |
385 | /// building dependencies that are no longer used. This lint can be | |
386 | /// enabled to detect dependencies that are never used (more specifically, | |
387 | /// any dependency passed with the `--extern` command-line flag that is | |
388 | /// never referenced via [`use`], [`extern crate`], or in any [path]). | |
389 | /// | |
390 | /// This lint is "allow" by default because it can provide false positives | |
391 | /// depending on how the build system is configured. For example, when | |
392 | /// using Cargo, a "package" consists of multiple crates (such as a | |
393 | /// library and a binary), but the dependencies are defined for the | |
394 | /// package as a whole. If there is a dependency that is only used in the | |
395 | /// binary, but not the library, then the lint will be incorrectly issued | |
396 | /// in the library. | |
397 | /// | |
398 | /// [path]: https://doc.rust-lang.org/reference/paths.html | |
399 | /// [`use`]: https://doc.rust-lang.org/reference/items/use-declarations.html | |
400 | /// [`extern crate`]: https://doc.rust-lang.org/reference/items/extern-crates.html | |
401 | pub UNUSED_CRATE_DEPENDENCIES, | |
402 | Allow, | |
403 | "crate dependencies that are never used", | |
404 | crate_level_only | |
405 | } | |
406 | ||
407 | declare_lint! { | |
408 | /// The `unused_qualifications` lint detects unnecessarily qualified | |
409 | /// names. | |
410 | /// | |
411 | /// ### Example | |
412 | /// | |
413 | /// ```rust,compile_fail | |
414 | /// #![deny(unused_qualifications)] | |
415 | /// mod foo { | |
416 | /// pub fn bar() {} | |
417 | /// } | |
418 | /// | |
419 | /// fn main() { | |
420 | /// use foo::bar; | |
421 | /// foo::bar(); | |
422 | /// } | |
423 | /// ``` | |
424 | /// | |
425 | /// {{produces}} | |
426 | /// | |
427 | /// ### Explanation | |
428 | /// | |
429 | /// If an item from another module is already brought into scope, then | |
430 | /// there is no need to qualify it in this case. You can call `bar()` | |
431 | /// directly, without the `foo::`. | |
432 | /// | |
433 | /// This lint is "allow" by default because it is somewhat pedantic, and | |
434 | /// doesn't indicate an actual problem, but rather a stylistic choice, and | |
435 | /// can be noisy when refactoring or moving around code. | |
436 | pub UNUSED_QUALIFICATIONS, | |
437 | Allow, | |
438 | "detects unnecessarily qualified names" | |
439 | } | |
440 | ||
441 | declare_lint! { | |
442 | /// The `unknown_lints` lint detects unrecognized lint attribute. | |
443 | /// | |
444 | /// ### Example | |
445 | /// | |
446 | /// ```rust | |
447 | /// #![allow(not_a_real_lint)] | |
448 | /// ``` | |
449 | /// | |
450 | /// {{produces}} | |
451 | /// | |
452 | /// ### Explanation | |
453 | /// | |
454 | /// It is usually a mistake to specify a lint that does not exist. Check | |
455 | /// the spelling, and check the lint listing for the correct name. Also | |
456 | /// consider if you are using an old version of the compiler, and the lint | |
457 | /// is only available in a newer version. | |
458 | pub UNKNOWN_LINTS, | |
459 | Warn, | |
460 | "unrecognized lint attribute" | |
461 | } | |
462 | ||
463 | declare_lint! { | |
464 | /// The `unused_variables` lint detects variables which are not used in | |
465 | /// any way. | |
466 | /// | |
467 | /// ### Example | |
468 | /// | |
469 | /// ```rust | |
470 | /// let x = 5; | |
471 | /// ``` | |
472 | /// | |
473 | /// {{produces}} | |
474 | /// | |
475 | /// ### Explanation | |
476 | /// | |
477 | /// Unused variables may signal a mistake or unfinished code. To silence | |
478 | /// the warning for the individual variable, prefix it with an underscore | |
479 | /// such as `_x`. | |
480 | pub UNUSED_VARIABLES, | |
481 | Warn, | |
482 | "detect variables which are not used in any way" | |
483 | } | |
484 | ||
485 | declare_lint! { | |
486 | /// The `unused_assignments` lint detects assignments that will never be read. | |
487 | /// | |
488 | /// ### Example | |
489 | /// | |
490 | /// ```rust | |
491 | /// let mut x = 5; | |
492 | /// x = 6; | |
493 | /// ``` | |
494 | /// | |
495 | /// {{produces}} | |
496 | /// | |
497 | /// ### Explanation | |
498 | /// | |
499 | /// Unused assignments may signal a mistake or unfinished code. If the | |
500 | /// variable is never used after being assigned, then the assignment can | |
501 | /// be removed. Variables with an underscore prefix such as `_x` will not | |
502 | /// trigger this lint. | |
503 | pub UNUSED_ASSIGNMENTS, | |
504 | Warn, | |
505 | "detect assignments that will never be read" | |
506 | } | |
507 | ||
508 | declare_lint! { | |
509 | /// The `dead_code` lint detects unused, unexported items. | |
510 | /// | |
511 | /// ### Example | |
512 | /// | |
513 | /// ```rust | |
514 | /// fn foo() {} | |
515 | /// ``` | |
516 | /// | |
517 | /// {{produces}} | |
518 | /// | |
519 | /// ### Explanation | |
520 | /// | |
521 | /// Dead code may signal a mistake or unfinished code. To silence the | |
522 | /// warning for individual items, prefix the name with an underscore such | |
523 | /// as `_foo`. If it was intended to expose the item outside of the crate, | |
524 | /// consider adding a visibility modifier like `pub`. Otherwise consider | |
525 | /// removing the unused code. | |
526 | pub DEAD_CODE, | |
527 | Warn, | |
528 | "detect unused, unexported items" | |
529 | } | |
530 | ||
531 | declare_lint! { | |
532 | /// The `unused_attributes` lint detects attributes that were not used by | |
533 | /// the compiler. | |
534 | /// | |
535 | /// ### Example | |
536 | /// | |
537 | /// ```rust | |
29967ef6 | 538 | /// #![ignore] |
1b1a35ee XL |
539 | /// ``` |
540 | /// | |
541 | /// {{produces}} | |
542 | /// | |
543 | /// ### Explanation | |
544 | /// | |
545 | /// Unused [attributes] may indicate the attribute is placed in the wrong | |
546 | /// position. Consider removing it, or placing it in the correct position. | |
547 | /// Also consider if you intended to use an _inner attribute_ (with a `!` | |
548 | /// such as `#![allow(unused)]`) which applies to the item the attribute | |
549 | /// is within, or an _outer attribute_ (without a `!` such as | |
cdc7bbd5 | 550 | /// `#[allow(unused)]`) which applies to the item *following* the |
1b1a35ee XL |
551 | /// attribute. |
552 | /// | |
553 | /// [attributes]: https://doc.rust-lang.org/reference/attributes.html | |
554 | pub UNUSED_ATTRIBUTES, | |
555 | Warn, | |
556 | "detects attributes that were not used by the compiler" | |
557 | } | |
558 | ||
559 | declare_lint! { | |
560 | /// The `unreachable_code` lint detects unreachable code paths. | |
561 | /// | |
562 | /// ### Example | |
563 | /// | |
564 | /// ```rust,no_run | |
565 | /// panic!("we never go past here!"); | |
566 | /// | |
567 | /// let x = 5; | |
568 | /// ``` | |
569 | /// | |
570 | /// {{produces}} | |
571 | /// | |
572 | /// ### Explanation | |
573 | /// | |
574 | /// Unreachable code may signal a mistake or unfinished code. If the code | |
575 | /// is no longer in use, consider removing it. | |
576 | pub UNREACHABLE_CODE, | |
577 | Warn, | |
578 | "detects unreachable code paths", | |
579 | report_in_external_macro | |
580 | } | |
581 | ||
582 | declare_lint! { | |
583 | /// The `unreachable_patterns` lint detects unreachable patterns. | |
584 | /// | |
585 | /// ### Example | |
586 | /// | |
587 | /// ```rust | |
588 | /// let x = 5; | |
589 | /// match x { | |
590 | /// y => (), | |
591 | /// 5 => (), | |
592 | /// } | |
593 | /// ``` | |
594 | /// | |
595 | /// {{produces}} | |
596 | /// | |
597 | /// ### Explanation | |
598 | /// | |
599 | /// This usually indicates a mistake in how the patterns are specified or | |
600 | /// ordered. In this example, the `y` pattern will always match, so the | |
601 | /// five is impossible to reach. Remember, match arms match in order, you | |
602 | /// probably wanted to put the `5` case above the `y` case. | |
603 | pub UNREACHABLE_PATTERNS, | |
604 | Warn, | |
605 | "detects unreachable patterns" | |
606 | } | |
607 | ||
608 | declare_lint! { | |
fc512014 XL |
609 | /// The `overlapping_range_endpoints` lint detects `match` arms that have [range patterns] that |
610 | /// overlap on their endpoints. | |
1b1a35ee XL |
611 | /// |
612 | /// [range patterns]: https://doc.rust-lang.org/nightly/reference/patterns.html#range-patterns | |
613 | /// | |
614 | /// ### Example | |
615 | /// | |
616 | /// ```rust | |
617 | /// let x = 123u8; | |
618 | /// match x { | |
619 | /// 0..=100 => { println!("small"); } | |
620 | /// 100..=255 => { println!("large"); } | |
621 | /// } | |
622 | /// ``` | |
623 | /// | |
624 | /// {{produces}} | |
625 | /// | |
626 | /// ### Explanation | |
627 | /// | |
fc512014 XL |
628 | /// It is likely a mistake to have range patterns in a match expression that overlap in this |
629 | /// way. Check that the beginning and end values are what you expect, and keep in mind that | |
630 | /// with `..=` the left and right bounds are inclusive. | |
631 | pub OVERLAPPING_RANGE_ENDPOINTS, | |
1b1a35ee | 632 | Warn, |
fc512014 | 633 | "detects range patterns with overlapping endpoints" |
1b1a35ee XL |
634 | } |
635 | ||
636 | declare_lint! { | |
637 | /// The `bindings_with_variant_name` lint detects pattern bindings with | |
638 | /// the same name as one of the matched variants. | |
639 | /// | |
640 | /// ### Example | |
641 | /// | |
642 | /// ```rust | |
643 | /// pub enum Enum { | |
644 | /// Foo, | |
645 | /// Bar, | |
646 | /// } | |
647 | /// | |
648 | /// pub fn foo(x: Enum) { | |
649 | /// match x { | |
650 | /// Foo => {} | |
651 | /// Bar => {} | |
652 | /// } | |
653 | /// } | |
654 | /// ``` | |
655 | /// | |
656 | /// {{produces}} | |
657 | /// | |
658 | /// ### Explanation | |
659 | /// | |
660 | /// It is usually a mistake to specify an enum variant name as an | |
661 | /// [identifier pattern]. In the example above, the `match` arms are | |
662 | /// specifying a variable name to bind the value of `x` to. The second arm | |
663 | /// is ignored because the first one matches *all* values. The likely | |
664 | /// intent is that the arm was intended to match on the enum variant. | |
665 | /// | |
666 | /// Two possible solutions are: | |
667 | /// | |
668 | /// * Specify the enum variant using a [path pattern], such as | |
669 | /// `Enum::Foo`. | |
670 | /// * Bring the enum variants into local scope, such as adding `use | |
671 | /// Enum::*;` to the beginning of the `foo` function in the example | |
672 | /// above. | |
673 | /// | |
674 | /// [identifier pattern]: https://doc.rust-lang.org/reference/patterns.html#identifier-patterns | |
675 | /// [path pattern]: https://doc.rust-lang.org/reference/patterns.html#path-patterns | |
676 | pub BINDINGS_WITH_VARIANT_NAME, | |
677 | Warn, | |
678 | "detects pattern bindings with the same name as one of the matched variants" | |
679 | } | |
680 | ||
681 | declare_lint! { | |
682 | /// The `unused_macros` lint detects macros that were not used. | |
683 | /// | |
684 | /// ### Example | |
685 | /// | |
686 | /// ```rust | |
687 | /// macro_rules! unused { | |
688 | /// () => {}; | |
689 | /// } | |
690 | /// | |
691 | /// fn main() { | |
692 | /// } | |
693 | /// ``` | |
694 | /// | |
695 | /// {{produces}} | |
696 | /// | |
697 | /// ### Explanation | |
698 | /// | |
699 | /// Unused macros may signal a mistake or unfinished code. To silence the | |
700 | /// warning for the individual macro, prefix the name with an underscore | |
701 | /// such as `_my_macro`. If you intended to export the macro to make it | |
702 | /// available outside of the crate, use the [`macro_export` attribute]. | |
703 | /// | |
704 | /// [`macro_export` attribute]: https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope | |
705 | pub UNUSED_MACROS, | |
706 | Warn, | |
707 | "detects macros that were not used" | |
708 | } | |
709 | ||
710 | declare_lint! { | |
711 | /// The `warnings` lint allows you to change the level of other | |
712 | /// lints which produce warnings. | |
713 | /// | |
714 | /// ### Example | |
715 | /// | |
716 | /// ```rust | |
717 | /// #![deny(warnings)] | |
718 | /// fn foo() {} | |
719 | /// ``` | |
720 | /// | |
721 | /// {{produces}} | |
722 | /// | |
723 | /// ### Explanation | |
724 | /// | |
725 | /// The `warnings` lint is a bit special; by changing its level, you | |
726 | /// change every other warning that would produce a warning to whatever | |
727 | /// value you'd like. As such, you won't ever trigger this lint in your | |
728 | /// code directly. | |
729 | pub WARNINGS, | |
730 | Warn, | |
731 | "mass-change the level for lints which produce warnings" | |
732 | } | |
733 | ||
734 | declare_lint! { | |
735 | /// The `unused_features` lint detects unused or unknown features found in | |
736 | /// crate-level [`feature` attributes]. | |
737 | /// | |
738 | /// [`feature` attributes]: https://doc.rust-lang.org/nightly/unstable-book/ | |
739 | /// | |
740 | /// Note: This lint is currently not functional, see [issue #44232] for | |
741 | /// more details. | |
742 | /// | |
743 | /// [issue #44232]: https://github.com/rust-lang/rust/issues/44232 | |
744 | pub UNUSED_FEATURES, | |
745 | Warn, | |
746 | "unused features found in crate-level `#[feature]` directives" | |
747 | } | |
748 | ||
749 | declare_lint! { | |
750 | /// The `stable_features` lint detects a [`feature` attribute] that | |
751 | /// has since been made stable. | |
752 | /// | |
753 | /// [`feature` attribute]: https://doc.rust-lang.org/nightly/unstable-book/ | |
754 | /// | |
755 | /// ### Example | |
756 | /// | |
757 | /// ```rust | |
758 | /// #![feature(test_accepted_feature)] | |
759 | /// fn main() {} | |
760 | /// ``` | |
761 | /// | |
762 | /// {{produces}} | |
763 | /// | |
764 | /// ### Explanation | |
765 | /// | |
766 | /// When a feature is stabilized, it is no longer necessary to include a | |
767 | /// `#![feature]` attribute for it. To fix, simply remove the | |
768 | /// `#![feature]` attribute. | |
769 | pub STABLE_FEATURES, | |
770 | Warn, | |
771 | "stable features found in `#[feature]` directive" | |
772 | } | |
773 | ||
774 | declare_lint! { | |
775 | /// The `unknown_crate_types` lint detects an unknown crate type found in | |
776 | /// a [`crate_type` attribute]. | |
777 | /// | |
778 | /// ### Example | |
779 | /// | |
780 | /// ```rust,compile_fail | |
781 | /// #![crate_type="lol"] | |
782 | /// fn main() {} | |
783 | /// ``` | |
784 | /// | |
785 | /// {{produces}} | |
786 | /// | |
787 | /// ### Explanation | |
788 | /// | |
789 | /// An unknown value give to the `crate_type` attribute is almost | |
790 | /// certainly a mistake. | |
791 | /// | |
792 | /// [`crate_type` attribute]: https://doc.rust-lang.org/reference/linkage.html | |
793 | pub UNKNOWN_CRATE_TYPES, | |
794 | Deny, | |
795 | "unknown crate type found in `#[crate_type]` directive", | |
796 | crate_level_only | |
797 | } | |
798 | ||
799 | declare_lint! { | |
800 | /// The `trivial_casts` lint detects trivial casts which could be replaced | |
801 | /// with coercion, which may require [type ascription] or a temporary | |
802 | /// variable. | |
803 | /// | |
804 | /// ### Example | |
805 | /// | |
806 | /// ```rust,compile_fail | |
807 | /// #![deny(trivial_casts)] | |
808 | /// let x: &u32 = &42; | |
809 | /// let y = x as *const u32; | |
810 | /// ``` | |
811 | /// | |
812 | /// {{produces}} | |
813 | /// | |
814 | /// ### Explanation | |
815 | /// | |
816 | /// A trivial cast is a cast `e as T` where `e` has type `U` and `U` is a | |
817 | /// subtype of `T`. This type of cast is usually unnecessary, as it can be | |
818 | /// usually be inferred. | |
819 | /// | |
820 | /// This lint is "allow" by default because there are situations, such as | |
821 | /// with FFI interfaces or complex type aliases, where it triggers | |
822 | /// incorrectly, or in situations where it will be more difficult to | |
823 | /// clearly express the intent. It may be possible that this will become a | |
824 | /// warning in the future, possibly with [type ascription] providing a | |
825 | /// convenient way to work around the current issues. See [RFC 401] for | |
826 | /// historical context. | |
827 | /// | |
828 | /// [type ascription]: https://github.com/rust-lang/rust/issues/23416 | |
829 | /// [RFC 401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md | |
830 | pub TRIVIAL_CASTS, | |
831 | Allow, | |
832 | "detects trivial casts which could be removed" | |
833 | } | |
834 | ||
835 | declare_lint! { | |
836 | /// The `trivial_numeric_casts` lint detects trivial numeric casts of types | |
837 | /// which could be removed. | |
838 | /// | |
839 | /// ### Example | |
840 | /// | |
841 | /// ```rust,compile_fail | |
842 | /// #![deny(trivial_numeric_casts)] | |
843 | /// let x = 42_i32 as i32; | |
844 | /// ``` | |
845 | /// | |
846 | /// {{produces}} | |
847 | /// | |
848 | /// ### Explanation | |
849 | /// | |
850 | /// A trivial numeric cast is a cast of a numeric type to the same numeric | |
851 | /// type. This type of cast is usually unnecessary. | |
852 | /// | |
853 | /// This lint is "allow" by default because there are situations, such as | |
854 | /// with FFI interfaces or complex type aliases, where it triggers | |
855 | /// incorrectly, or in situations where it will be more difficult to | |
856 | /// clearly express the intent. It may be possible that this will become a | |
857 | /// warning in the future, possibly with [type ascription] providing a | |
858 | /// convenient way to work around the current issues. See [RFC 401] for | |
859 | /// historical context. | |
860 | /// | |
861 | /// [type ascription]: https://github.com/rust-lang/rust/issues/23416 | |
862 | /// [RFC 401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md | |
863 | pub TRIVIAL_NUMERIC_CASTS, | |
864 | Allow, | |
865 | "detects trivial casts of numeric types which could be removed" | |
866 | } | |
867 | ||
868 | declare_lint! { | |
869 | /// The `private_in_public` lint detects private items in public | |
870 | /// interfaces not caught by the old implementation. | |
871 | /// | |
872 | /// ### Example | |
873 | /// | |
874 | /// ```rust | |
875 | /// # #![allow(unused)] | |
876 | /// struct SemiPriv; | |
877 | /// | |
878 | /// mod m1 { | |
879 | /// struct Priv; | |
880 | /// impl super::SemiPriv { | |
881 | /// pub fn f(_: Priv) {} | |
882 | /// } | |
883 | /// } | |
884 | /// # fn main() {} | |
885 | /// ``` | |
886 | /// | |
887 | /// {{produces}} | |
888 | /// | |
889 | /// ### Explanation | |
890 | /// | |
891 | /// The visibility rules are intended to prevent exposing private items in | |
892 | /// public interfaces. This is a [future-incompatible] lint to transition | |
893 | /// this to a hard error in the future. See [issue #34537] for more | |
894 | /// details. | |
895 | /// | |
896 | /// [issue #34537]: https://github.com/rust-lang/rust/issues/34537 | |
897 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
898 | pub PRIVATE_IN_PUBLIC, | |
899 | Warn, | |
900 | "detect private items in public interfaces not caught by the old implementation", | |
901 | @future_incompatible = FutureIncompatibleInfo { | |
902 | reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>", | |
903 | edition: None, | |
904 | }; | |
905 | } | |
906 | ||
907 | declare_lint! { | |
908 | /// The `exported_private_dependencies` lint detects private dependencies | |
909 | /// that are exposed in a public interface. | |
910 | /// | |
911 | /// ### Example | |
912 | /// | |
913 | /// ```rust,ignore (needs-dependency) | |
914 | /// pub fn foo() -> Option<some_private_dependency::Thing> { | |
915 | /// None | |
916 | /// } | |
917 | /// ``` | |
918 | /// | |
919 | /// This will produce: | |
920 | /// | |
921 | /// ```text | |
922 | /// warning: type `bar::Thing` from private dependency 'bar' in public interface | |
923 | /// --> src/lib.rs:3:1 | |
924 | /// | | |
925 | /// 3 | pub fn foo() -> Option<bar::Thing> { | |
926 | /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
927 | /// | | |
928 | /// = note: `#[warn(exported_private_dependencies)]` on by default | |
929 | /// ``` | |
930 | /// | |
931 | /// ### Explanation | |
932 | /// | |
933 | /// Dependencies can be marked as "private" to indicate that they are not | |
934 | /// exposed in the public interface of a crate. This can be used by Cargo | |
935 | /// to independently resolve those dependencies because it can assume it | |
936 | /// does not need to unify them with other packages using that same | |
937 | /// dependency. This lint is an indication of a violation of that | |
938 | /// contract. | |
939 | /// | |
940 | /// To fix this, avoid exposing the dependency in your public interface. | |
941 | /// Or, switch the dependency to a public dependency. | |
942 | /// | |
943 | /// Note that support for this is only available on the nightly channel. | |
944 | /// See [RFC 1977] for more details, as well as the [Cargo documentation]. | |
945 | /// | |
946 | /// [RFC 1977]: https://github.com/rust-lang/rfcs/blob/master/text/1977-public-private-dependencies.md | |
947 | /// [Cargo documentation]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#public-dependency | |
948 | pub EXPORTED_PRIVATE_DEPENDENCIES, | |
949 | Warn, | |
950 | "public interface leaks type from a private dependency" | |
951 | } | |
952 | ||
953 | declare_lint! { | |
954 | /// The `pub_use_of_private_extern_crate` lint detects a specific | |
955 | /// situation of re-exporting a private `extern crate`. | |
956 | /// | |
957 | /// ### Example | |
958 | /// | |
959 | /// ```rust,compile_fail | |
960 | /// extern crate core; | |
961 | /// pub use core as reexported_core; | |
962 | /// ``` | |
963 | /// | |
964 | /// {{produces}} | |
965 | /// | |
966 | /// ### Explanation | |
967 | /// | |
968 | /// A public `use` declaration should not be used to publicly re-export a | |
969 | /// private `extern crate`. `pub extern crate` should be used instead. | |
970 | /// | |
971 | /// This was historically allowed, but is not the intended behavior | |
972 | /// according to the visibility rules. This is a [future-incompatible] | |
973 | /// lint to transition this to a hard error in the future. See [issue | |
974 | /// #34537] for more details. | |
975 | /// | |
976 | /// [issue #34537]: https://github.com/rust-lang/rust/issues/34537 | |
977 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
978 | pub PUB_USE_OF_PRIVATE_EXTERN_CRATE, | |
979 | Deny, | |
980 | "detect public re-exports of private extern crates", | |
981 | @future_incompatible = FutureIncompatibleInfo { | |
982 | reference: "issue #34537 <https://github.com/rust-lang/rust/issues/34537>", | |
983 | edition: None, | |
984 | }; | |
985 | } | |
986 | ||
987 | declare_lint! { | |
988 | /// The `invalid_type_param_default` lint detects type parameter defaults | |
989 | /// erroneously allowed in an invalid location. | |
990 | /// | |
991 | /// ### Example | |
992 | /// | |
993 | /// ```rust,compile_fail | |
994 | /// fn foo<T=i32>(t: T) {} | |
995 | /// ``` | |
996 | /// | |
997 | /// {{produces}} | |
998 | /// | |
999 | /// ### Explanation | |
1000 | /// | |
1001 | /// Default type parameters were only intended to be allowed in certain | |
1002 | /// situations, but historically the compiler allowed them everywhere. | |
1003 | /// This is a [future-incompatible] lint to transition this to a hard | |
1004 | /// error in the future. See [issue #36887] for more details. | |
1005 | /// | |
1006 | /// [issue #36887]: https://github.com/rust-lang/rust/issues/36887 | |
1007 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
1008 | pub INVALID_TYPE_PARAM_DEFAULT, | |
1009 | Deny, | |
1010 | "type parameter default erroneously allowed in invalid location", | |
1011 | @future_incompatible = FutureIncompatibleInfo { | |
1012 | reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>", | |
1013 | edition: None, | |
1014 | }; | |
1015 | } | |
1016 | ||
1017 | declare_lint! { | |
1018 | /// The `renamed_and_removed_lints` lint detects lints that have been | |
1019 | /// renamed or removed. | |
1020 | /// | |
1021 | /// ### Example | |
1022 | /// | |
1023 | /// ```rust | |
1024 | /// #![deny(raw_pointer_derive)] | |
1025 | /// ``` | |
1026 | /// | |
1027 | /// {{produces}} | |
1028 | /// | |
1029 | /// ### Explanation | |
1030 | /// | |
1031 | /// To fix this, either remove the lint or use the new name. This can help | |
1032 | /// avoid confusion about lints that are no longer valid, and help | |
1033 | /// maintain consistency for renamed lints. | |
1034 | pub RENAMED_AND_REMOVED_LINTS, | |
1035 | Warn, | |
1036 | "lints that have been renamed or removed" | |
1037 | } | |
1038 | ||
1039 | declare_lint! { | |
1040 | /// The `unaligned_references` lint detects unaligned references to fields | |
1041 | /// of [packed] structs. | |
1042 | /// | |
1043 | /// [packed]: https://doc.rust-lang.org/reference/type-layout.html#the-alignment-modifiers | |
1044 | /// | |
1045 | /// ### Example | |
1046 | /// | |
1047 | /// ```rust,compile_fail | |
1048 | /// #![deny(unaligned_references)] | |
1049 | /// | |
1050 | /// #[repr(packed)] | |
1051 | /// pub struct Foo { | |
1052 | /// field1: u64, | |
1053 | /// field2: u8, | |
1054 | /// } | |
1055 | /// | |
1056 | /// fn main() { | |
1057 | /// unsafe { | |
1058 | /// let foo = Foo { field1: 0, field2: 0 }; | |
1059 | /// let _ = &foo.field1; | |
cdc7bbd5 | 1060 | /// println!("{}", foo.field1); // An implicit `&` is added here, triggering the lint. |
1b1a35ee XL |
1061 | /// } |
1062 | /// } | |
1063 | /// ``` | |
1064 | /// | |
1065 | /// {{produces}} | |
1066 | /// | |
1067 | /// ### Explanation | |
1068 | /// | |
cdc7bbd5 XL |
1069 | /// Creating a reference to an insufficiently aligned packed field is [undefined behavior] and |
1070 | /// should be disallowed. Using an `unsafe` block does not change anything about this. Instead, | |
1071 | /// the code should do a copy of the data in the packed field or use raw pointers and unaligned | |
1072 | /// accesses. See [issue #82523] for more information. | |
1b1a35ee XL |
1073 | /// |
1074 | /// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html | |
cdc7bbd5 | 1075 | /// [issue #82523]: https://github.com/rust-lang/rust/issues/82523 |
1b1a35ee | 1076 | pub UNALIGNED_REFERENCES, |
cdc7bbd5 | 1077 | Warn, |
1b1a35ee | 1078 | "detects unaligned references to fields of packed structs", |
cdc7bbd5 XL |
1079 | @future_incompatible = FutureIncompatibleInfo { |
1080 | reference: "issue #82523 <https://github.com/rust-lang/rust/issues/82523>", | |
1081 | edition: None, | |
1082 | }; | |
6a06907d | 1083 | report_in_external_macro |
1b1a35ee XL |
1084 | } |
1085 | ||
1086 | declare_lint! { | |
1087 | /// The `const_item_mutation` lint detects attempts to mutate a `const` | |
1088 | /// item. | |
1089 | /// | |
1090 | /// ### Example | |
1091 | /// | |
1092 | /// ```rust | |
1093 | /// const FOO: [i32; 1] = [0]; | |
1094 | /// | |
1095 | /// fn main() { | |
1096 | /// FOO[0] = 1; | |
1097 | /// // This will print "[0]". | |
1098 | /// println!("{:?}", FOO); | |
1099 | /// } | |
1100 | /// ``` | |
1101 | /// | |
1102 | /// {{produces}} | |
1103 | /// | |
1104 | /// ### Explanation | |
1105 | /// | |
1106 | /// Trying to directly mutate a `const` item is almost always a mistake. | |
1107 | /// What is happening in the example above is that a temporary copy of the | |
1108 | /// `const` is mutated, but the original `const` is not. Each time you | |
1109 | /// refer to the `const` by name (such as `FOO` in the example above), a | |
1110 | /// separate copy of the value is inlined at that location. | |
1111 | /// | |
1112 | /// This lint checks for writing directly to a field (`FOO.field = | |
1113 | /// some_value`) or array entry (`FOO[0] = val`), or taking a mutable | |
1114 | /// reference to the const item (`&mut FOO`), including through an | |
1115 | /// autoderef (`FOO.some_mut_self_method()`). | |
1116 | /// | |
1117 | /// There are various alternatives depending on what you are trying to | |
1118 | /// accomplish: | |
1119 | /// | |
1120 | /// * First, always reconsider using mutable globals, as they can be | |
1121 | /// difficult to use correctly, and can make the code more difficult to | |
1122 | /// use or understand. | |
1123 | /// * If you are trying to perform a one-time initialization of a global: | |
1124 | /// * If the value can be computed at compile-time, consider using | |
1125 | /// const-compatible values (see [Constant Evaluation]). | |
1126 | /// * For more complex single-initialization cases, consider using a | |
1127 | /// third-party crate, such as [`lazy_static`] or [`once_cell`]. | |
1128 | /// * If you are using the [nightly channel], consider the new | |
1129 | /// [`lazy`] module in the standard library. | |
1130 | /// * If you truly need a mutable global, consider using a [`static`], | |
1131 | /// which has a variety of options: | |
1132 | /// * Simple data types can be directly defined and mutated with an | |
1133 | /// [`atomic`] type. | |
1134 | /// * More complex types can be placed in a synchronization primitive | |
1135 | /// like a [`Mutex`], which can be initialized with one of the options | |
1136 | /// listed above. | |
1137 | /// * A [mutable `static`] is a low-level primitive, requiring unsafe. | |
1138 | /// Typically This should be avoided in preference of something | |
1139 | /// higher-level like one of the above. | |
1140 | /// | |
1141 | /// [Constant Evaluation]: https://doc.rust-lang.org/reference/const_eval.html | |
1142 | /// [`static`]: https://doc.rust-lang.org/reference/items/static-items.html | |
1143 | /// [mutable `static`]: https://doc.rust-lang.org/reference/items/static-items.html#mutable-statics | |
1144 | /// [`lazy`]: https://doc.rust-lang.org/nightly/std/lazy/index.html | |
1145 | /// [`lazy_static`]: https://crates.io/crates/lazy_static | |
1146 | /// [`once_cell`]: https://crates.io/crates/once_cell | |
1147 | /// [`atomic`]: https://doc.rust-lang.org/std/sync/atomic/index.html | |
1148 | /// [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html | |
1149 | pub CONST_ITEM_MUTATION, | |
1150 | Warn, | |
1151 | "detects attempts to mutate a `const` item", | |
1152 | } | |
1153 | ||
1b1a35ee XL |
1154 | declare_lint! { |
1155 | /// The `patterns_in_fns_without_body` lint detects `mut` identifier | |
1156 | /// patterns as a parameter in functions without a body. | |
1157 | /// | |
1158 | /// ### Example | |
1159 | /// | |
1160 | /// ```rust,compile_fail | |
1161 | /// trait Trait { | |
1162 | /// fn foo(mut arg: u8); | |
1163 | /// } | |
1164 | /// ``` | |
1165 | /// | |
1166 | /// {{produces}} | |
1167 | /// | |
1168 | /// ### Explanation | |
1169 | /// | |
1170 | /// To fix this, remove `mut` from the parameter in the trait definition; | |
1171 | /// it can be used in the implementation. That is, the following is OK: | |
1172 | /// | |
1173 | /// ```rust | |
1174 | /// trait Trait { | |
1175 | /// fn foo(arg: u8); // Removed `mut` here | |
1176 | /// } | |
1177 | /// | |
1178 | /// impl Trait for i32 { | |
1179 | /// fn foo(mut arg: u8) { // `mut` here is OK | |
1180 | /// | |
1181 | /// } | |
1182 | /// } | |
1183 | /// ``` | |
1184 | /// | |
1185 | /// Trait definitions can define functions without a body to specify a | |
1186 | /// function that implementors must define. The parameter names in the | |
1187 | /// body-less functions are only allowed to be `_` or an [identifier] for | |
1188 | /// documentation purposes (only the type is relevant). Previous versions | |
1189 | /// of the compiler erroneously allowed [identifier patterns] with the | |
1190 | /// `mut` keyword, but this was not intended to be allowed. This is a | |
1191 | /// [future-incompatible] lint to transition this to a hard error in the | |
1192 | /// future. See [issue #35203] for more details. | |
1193 | /// | |
1194 | /// [identifier]: https://doc.rust-lang.org/reference/identifiers.html | |
1195 | /// [identifier patterns]: https://doc.rust-lang.org/reference/patterns.html#identifier-patterns | |
1196 | /// [issue #35203]: https://github.com/rust-lang/rust/issues/35203 | |
1197 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
1198 | pub PATTERNS_IN_FNS_WITHOUT_BODY, | |
1199 | Deny, | |
1200 | "patterns in functions without body were erroneously allowed", | |
1201 | @future_incompatible = FutureIncompatibleInfo { | |
1202 | reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>", | |
1203 | edition: None, | |
1204 | }; | |
1205 | } | |
1206 | ||
b9856134 XL |
1207 | declare_lint! { |
1208 | /// The `missing_fragment_specifier` lint is issued when an unused pattern in a | |
1209 | /// `macro_rules!` macro definition has a meta-variable (e.g. `$e`) that is not | |
1210 | /// followed by a fragment specifier (e.g. `:expr`). | |
1211 | /// | |
1212 | /// This warning can always be fixed by removing the unused pattern in the | |
1213 | /// `macro_rules!` macro definition. | |
1214 | /// | |
1215 | /// ### Example | |
1216 | /// | |
1217 | /// ```rust,compile_fail | |
1218 | /// macro_rules! foo { | |
1219 | /// () => {}; | |
1220 | /// ($name) => { }; | |
1221 | /// } | |
1222 | /// | |
1223 | /// fn main() { | |
1224 | /// foo!(); | |
1225 | /// } | |
1226 | /// ``` | |
1227 | /// | |
1228 | /// {{produces}} | |
1229 | /// | |
1230 | /// ### Explanation | |
1231 | /// | |
1232 | /// To fix this, remove the unused pattern from the `macro_rules!` macro definition: | |
1233 | /// | |
1234 | /// ```rust | |
1235 | /// macro_rules! foo { | |
1236 | /// () => {}; | |
1237 | /// } | |
1238 | /// fn main() { | |
1239 | /// foo!(); | |
1240 | /// } | |
1241 | /// ``` | |
1242 | pub MISSING_FRAGMENT_SPECIFIER, | |
1243 | Deny, | |
1244 | "detects missing fragment specifiers in unused `macro_rules!` patterns", | |
1245 | @future_incompatible = FutureIncompatibleInfo { | |
1246 | reference: "issue #40107 <https://github.com/rust-lang/rust/issues/40107>", | |
1247 | edition: None, | |
1248 | }; | |
1249 | } | |
1250 | ||
1b1a35ee XL |
1251 | declare_lint! { |
1252 | /// The `late_bound_lifetime_arguments` lint detects generic lifetime | |
1253 | /// arguments in path segments with late bound lifetime parameters. | |
1254 | /// | |
1255 | /// ### Example | |
1256 | /// | |
1257 | /// ```rust | |
1258 | /// struct S; | |
1259 | /// | |
1260 | /// impl S { | |
1261 | /// fn late<'a, 'b>(self, _: &'a u8, _: &'b u8) {} | |
1262 | /// } | |
1263 | /// | |
1264 | /// fn main() { | |
1265 | /// S.late::<'static>(&0, &0); | |
1266 | /// } | |
1267 | /// ``` | |
1268 | /// | |
1269 | /// {{produces}} | |
1270 | /// | |
1271 | /// ### Explanation | |
1272 | /// | |
1273 | /// It is not clear how to provide arguments for early-bound lifetime | |
1274 | /// parameters if they are intermixed with late-bound parameters in the | |
1275 | /// same list. For now, providing any explicit arguments will trigger this | |
1276 | /// lint if late-bound parameters are present, so in the future a solution | |
1277 | /// can be adopted without hitting backward compatibility issues. This is | |
1278 | /// a [future-incompatible] lint to transition this to a hard error in the | |
1279 | /// future. See [issue #42868] for more details, along with a description | |
1280 | /// of the difference between early and late-bound parameters. | |
1281 | /// | |
1282 | /// [issue #42868]: https://github.com/rust-lang/rust/issues/42868 | |
1283 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
1284 | pub LATE_BOUND_LIFETIME_ARGUMENTS, | |
1285 | Warn, | |
1286 | "detects generic lifetime arguments in path segments with late bound lifetime parameters", | |
1287 | @future_incompatible = FutureIncompatibleInfo { | |
1288 | reference: "issue #42868 <https://github.com/rust-lang/rust/issues/42868>", | |
1289 | edition: None, | |
1290 | }; | |
1291 | } | |
1292 | ||
1293 | declare_lint! { | |
1294 | /// The `order_dependent_trait_objects` lint detects a trait coherency | |
1295 | /// violation that would allow creating two trait impls for the same | |
1296 | /// dynamic trait object involving marker traits. | |
1297 | /// | |
1298 | /// ### Example | |
1299 | /// | |
1300 | /// ```rust,compile_fail | |
1301 | /// pub trait Trait {} | |
1302 | /// | |
1303 | /// impl Trait for dyn Send + Sync { } | |
1304 | /// impl Trait for dyn Sync + Send { } | |
1305 | /// ``` | |
1306 | /// | |
1307 | /// {{produces}} | |
1308 | /// | |
1309 | /// ### Explanation | |
1310 | /// | |
1311 | /// A previous bug caused the compiler to interpret traits with different | |
1312 | /// orders (such as `Send + Sync` and `Sync + Send`) as distinct types | |
1313 | /// when they were intended to be treated the same. This allowed code to | |
1314 | /// define separate trait implementations when there should be a coherence | |
1315 | /// error. This is a [future-incompatible] lint to transition this to a | |
1316 | /// hard error in the future. See [issue #56484] for more details. | |
1317 | /// | |
1318 | /// [issue #56484]: https://github.com/rust-lang/rust/issues/56484 | |
1319 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
1320 | pub ORDER_DEPENDENT_TRAIT_OBJECTS, | |
1321 | Deny, | |
1322 | "trait-object types were treated as different depending on marker-trait order", | |
1323 | @future_incompatible = FutureIncompatibleInfo { | |
1324 | reference: "issue #56484 <https://github.com/rust-lang/rust/issues/56484>", | |
1325 | edition: None, | |
1326 | }; | |
1327 | } | |
1328 | ||
1329 | declare_lint! { | |
1330 | /// The `coherence_leak_check` lint detects conflicting implementations of | |
1331 | /// a trait that are only distinguished by the old leak-check code. | |
1332 | /// | |
1333 | /// ### Example | |
1334 | /// | |
1335 | /// ```rust | |
1336 | /// trait SomeTrait { } | |
1337 | /// impl SomeTrait for for<'a> fn(&'a u8) { } | |
1338 | /// impl<'a> SomeTrait for fn(&'a u8) { } | |
1339 | /// ``` | |
1340 | /// | |
1341 | /// {{produces}} | |
1342 | /// | |
1343 | /// ### Explanation | |
1344 | /// | |
1345 | /// In the past, the compiler would accept trait implementations for | |
1346 | /// identical functions that differed only in where the lifetime binder | |
1347 | /// appeared. Due to a change in the borrow checker implementation to fix | |
1348 | /// several bugs, this is no longer allowed. However, since this affects | |
1349 | /// existing code, this is a [future-incompatible] lint to transition this | |
1350 | /// to a hard error in the future. | |
1351 | /// | |
1352 | /// Code relying on this pattern should introduce "[newtypes]", | |
1353 | /// like `struct Foo(for<'a> fn(&'a u8))`. | |
1354 | /// | |
1355 | /// See [issue #56105] for more details. | |
1356 | /// | |
1357 | /// [issue #56105]: https://github.com/rust-lang/rust/issues/56105 | |
1358 | /// [newtypes]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction | |
1359 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
1360 | pub COHERENCE_LEAK_CHECK, | |
1361 | Warn, | |
1362 | "distinct impls distinguished only by the leak-check code", | |
1363 | @future_incompatible = FutureIncompatibleInfo { | |
1364 | reference: "issue #56105 <https://github.com/rust-lang/rust/issues/56105>", | |
1365 | edition: None, | |
1366 | }; | |
1367 | } | |
1368 | ||
1369 | declare_lint! { | |
1370 | /// The `deprecated` lint detects use of deprecated items. | |
1371 | /// | |
1372 | /// ### Example | |
1373 | /// | |
1374 | /// ```rust | |
1375 | /// #[deprecated] | |
1376 | /// fn foo() {} | |
1377 | /// | |
1378 | /// fn bar() { | |
1379 | /// foo(); | |
1380 | /// } | |
1381 | /// ``` | |
1382 | /// | |
1383 | /// {{produces}} | |
1384 | /// | |
1385 | /// ### Explanation | |
1386 | /// | |
1387 | /// Items may be marked "deprecated" with the [`deprecated` attribute] to | |
1388 | /// indicate that they should no longer be used. Usually the attribute | |
1389 | /// should include a note on what to use instead, or check the | |
1390 | /// documentation. | |
1391 | /// | |
1392 | /// [`deprecated` attribute]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute | |
1393 | pub DEPRECATED, | |
1394 | Warn, | |
1395 | "detects use of deprecated items", | |
1396 | report_in_external_macro | |
1397 | } | |
1398 | ||
1399 | declare_lint! { | |
1400 | /// The `unused_unsafe` lint detects unnecessary use of an `unsafe` block. | |
1401 | /// | |
1402 | /// ### Example | |
1403 | /// | |
1404 | /// ```rust | |
1405 | /// unsafe {} | |
1406 | /// ``` | |
1407 | /// | |
1408 | /// {{produces}} | |
1409 | /// | |
1410 | /// ### Explanation | |
1411 | /// | |
1412 | /// If nothing within the block requires `unsafe`, then remove the | |
1413 | /// `unsafe` marker because it is not required and may cause confusion. | |
1414 | pub UNUSED_UNSAFE, | |
1415 | Warn, | |
1416 | "unnecessary use of an `unsafe` block" | |
1417 | } | |
1418 | ||
1419 | declare_lint! { | |
1420 | /// The `unused_mut` lint detects mut variables which don't need to be | |
1421 | /// mutable. | |
1422 | /// | |
1423 | /// ### Example | |
1424 | /// | |
1425 | /// ```rust | |
1426 | /// let mut x = 5; | |
1427 | /// ``` | |
1428 | /// | |
1429 | /// {{produces}} | |
1430 | /// | |
1431 | /// ### Explanation | |
1432 | /// | |
1433 | /// The preferred style is to only mark variables as `mut` if it is | |
1434 | /// required. | |
1435 | pub UNUSED_MUT, | |
1436 | Warn, | |
1437 | "detect mut variables which don't need to be mutable" | |
1438 | } | |
1439 | ||
1440 | declare_lint! { | |
1441 | /// The `unconditional_recursion` lint detects functions that cannot | |
1442 | /// return without calling themselves. | |
1443 | /// | |
1444 | /// ### Example | |
1445 | /// | |
1446 | /// ```rust | |
1447 | /// fn foo() { | |
1448 | /// foo(); | |
1449 | /// } | |
1450 | /// ``` | |
1451 | /// | |
1452 | /// {{produces}} | |
1453 | /// | |
1454 | /// ### Explanation | |
1455 | /// | |
1456 | /// It is usually a mistake to have a recursive call that does not have | |
1457 | /// some condition to cause it to terminate. If you really intend to have | |
1458 | /// an infinite loop, using a `loop` expression is recommended. | |
1459 | pub UNCONDITIONAL_RECURSION, | |
1460 | Warn, | |
1461 | "functions that cannot return without calling themselves" | |
1462 | } | |
1463 | ||
1464 | declare_lint! { | |
1465 | /// The `single_use_lifetimes` lint detects lifetimes that are only used | |
1466 | /// once. | |
1467 | /// | |
1468 | /// ### Example | |
1469 | /// | |
1470 | /// ```rust,compile_fail | |
1471 | /// #![deny(single_use_lifetimes)] | |
1472 | /// | |
1473 | /// fn foo<'a>(x: &'a u32) {} | |
1474 | /// ``` | |
1475 | /// | |
1476 | /// {{produces}} | |
1477 | /// | |
1478 | /// ### Explanation | |
1479 | /// | |
1480 | /// Specifying an explicit lifetime like `'a` in a function or `impl` | |
1481 | /// should only be used to link together two things. Otherwise, you should | |
1482 | /// just use `'_` to indicate that the lifetime is not linked to anything, | |
1483 | /// or elide the lifetime altogether if possible. | |
1484 | /// | |
1485 | /// This lint is "allow" by default because it was introduced at a time | |
1486 | /// when `'_` and elided lifetimes were first being introduced, and this | |
1487 | /// lint would be too noisy. Also, there are some known false positives | |
1488 | /// that it produces. See [RFC 2115] for historical context, and [issue | |
1489 | /// #44752] for more details. | |
1490 | /// | |
1491 | /// [RFC 2115]: https://github.com/rust-lang/rfcs/blob/master/text/2115-argument-lifetimes.md | |
1492 | /// [issue #44752]: https://github.com/rust-lang/rust/issues/44752 | |
1493 | pub SINGLE_USE_LIFETIMES, | |
1494 | Allow, | |
1495 | "detects lifetime parameters that are only used once" | |
1496 | } | |
1497 | ||
1498 | declare_lint! { | |
1499 | /// The `unused_lifetimes` lint detects lifetime parameters that are never | |
1500 | /// used. | |
1501 | /// | |
1502 | /// ### Example | |
1503 | /// | |
1504 | /// ```rust,compile_fail | |
1505 | /// #[deny(unused_lifetimes)] | |
1506 | /// | |
1507 | /// pub fn foo<'a>() {} | |
1508 | /// ``` | |
1509 | /// | |
1510 | /// {{produces}} | |
1511 | /// | |
1512 | /// ### Explanation | |
1513 | /// | |
1514 | /// Unused lifetime parameters may signal a mistake or unfinished code. | |
1515 | /// Consider removing the parameter. | |
1516 | pub UNUSED_LIFETIMES, | |
1517 | Allow, | |
1518 | "detects lifetime parameters that are never used" | |
1519 | } | |
1520 | ||
1521 | declare_lint! { | |
1522 | /// The `tyvar_behind_raw_pointer` lint detects raw pointer to an | |
1523 | /// inference variable. | |
1524 | /// | |
1525 | /// ### Example | |
1526 | /// | |
1527 | /// ```rust,edition2015 | |
1528 | /// // edition 2015 | |
1529 | /// let data = std::ptr::null(); | |
1530 | /// let _ = &data as *const *const (); | |
1531 | /// | |
1532 | /// if data.is_null() {} | |
1533 | /// ``` | |
1534 | /// | |
1535 | /// {{produces}} | |
1536 | /// | |
1537 | /// ### Explanation | |
1538 | /// | |
1539 | /// This kind of inference was previously allowed, but with the future | |
1540 | /// arrival of [arbitrary self types], this can introduce ambiguity. To | |
1541 | /// resolve this, use an explicit type instead of relying on type | |
1542 | /// inference. | |
1543 | /// | |
1544 | /// This is a [future-incompatible] lint to transition this to a hard | |
1545 | /// error in the 2018 edition. See [issue #46906] for more details. This | |
1546 | /// is currently a hard-error on the 2018 edition, and is "warn" by | |
1547 | /// default in the 2015 edition. | |
1548 | /// | |
1549 | /// [arbitrary self types]: https://github.com/rust-lang/rust/issues/44874 | |
1550 | /// [issue #46906]: https://github.com/rust-lang/rust/issues/46906 | |
1551 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
1552 | pub TYVAR_BEHIND_RAW_POINTER, | |
1553 | Warn, | |
1554 | "raw pointer to an inference variable", | |
1555 | @future_incompatible = FutureIncompatibleInfo { | |
1556 | reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>", | |
1557 | edition: Some(Edition::Edition2018), | |
1558 | }; | |
1559 | } | |
1560 | ||
1561 | declare_lint! { | |
1562 | /// The `elided_lifetimes_in_paths` lint detects the use of hidden | |
1563 | /// lifetime parameters. | |
1564 | /// | |
1565 | /// ### Example | |
1566 | /// | |
1567 | /// ```rust,compile_fail | |
1568 | /// #![deny(elided_lifetimes_in_paths)] | |
1569 | /// struct Foo<'a> { | |
1570 | /// x: &'a u32 | |
1571 | /// } | |
1572 | /// | |
1573 | /// fn foo(x: &Foo) { | |
1574 | /// } | |
1575 | /// ``` | |
1576 | /// | |
1577 | /// {{produces}} | |
1578 | /// | |
1579 | /// ### Explanation | |
1580 | /// | |
1581 | /// Elided lifetime parameters can make it difficult to see at a glance | |
1582 | /// that borrowing is occurring. This lint ensures that lifetime | |
1583 | /// parameters are always explicitly stated, even if it is the `'_` | |
1584 | /// [placeholder lifetime]. | |
1585 | /// | |
1586 | /// This lint is "allow" by default because it has some known issues, and | |
1587 | /// may require a significant transition for old code. | |
1588 | /// | |
1589 | /// [placeholder lifetime]: https://doc.rust-lang.org/reference/lifetime-elision.html#lifetime-elision-in-functions | |
1590 | pub ELIDED_LIFETIMES_IN_PATHS, | |
1591 | Allow, | |
1592 | "hidden lifetime parameters in types are deprecated", | |
1593 | crate_level_only | |
1594 | } | |
1595 | ||
1596 | declare_lint! { | |
1597 | /// The `bare_trait_objects` lint suggests using `dyn Trait` for trait | |
1598 | /// objects. | |
1599 | /// | |
1600 | /// ### Example | |
1601 | /// | |
1602 | /// ```rust | |
1603 | /// trait Trait { } | |
1604 | /// | |
1605 | /// fn takes_trait_object(_: Box<Trait>) { | |
1606 | /// } | |
1607 | /// ``` | |
1608 | /// | |
1609 | /// {{produces}} | |
1610 | /// | |
1611 | /// ### Explanation | |
1612 | /// | |
1613 | /// Without the `dyn` indicator, it can be ambiguous or confusing when | |
1614 | /// reading code as to whether or not you are looking at a trait object. | |
1615 | /// The `dyn` keyword makes it explicit, and adds a symmetry to contrast | |
1616 | /// with [`impl Trait`]. | |
1617 | /// | |
1618 | /// [`impl Trait`]: https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters | |
1619 | pub BARE_TRAIT_OBJECTS, | |
1620 | Warn, | |
17df50a5 XL |
1621 | "suggest using `dyn Trait` for trait objects", |
1622 | @future_incompatible = FutureIncompatibleInfo { | |
1623 | reference: "issue #80165 <https://github.com/rust-lang/rust/issues/80165>", | |
1624 | edition: Some(Edition::Edition2021), | |
1625 | }; | |
1b1a35ee XL |
1626 | } |
1627 | ||
1628 | declare_lint! { | |
1629 | /// The `absolute_paths_not_starting_with_crate` lint detects fully | |
1630 | /// qualified paths that start with a module name instead of `crate`, | |
1631 | /// `self`, or an extern crate name | |
1632 | /// | |
1633 | /// ### Example | |
1634 | /// | |
1635 | /// ```rust,edition2015,compile_fail | |
1636 | /// #![deny(absolute_paths_not_starting_with_crate)] | |
1637 | /// | |
1638 | /// mod foo { | |
1639 | /// pub fn bar() {} | |
1640 | /// } | |
1641 | /// | |
1642 | /// fn main() { | |
1643 | /// ::foo::bar(); | |
1644 | /// } | |
1645 | /// ``` | |
1646 | /// | |
1647 | /// {{produces}} | |
1648 | /// | |
1649 | /// ### Explanation | |
1650 | /// | |
1651 | /// Rust [editions] allow the language to evolve without breaking | |
1652 | /// backwards compatibility. This lint catches code that uses absolute | |
1653 | /// paths in the style of the 2015 edition. In the 2015 edition, absolute | |
1654 | /// paths (those starting with `::`) refer to either the crate root or an | |
1655 | /// external crate. In the 2018 edition it was changed so that they only | |
1656 | /// refer to external crates. The path prefix `crate::` should be used | |
1657 | /// instead to reference items from the crate root. | |
1658 | /// | |
1659 | /// If you switch the compiler from the 2015 to 2018 edition without | |
1660 | /// updating the code, then it will fail to compile if the old style paths | |
1661 | /// are used. You can manually change the paths to use the `crate::` | |
1662 | /// prefix to transition to the 2018 edition. | |
1663 | /// | |
1664 | /// This lint solves the problem automatically. It is "allow" by default | |
1665 | /// because the code is perfectly valid in the 2015 edition. The [`cargo | |
1666 | /// fix`] tool with the `--edition` flag will switch this lint to "warn" | |
1667 | /// and automatically apply the suggested fix from the compiler. This | |
1668 | /// provides a completely automated way to update old code to the 2018 | |
1669 | /// edition. | |
1670 | /// | |
1671 | /// [editions]: https://doc.rust-lang.org/edition-guide/ | |
1672 | /// [`cargo fix`]: https://doc.rust-lang.org/cargo/commands/cargo-fix.html | |
1673 | pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, | |
1674 | Allow, | |
1675 | "fully qualified paths that start with a module name \ | |
1676 | instead of `crate`, `self`, or an extern crate name", | |
1677 | @future_incompatible = FutureIncompatibleInfo { | |
1678 | reference: "issue #53130 <https://github.com/rust-lang/rust/issues/53130>", | |
1679 | edition: Some(Edition::Edition2018), | |
1680 | }; | |
1681 | } | |
1682 | ||
1683 | declare_lint! { | |
1684 | /// The `illegal_floating_point_literal_pattern` lint detects | |
1685 | /// floating-point literals used in patterns. | |
1686 | /// | |
1687 | /// ### Example | |
1688 | /// | |
1689 | /// ```rust | |
1690 | /// let x = 42.0; | |
1691 | /// | |
1692 | /// match x { | |
1693 | /// 5.0 => {} | |
1694 | /// _ => {} | |
1695 | /// } | |
1696 | /// ``` | |
1697 | /// | |
1698 | /// {{produces}} | |
1699 | /// | |
1700 | /// ### Explanation | |
1701 | /// | |
1702 | /// Previous versions of the compiler accepted floating-point literals in | |
1703 | /// patterns, but it was later determined this was a mistake. The | |
1704 | /// semantics of comparing floating-point values may not be clear in a | |
1705 | /// pattern when contrasted with "structural equality". Typically you can | |
1706 | /// work around this by using a [match guard], such as: | |
1707 | /// | |
1708 | /// ```rust | |
1709 | /// # let x = 42.0; | |
1710 | /// | |
1711 | /// match x { | |
1712 | /// y if y == 5.0 => {} | |
1713 | /// _ => {} | |
1714 | /// } | |
1715 | /// ``` | |
1716 | /// | |
1717 | /// This is a [future-incompatible] lint to transition this to a hard | |
1718 | /// error in the future. See [issue #41620] for more details. | |
1719 | /// | |
1720 | /// [issue #41620]: https://github.com/rust-lang/rust/issues/41620 | |
1721 | /// [match guard]: https://doc.rust-lang.org/reference/expressions/match-expr.html#match-guards | |
1722 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
1723 | pub ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, | |
1724 | Warn, | |
1725 | "floating-point literals cannot be used in patterns", | |
1726 | @future_incompatible = FutureIncompatibleInfo { | |
1727 | reference: "issue #41620 <https://github.com/rust-lang/rust/issues/41620>", | |
1728 | edition: None, | |
1729 | }; | |
1730 | } | |
1731 | ||
1732 | declare_lint! { | |
1733 | /// The `unstable_name_collisions` lint detects that you have used a name | |
1734 | /// that the standard library plans to add in the future. | |
1735 | /// | |
1736 | /// ### Example | |
1737 | /// | |
1738 | /// ```rust | |
1739 | /// trait MyIterator : Iterator { | |
1740 | /// // is_sorted is an unstable method that already exists on the Iterator trait | |
1741 | /// fn is_sorted(self) -> bool where Self: Sized {true} | |
1742 | /// } | |
1743 | /// | |
1744 | /// impl<T: ?Sized> MyIterator for T where T: Iterator { } | |
1745 | /// | |
fc512014 | 1746 | /// let x = vec![1, 2, 3]; |
1b1a35ee XL |
1747 | /// let _ = x.iter().is_sorted(); |
1748 | /// ``` | |
1749 | /// | |
1750 | /// {{produces}} | |
1751 | /// | |
1752 | /// ### Explanation | |
1753 | /// | |
1754 | /// When new methods are added to traits in the standard library, they are | |
1755 | /// usually added in an "unstable" form which is only available on the | |
1756 | /// [nightly channel] with a [`feature` attribute]. If there is any | |
1757 | /// pre-existing code which extends a trait to have a method with the same | |
1758 | /// name, then the names will collide. In the future, when the method is | |
1759 | /// stabilized, this will cause an error due to the ambiguity. This lint | |
1760 | /// is an early-warning to let you know that there may be a collision in | |
1761 | /// the future. This can be avoided by adding type annotations to | |
1762 | /// disambiguate which trait method you intend to call, such as | |
1763 | /// `MyIterator::is_sorted(my_iter)` or renaming or removing the method. | |
1764 | /// | |
1765 | /// [nightly channel]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html | |
1766 | /// [`feature` attribute]: https://doc.rust-lang.org/nightly/unstable-book/ | |
1767 | pub UNSTABLE_NAME_COLLISIONS, | |
1768 | Warn, | |
1769 | "detects name collision with an existing but unstable method", | |
1770 | @future_incompatible = FutureIncompatibleInfo { | |
1771 | reference: "issue #48919 <https://github.com/rust-lang/rust/issues/48919>", | |
1772 | edition: None, | |
1773 | // Note: this item represents future incompatibility of all unstable functions in the | |
1774 | // standard library, and thus should never be removed or changed to an error. | |
1775 | }; | |
1776 | } | |
1777 | ||
1778 | declare_lint! { | |
6a06907d XL |
1779 | /// The `irrefutable_let_patterns` lint detects [irrefutable patterns] |
1780 | /// in [`if let`]s, [`while let`]s, and `if let` guards. | |
1b1a35ee XL |
1781 | /// |
1782 | /// ### Example | |
1783 | /// | |
6a06907d | 1784 | /// ``` |
1b1a35ee XL |
1785 | /// if let _ = 123 { |
1786 | /// println!("always runs!"); | |
1787 | /// } | |
1788 | /// ``` | |
1789 | /// | |
1790 | /// {{produces}} | |
1791 | /// | |
1792 | /// ### Explanation | |
1793 | /// | |
1794 | /// There usually isn't a reason to have an irrefutable pattern in an | |
6a06907d | 1795 | /// `if let` or `while let` statement, because the pattern will always match |
1b1a35ee XL |
1796 | /// successfully. A [`let`] or [`loop`] statement will suffice. However, |
1797 | /// when generating code with a macro, forbidding irrefutable patterns | |
1798 | /// would require awkward workarounds in situations where the macro | |
1799 | /// doesn't know if the pattern is refutable or not. This lint allows | |
1800 | /// macros to accept this form, while alerting for a possibly incorrect | |
1801 | /// use in normal code. | |
1802 | /// | |
1803 | /// See [RFC 2086] for more details. | |
1804 | /// | |
1805 | /// [irrefutable patterns]: https://doc.rust-lang.org/reference/patterns.html#refutability | |
6a06907d XL |
1806 | /// [`if let`]: https://doc.rust-lang.org/reference/expressions/if-expr.html#if-let-expressions |
1807 | /// [`while let`]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-pattern-loops | |
1b1a35ee XL |
1808 | /// [`let`]: https://doc.rust-lang.org/reference/statements.html#let-statements |
1809 | /// [`loop`]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#infinite-loops | |
1810 | /// [RFC 2086]: https://github.com/rust-lang/rfcs/blob/master/text/2086-allow-if-let-irrefutables.md | |
1811 | pub IRREFUTABLE_LET_PATTERNS, | |
1812 | Warn, | |
6a06907d | 1813 | "detects irrefutable patterns in `if let` and `while let` statements" |
1b1a35ee XL |
1814 | } |
1815 | ||
1816 | declare_lint! { | |
1817 | /// The `unused_labels` lint detects [labels] that are never used. | |
1818 | /// | |
1819 | /// [labels]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#loop-labels | |
1820 | /// | |
1821 | /// ### Example | |
1822 | /// | |
1823 | /// ```rust,no_run | |
1824 | /// 'unused_label: loop {} | |
1825 | /// ``` | |
1826 | /// | |
1827 | /// {{produces}} | |
1828 | /// | |
1829 | /// ### Explanation | |
1830 | /// | |
1831 | /// Unused labels may signal a mistake or unfinished code. To silence the | |
1832 | /// warning for the individual label, prefix it with an underscore such as | |
1833 | /// `'_my_label:`. | |
1834 | pub UNUSED_LABELS, | |
1835 | Warn, | |
1836 | "detects labels that are never used" | |
1837 | } | |
1838 | ||
1b1a35ee XL |
1839 | declare_lint! { |
1840 | /// The `where_clauses_object_safety` lint detects for [object safety] of | |
1841 | /// [where clauses]. | |
1842 | /// | |
1843 | /// [object safety]: https://doc.rust-lang.org/reference/items/traits.html#object-safety | |
1844 | /// [where clauses]: https://doc.rust-lang.org/reference/items/generics.html#where-clauses | |
1845 | /// | |
1846 | /// ### Example | |
1847 | /// | |
1848 | /// ```rust,no_run | |
1849 | /// trait Trait {} | |
1850 | /// | |
1851 | /// trait X { fn foo(&self) where Self: Trait; } | |
1852 | /// | |
1853 | /// impl X for () { fn foo(&self) {} } | |
1854 | /// | |
1855 | /// impl Trait for dyn X {} | |
1856 | /// | |
1857 | /// // Segfault at opt-level 0, SIGILL otherwise. | |
1858 | /// pub fn main() { <dyn X as X>::foo(&()); } | |
1859 | /// ``` | |
1860 | /// | |
1861 | /// {{produces}} | |
1862 | /// | |
1863 | /// ### Explanation | |
1864 | /// | |
1865 | /// The compiler previously allowed these object-unsafe bounds, which was | |
1866 | /// incorrect. This is a [future-incompatible] lint to transition this to | |
1867 | /// a hard error in the future. See [issue #51443] for more details. | |
1868 | /// | |
1869 | /// [issue #51443]: https://github.com/rust-lang/rust/issues/51443 | |
1870 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
1871 | pub WHERE_CLAUSES_OBJECT_SAFETY, | |
1872 | Warn, | |
1873 | "checks the object safety of where clauses", | |
1874 | @future_incompatible = FutureIncompatibleInfo { | |
1875 | reference: "issue #51443 <https://github.com/rust-lang/rust/issues/51443>", | |
1876 | edition: None, | |
1877 | }; | |
1878 | } | |
1879 | ||
1880 | declare_lint! { | |
1881 | /// The `proc_macro_derive_resolution_fallback` lint detects proc macro | |
1882 | /// derives using inaccessible names from parent modules. | |
1883 | /// | |
1884 | /// ### Example | |
1885 | /// | |
1886 | /// ```rust,ignore (proc-macro) | |
1887 | /// // foo.rs | |
1888 | /// #![crate_type = "proc-macro"] | |
1889 | /// | |
1890 | /// extern crate proc_macro; | |
1891 | /// | |
1892 | /// use proc_macro::*; | |
1893 | /// | |
1894 | /// #[proc_macro_derive(Foo)] | |
1895 | /// pub fn foo1(a: TokenStream) -> TokenStream { | |
1896 | /// drop(a); | |
1897 | /// "mod __bar { static mut BAR: Option<Something> = None; }".parse().unwrap() | |
1898 | /// } | |
1899 | /// ``` | |
1900 | /// | |
1901 | /// ```rust,ignore (needs-dependency) | |
1902 | /// // bar.rs | |
1903 | /// #[macro_use] | |
1904 | /// extern crate foo; | |
1905 | /// | |
1906 | /// struct Something; | |
1907 | /// | |
1908 | /// #[derive(Foo)] | |
1909 | /// struct Another; | |
1910 | /// | |
1911 | /// fn main() {} | |
1912 | /// ``` | |
1913 | /// | |
1914 | /// This will produce: | |
1915 | /// | |
1916 | /// ```text | |
1917 | /// warning: cannot find type `Something` in this scope | |
1918 | /// --> src/main.rs:8:10 | |
1919 | /// | | |
1920 | /// 8 | #[derive(Foo)] | |
1921 | /// | ^^^ names from parent modules are not accessible without an explicit import | |
1922 | /// | | |
1923 | /// = note: `#[warn(proc_macro_derive_resolution_fallback)]` on by default | |
1924 | /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
1925 | /// = note: for more information, see issue #50504 <https://github.com/rust-lang/rust/issues/50504> | |
1926 | /// ``` | |
1927 | /// | |
1928 | /// ### Explanation | |
1929 | /// | |
1930 | /// If a proc-macro generates a module, the compiler unintentionally | |
1931 | /// allowed items in that module to refer to items in the crate root | |
1932 | /// without importing them. This is a [future-incompatible] lint to | |
1933 | /// transition this to a hard error in the future. See [issue #50504] for | |
1934 | /// more details. | |
1935 | /// | |
1936 | /// [issue #50504]: https://github.com/rust-lang/rust/issues/50504 | |
1937 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
1938 | pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, | |
1939 | Warn, | |
1940 | "detects proc macro derives using inaccessible names from parent modules", | |
1941 | @future_incompatible = FutureIncompatibleInfo { | |
cdc7bbd5 | 1942 | reference: "issue #83583 <https://github.com/rust-lang/rust/issues/83583>", |
1b1a35ee XL |
1943 | edition: None, |
1944 | }; | |
1945 | } | |
1946 | ||
1947 | declare_lint! { | |
1948 | /// The `macro_use_extern_crate` lint detects the use of the | |
1949 | /// [`macro_use` attribute]. | |
1950 | /// | |
1951 | /// ### Example | |
1952 | /// | |
1953 | /// ```rust,ignore (needs extern crate) | |
1954 | /// #![deny(macro_use_extern_crate)] | |
1955 | /// | |
1956 | /// #[macro_use] | |
1957 | /// extern crate serde_json; | |
1958 | /// | |
1959 | /// fn main() { | |
1960 | /// let _ = json!{{}}; | |
1961 | /// } | |
1962 | /// ``` | |
1963 | /// | |
1964 | /// This will produce: | |
1965 | /// | |
1966 | /// ```text | |
1967 | /// error: deprecated `#[macro_use]` attribute used to import macros should be replaced at use sites with a `use` item to import the macro instead | |
1968 | /// --> src/main.rs:3:1 | |
1969 | /// | | |
1970 | /// 3 | #[macro_use] | |
1971 | /// | ^^^^^^^^^^^^ | |
1972 | /// | | |
1973 | /// note: the lint level is defined here | |
1974 | /// --> src/main.rs:1:9 | |
1975 | /// | | |
1976 | /// 1 | #![deny(macro_use_extern_crate)] | |
1977 | /// | ^^^^^^^^^^^^^^^^^^^^^^ | |
1978 | /// ``` | |
1979 | /// | |
1980 | /// ### Explanation | |
1981 | /// | |
1982 | /// The [`macro_use` attribute] on an [`extern crate`] item causes | |
1983 | /// macros in that external crate to be brought into the prelude of the | |
1984 | /// crate, making the macros in scope everywhere. As part of the efforts | |
1985 | /// to simplify handling of dependencies in the [2018 edition], the use of | |
1986 | /// `extern crate` is being phased out. To bring macros from extern crates | |
1987 | /// into scope, it is recommended to use a [`use` import]. | |
1988 | /// | |
1989 | /// This lint is "allow" by default because this is a stylistic choice | |
1990 | /// that has not been settled, see [issue #52043] for more information. | |
1991 | /// | |
1992 | /// [`macro_use` attribute]: https://doc.rust-lang.org/reference/macros-by-example.html#the-macro_use-attribute | |
1993 | /// [`use` import]: https://doc.rust-lang.org/reference/items/use-declarations.html | |
1994 | /// [issue #52043]: https://github.com/rust-lang/rust/issues/52043 | |
1995 | pub MACRO_USE_EXTERN_CRATE, | |
1996 | Allow, | |
1997 | "the `#[macro_use]` attribute is now deprecated in favor of using macros \ | |
1998 | via the module system" | |
1999 | } | |
2000 | ||
2001 | declare_lint! { | |
2002 | /// The `macro_expanded_macro_exports_accessed_by_absolute_paths` lint | |
2003 | /// detects macro-expanded [`macro_export`] macros from the current crate | |
2004 | /// that cannot be referred to by absolute paths. | |
2005 | /// | |
2006 | /// [`macro_export`]: https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope | |
2007 | /// | |
2008 | /// ### Example | |
2009 | /// | |
2010 | /// ```rust,compile_fail | |
2011 | /// macro_rules! define_exported { | |
2012 | /// () => { | |
2013 | /// #[macro_export] | |
2014 | /// macro_rules! exported { | |
2015 | /// () => {}; | |
2016 | /// } | |
2017 | /// }; | |
2018 | /// } | |
2019 | /// | |
2020 | /// define_exported!(); | |
2021 | /// | |
2022 | /// fn main() { | |
2023 | /// crate::exported!(); | |
2024 | /// } | |
2025 | /// ``` | |
2026 | /// | |
2027 | /// {{produces}} | |
2028 | /// | |
2029 | /// ### Explanation | |
2030 | /// | |
2031 | /// The intent is that all macros marked with the `#[macro_export]` | |
2032 | /// attribute are made available in the root of the crate. However, when a | |
2033 | /// `macro_rules!` definition is generated by another macro, the macro | |
2034 | /// expansion is unable to uphold this rule. This is a | |
2035 | /// [future-incompatible] lint to transition this to a hard error in the | |
2036 | /// future. See [issue #53495] for more details. | |
2037 | /// | |
2038 | /// [issue #53495]: https://github.com/rust-lang/rust/issues/53495 | |
2039 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
2040 | pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, | |
2041 | Deny, | |
2042 | "macro-expanded `macro_export` macros from the current crate \ | |
2043 | cannot be referred to by absolute paths", | |
2044 | @future_incompatible = FutureIncompatibleInfo { | |
2045 | reference: "issue #52234 <https://github.com/rust-lang/rust/issues/52234>", | |
2046 | edition: None, | |
2047 | }; | |
2048 | crate_level_only | |
2049 | } | |
2050 | ||
2051 | declare_lint! { | |
2052 | /// The `explicit_outlives_requirements` lint detects unnecessary | |
2053 | /// lifetime bounds that can be inferred. | |
2054 | /// | |
2055 | /// ### Example | |
2056 | /// | |
2057 | /// ```rust,compile_fail | |
2058 | /// # #![allow(unused)] | |
2059 | /// #![deny(explicit_outlives_requirements)] | |
2060 | /// | |
2061 | /// struct SharedRef<'a, T> | |
2062 | /// where | |
2063 | /// T: 'a, | |
2064 | /// { | |
2065 | /// data: &'a T, | |
2066 | /// } | |
2067 | /// ``` | |
2068 | /// | |
2069 | /// {{produces}} | |
2070 | /// | |
2071 | /// ### Explanation | |
2072 | /// | |
2073 | /// If a `struct` contains a reference, such as `&'a T`, the compiler | |
2074 | /// requires that `T` outlives the lifetime `'a`. This historically | |
2075 | /// required writing an explicit lifetime bound to indicate this | |
2076 | /// requirement. However, this can be overly explicit, causing clutter and | |
2077 | /// unnecessary complexity. The language was changed to automatically | |
2078 | /// infer the bound if it is not specified. Specifically, if the struct | |
2079 | /// contains a reference, directly or indirectly, to `T` with lifetime | |
2080 | /// `'x`, then it will infer that `T: 'x` is a requirement. | |
2081 | /// | |
2082 | /// This lint is "allow" by default because it can be noisy for existing | |
2083 | /// code that already had these requirements. This is a stylistic choice, | |
2084 | /// as it is still valid to explicitly state the bound. It also has some | |
2085 | /// false positives that can cause confusion. | |
2086 | /// | |
2087 | /// See [RFC 2093] for more details. | |
2088 | /// | |
2089 | /// [RFC 2093]: https://github.com/rust-lang/rfcs/blob/master/text/2093-infer-outlives.md | |
2090 | pub EXPLICIT_OUTLIVES_REQUIREMENTS, | |
2091 | Allow, | |
2092 | "outlives requirements can be inferred" | |
2093 | } | |
2094 | ||
2095 | declare_lint! { | |
2096 | /// The `indirect_structural_match` lint detects a `const` in a pattern | |
2097 | /// that manually implements [`PartialEq`] and [`Eq`]. | |
2098 | /// | |
2099 | /// [`PartialEq`]: https://doc.rust-lang.org/std/cmp/trait.PartialEq.html | |
2100 | /// [`Eq`]: https://doc.rust-lang.org/std/cmp/trait.Eq.html | |
2101 | /// | |
2102 | /// ### Example | |
2103 | /// | |
2104 | /// ```rust,compile_fail | |
2105 | /// #![deny(indirect_structural_match)] | |
2106 | /// | |
2107 | /// struct NoDerive(i32); | |
2108 | /// impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | |
2109 | /// impl Eq for NoDerive { } | |
2110 | /// #[derive(PartialEq, Eq)] | |
2111 | /// struct WrapParam<T>(T); | |
2112 | /// const WRAP_INDIRECT_PARAM: & &WrapParam<NoDerive> = & &WrapParam(NoDerive(0)); | |
2113 | /// fn main() { | |
2114 | /// match WRAP_INDIRECT_PARAM { | |
2115 | /// WRAP_INDIRECT_PARAM => { } | |
2116 | /// _ => { } | |
2117 | /// } | |
2118 | /// } | |
2119 | /// ``` | |
2120 | /// | |
2121 | /// {{produces}} | |
2122 | /// | |
2123 | /// ### Explanation | |
2124 | /// | |
2125 | /// The compiler unintentionally accepted this form in the past. This is a | |
2126 | /// [future-incompatible] lint to transition this to a hard error in the | |
2127 | /// future. See [issue #62411] for a complete description of the problem, | |
2128 | /// and some possible solutions. | |
2129 | /// | |
2130 | /// [issue #62411]: https://github.com/rust-lang/rust/issues/62411 | |
2131 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
2132 | pub INDIRECT_STRUCTURAL_MATCH, | |
2133 | Warn, | |
2134 | "constant used in pattern contains value of non-structural-match type in a field or a variant", | |
2135 | @future_incompatible = FutureIncompatibleInfo { | |
2136 | reference: "issue #62411 <https://github.com/rust-lang/rust/issues/62411>", | |
2137 | edition: None, | |
2138 | }; | |
2139 | } | |
2140 | ||
2141 | declare_lint! { | |
2142 | /// The `deprecated_in_future` lint is internal to rustc and should not be | |
2143 | /// used by user code. | |
2144 | /// | |
2145 | /// This lint is only enabled in the standard library. It works with the | |
2146 | /// use of `#[rustc_deprecated]` with a `since` field of a version in the | |
2147 | /// future. This allows something to be marked as deprecated in a future | |
2148 | /// version, and then this lint will ensure that the item is no longer | |
2149 | /// used in the standard library. See the [stability documentation] for | |
2150 | /// more details. | |
2151 | /// | |
2152 | /// [stability documentation]: https://rustc-dev-guide.rust-lang.org/stability.html#rustc_deprecated | |
2153 | pub DEPRECATED_IN_FUTURE, | |
2154 | Allow, | |
2155 | "detects use of items that will be deprecated in a future version", | |
2156 | report_in_external_macro | |
2157 | } | |
2158 | ||
2159 | declare_lint! { | |
2160 | /// The `pointer_structural_match` lint detects pointers used in patterns whose behaviour | |
2161 | /// cannot be relied upon across compiler versions and optimization levels. | |
2162 | /// | |
2163 | /// ### Example | |
2164 | /// | |
2165 | /// ```rust,compile_fail | |
2166 | /// #![deny(pointer_structural_match)] | |
2167 | /// fn foo(a: usize, b: usize) -> usize { a + b } | |
2168 | /// const FOO: fn(usize, usize) -> usize = foo; | |
2169 | /// fn main() { | |
2170 | /// match FOO { | |
2171 | /// FOO => {}, | |
2172 | /// _ => {}, | |
2173 | /// } | |
2174 | /// } | |
2175 | /// ``` | |
2176 | /// | |
2177 | /// {{produces}} | |
2178 | /// | |
2179 | /// ### Explanation | |
2180 | /// | |
2181 | /// Previous versions of Rust allowed function pointers and wide raw pointers in patterns. | |
2182 | /// While these work in many cases as expected by users, it is possible that due to | |
2183 | /// optimizations pointers are "not equal to themselves" or pointers to different functions | |
2184 | /// compare as equal during runtime. This is because LLVM optimizations can deduplicate | |
2185 | /// functions if their bodies are the same, thus also making pointers to these functions point | |
2186 | /// to the same location. Additionally functions may get duplicated if they are instantiated | |
2187 | /// in different crates and not deduplicated again via LTO. | |
2188 | pub POINTER_STRUCTURAL_MATCH, | |
2189 | Allow, | |
2190 | "pointers are not structural-match", | |
2191 | @future_incompatible = FutureIncompatibleInfo { | |
2192 | reference: "issue #62411 <https://github.com/rust-lang/rust/issues/70861>", | |
2193 | edition: None, | |
2194 | }; | |
2195 | } | |
2196 | ||
2197 | declare_lint! { | |
2198 | /// The `nontrivial_structural_match` lint detects constants that are used in patterns, | |
2199 | /// whose type is not structural-match and whose initializer body actually uses values | |
2200 | /// that are not structural-match. So `Option<NotStruturalMatch>` is ok if the constant | |
2201 | /// is just `None`. | |
2202 | /// | |
2203 | /// ### Example | |
2204 | /// | |
2205 | /// ```rust,compile_fail | |
2206 | /// #![deny(nontrivial_structural_match)] | |
2207 | /// | |
2208 | /// #[derive(Copy, Clone, Debug)] | |
2209 | /// struct NoDerive(u32); | |
2210 | /// impl PartialEq for NoDerive { fn eq(&self, _: &Self) -> bool { false } } | |
2211 | /// impl Eq for NoDerive { } | |
2212 | /// fn main() { | |
2213 | /// const INDEX: Option<NoDerive> = [None, Some(NoDerive(10))][0]; | |
2214 | /// match None { Some(_) => panic!("whoops"), INDEX => dbg!(INDEX), }; | |
2215 | /// } | |
2216 | /// ``` | |
2217 | /// | |
2218 | /// {{produces}} | |
2219 | /// | |
2220 | /// ### Explanation | |
2221 | /// | |
2222 | /// Previous versions of Rust accepted constants in patterns, even if those constants's types | |
2223 | /// did not have `PartialEq` derived. Thus the compiler falls back to runtime execution of | |
2224 | /// `PartialEq`, which can report that two constants are not equal even if they are | |
2225 | /// bit-equivalent. | |
2226 | pub NONTRIVIAL_STRUCTURAL_MATCH, | |
2227 | Warn, | |
2228 | "constant used in pattern of non-structural-match type and the constant's initializer \ | |
2229 | expression contains values of non-structural-match types", | |
2230 | @future_incompatible = FutureIncompatibleInfo { | |
2231 | reference: "issue #73448 <https://github.com/rust-lang/rust/issues/73448>", | |
2232 | edition: None, | |
2233 | }; | |
2234 | } | |
2235 | ||
2236 | declare_lint! { | |
2237 | /// The `ambiguous_associated_items` lint detects ambiguity between | |
2238 | /// [associated items] and [enum variants]. | |
2239 | /// | |
2240 | /// [associated items]: https://doc.rust-lang.org/reference/items/associated-items.html | |
2241 | /// [enum variants]: https://doc.rust-lang.org/reference/items/enumerations.html | |
2242 | /// | |
2243 | /// ### Example | |
2244 | /// | |
2245 | /// ```rust,compile_fail | |
2246 | /// enum E { | |
2247 | /// V | |
2248 | /// } | |
2249 | /// | |
2250 | /// trait Tr { | |
2251 | /// type V; | |
2252 | /// fn foo() -> Self::V; | |
2253 | /// } | |
2254 | /// | |
2255 | /// impl Tr for E { | |
2256 | /// type V = u8; | |
2257 | /// // `Self::V` is ambiguous because it may refer to the associated type or | |
2258 | /// // the enum variant. | |
2259 | /// fn foo() -> Self::V { 0 } | |
2260 | /// } | |
2261 | /// ``` | |
2262 | /// | |
2263 | /// {{produces}} | |
2264 | /// | |
2265 | /// ### Explanation | |
2266 | /// | |
2267 | /// Previous versions of Rust did not allow accessing enum variants | |
2268 | /// through [type aliases]. When this ability was added (see [RFC 2338]), this | |
2269 | /// introduced some situations where it can be ambiguous what a type | |
2270 | /// was referring to. | |
2271 | /// | |
2272 | /// To fix this ambiguity, you should use a [qualified path] to explicitly | |
2273 | /// state which type to use. For example, in the above example the | |
2274 | /// function can be written as `fn f() -> <Self as Tr>::V { 0 }` to | |
2275 | /// specifically refer to the associated type. | |
2276 | /// | |
2277 | /// This is a [future-incompatible] lint to transition this to a hard | |
2278 | /// error in the future. See [issue #57644] for more details. | |
2279 | /// | |
2280 | /// [issue #57644]: https://github.com/rust-lang/rust/issues/57644 | |
2281 | /// [type aliases]: https://doc.rust-lang.org/reference/items/type-aliases.html#type-aliases | |
2282 | /// [RFC 2338]: https://github.com/rust-lang/rfcs/blob/master/text/2338-type-alias-enum-variants.md | |
2283 | /// [qualified path]: https://doc.rust-lang.org/reference/paths.html#qualified-paths | |
2284 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
2285 | pub AMBIGUOUS_ASSOCIATED_ITEMS, | |
2286 | Deny, | |
2287 | "ambiguous associated items", | |
2288 | @future_incompatible = FutureIncompatibleInfo { | |
2289 | reference: "issue #57644 <https://github.com/rust-lang/rust/issues/57644>", | |
2290 | edition: None, | |
2291 | }; | |
2292 | } | |
2293 | ||
2294 | declare_lint! { | |
2295 | /// The `mutable_borrow_reservation_conflict` lint detects the reservation | |
2296 | /// of a two-phased borrow that conflicts with other shared borrows. | |
2297 | /// | |
2298 | /// ### Example | |
2299 | /// | |
2300 | /// ```rust | |
2301 | /// let mut v = vec![0, 1, 2]; | |
2302 | /// let shared = &v; | |
2303 | /// v.push(shared.len()); | |
2304 | /// ``` | |
2305 | /// | |
2306 | /// {{produces}} | |
2307 | /// | |
2308 | /// ### Explanation | |
2309 | /// | |
2310 | /// This is a [future-incompatible] lint to transition this to a hard error | |
2311 | /// in the future. See [issue #59159] for a complete description of the | |
2312 | /// problem, and some possible solutions. | |
2313 | /// | |
2314 | /// [issue #59159]: https://github.com/rust-lang/rust/issues/59159 | |
2315 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
2316 | pub MUTABLE_BORROW_RESERVATION_CONFLICT, | |
2317 | Warn, | |
2318 | "reservation of a two-phased borrow conflicts with other shared borrows", | |
2319 | @future_incompatible = FutureIncompatibleInfo { | |
2320 | reference: "issue #59159 <https://github.com/rust-lang/rust/issues/59159>", | |
2321 | edition: None, | |
2322 | }; | |
2323 | } | |
2324 | ||
2325 | declare_lint! { | |
2326 | /// The `soft_unstable` lint detects unstable features that were | |
2327 | /// unintentionally allowed on stable. | |
2328 | /// | |
2329 | /// ### Example | |
2330 | /// | |
2331 | /// ```rust,compile_fail | |
2332 | /// #[cfg(test)] | |
2333 | /// extern crate test; | |
2334 | /// | |
2335 | /// #[bench] | |
2336 | /// fn name(b: &mut test::Bencher) { | |
2337 | /// b.iter(|| 123) | |
2338 | /// } | |
2339 | /// ``` | |
2340 | /// | |
2341 | /// {{produces}} | |
2342 | /// | |
2343 | /// ### Explanation | |
2344 | /// | |
2345 | /// The [`bench` attribute] was accidentally allowed to be specified on | |
2346 | /// the [stable release channel]. Turning this to a hard error would have | |
2347 | /// broken some projects. This lint allows those projects to continue to | |
2348 | /// build correctly when [`--cap-lints`] is used, but otherwise signal an | |
2349 | /// error that `#[bench]` should not be used on the stable channel. This | |
2350 | /// is a [future-incompatible] lint to transition this to a hard error in | |
2351 | /// the future. See [issue #64266] for more details. | |
2352 | /// | |
2353 | /// [issue #64266]: https://github.com/rust-lang/rust/issues/64266 | |
2354 | /// [`bench` attribute]: https://doc.rust-lang.org/nightly/unstable-book/library-features/test.html | |
2355 | /// [stable release channel]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html | |
2356 | /// [`--cap-lints`]: https://doc.rust-lang.org/rustc/lints/levels.html#capping-lints | |
2357 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
2358 | pub SOFT_UNSTABLE, | |
2359 | Deny, | |
2360 | "a feature gate that doesn't break dependent crates", | |
2361 | @future_incompatible = FutureIncompatibleInfo { | |
2362 | reference: "issue #64266 <https://github.com/rust-lang/rust/issues/64266>", | |
2363 | edition: None, | |
2364 | }; | |
2365 | } | |
2366 | ||
2367 | declare_lint! { | |
2368 | /// The `inline_no_sanitize` lint detects incompatible use of | |
2369 | /// [`#[inline(always)]`][inline] and [`#[no_sanitize(...)]`][no_sanitize]. | |
2370 | /// | |
2371 | /// [inline]: https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute | |
2372 | /// [no_sanitize]: https://doc.rust-lang.org/nightly/unstable-book/language-features/no-sanitize.html | |
2373 | /// | |
2374 | /// ### Example | |
2375 | /// | |
2376 | /// ```rust | |
2377 | /// #![feature(no_sanitize)] | |
2378 | /// | |
2379 | /// #[inline(always)] | |
2380 | /// #[no_sanitize(address)] | |
2381 | /// fn x() {} | |
2382 | /// | |
2383 | /// fn main() { | |
2384 | /// x() | |
2385 | /// } | |
2386 | /// ``` | |
2387 | /// | |
2388 | /// {{produces}} | |
2389 | /// | |
2390 | /// ### Explanation | |
2391 | /// | |
2392 | /// The use of the [`#[inline(always)]`][inline] attribute prevents the | |
2393 | /// the [`#[no_sanitize(...)]`][no_sanitize] attribute from working. | |
2394 | /// Consider temporarily removing `inline` attribute. | |
2395 | pub INLINE_NO_SANITIZE, | |
2396 | Warn, | |
2397 | "detects incompatible use of `#[inline(always)]` and `#[no_sanitize(...)]`", | |
2398 | } | |
2399 | ||
2400 | declare_lint! { | |
2401 | /// The `asm_sub_register` lint detects using only a subset of a register | |
2402 | /// for inline asm inputs. | |
2403 | /// | |
2404 | /// ### Example | |
2405 | /// | |
2406 | /// ```rust,ignore (fails on system llvm) | |
2407 | /// #![feature(asm)] | |
2408 | /// | |
2409 | /// fn main() { | |
2410 | /// #[cfg(target_arch="x86_64")] | |
2411 | /// unsafe { | |
2412 | /// asm!("mov {0}, {0}", in(reg) 0i16); | |
2413 | /// } | |
2414 | /// } | |
2415 | /// ``` | |
2416 | /// | |
2417 | /// This will produce: | |
2418 | /// | |
2419 | /// ```text | |
2420 | /// warning: formatting may not be suitable for sub-register argument | |
2421 | /// --> src/main.rs:6:19 | |
2422 | /// | | |
2423 | /// 6 | asm!("mov {0}, {0}", in(reg) 0i16); | |
2424 | /// | ^^^ ^^^ ---- for this argument | |
2425 | /// | | |
2426 | /// = note: `#[warn(asm_sub_register)]` on by default | |
2427 | /// = help: use the `x` modifier to have the register formatted as `ax` | |
2428 | /// = help: or use the `r` modifier to keep the default formatting of `rax` | |
2429 | /// ``` | |
2430 | /// | |
2431 | /// ### Explanation | |
2432 | /// | |
2433 | /// Registers on some architectures can use different names to refer to a | |
2434 | /// subset of the register. By default, the compiler will use the name for | |
2435 | /// the full register size. To explicitly use a subset of the register, | |
2436 | /// you can override the default by using a modifier on the template | |
2437 | /// string operand to specify when subregister to use. This lint is issued | |
2438 | /// if you pass in a value with a smaller data type than the default | |
2439 | /// register size, to alert you of possibly using the incorrect width. To | |
2440 | /// fix this, add the suggested modifier to the template, or cast the | |
2441 | /// value to the correct size. | |
2442 | /// | |
2443 | /// See [register template modifiers] for more details. | |
2444 | /// | |
2445 | /// [register template modifiers]: https://doc.rust-lang.org/nightly/unstable-book/library-features/asm.html#register-template-modifiers | |
2446 | pub ASM_SUB_REGISTER, | |
2447 | Warn, | |
2448 | "using only a subset of a register for inline asm inputs", | |
2449 | } | |
2450 | ||
cdc7bbd5 XL |
2451 | declare_lint! { |
2452 | /// The `bad_asm_style` lint detects the use of the `.intel_syntax` and | |
2453 | /// `.att_syntax` directives. | |
2454 | /// | |
2455 | /// ### Example | |
2456 | /// | |
2457 | /// ```rust,ignore (fails on system llvm) | |
2458 | /// #![feature(asm)] | |
2459 | /// | |
2460 | /// fn main() { | |
2461 | /// #[cfg(target_arch="x86_64")] | |
2462 | /// unsafe { | |
2463 | /// asm!( | |
2464 | /// ".att_syntax", | |
2465 | /// "movl {0}, {0}", in(reg) 0usize | |
2466 | /// ); | |
2467 | /// } | |
2468 | /// } | |
2469 | /// ``` | |
2470 | /// | |
2471 | /// This will produce: | |
2472 | /// | |
2473 | /// ```text | |
2474 | /// warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead | |
2475 | /// --> test.rs:7:14 | |
2476 | /// | | |
2477 | /// 7 | ".att_syntax", | |
2478 | /// | ^^^^^^^^^^^ | |
2479 | /// 8 | "movq {0}, {0}", out(reg) _, | |
2480 | /// 9 | ); | |
2481 | /// | - help: add option: `, options(att_syntax)` | |
2482 | /// | | |
2483 | /// = note: `#[warn(bad_asm_style)]` on by default | |
2484 | /// ``` | |
2485 | /// | |
2486 | /// ### Explanation | |
2487 | /// | |
2488 | /// On x86, `asm!` uses the intel assembly syntax by default. While this | |
2489 | /// can be switched using assembler directives like `.att_syntax`, using the | |
2490 | /// `att_syntax` option is recommended instead because it will also properly | |
2491 | /// prefix register placeholders with `%` as required by AT&T syntax. | |
2492 | pub BAD_ASM_STYLE, | |
2493 | Warn, | |
2494 | "incorrect use of inline assembly", | |
2495 | } | |
2496 | ||
1b1a35ee XL |
2497 | declare_lint! { |
2498 | /// The `unsafe_op_in_unsafe_fn` lint detects unsafe operations in unsafe | |
6a06907d | 2499 | /// functions without an explicit unsafe block. |
1b1a35ee XL |
2500 | /// |
2501 | /// ### Example | |
2502 | /// | |
2503 | /// ```rust,compile_fail | |
1b1a35ee XL |
2504 | /// #![deny(unsafe_op_in_unsafe_fn)] |
2505 | /// | |
2506 | /// unsafe fn foo() {} | |
2507 | /// | |
2508 | /// unsafe fn bar() { | |
2509 | /// foo(); | |
2510 | /// } | |
2511 | /// | |
2512 | /// fn main() {} | |
2513 | /// ``` | |
2514 | /// | |
2515 | /// {{produces}} | |
2516 | /// | |
2517 | /// ### Explanation | |
2518 | /// | |
2519 | /// Currently, an [`unsafe fn`] allows any [unsafe] operation within its | |
2520 | /// body. However, this can increase the surface area of code that needs | |
2521 | /// to be scrutinized for proper behavior. The [`unsafe` block] provides a | |
2522 | /// convenient way to make it clear exactly which parts of the code are | |
2523 | /// performing unsafe operations. In the future, it is desired to change | |
2524 | /// it so that unsafe operations cannot be performed in an `unsafe fn` | |
2525 | /// without an `unsafe` block. | |
2526 | /// | |
2527 | /// The fix to this is to wrap the unsafe code in an `unsafe` block. | |
2528 | /// | |
cdc7bbd5 XL |
2529 | /// This lint is "allow" by default since this will affect a large amount |
2530 | /// of existing code, and the exact plan for increasing the severity is | |
2531 | /// still being considered. See [RFC #2585] and [issue #71668] for more | |
2532 | /// details. | |
1b1a35ee XL |
2533 | /// |
2534 | /// [`unsafe fn`]: https://doc.rust-lang.org/reference/unsafe-functions.html | |
2535 | /// [`unsafe` block]: https://doc.rust-lang.org/reference/expressions/block-expr.html#unsafe-blocks | |
2536 | /// [unsafe]: https://doc.rust-lang.org/reference/unsafety.html | |
2537 | /// [RFC #2585]: https://github.com/rust-lang/rfcs/blob/master/text/2585-unsafe-block-in-unsafe-fn.md | |
2538 | /// [issue #71668]: https://github.com/rust-lang/rust/issues/71668 | |
2539 | pub UNSAFE_OP_IN_UNSAFE_FN, | |
2540 | Allow, | |
2541 | "unsafe operations in unsafe functions without an explicit unsafe block are deprecated", | |
1b1a35ee XL |
2542 | } |
2543 | ||
2544 | declare_lint! { | |
2545 | /// The `cenum_impl_drop_cast` lint detects an `as` cast of a field-less | |
2546 | /// `enum` that implements [`Drop`]. | |
2547 | /// | |
2548 | /// [`Drop`]: https://doc.rust-lang.org/std/ops/trait.Drop.html | |
2549 | /// | |
2550 | /// ### Example | |
2551 | /// | |
2552 | /// ```rust | |
2553 | /// # #![allow(unused)] | |
2554 | /// enum E { | |
2555 | /// A, | |
2556 | /// } | |
2557 | /// | |
2558 | /// impl Drop for E { | |
2559 | /// fn drop(&mut self) { | |
2560 | /// println!("Drop"); | |
2561 | /// } | |
2562 | /// } | |
2563 | /// | |
2564 | /// fn main() { | |
2565 | /// let e = E::A; | |
2566 | /// let i = e as u32; | |
2567 | /// } | |
2568 | /// ``` | |
2569 | /// | |
2570 | /// {{produces}} | |
2571 | /// | |
2572 | /// ### Explanation | |
2573 | /// | |
2574 | /// Casting a field-less `enum` that does not implement [`Copy`] to an | |
2575 | /// integer moves the value without calling `drop`. This can result in | |
2576 | /// surprising behavior if it was expected that `drop` should be called. | |
2577 | /// Calling `drop` automatically would be inconsistent with other move | |
2578 | /// operations. Since neither behavior is clear or consistent, it was | |
2579 | /// decided that a cast of this nature will no longer be allowed. | |
2580 | /// | |
2581 | /// This is a [future-incompatible] lint to transition this to a hard error | |
2582 | /// in the future. See [issue #73333] for more details. | |
2583 | /// | |
2584 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
2585 | /// [issue #73333]: https://github.com/rust-lang/rust/issues/73333 | |
2586 | /// [`Copy`]: https://doc.rust-lang.org/std/marker/trait.Copy.html | |
2587 | pub CENUM_IMPL_DROP_CAST, | |
2588 | Warn, | |
2589 | "a C-like enum implementing Drop is cast", | |
2590 | @future_incompatible = FutureIncompatibleInfo { | |
2591 | reference: "issue #73333 <https://github.com/rust-lang/rust/issues/73333>", | |
2592 | edition: None, | |
2593 | }; | |
2594 | } | |
2595 | ||
2596 | declare_lint! { | |
2597 | /// The `const_evaluatable_unchecked` lint detects a generic constant used | |
2598 | /// in a type. | |
2599 | /// | |
2600 | /// ### Example | |
2601 | /// | |
2602 | /// ```rust | |
2603 | /// const fn foo<T>() -> usize { | |
2604 | /// if std::mem::size_of::<*mut T>() < 8 { // size of *mut T does not depend on T | |
2605 | /// 4 | |
2606 | /// } else { | |
2607 | /// 8 | |
2608 | /// } | |
2609 | /// } | |
2610 | /// | |
2611 | /// fn test<T>() { | |
2612 | /// let _ = [0; foo::<T>()]; | |
2613 | /// } | |
2614 | /// ``` | |
2615 | /// | |
2616 | /// {{produces}} | |
2617 | /// | |
2618 | /// ### Explanation | |
2619 | /// | |
2620 | /// In the 1.43 release, some uses of generic parameters in array repeat | |
2621 | /// expressions were accidentally allowed. This is a [future-incompatible] | |
2622 | /// lint to transition this to a hard error in the future. See [issue | |
2623 | /// #76200] for a more detailed description and possible fixes. | |
2624 | /// | |
2625 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
2626 | /// [issue #76200]: https://github.com/rust-lang/rust/issues/76200 | |
2627 | pub CONST_EVALUATABLE_UNCHECKED, | |
2628 | Warn, | |
2629 | "detects a generic constant is used in a type without a emitting a warning", | |
2630 | @future_incompatible = FutureIncompatibleInfo { | |
2631 | reference: "issue #76200 <https://github.com/rust-lang/rust/issues/76200>", | |
2632 | edition: None, | |
2633 | }; | |
2634 | } | |
2635 | ||
29967ef6 XL |
2636 | declare_lint! { |
2637 | /// The `function_item_references` lint detects function references that are | |
2638 | /// formatted with [`fmt::Pointer`] or transmuted. | |
2639 | /// | |
2640 | /// [`fmt::Pointer`]: https://doc.rust-lang.org/std/fmt/trait.Pointer.html | |
2641 | /// | |
2642 | /// ### Example | |
2643 | /// | |
2644 | /// ```rust | |
2645 | /// fn foo() { } | |
2646 | /// | |
2647 | /// fn main() { | |
2648 | /// println!("{:p}", &foo); | |
2649 | /// } | |
2650 | /// ``` | |
2651 | /// | |
2652 | /// {{produces}} | |
2653 | /// | |
2654 | /// ### Explanation | |
2655 | /// | |
2656 | /// Taking a reference to a function may be mistaken as a way to obtain a | |
2657 | /// pointer to that function. This can give unexpected results when | |
2658 | /// formatting the reference as a pointer or transmuting it. This lint is | |
2659 | /// issued when function references are formatted as pointers, passed as | |
2660 | /// arguments bound by [`fmt::Pointer`] or transmuted. | |
2661 | pub FUNCTION_ITEM_REFERENCES, | |
2662 | Warn, | |
2663 | "suggest casting to a function pointer when attempting to take references to function items", | |
2664 | } | |
2665 | ||
2666 | declare_lint! { | |
2667 | /// The `uninhabited_static` lint detects uninhabited statics. | |
2668 | /// | |
2669 | /// ### Example | |
2670 | /// | |
2671 | /// ```rust | |
2672 | /// enum Void {} | |
2673 | /// extern { | |
2674 | /// static EXTERN: Void; | |
2675 | /// } | |
2676 | /// ``` | |
2677 | /// | |
2678 | /// {{produces}} | |
2679 | /// | |
2680 | /// ### Explanation | |
2681 | /// | |
2682 | /// Statics with an uninhabited type can never be initialized, so they are impossible to define. | |
2683 | /// However, this can be side-stepped with an `extern static`, leading to problems later in the | |
2684 | /// compiler which assumes that there are no initialized uninhabited places (such as locals or | |
cdc7bbd5 | 2685 | /// statics). This was accidentally allowed, but is being phased out. |
29967ef6 XL |
2686 | pub UNINHABITED_STATIC, |
2687 | Warn, | |
2688 | "uninhabited static", | |
2689 | @future_incompatible = FutureIncompatibleInfo { | |
2690 | reference: "issue #74840 <https://github.com/rust-lang/rust/issues/74840>", | |
2691 | edition: None, | |
2692 | }; | |
2693 | } | |
2694 | ||
2695 | declare_lint! { | |
2696 | /// The `useless_deprecated` lint detects deprecation attributes with no effect. | |
2697 | /// | |
2698 | /// ### Example | |
2699 | /// | |
2700 | /// ```rust,compile_fail | |
2701 | /// struct X; | |
2702 | /// | |
2703 | /// #[deprecated = "message"] | |
2704 | /// impl Default for X { | |
2705 | /// fn default() -> Self { | |
2706 | /// X | |
2707 | /// } | |
2708 | /// } | |
2709 | /// ``` | |
2710 | /// | |
2711 | /// {{produces}} | |
2712 | /// | |
2713 | /// ### Explanation | |
2714 | /// | |
2715 | /// Deprecation attributes have no effect on trait implementations. | |
2716 | pub USELESS_DEPRECATED, | |
2717 | Deny, | |
2718 | "detects deprecation attributes with no effect", | |
2719 | } | |
2720 | ||
fc512014 XL |
2721 | declare_lint! { |
2722 | /// The `unsupported_naked_functions` lint detects naked function | |
2723 | /// definitions that are unsupported but were previously accepted. | |
2724 | /// | |
2725 | /// ### Example | |
2726 | /// | |
2727 | /// ```rust | |
2728 | /// #![feature(naked_functions)] | |
2729 | /// | |
2730 | /// #[naked] | |
2731 | /// pub fn f() -> u32 { | |
2732 | /// 42 | |
2733 | /// } | |
2734 | /// ``` | |
2735 | /// | |
2736 | /// {{produces}} | |
2737 | /// | |
2738 | /// ### Explanation | |
2739 | /// | |
2740 | /// The naked functions must be defined using a single inline assembly | |
2741 | /// block. | |
2742 | /// | |
2743 | /// The execution must never fall through past the end of the assembly | |
2744 | /// code so the block must use `noreturn` option. The asm block can also | |
2745 | /// use `att_syntax` option, but other options are not allowed. | |
2746 | /// | |
2747 | /// The asm block must not contain any operands other than `const` and | |
2748 | /// `sym`. Additionally, naked function should specify a non-Rust ABI. | |
2749 | /// | |
2750 | /// While other definitions of naked functions were previously accepted, | |
2751 | /// they are unsupported and might not work reliably. This is a | |
2752 | /// [future-incompatible] lint that will transition into hard error in | |
2753 | /// the future. | |
2754 | /// | |
2755 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
2756 | pub UNSUPPORTED_NAKED_FUNCTIONS, | |
2757 | Warn, | |
2758 | "unsupported naked function definitions", | |
2759 | @future_incompatible = FutureIncompatibleInfo { | |
2760 | reference: "issue #32408 <https://github.com/rust-lang/rust/issues/32408>", | |
2761 | edition: None, | |
2762 | }; | |
2763 | } | |
2764 | ||
5869c6ff XL |
2765 | declare_lint! { |
2766 | /// The `ineffective_unstable_trait_impl` lint detects `#[unstable]` attributes which are not used. | |
2767 | /// | |
2768 | /// ### Example | |
2769 | /// | |
2770 | /// ```compile_fail | |
2771 | /// #![feature(staged_api)] | |
2772 | /// | |
2773 | /// #[derive(Clone)] | |
2774 | /// #[stable(feature = "x", since = "1")] | |
2775 | /// struct S {} | |
2776 | /// | |
2777 | /// #[unstable(feature = "y", issue = "none")] | |
2778 | /// impl Copy for S {} | |
2779 | /// ``` | |
2780 | /// | |
2781 | /// {{produces}} | |
2782 | /// | |
2783 | /// ### Explanation | |
2784 | /// | |
2785 | /// `staged_api` does not currently support using a stability attribute on `impl` blocks. | |
2786 | /// `impl`s are always stable if both the type and trait are stable, and always unstable otherwise. | |
2787 | pub INEFFECTIVE_UNSTABLE_TRAIT_IMPL, | |
1b1a35ee XL |
2788 | Deny, |
2789 | "detects `#[unstable]` on stable trait implementations for stable types" | |
2790 | } | |
2791 | ||
5869c6ff XL |
2792 | declare_lint! { |
2793 | /// The `semicolon_in_expressions_from_macros` lint detects trailing semicolons | |
2794 | /// in macro bodies when the macro is invoked in expression position. | |
2795 | /// This was previous accepted, but is being phased out. | |
2796 | /// | |
2797 | /// ### Example | |
2798 | /// | |
2799 | /// ```rust,compile_fail | |
2800 | /// #![deny(semicolon_in_expressions_from_macros)] | |
2801 | /// macro_rules! foo { | |
2802 | /// () => { true; } | |
2803 | /// } | |
2804 | /// | |
2805 | /// fn main() { | |
2806 | /// let val = match true { | |
2807 | /// true => false, | |
2808 | /// _ => foo!() | |
2809 | /// }; | |
2810 | /// } | |
2811 | /// ``` | |
2812 | /// | |
2813 | /// {{produces}} | |
2814 | /// | |
2815 | /// ### Explanation | |
2816 | /// | |
2817 | /// Previous, Rust ignored trailing semicolon in a macro | |
2818 | /// body when a macro was invoked in expression position. | |
2819 | /// However, this makes the treatment of semicolons in the language | |
2820 | /// inconsistent, and could lead to unexpected runtime behavior | |
2821 | /// in some circumstances (e.g. if the macro author expects | |
2822 | /// a value to be dropped). | |
2823 | /// | |
2824 | /// This is a [future-incompatible] lint to transition this | |
2825 | /// to a hard error in the future. See [issue #79813] for more details. | |
2826 | /// | |
2827 | /// [issue #79813]: https://github.com/rust-lang/rust/issues/79813 | |
2828 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
2829 | pub SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, | |
2830 | Allow, | |
2831 | "trailing semicolon in macro body used as expression", | |
2832 | @future_incompatible = FutureIncompatibleInfo { | |
2833 | reference: "issue #79813 <https://github.com/rust-lang/rust/issues/79813>", | |
2834 | edition: None, | |
2835 | }; | |
2836 | } | |
2837 | ||
6a06907d XL |
2838 | declare_lint! { |
2839 | /// The `legacy_derive_helpers` lint detects derive helper attributes | |
2840 | /// that are used before they are introduced. | |
2841 | /// | |
2842 | /// ### Example | |
2843 | /// | |
2844 | /// ```rust,ignore (needs extern crate) | |
2845 | /// #[serde(rename_all = "camelCase")] | |
2846 | /// #[derive(Deserialize)] | |
2847 | /// struct S { /* fields */ } | |
2848 | /// ``` | |
2849 | /// | |
2850 | /// produces: | |
2851 | /// | |
2852 | /// ```text | |
2853 | /// warning: derive helper attribute is used before it is introduced | |
2854 | /// --> $DIR/legacy-derive-helpers.rs:1:3 | |
2855 | /// | | |
2856 | /// 1 | #[serde(rename_all = "camelCase")] | |
2857 | /// | ^^^^^ | |
2858 | /// ... | |
2859 | /// 2 | #[derive(Deserialize)] | |
2860 | /// | ----------- the attribute is introduced here | |
2861 | /// ``` | |
2862 | /// | |
2863 | /// ### Explanation | |
2864 | /// | |
2865 | /// Attributes like this work for historical reasons, but attribute expansion works in | |
2866 | /// left-to-right order in general, so, to resolve `#[serde]`, compiler has to try to "look | |
2867 | /// into the future" at not yet expanded part of the item , but such attempts are not always | |
2868 | /// reliable. | |
2869 | /// | |
2870 | /// To fix the warning place the helper attribute after its corresponding derive. | |
2871 | /// ```rust,ignore (needs extern crate) | |
2872 | /// #[derive(Deserialize)] | |
2873 | /// #[serde(rename_all = "camelCase")] | |
2874 | /// struct S { /* fields */ } | |
2875 | /// ``` | |
2876 | pub LEGACY_DERIVE_HELPERS, | |
2877 | Warn, | |
2878 | "detects derive helper attributes that are used before they are introduced", | |
2879 | @future_incompatible = FutureIncompatibleInfo { | |
2880 | reference: "issue #79202 <https://github.com/rust-lang/rust/issues/79202>", | |
2881 | }; | |
2882 | } | |
2883 | ||
cdc7bbd5 XL |
2884 | declare_lint! { |
2885 | /// The `large_assignments` lint detects when objects of large | |
2886 | /// types are being moved around. | |
2887 | /// | |
2888 | /// ### Example | |
2889 | /// | |
2890 | /// ```rust,ignore (can crash on some platforms) | |
2891 | /// let x = [0; 50000]; | |
2892 | /// let y = x; | |
2893 | /// ``` | |
2894 | /// | |
2895 | /// produces: | |
2896 | /// | |
2897 | /// ```text | |
2898 | /// warning: moving a large value | |
2899 | /// --> $DIR/move-large.rs:1:3 | |
2900 | /// let y = x; | |
2901 | /// - Copied large value here | |
2902 | /// ``` | |
2903 | /// | |
2904 | /// ### Explanation | |
2905 | /// | |
2906 | /// When using a large type in a plain assignment or in a function | |
2907 | /// argument, idiomatic code can be inefficient. | |
2908 | /// Ideally appropriate optimizations would resolve this, but such | |
2909 | /// optimizations are only done in a best-effort manner. | |
2910 | /// This lint will trigger on all sites of large moves and thus allow the | |
2911 | /// user to resolve them in code. | |
2912 | pub LARGE_ASSIGNMENTS, | |
2913 | Warn, | |
2914 | "detects large moves or copies", | |
2915 | } | |
2916 | ||
1b1a35ee XL |
2917 | declare_lint_pass! { |
2918 | /// Does nothing as a lint pass, but registers some `Lint`s | |
2919 | /// that are used by other parts of the compiler. | |
2920 | HardwiredLints => [ | |
fc512014 | 2921 | FORBIDDEN_LINT_GROUPS, |
1b1a35ee XL |
2922 | ILLEGAL_FLOATING_POINT_LITERAL_PATTERN, |
2923 | ARITHMETIC_OVERFLOW, | |
2924 | UNCONDITIONAL_PANIC, | |
2925 | UNUSED_IMPORTS, | |
2926 | UNUSED_EXTERN_CRATES, | |
2927 | UNUSED_CRATE_DEPENDENCIES, | |
2928 | UNUSED_QUALIFICATIONS, | |
2929 | UNKNOWN_LINTS, | |
2930 | UNUSED_VARIABLES, | |
2931 | UNUSED_ASSIGNMENTS, | |
2932 | DEAD_CODE, | |
2933 | UNREACHABLE_CODE, | |
2934 | UNREACHABLE_PATTERNS, | |
fc512014 | 2935 | OVERLAPPING_RANGE_ENDPOINTS, |
1b1a35ee XL |
2936 | BINDINGS_WITH_VARIANT_NAME, |
2937 | UNUSED_MACROS, | |
2938 | WARNINGS, | |
2939 | UNUSED_FEATURES, | |
2940 | STABLE_FEATURES, | |
2941 | UNKNOWN_CRATE_TYPES, | |
2942 | TRIVIAL_CASTS, | |
2943 | TRIVIAL_NUMERIC_CASTS, | |
2944 | PRIVATE_IN_PUBLIC, | |
2945 | EXPORTED_PRIVATE_DEPENDENCIES, | |
2946 | PUB_USE_OF_PRIVATE_EXTERN_CRATE, | |
2947 | INVALID_TYPE_PARAM_DEFAULT, | |
2948 | CONST_ERR, | |
2949 | RENAMED_AND_REMOVED_LINTS, | |
2950 | UNALIGNED_REFERENCES, | |
2951 | CONST_ITEM_MUTATION, | |
1b1a35ee | 2952 | PATTERNS_IN_FNS_WITHOUT_BODY, |
b9856134 | 2953 | MISSING_FRAGMENT_SPECIFIER, |
1b1a35ee XL |
2954 | LATE_BOUND_LIFETIME_ARGUMENTS, |
2955 | ORDER_DEPENDENT_TRAIT_OBJECTS, | |
2956 | COHERENCE_LEAK_CHECK, | |
2957 | DEPRECATED, | |
2958 | UNUSED_UNSAFE, | |
2959 | UNUSED_MUT, | |
2960 | UNCONDITIONAL_RECURSION, | |
2961 | SINGLE_USE_LIFETIMES, | |
2962 | UNUSED_LIFETIMES, | |
2963 | UNUSED_LABELS, | |
2964 | TYVAR_BEHIND_RAW_POINTER, | |
2965 | ELIDED_LIFETIMES_IN_PATHS, | |
2966 | BARE_TRAIT_OBJECTS, | |
2967 | ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, | |
2968 | UNSTABLE_NAME_COLLISIONS, | |
2969 | IRREFUTABLE_LET_PATTERNS, | |
1b1a35ee XL |
2970 | WHERE_CLAUSES_OBJECT_SAFETY, |
2971 | PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, | |
2972 | MACRO_USE_EXTERN_CRATE, | |
2973 | MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, | |
2974 | ILL_FORMED_ATTRIBUTE_INPUT, | |
2975 | CONFLICTING_REPR_HINTS, | |
2976 | META_VARIABLE_MISUSE, | |
2977 | DEPRECATED_IN_FUTURE, | |
2978 | AMBIGUOUS_ASSOCIATED_ITEMS, | |
2979 | MUTABLE_BORROW_RESERVATION_CONFLICT, | |
2980 | INDIRECT_STRUCTURAL_MATCH, | |
2981 | POINTER_STRUCTURAL_MATCH, | |
2982 | NONTRIVIAL_STRUCTURAL_MATCH, | |
2983 | SOFT_UNSTABLE, | |
2984 | INLINE_NO_SANITIZE, | |
cdc7bbd5 | 2985 | BAD_ASM_STYLE, |
1b1a35ee XL |
2986 | ASM_SUB_REGISTER, |
2987 | UNSAFE_OP_IN_UNSAFE_FN, | |
2988 | INCOMPLETE_INCLUDE, | |
2989 | CENUM_IMPL_DROP_CAST, | |
2990 | CONST_EVALUATABLE_UNCHECKED, | |
2991 | INEFFECTIVE_UNSTABLE_TRAIT_IMPL, | |
29967ef6 XL |
2992 | UNINHABITED_STATIC, |
2993 | FUNCTION_ITEM_REFERENCES, | |
2994 | USELESS_DEPRECATED, | |
fc512014 | 2995 | UNSUPPORTED_NAKED_FUNCTIONS, |
5869c6ff | 2996 | MISSING_ABI, |
17df50a5 | 2997 | INVALID_DOC_ATTRIBUTES, |
5869c6ff | 2998 | SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, |
17df50a5 | 2999 | DISJOINT_CAPTURE_MIGRATION, |
6a06907d XL |
3000 | LEGACY_DERIVE_HELPERS, |
3001 | PROC_MACRO_BACK_COMPAT, | |
cdc7bbd5 XL |
3002 | OR_PATTERNS_BACK_COMPAT, |
3003 | LARGE_ASSIGNMENTS, | |
1b1a35ee XL |
3004 | ] |
3005 | } | |
3006 | ||
3007 | declare_lint! { | |
3008 | /// The `unused_doc_comments` lint detects doc comments that aren't used | |
3009 | /// by `rustdoc`. | |
3010 | /// | |
3011 | /// ### Example | |
3012 | /// | |
3013 | /// ```rust | |
3014 | /// /// docs for x | |
3015 | /// let x = 12; | |
3016 | /// ``` | |
3017 | /// | |
3018 | /// {{produces}} | |
3019 | /// | |
3020 | /// ### Explanation | |
3021 | /// | |
3022 | /// `rustdoc` does not use doc comments in all positions, and so the doc | |
3023 | /// comment will be ignored. Try changing it to a normal comment with `//` | |
3024 | /// to avoid the warning. | |
3025 | pub UNUSED_DOC_COMMENTS, | |
3026 | Warn, | |
3027 | "detects doc comments that aren't used by rustdoc" | |
3028 | } | |
3029 | ||
5869c6ff | 3030 | declare_lint! { |
17df50a5 | 3031 | /// The `disjoint_capture_migration` lint detects variables that aren't completely |
5869c6ff XL |
3032 | /// captured when the feature `capture_disjoint_fields` is enabled and it affects the Drop |
3033 | /// order of at least one path starting at this variable. | |
17df50a5 XL |
3034 | /// It can also detect when a variable implements a trait, but one of its field does not and |
3035 | /// the field is captured by a closure and used with the assumption that said field implements | |
3036 | /// the same trait as the root variable. | |
5869c6ff | 3037 | /// |
17df50a5 | 3038 | /// ### Example of drop reorder |
5869c6ff XL |
3039 | /// |
3040 | /// ```rust,compile_fail | |
17df50a5 | 3041 | /// # #![deny(disjoint_capture_migration)] |
5869c6ff XL |
3042 | /// # #![allow(unused)] |
3043 | /// struct FancyInteger(i32); | |
3044 | /// | |
3045 | /// impl Drop for FancyInteger { | |
3046 | /// fn drop(&mut self) { | |
3047 | /// println!("Just dropped {}", self.0); | |
3048 | /// } | |
3049 | /// } | |
3050 | /// | |
3051 | /// struct Point { x: FancyInteger, y: FancyInteger } | |
3052 | /// | |
3053 | /// fn main() { | |
3054 | /// let p = Point { x: FancyInteger(10), y: FancyInteger(20) }; | |
3055 | /// | |
3056 | /// let c = || { | |
3057 | /// let x = p.x; | |
3058 | /// }; | |
3059 | /// | |
3060 | /// c(); | |
3061 | /// | |
3062 | /// // ... More code ... | |
3063 | /// } | |
3064 | /// ``` | |
3065 | /// | |
3066 | /// {{produces}} | |
3067 | /// | |
3068 | /// ### Explanation | |
3069 | /// | |
3070 | /// In the above example `p.y` will be dropped at the end of `f` instead of with `c` if | |
3071 | /// the feature `capture_disjoint_fields` is enabled. | |
17df50a5 XL |
3072 | /// |
3073 | /// ### Example of auto-trait | |
3074 | /// | |
3075 | /// ```rust,compile_fail | |
3076 | /// #![deny(disjoint_capture_migration)] | |
3077 | /// use std::thread; | |
3078 | /// | |
3079 | /// struct Pointer (*mut i32); | |
3080 | /// unsafe impl Send for Pointer {} | |
3081 | /// | |
3082 | /// fn main() { | |
3083 | /// let mut f = 10; | |
3084 | /// let fptr = Pointer(&mut f as *mut i32); | |
3085 | /// thread::spawn(move || unsafe { | |
3086 | /// *fptr.0 = 20; | |
3087 | /// }); | |
3088 | /// } | |
3089 | /// ``` | |
3090 | /// | |
3091 | /// {{produces}} | |
3092 | /// | |
3093 | /// ### Explanation | |
3094 | /// | |
3095 | /// In the above example `fptr.0` is captured when feature `capture_disjoint_fields` is enabled. | |
3096 | /// The field is of type *mut i32 which doesn't implement Send, making the code invalid as the | |
3097 | /// field cannot be sent between thread safely. | |
3098 | pub DISJOINT_CAPTURE_MIGRATION, | |
5869c6ff | 3099 | Allow, |
17df50a5 | 3100 | "Drop reorder and auto traits error because of `capture_disjoint_fields`" |
5869c6ff XL |
3101 | } |
3102 | ||
1b1a35ee | 3103 | declare_lint_pass!(UnusedDocComment => [UNUSED_DOC_COMMENTS]); |
5869c6ff XL |
3104 | |
3105 | declare_lint! { | |
3106 | /// The `missing_abi` lint detects cases where the ABI is omitted from | |
3107 | /// extern declarations. | |
3108 | /// | |
3109 | /// ### Example | |
3110 | /// | |
3111 | /// ```rust,compile_fail | |
3112 | /// #![deny(missing_abi)] | |
3113 | /// | |
3114 | /// extern fn foo() {} | |
3115 | /// ``` | |
3116 | /// | |
3117 | /// {{produces}} | |
3118 | /// | |
3119 | /// ### Explanation | |
3120 | /// | |
3121 | /// Historically, Rust implicitly selected C as the ABI for extern | |
3122 | /// declarations. We expect to add new ABIs, like `C-unwind`, in the future, | |
3123 | /// though this has not yet happened, and especially with their addition | |
3124 | /// seeing the ABI easily will make code review easier. | |
3125 | pub MISSING_ABI, | |
3126 | Allow, | |
3127 | "No declared ABI for extern declaration" | |
3128 | } | |
6a06907d XL |
3129 | |
3130 | declare_lint! { | |
3131 | /// The `invalid_doc_attributes` lint detects when the `#[doc(...)]` is | |
3132 | /// misused. | |
3133 | /// | |
3134 | /// ### Example | |
3135 | /// | |
3136 | /// ```rust,compile_fail | |
3137 | /// #![deny(warnings)] | |
3138 | /// | |
3139 | /// pub mod submodule { | |
3140 | /// #![doc(test(no_crate_inject))] | |
3141 | /// } | |
3142 | /// ``` | |
3143 | /// | |
3144 | /// {{produces}} | |
3145 | /// | |
3146 | /// ### Explanation | |
3147 | /// | |
3148 | /// Previously, there were very like checks being performed on `#[doc(..)]` | |
3149 | /// unlike the other attributes. It'll now catch all the issues that it | |
3150 | /// silently ignored previously. | |
3151 | pub INVALID_DOC_ATTRIBUTES, | |
3152 | Warn, | |
3153 | "detects invalid `#[doc(...)]` attributes", | |
3154 | @future_incompatible = FutureIncompatibleInfo { | |
3155 | reference: "issue #82730 <https://github.com/rust-lang/rust/issues/82730>", | |
3156 | edition: None, | |
3157 | }; | |
3158 | } | |
3159 | ||
3160 | declare_lint! { | |
3161 | /// The `proc_macro_back_compat` lint detects uses of old versions of certain | |
3162 | /// proc-macro crates, which have hardcoded workarounds in the compiler. | |
3163 | /// | |
3164 | /// ### Example | |
3165 | /// | |
3166 | /// ```rust,ignore (needs-dependency) | |
3167 | /// | |
3168 | /// use time_macros_impl::impl_macros; | |
3169 | /// struct Foo; | |
3170 | /// impl_macros!(Foo); | |
3171 | /// ``` | |
3172 | /// | |
3173 | /// This will produce: | |
3174 | /// | |
3175 | /// ```text | |
3176 | /// warning: using an old version of `time-macros-impl` | |
3177 | /// ::: $DIR/group-compat-hack.rs:27:5 | |
3178 | /// | | |
3179 | /// LL | impl_macros!(Foo); | |
3180 | /// | ------------------ in this macro invocation | |
3181 | /// | | |
3182 | /// = note: `#[warn(proc_macro_back_compat)]` on by default | |
3183 | /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! | |
3184 | /// = note: for more information, see issue #83125 <https://github.com/rust-lang/rust/issues/83125> | |
3185 | /// = note: the `time-macros-impl` crate will stop compiling in futures version of Rust. Please update to the latest version of the `time` crate to avoid breakage | |
3186 | /// = note: this warning originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) | |
3187 | /// ``` | |
3188 | /// | |
3189 | /// ### Explanation | |
3190 | /// | |
3191 | /// Eventually, the backwards-compatibility hacks present in the compiler will be removed, | |
3192 | /// causing older versions of certain crates to stop compiling. | |
3193 | /// This is a [future-incompatible] lint to ease the transition to an error. | |
3194 | /// See [issue #83125] for more details. | |
3195 | /// | |
3196 | /// [issue #83125]: https://github.com/rust-lang/rust/issues/83125 | |
3197 | /// [future-incompatible]: ../index.md#future-incompatible-lints | |
3198 | pub PROC_MACRO_BACK_COMPAT, | |
3199 | Warn, | |
3200 | "detects usage of old versions of certain proc-macro crates", | |
3201 | @future_incompatible = FutureIncompatibleInfo { | |
3202 | reference: "issue #83125 <https://github.com/rust-lang/rust/issues/83125>", | |
3203 | edition: None, | |
3204 | future_breakage: Some(FutureBreakage { | |
3205 | date: None | |
3206 | }) | |
3207 | }; | |
3208 | } | |
cdc7bbd5 XL |
3209 | |
3210 | declare_lint! { | |
3211 | /// The `or_patterns_back_compat` lint detects usage of old versions of or-patterns. | |
3212 | /// | |
3213 | /// ### Example | |
3214 | /// | |
3215 | /// ```rust,compile_fail | |
3216 | /// #![deny(or_patterns_back_compat)] | |
3217 | /// macro_rules! match_any { | |
3218 | /// ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => { | |
3219 | /// match $expr { | |
3220 | /// $( | |
3221 | /// $( $pat => $expr_arm, )+ | |
3222 | /// )+ | |
3223 | /// } | |
3224 | /// }; | |
3225 | /// } | |
3226 | /// | |
3227 | /// fn main() { | |
3228 | /// let result: Result<i64, i32> = Err(42); | |
3229 | /// let int: i64 = match_any!(result, Ok(i) | Err(i) => i.into()); | |
3230 | /// assert_eq!(int, 42); | |
3231 | /// } | |
3232 | /// ``` | |
3233 | /// | |
3234 | /// {{produces}} | |
3235 | /// | |
3236 | /// ### Explanation | |
3237 | /// | |
3238 | /// In Rust 2021, the pat matcher will match new patterns, which include the | character. | |
3239 | pub OR_PATTERNS_BACK_COMPAT, | |
3240 | Allow, | |
3241 | "detects usage of old versions of or-patterns", | |
3242 | } |