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