rustc_lint_defs/builtin.rs
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//!
7//! When removing a lint, make sure to also add a call to `register_removed` in
8//! compiler/rustc_lint/src/lib.rs.
9
10use rustc_span::edition::Edition;
11
12use crate::{FutureIncompatibilityReason, declare_lint, declare_lint_pass};
13
14declare_lint_pass! {
15 /// Does nothing as a lint pass, but registers some `Lint`s
16 /// that are used by other parts of the compiler.
17 HardwiredLints => [
18 // tidy-alphabetical-start
19 AARCH64_SOFTFLOAT_NEON,
20 ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
21 AMBIGUOUS_ASSOCIATED_ITEMS,
22 AMBIGUOUS_GLOB_IMPORTS,
23 AMBIGUOUS_GLOB_REEXPORTS,
24 ARITHMETIC_OVERFLOW,
25 ASM_SUB_REGISTER,
26 BAD_ASM_STYLE,
27 BARE_TRAIT_OBJECTS,
28 BINDINGS_WITH_VARIANT_NAME,
29 BREAK_WITH_LABEL_AND_LOOP,
30 COHERENCE_LEAK_CHECK,
31 CONFLICTING_REPR_HINTS,
32 CONST_EVALUATABLE_UNCHECKED,
33 CONST_ITEM_MUTATION,
34 DEAD_CODE,
35 DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK,
36 DEPRECATED,
37 DEPRECATED_IN_FUTURE,
38 DEPRECATED_SAFE_2024,
39 DEPRECATED_WHERE_CLAUSE_LOCATION,
40 DUPLICATE_MACRO_ATTRIBUTES,
41 ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
42 ELIDED_LIFETIMES_IN_PATHS,
43 EXPLICIT_BUILTIN_CFGS_IN_FLAGS,
44 EXPORTED_PRIVATE_DEPENDENCIES,
45 FFI_UNWIND_CALLS,
46 FORBIDDEN_LINT_GROUPS,
47 FUNCTION_ITEM_REFERENCES,
48 FUZZY_PROVENANCE_CASTS,
49 HIDDEN_GLOB_REEXPORTS,
50 ILL_FORMED_ATTRIBUTE_INPUT,
51 INCOMPLETE_INCLUDE,
52 INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
53 INLINE_NO_SANITIZE,
54 INVALID_DOC_ATTRIBUTES,
55 INVALID_MACRO_EXPORT_ARGUMENTS,
56 INVALID_TYPE_PARAM_DEFAULT,
57 IRREFUTABLE_LET_PATTERNS,
58 LARGE_ASSIGNMENTS,
59 LATE_BOUND_LIFETIME_ARGUMENTS,
60 LEGACY_DERIVE_HELPERS,
61 LINKER_MESSAGES,
62 LONG_RUNNING_CONST_EVAL,
63 LOSSY_PROVENANCE_CASTS,
64 MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
65 MACRO_USE_EXTERN_CRATE,
66 MALFORMED_DIAGNOSTIC_ATTRIBUTES,
67 MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
68 META_VARIABLE_MISUSE,
69 MISPLACED_DIAGNOSTIC_ATTRIBUTES,
70 MISSING_ABI,
71 MISSING_UNSAFE_ON_EXTERN,
72 MUST_NOT_SUSPEND,
73 NAMED_ARGUMENTS_USED_POSITIONALLY,
74 NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
75 NON_CONTIGUOUS_RANGE_ENDPOINTS,
76 NON_EXHAUSTIVE_OMITTED_PATTERNS,
77 OUT_OF_SCOPE_MACRO_CALLS,
78 OVERLAPPING_RANGE_ENDPOINTS,
79 PATTERNS_IN_FNS_WITHOUT_BODY,
80 PRIVATE_BOUNDS,
81 PRIVATE_INTERFACES,
82 PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
83 PUB_USE_OF_PRIVATE_EXTERN_CRATE,
84 REDUNDANT_IMPORTS,
85 REDUNDANT_LIFETIMES,
86 REFINING_IMPL_TRAIT_INTERNAL,
87 REFINING_IMPL_TRAIT_REACHABLE,
88 RENAMED_AND_REMOVED_LINTS,
89 REPR_C_ENUMS_LARGER_THAN_INT,
90 REPR_TRANSPARENT_NON_ZST_FIELDS,
91 RTSAN_NONBLOCKING_ASYNC,
92 RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES,
93 RUST_2021_INCOMPATIBLE_OR_PATTERNS,
94 RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
95 RUST_2021_PRELUDE_COLLISIONS,
96 RUST_2024_GUARDED_STRING_INCOMPATIBLE_SYNTAX,
97 RUST_2024_INCOMPATIBLE_PAT,
98 RUST_2024_PRELUDE_COLLISIONS,
99 SELF_CONSTRUCTOR_FROM_OUTER_ITEM,
100 SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
101 SINGLE_USE_LIFETIMES,
102 SOFT_UNSTABLE,
103 STABLE_FEATURES,
104 SUPERTRAIT_ITEM_SHADOWING_DEFINITION,
105 SUPERTRAIT_ITEM_SHADOWING_USAGE,
106 TAIL_EXPR_DROP_ORDER,
107 TEST_UNSTABLE_LINT,
108 TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
109 TEXT_DIRECTION_CODEPOINT_IN_LITERAL,
110 TRIVIAL_CASTS,
111 TRIVIAL_NUMERIC_CASTS,
112 TYVAR_BEHIND_RAW_POINTER,
113 UNCONDITIONAL_PANIC,
114 UNCONDITIONAL_RECURSION,
115 UNCOVERED_PARAM_IN_PROJECTION,
116 UNEXPECTED_CFGS,
117 UNFULFILLED_LINT_EXPECTATIONS,
118 UNINHABITED_STATIC,
119 UNKNOWN_CRATE_TYPES,
120 UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
121 UNKNOWN_LINTS,
122 UNNAMEABLE_TEST_ITEMS,
123 UNNAMEABLE_TYPES,
124 UNREACHABLE_CODE,
125 UNREACHABLE_PATTERNS,
126 UNSAFE_ATTR_OUTSIDE_UNSAFE,
127 UNSAFE_OP_IN_UNSAFE_FN,
128 UNSTABLE_NAME_COLLISIONS,
129 UNSTABLE_SYNTAX_PRE_EXPANSION,
130 UNSUPPORTED_CALLING_CONVENTIONS,
131 UNUSED_ASSIGNMENTS,
132 UNUSED_ASSOCIATED_TYPE_BOUNDS,
133 UNUSED_ATTRIBUTES,
134 UNUSED_CRATE_DEPENDENCIES,
135 UNUSED_EXTERN_CRATES,
136 UNUSED_FEATURES,
137 UNUSED_IMPORTS,
138 UNUSED_LABELS,
139 UNUSED_LIFETIMES,
140 UNUSED_MACROS,
141 UNUSED_MACRO_RULES,
142 UNUSED_MUT,
143 UNUSED_QUALIFICATIONS,
144 UNUSED_UNSAFE,
145 UNUSED_VARIABLES,
146 USELESS_DEPRECATED,
147 VARARGS_WITHOUT_PATTERN,
148 WARNINGS,
149 // tidy-alphabetical-end
150 ]
151}
152
153declare_lint! {
154 /// The `forbidden_lint_groups` lint detects violations of
155 /// `forbid` applied to a lint group. Due to a bug in the compiler,
156 /// these used to be overlooked entirely. They now generate a warning.
157 ///
158 /// ### Example
159 ///
160 /// ```rust
161 /// #![forbid(warnings)]
162 /// #![warn(bad_style)]
163 ///
164 /// fn main() {}
165 /// ```
166 ///
167 /// {{produces}}
168 ///
169 /// ### Recommended fix
170 ///
171 /// If your crate is using `#![forbid(warnings)]`,
172 /// we recommend that you change to `#![deny(warnings)]`.
173 ///
174 /// ### Explanation
175 ///
176 /// Due to a compiler bug, applying `forbid` to lint groups
177 /// previously had no effect. The bug is now fixed but instead of
178 /// enforcing `forbid` we issue this future-compatibility warning
179 /// to avoid breaking existing crates.
180 pub FORBIDDEN_LINT_GROUPS,
181 Warn,
182 "applying forbid to lint-groups",
183 @future_incompatible = FutureIncompatibleInfo {
184 reason: FutureIncompatibilityReason::FutureReleaseError,
185 reference: "issue #81670 <https://github.com/rust-lang/rust/issues/81670>",
186 report_in_deps: true,
187 };
188}
189
190declare_lint! {
191 /// The `ill_formed_attribute_input` lint detects ill-formed attribute
192 /// inputs that were previously accepted and used in practice.
193 ///
194 /// ### Example
195 ///
196 /// ```rust,compile_fail
197 /// #[inline = "this is not valid"]
198 /// fn foo() {}
199 /// ```
200 ///
201 /// {{produces}}
202 ///
203 /// ### Explanation
204 ///
205 /// Previously, inputs for many built-in attributes weren't validated and
206 /// nonsensical attribute inputs were accepted. After validation was
207 /// added, it was determined that some existing projects made use of these
208 /// invalid forms. This is a [future-incompatible] lint to transition this
209 /// to a hard error in the future. See [issue #57571] for more details.
210 ///
211 /// Check the [attribute reference] for details on the valid inputs for
212 /// attributes.
213 ///
214 /// [issue #57571]: https://github.com/rust-lang/rust/issues/57571
215 /// [attribute reference]: https://doc.rust-lang.org/nightly/reference/attributes.html
216 /// [future-incompatible]: ../index.md#future-incompatible-lints
217 pub ILL_FORMED_ATTRIBUTE_INPUT,
218 Deny,
219 "ill-formed attribute inputs that were previously accepted and used in practice",
220 @future_incompatible = FutureIncompatibleInfo {
221 reason: FutureIncompatibilityReason::FutureReleaseError,
222 reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
223 report_in_deps: true,
224 };
225 crate_level_only
226}
227
228declare_lint! {
229 /// The `conflicting_repr_hints` lint detects [`repr` attributes] with
230 /// conflicting hints.
231 ///
232 /// [`repr` attributes]: https://doc.rust-lang.org/reference/type-layout.html#representations
233 ///
234 /// ### Example
235 ///
236 /// ```rust,compile_fail
237 /// #[repr(u32, u64)]
238 /// enum Foo {
239 /// Variant1,
240 /// }
241 /// ```
242 ///
243 /// {{produces}}
244 ///
245 /// ### Explanation
246 ///
247 /// The compiler incorrectly accepted these conflicting representations in
248 /// the past. This is a [future-incompatible] lint to transition this to a
249 /// hard error in the future. See [issue #68585] for more details.
250 ///
251 /// To correct the issue, remove one of the conflicting hints.
252 ///
253 /// [issue #68585]: https://github.com/rust-lang/rust/issues/68585
254 /// [future-incompatible]: ../index.md#future-incompatible-lints
255 pub CONFLICTING_REPR_HINTS,
256 Deny,
257 "conflicts between `#[repr(..)]` hints that were previously accepted and used in practice",
258 @future_incompatible = FutureIncompatibleInfo {
259 reason: FutureIncompatibilityReason::FutureReleaseError,
260 reference: "issue #68585 <https://github.com/rust-lang/rust/issues/68585>",
261 report_in_deps: true,
262 };
263}
264
265declare_lint! {
266 /// The `meta_variable_misuse` lint detects possible meta-variable misuse
267 /// in macro definitions.
268 ///
269 /// ### Example
270 ///
271 /// ```rust,compile_fail
272 /// #![deny(meta_variable_misuse)]
273 ///
274 /// macro_rules! foo {
275 /// () => {};
276 /// ($( $i:ident = $($j:ident),+ );*) => { $( $( $i = $k; )+ )* };
277 /// }
278 ///
279 /// fn main() {
280 /// foo!();
281 /// }
282 /// ```
283 ///
284 /// {{produces}}
285 ///
286 /// ### Explanation
287 ///
288 /// There are quite a few different ways a [`macro_rules`] macro can be
289 /// improperly defined. Many of these errors were previously only detected
290 /// when the macro was expanded or not at all. This lint is an attempt to
291 /// catch some of these problems when the macro is *defined*.
292 ///
293 /// This lint is "allow" by default because it may have false positives
294 /// and other issues. See [issue #61053] for more details.
295 ///
296 /// [`macro_rules`]: https://doc.rust-lang.org/reference/macros-by-example.html
297 /// [issue #61053]: https://github.com/rust-lang/rust/issues/61053
298 pub META_VARIABLE_MISUSE,
299 Allow,
300 "possible meta-variable misuse at macro definition"
301}
302
303declare_lint! {
304 /// The `incomplete_include` lint detects the use of the [`include!`]
305 /// macro with a file that contains more than one expression.
306 ///
307 /// [`include!`]: https://doc.rust-lang.org/std/macro.include.html
308 ///
309 /// ### Example
310 ///
311 /// ```rust,ignore (needs separate file)
312 /// fn main() {
313 /// include!("foo.txt");
314 /// }
315 /// ```
316 ///
317 /// where the file `foo.txt` contains:
318 ///
319 /// ```text
320 /// println!("hi!");
321 /// ```
322 ///
323 /// produces:
324 ///
325 /// ```text
326 /// error: include macro expected single expression in source
327 /// --> foo.txt:1:14
328 /// |
329 /// 1 | println!("1");
330 /// | ^
331 /// |
332 /// = note: `#[deny(incomplete_include)]` on by default
333 /// ```
334 ///
335 /// ### Explanation
336 ///
337 /// The [`include!`] macro is currently only intended to be used to
338 /// include a single [expression] or multiple [items]. Historically it
339 /// would ignore any contents after the first expression, but that can be
340 /// confusing. In the example above, the `println!` expression ends just
341 /// before the semicolon, making the semicolon "extra" information that is
342 /// ignored. Perhaps even more surprising, if the included file had
343 /// multiple print statements, the subsequent ones would be ignored!
344 ///
345 /// One workaround is to place the contents in braces to create a [block
346 /// expression]. Also consider alternatives, like using functions to
347 /// encapsulate the expressions, or use [proc-macros].
348 ///
349 /// This is a lint instead of a hard error because existing projects were
350 /// found to hit this error. To be cautious, it is a lint for now. The
351 /// future semantics of the `include!` macro are also uncertain, see
352 /// [issue #35560].
353 ///
354 /// [items]: https://doc.rust-lang.org/reference/items.html
355 /// [expression]: https://doc.rust-lang.org/reference/expressions.html
356 /// [block expression]: https://doc.rust-lang.org/reference/expressions/block-expr.html
357 /// [proc-macros]: https://doc.rust-lang.org/reference/procedural-macros.html
358 /// [issue #35560]: https://github.com/rust-lang/rust/issues/35560
359 pub INCOMPLETE_INCLUDE,
360 Deny,
361 "trailing content in included file"
362}
363
364declare_lint! {
365 /// The `arithmetic_overflow` lint detects that an arithmetic operation
366 /// will [overflow].
367 ///
368 /// [overflow]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#overflow
369 ///
370 /// ### Example
371 ///
372 /// ```rust,compile_fail
373 /// 1_i32 << 32;
374 /// ```
375 ///
376 /// {{produces}}
377 ///
378 /// ### Explanation
379 ///
380 /// It is very likely a mistake to perform an arithmetic operation that
381 /// overflows its value. If the compiler is able to detect these kinds of
382 /// overflows at compile-time, it will trigger this lint. Consider
383 /// adjusting the expression to avoid overflow, or use a data type that
384 /// will not overflow.
385 pub ARITHMETIC_OVERFLOW,
386 Deny,
387 "arithmetic operation overflows",
388 @eval_always = true
389}
390
391declare_lint! {
392 /// The `unconditional_panic` lint detects an operation that will cause a
393 /// panic at runtime.
394 ///
395 /// ### Example
396 ///
397 /// ```rust,compile_fail
398 /// # #![allow(unused)]
399 /// let x = 1 / 0;
400 /// ```
401 ///
402 /// {{produces}}
403 ///
404 /// ### Explanation
405 ///
406 /// This lint detects code that is very likely incorrect because it will
407 /// always panic, such as division by zero and out-of-bounds array
408 /// accesses. Consider adjusting your code if this is a bug, or using the
409 /// `panic!` or `unreachable!` macro instead in case the panic is intended.
410 pub UNCONDITIONAL_PANIC,
411 Deny,
412 "operation will cause a panic at runtime",
413 @eval_always = true
414}
415
416declare_lint! {
417 /// The `unused_imports` lint detects imports that are never used.
418 ///
419 /// ### Example
420 ///
421 /// ```rust
422 /// use std::collections::HashMap;
423 /// ```
424 ///
425 /// {{produces}}
426 ///
427 /// ### Explanation
428 ///
429 /// Unused imports may signal a mistake or unfinished code, and clutter
430 /// the code, and should be removed. If you intended to re-export the item
431 /// to make it available outside of the module, add a visibility modifier
432 /// like `pub`.
433 pub UNUSED_IMPORTS,
434 Warn,
435 "imports that are never used"
436}
437
438declare_lint! {
439 /// The `redundant_imports` lint detects imports that are redundant due to being
440 /// imported already; either through a previous import, or being present in
441 /// the prelude.
442 ///
443 /// ### Example
444 ///
445 /// ```rust,compile_fail
446 /// #![deny(redundant_imports)]
447 /// use std::option::Option::None;
448 /// fn foo() -> Option<i32> { None }
449 /// ```
450 ///
451 /// {{produces}}
452 ///
453 /// ### Explanation
454 ///
455 /// Redundant imports are unnecessary and can be removed to simplify code.
456 /// If you intended to re-export the item to make it available outside of the
457 /// module, add a visibility modifier like `pub`.
458 pub REDUNDANT_IMPORTS,
459 Allow,
460 "imports that are redundant due to being imported already"
461}
462
463declare_lint! {
464 /// The `must_not_suspend` lint guards against values that shouldn't be held across suspend points
465 /// (`.await`)
466 ///
467 /// ### Example
468 ///
469 /// ```rust
470 /// #![feature(must_not_suspend)]
471 /// #![warn(must_not_suspend)]
472 ///
473 /// #[must_not_suspend]
474 /// struct SyncThing {}
475 ///
476 /// async fn yield_now() {}
477 ///
478 /// pub async fn uhoh() {
479 /// let guard = SyncThing {};
480 /// yield_now().await;
481 /// let _guard = guard;
482 /// }
483 /// ```
484 ///
485 /// {{produces}}
486 ///
487 /// ### Explanation
488 ///
489 /// The `must_not_suspend` lint detects values that are marked with the `#[must_not_suspend]`
490 /// attribute being held across suspend points. A "suspend" point is usually a `.await` in an async
491 /// function.
492 ///
493 /// This attribute can be used to mark values that are semantically incorrect across suspends
494 /// (like certain types of timers), values that have async alternatives, and values that
495 /// regularly cause problems with the `Send`-ness of async fn's returned futures (like
496 /// `MutexGuard`'s)
497 ///
498 pub MUST_NOT_SUSPEND,
499 Allow,
500 "use of a `#[must_not_suspend]` value across a yield point",
501 @feature_gate = must_not_suspend;
502}
503
504declare_lint! {
505 /// The `unused_extern_crates` lint guards against `extern crate` items
506 /// that are never used.
507 ///
508 /// ### Example
509 ///
510 /// ```rust,compile_fail
511 /// #![deny(unused_extern_crates)]
512 /// #![deny(warnings)]
513 /// extern crate proc_macro;
514 /// ```
515 ///
516 /// {{produces}}
517 ///
518 /// ### Explanation
519 ///
520 /// `extern crate` items that are unused have no effect and should be
521 /// removed. Note that there are some cases where specifying an `extern
522 /// crate` is desired for the side effect of ensuring the given crate is
523 /// linked, even though it is not otherwise directly referenced. The lint
524 /// can be silenced by aliasing the crate to an underscore, such as
525 /// `extern crate foo as _`. Also note that it is no longer idiomatic to
526 /// use `extern crate` in the [2018 edition], as extern crates are now
527 /// automatically added in scope.
528 ///
529 /// This lint is "allow" by default because it can be noisy, and produce
530 /// false-positives. If a dependency is being removed from a project, it
531 /// is recommended to remove it from the build configuration (such as
532 /// `Cargo.toml`) to ensure stale build entries aren't left behind.
533 ///
534 /// [2018 edition]: https://doc.rust-lang.org/edition-guide/rust-2018/module-system/path-clarity.html#no-more-extern-crate
535 pub UNUSED_EXTERN_CRATES,
536 Allow,
537 "extern crates that are never used"
538}
539
540declare_lint! {
541 /// The `unused_crate_dependencies` lint detects crate dependencies that
542 /// are never used.
543 ///
544 /// ### Example
545 ///
546 /// ```rust,ignore (needs extern crate)
547 /// #![deny(unused_crate_dependencies)]
548 /// ```
549 ///
550 /// This will produce:
551 ///
552 /// ```text
553 /// error: extern crate `regex` is unused in crate `lint_example`
554 /// |
555 /// = help: remove the dependency or add `use regex as _;` to the crate root
556 /// note: the lint level is defined here
557 /// --> src/lib.rs:1:9
558 /// |
559 /// 1 | #![deny(unused_crate_dependencies)]
560 /// | ^^^^^^^^^^^^^^^^^^^^^^^^^
561 /// ```
562 ///
563 /// ### Explanation
564 ///
565 /// After removing the code that uses a dependency, this usually also
566 /// requires removing the dependency from the build configuration.
567 /// However, sometimes that step can be missed, which leads to time wasted
568 /// building dependencies that are no longer used. This lint can be
569 /// enabled to detect dependencies that are never used (more specifically,
570 /// any dependency passed with the `--extern` command-line flag that is
571 /// never referenced via [`use`], [`extern crate`], or in any [path]).
572 ///
573 /// This lint is "allow" by default because it can provide false positives
574 /// depending on how the build system is configured. For example, when
575 /// using Cargo, a "package" consists of multiple crates (such as a
576 /// library and a binary), but the dependencies are defined for the
577 /// package as a whole. If there is a dependency that is only used in the
578 /// binary, but not the library, then the lint will be incorrectly issued
579 /// in the library.
580 ///
581 /// [path]: https://doc.rust-lang.org/reference/paths.html
582 /// [`use`]: https://doc.rust-lang.org/reference/items/use-declarations.html
583 /// [`extern crate`]: https://doc.rust-lang.org/reference/items/extern-crates.html
584 pub UNUSED_CRATE_DEPENDENCIES,
585 Allow,
586 "crate dependencies that are never used",
587 crate_level_only
588}
589
590declare_lint! {
591 /// The `unused_qualifications` lint detects unnecessarily qualified
592 /// names.
593 ///
594 /// ### Example
595 ///
596 /// ```rust,compile_fail
597 /// #![deny(unused_qualifications)]
598 /// mod foo {
599 /// pub fn bar() {}
600 /// }
601 ///
602 /// fn main() {
603 /// use foo::bar;
604 /// foo::bar();
605 /// bar();
606 /// }
607 /// ```
608 ///
609 /// {{produces}}
610 ///
611 /// ### Explanation
612 ///
613 /// If an item from another module is already brought into scope, then
614 /// there is no need to qualify it in this case. You can call `bar()`
615 /// directly, without the `foo::`.
616 ///
617 /// This lint is "allow" by default because it is somewhat pedantic, and
618 /// doesn't indicate an actual problem, but rather a stylistic choice, and
619 /// can be noisy when refactoring or moving around code.
620 pub UNUSED_QUALIFICATIONS,
621 Allow,
622 "detects unnecessarily qualified names"
623}
624
625declare_lint! {
626 /// The `unknown_lints` lint detects unrecognized lint attributes.
627 ///
628 /// ### Example
629 ///
630 /// ```rust
631 /// #![allow(not_a_real_lint)]
632 /// ```
633 ///
634 /// {{produces}}
635 ///
636 /// ### Explanation
637 ///
638 /// It is usually a mistake to specify a lint that does not exist. Check
639 /// the spelling, and check the lint listing for the correct name. Also
640 /// consider if you are using an old version of the compiler, and the lint
641 /// is only available in a newer version.
642 pub UNKNOWN_LINTS,
643 Warn,
644 "unrecognized lint attribute",
645 @eval_always = true
646}
647
648declare_lint! {
649 /// The `unfulfilled_lint_expectations` lint detects when a lint expectation is
650 /// unfulfilled.
651 ///
652 /// ### Example
653 ///
654 /// ```rust
655 /// #[expect(unused_variables)]
656 /// let x = 10;
657 /// println!("{}", x);
658 /// ```
659 ///
660 /// {{produces}}
661 ///
662 /// ### Explanation
663 ///
664 /// The `#[expect]` attribute can be used to create a lint expectation. The
665 /// expectation is fulfilled, if a `#[warn]` attribute at the same location
666 /// would result in a lint emission. If the expectation is unfulfilled,
667 /// because no lint was emitted, this lint will be emitted on the attribute.
668 ///
669 pub UNFULFILLED_LINT_EXPECTATIONS,
670 Warn,
671 "unfulfilled lint expectation"
672}
673
674declare_lint! {
675 /// The `unused_variables` lint detects variables which are not used in
676 /// any way.
677 ///
678 /// ### Example
679 ///
680 /// ```rust
681 /// let x = 5;
682 /// ```
683 ///
684 /// {{produces}}
685 ///
686 /// ### Explanation
687 ///
688 /// Unused variables may signal a mistake or unfinished code. To silence
689 /// the warning for the individual variable, prefix it with an underscore
690 /// such as `_x`.
691 pub UNUSED_VARIABLES,
692 Warn,
693 "detect variables which are not used in any way"
694}
695
696declare_lint! {
697 /// The `unused_assignments` lint detects assignments that will never be read.
698 ///
699 /// ### Example
700 ///
701 /// ```rust
702 /// let mut x = 5;
703 /// x = 6;
704 /// ```
705 ///
706 /// {{produces}}
707 ///
708 /// ### Explanation
709 ///
710 /// Unused assignments may signal a mistake or unfinished code. If the
711 /// variable is never used after being assigned, then the assignment can
712 /// be removed. Variables with an underscore prefix such as `_x` will not
713 /// trigger this lint.
714 pub UNUSED_ASSIGNMENTS,
715 Warn,
716 "detect assignments that will never be read"
717}
718
719declare_lint! {
720 /// The `dead_code` lint detects unused, unexported items.
721 ///
722 /// ### Example
723 ///
724 /// ```rust
725 /// fn foo() {}
726 /// ```
727 ///
728 /// {{produces}}
729 ///
730 /// ### Explanation
731 ///
732 /// Dead code may signal a mistake or unfinished code. To silence the
733 /// warning for individual items, prefix the name with an underscore such
734 /// as `_foo`. If it was intended to expose the item outside of the crate,
735 /// consider adding a visibility modifier like `pub`.
736 ///
737 /// To preserve the numbering of tuple structs with unused fields,
738 /// change the unused fields to have unit type or use
739 /// `PhantomData`.
740 ///
741 /// Otherwise consider removing the unused code.
742 ///
743 /// ### Limitations
744 ///
745 /// Removing fields that are only used for side-effects and never
746 /// read will result in behavioral changes. Examples of this
747 /// include:
748 ///
749 /// - If a field's value performs an action when it is dropped.
750 /// - If a field's type does not implement an auto trait
751 /// (e.g. `Send`, `Sync`, `Unpin`).
752 ///
753 /// For side-effects from dropping field values, this lint should
754 /// be allowed on those fields. For side-effects from containing
755 /// field types, `PhantomData` should be used.
756 pub DEAD_CODE,
757 Warn,
758 "detect unused, unexported items"
759}
760
761declare_lint! {
762 /// The `unused_attributes` lint detects attributes that were not used by
763 /// the compiler.
764 ///
765 /// ### Example
766 ///
767 /// ```rust
768 /// #![ignore]
769 /// ```
770 ///
771 /// {{produces}}
772 ///
773 /// ### Explanation
774 ///
775 /// Unused [attributes] may indicate the attribute is placed in the wrong
776 /// position. Consider removing it, or placing it in the correct position.
777 /// Also consider if you intended to use an _inner attribute_ (with a `!`
778 /// such as `#![allow(unused)]`) which applies to the item the attribute
779 /// is within, or an _outer attribute_ (without a `!` such as
780 /// `#[allow(unused)]`) which applies to the item *following* the
781 /// attribute.
782 ///
783 /// [attributes]: https://doc.rust-lang.org/reference/attributes.html
784 pub UNUSED_ATTRIBUTES,
785 Warn,
786 "detects attributes that were not used by the compiler"
787}
788
789declare_lint! {
790 /// The `unreachable_code` lint detects unreachable code paths.
791 ///
792 /// ### Example
793 ///
794 /// ```rust,no_run
795 /// panic!("we never go past here!");
796 ///
797 /// let x = 5;
798 /// ```
799 ///
800 /// {{produces}}
801 ///
802 /// ### Explanation
803 ///
804 /// Unreachable code may signal a mistake or unfinished code. If the code
805 /// is no longer in use, consider removing it.
806 pub UNREACHABLE_CODE,
807 Warn,
808 "detects unreachable code paths",
809 report_in_external_macro
810}
811
812declare_lint! {
813 /// The `unreachable_patterns` lint detects unreachable patterns.
814 ///
815 /// ### Example
816 ///
817 /// ```rust
818 /// let x = 5;
819 /// match x {
820 /// y => (),
821 /// 5 => (),
822 /// }
823 /// ```
824 ///
825 /// {{produces}}
826 ///
827 /// ### Explanation
828 ///
829 /// This usually indicates a mistake in how the patterns are specified or
830 /// ordered. In this example, the `y` pattern will always match, so the
831 /// five is impossible to reach. Remember, match arms match in order, you
832 /// probably wanted to put the `5` case above the `y` case.
833 pub UNREACHABLE_PATTERNS,
834 Warn,
835 "detects unreachable patterns"
836}
837
838declare_lint! {
839 /// The `overlapping_range_endpoints` lint detects `match` arms that have [range patterns] that
840 /// overlap on their endpoints.
841 ///
842 /// [range patterns]: https://doc.rust-lang.org/nightly/reference/patterns.html#range-patterns
843 ///
844 /// ### Example
845 ///
846 /// ```rust
847 /// let x = 123u8;
848 /// match x {
849 /// 0..=100 => { println!("small"); }
850 /// 100..=255 => { println!("large"); }
851 /// }
852 /// ```
853 ///
854 /// {{produces}}
855 ///
856 /// ### Explanation
857 ///
858 /// It is likely a mistake to have range patterns in a match expression that overlap in this
859 /// way. Check that the beginning and end values are what you expect, and keep in mind that
860 /// with `..=` the left and right bounds are inclusive.
861 pub OVERLAPPING_RANGE_ENDPOINTS,
862 Warn,
863 "detects range patterns with overlapping endpoints"
864}
865
866declare_lint! {
867 /// The `non_contiguous_range_endpoints` lint detects likely off-by-one errors when using
868 /// exclusive [range patterns].
869 ///
870 /// [range patterns]: https://doc.rust-lang.org/nightly/reference/patterns.html#range-patterns
871 ///
872 /// ### Example
873 ///
874 /// ```rust
875 /// let x = 123u32;
876 /// match x {
877 /// 0..100 => { println!("small"); }
878 /// 101..1000 => { println!("large"); }
879 /// _ => { println!("larger"); }
880 /// }
881 /// ```
882 ///
883 /// {{produces}}
884 ///
885 /// ### Explanation
886 ///
887 /// It is likely a mistake to have range patterns in a match expression that miss out a single
888 /// number. Check that the beginning and end values are what you expect, and keep in mind that
889 /// with `..=` the right bound is inclusive, and with `..` it is exclusive.
890 pub NON_CONTIGUOUS_RANGE_ENDPOINTS,
891 Warn,
892 "detects off-by-one errors with exclusive range patterns"
893}
894
895declare_lint! {
896 /// The `bindings_with_variant_name` lint detects pattern bindings with
897 /// the same name as one of the matched variants.
898 ///
899 /// ### Example
900 ///
901 /// ```rust,compile_fail
902 /// pub enum Enum {
903 /// Foo,
904 /// Bar,
905 /// }
906 ///
907 /// pub fn foo(x: Enum) {
908 /// match x {
909 /// Foo => {}
910 /// Bar => {}
911 /// }
912 /// }
913 /// ```
914 ///
915 /// {{produces}}
916 ///
917 /// ### Explanation
918 ///
919 /// It is usually a mistake to specify an enum variant name as an
920 /// [identifier pattern]. In the example above, the `match` arms are
921 /// specifying a variable name to bind the value of `x` to. The second arm
922 /// is ignored because the first one matches *all* values. The likely
923 /// intent is that the arm was intended to match on the enum variant.
924 ///
925 /// Two possible solutions are:
926 ///
927 /// * Specify the enum variant using a [path pattern], such as
928 /// `Enum::Foo`.
929 /// * Bring the enum variants into local scope, such as adding `use
930 /// Enum::*;` to the beginning of the `foo` function in the example
931 /// above.
932 ///
933 /// [identifier pattern]: https://doc.rust-lang.org/reference/patterns.html#identifier-patterns
934 /// [path pattern]: https://doc.rust-lang.org/reference/patterns.html#path-patterns
935 pub BINDINGS_WITH_VARIANT_NAME,
936 Deny,
937 "detects pattern bindings with the same name as one of the matched variants"
938}
939
940declare_lint! {
941 /// The `unused_macros` lint detects macros that were not used.
942 ///
943 /// Note that this lint is distinct from the `unused_macro_rules` lint,
944 /// which checks for single rules that never match of an otherwise used
945 /// macro, and thus never expand.
946 ///
947 /// ### Example
948 ///
949 /// ```rust
950 /// macro_rules! unused {
951 /// () => {};
952 /// }
953 ///
954 /// fn main() {
955 /// }
956 /// ```
957 ///
958 /// {{produces}}
959 ///
960 /// ### Explanation
961 ///
962 /// Unused macros may signal a mistake or unfinished code. To silence the
963 /// warning for the individual macro, prefix the name with an underscore
964 /// such as `_my_macro`. If you intended to export the macro to make it
965 /// available outside of the crate, use the [`macro_export` attribute].
966 ///
967 /// [`macro_export` attribute]: https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope
968 pub UNUSED_MACROS,
969 Warn,
970 "detects macros that were not used"
971}
972
973declare_lint! {
974 /// The `unused_macro_rules` lint detects macro rules that were not used.
975 ///
976 /// Note that the lint is distinct from the `unused_macros` lint, which
977 /// fires if the entire macro is never called, while this lint fires for
978 /// single unused rules of the macro that is otherwise used.
979 /// `unused_macro_rules` fires only if `unused_macros` wouldn't fire.
980 ///
981 /// ### Example
982 ///
983 /// ```rust
984 /// #[warn(unused_macro_rules)]
985 /// macro_rules! unused_empty {
986 /// (hello) => { println!("Hello, world!") }; // This rule is unused
987 /// () => { println!("empty") }; // This rule is used
988 /// }
989 ///
990 /// fn main() {
991 /// unused_empty!(hello);
992 /// }
993 /// ```
994 ///
995 /// {{produces}}
996 ///
997 /// ### Explanation
998 ///
999 /// Unused macro rules may signal a mistake or unfinished code. Furthermore,
1000 /// they slow down compilation. Right now, silencing the warning is not
1001 /// supported on a single rule level, so you have to add an allow to the
1002 /// entire macro definition.
1003 ///
1004 /// If you intended to export the macro to make it
1005 /// available outside of the crate, use the [`macro_export` attribute].
1006 ///
1007 /// [`macro_export` attribute]: https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope
1008 pub UNUSED_MACRO_RULES,
1009 Allow,
1010 "detects macro rules that were not used"
1011}
1012
1013declare_lint! {
1014 /// The `warnings` lint allows you to change the level of other
1015 /// lints which produce warnings.
1016 ///
1017 /// ### Example
1018 ///
1019 /// ```rust
1020 /// #![deny(warnings)]
1021 /// fn foo() {}
1022 /// ```
1023 ///
1024 /// {{produces}}
1025 ///
1026 /// ### Explanation
1027 ///
1028 /// The `warnings` lint is a bit special; by changing its level, you
1029 /// change every other warning that would produce a warning to whatever
1030 /// value you'd like. As such, you won't ever trigger this lint in your
1031 /// code directly.
1032 pub WARNINGS,
1033 Warn,
1034 "mass-change the level for lints which produce warnings"
1035}
1036
1037declare_lint! {
1038 /// The `unused_features` lint detects unused or unknown features found in
1039 /// crate-level [`feature` attributes].
1040 ///
1041 /// [`feature` attributes]: https://doc.rust-lang.org/nightly/unstable-book/
1042 ///
1043 /// Note: This lint is currently not functional, see [issue #44232] for
1044 /// more details.
1045 ///
1046 /// [issue #44232]: https://github.com/rust-lang/rust/issues/44232
1047 pub UNUSED_FEATURES,
1048 Warn,
1049 "unused features found in crate-level `#[feature]` directives"
1050}
1051
1052declare_lint! {
1053 /// The `stable_features` lint detects a [`feature` attribute] that
1054 /// has since been made stable.
1055 ///
1056 /// [`feature` attribute]: https://doc.rust-lang.org/nightly/unstable-book/
1057 ///
1058 /// ### Example
1059 ///
1060 /// ```rust
1061 /// #![feature(test_accepted_feature)]
1062 /// fn main() {}
1063 /// ```
1064 ///
1065 /// {{produces}}
1066 ///
1067 /// ### Explanation
1068 ///
1069 /// When a feature is stabilized, it is no longer necessary to include a
1070 /// `#![feature]` attribute for it. To fix, simply remove the
1071 /// `#![feature]` attribute.
1072 pub STABLE_FEATURES,
1073 Warn,
1074 "stable features found in `#[feature]` directive"
1075}
1076
1077declare_lint! {
1078 /// The `unknown_crate_types` lint detects an unknown crate type found in
1079 /// a [`crate_type` attribute].
1080 ///
1081 /// ### Example
1082 ///
1083 /// ```rust,compile_fail
1084 /// #![crate_type="lol"]
1085 /// fn main() {}
1086 /// ```
1087 ///
1088 /// {{produces}}
1089 ///
1090 /// ### Explanation
1091 ///
1092 /// An unknown value give to the `crate_type` attribute is almost
1093 /// certainly a mistake.
1094 ///
1095 /// [`crate_type` attribute]: https://doc.rust-lang.org/reference/linkage.html
1096 pub UNKNOWN_CRATE_TYPES,
1097 Deny,
1098 "unknown crate type found in `#[crate_type]` directive",
1099 crate_level_only
1100}
1101
1102declare_lint! {
1103 /// The `trivial_casts` lint detects trivial casts which could be replaced
1104 /// with coercion, which may require a temporary variable.
1105 ///
1106 /// ### Example
1107 ///
1108 /// ```rust,compile_fail
1109 /// #![deny(trivial_casts)]
1110 /// let x: &u32 = &42;
1111 /// let y = x as *const u32;
1112 /// ```
1113 ///
1114 /// {{produces}}
1115 ///
1116 /// ### Explanation
1117 ///
1118 /// A trivial cast is a cast `e as T` where `e` has type `U` and `U` is a
1119 /// subtype of `T`. This type of cast is usually unnecessary, as it can be
1120 /// usually be inferred.
1121 ///
1122 /// This lint is "allow" by default because there are situations, such as
1123 /// with FFI interfaces or complex type aliases, where it triggers
1124 /// incorrectly, or in situations where it will be more difficult to
1125 /// clearly express the intent. It may be possible that this will become a
1126 /// warning in the future, possibly with an explicit syntax for coercions
1127 /// providing a convenient way to work around the current issues.
1128 /// See [RFC 401 (coercions)][rfc-401], [RFC 803 (type ascription)][rfc-803] and
1129 /// [RFC 3307 (remove type ascription)][rfc-3307] for historical context.
1130 ///
1131 /// [rfc-401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
1132 /// [rfc-803]: https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md
1133 /// [rfc-3307]: https://github.com/rust-lang/rfcs/blob/master/text/3307-de-rfc-type-ascription.md
1134 pub TRIVIAL_CASTS,
1135 Allow,
1136 "detects trivial casts which could be removed"
1137}
1138
1139declare_lint! {
1140 /// The `trivial_numeric_casts` lint detects trivial numeric casts of types
1141 /// which could be removed.
1142 ///
1143 /// ### Example
1144 ///
1145 /// ```rust,compile_fail
1146 /// #![deny(trivial_numeric_casts)]
1147 /// let x = 42_i32 as i32;
1148 /// ```
1149 ///
1150 /// {{produces}}
1151 ///
1152 /// ### Explanation
1153 ///
1154 /// A trivial numeric cast is a cast of a numeric type to the same numeric
1155 /// type. This type of cast is usually unnecessary.
1156 ///
1157 /// This lint is "allow" by default because there are situations, such as
1158 /// with FFI interfaces or complex type aliases, where it triggers
1159 /// incorrectly, or in situations where it will be more difficult to
1160 /// clearly express the intent. It may be possible that this will become a
1161 /// warning in the future, possibly with an explicit syntax for coercions
1162 /// providing a convenient way to work around the current issues.
1163 /// See [RFC 401 (coercions)][rfc-401], [RFC 803 (type ascription)][rfc-803] and
1164 /// [RFC 3307 (remove type ascription)][rfc-3307] for historical context.
1165 ///
1166 /// [rfc-401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
1167 /// [rfc-803]: https://github.com/rust-lang/rfcs/blob/master/text/0803-type-ascription.md
1168 /// [rfc-3307]: https://github.com/rust-lang/rfcs/blob/master/text/3307-de-rfc-type-ascription.md
1169 pub TRIVIAL_NUMERIC_CASTS,
1170 Allow,
1171 "detects trivial casts of numeric types which could be removed"
1172}
1173
1174declare_lint! {
1175 /// The `exported_private_dependencies` lint detects private dependencies
1176 /// that are exposed in a public interface.
1177 ///
1178 /// ### Example
1179 ///
1180 /// ```rust,ignore (needs-dependency)
1181 /// pub fn foo() -> Option<some_private_dependency::Thing> {
1182 /// None
1183 /// }
1184 /// ```
1185 ///
1186 /// This will produce:
1187 ///
1188 /// ```text
1189 /// warning: type `bar::Thing` from private dependency 'bar' in public interface
1190 /// --> src/lib.rs:3:1
1191 /// |
1192 /// 3 | pub fn foo() -> Option<bar::Thing> {
1193 /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
1194 /// |
1195 /// = note: `#[warn(exported_private_dependencies)]` on by default
1196 /// ```
1197 ///
1198 /// ### Explanation
1199 ///
1200 /// Dependencies can be marked as "private" to indicate that they are not
1201 /// exposed in the public interface of a crate. This can be used by Cargo
1202 /// to independently resolve those dependencies because it can assume it
1203 /// does not need to unify them with other packages using that same
1204 /// dependency. This lint is an indication of a violation of that
1205 /// contract.
1206 ///
1207 /// To fix this, avoid exposing the dependency in your public interface.
1208 /// Or, switch the dependency to a public dependency.
1209 ///
1210 /// Note that support for this is only available on the nightly channel.
1211 /// See [RFC 1977] for more details, as well as the [Cargo documentation].
1212 ///
1213 /// [RFC 1977]: https://github.com/rust-lang/rfcs/blob/master/text/1977-public-private-dependencies.md
1214 /// [Cargo documentation]: https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#public-dependency
1215 pub EXPORTED_PRIVATE_DEPENDENCIES,
1216 Warn,
1217 "public interface leaks type from a private dependency"
1218}
1219
1220declare_lint! {
1221 /// The `pub_use_of_private_extern_crate` lint detects a specific
1222 /// situation of re-exporting a private `extern crate`.
1223 ///
1224 /// ### Example
1225 ///
1226 /// ```rust,compile_fail
1227 /// extern crate core;
1228 /// pub use core as reexported_core;
1229 /// ```
1230 ///
1231 /// {{produces}}
1232 ///
1233 /// ### Explanation
1234 ///
1235 /// A public `use` declaration should not be used to publically re-export a
1236 /// private `extern crate`. `pub extern crate` should be used instead.
1237 ///
1238 /// This was historically allowed, but is not the intended behavior
1239 /// according to the visibility rules. This is a [future-incompatible]
1240 /// lint to transition this to a hard error in the future. See [issue
1241 /// #127909] for more details.
1242 ///
1243 /// [issue #127909]: https://github.com/rust-lang/rust/issues/127909
1244 /// [future-incompatible]: ../index.md#future-incompatible-lints
1245 pub PUB_USE_OF_PRIVATE_EXTERN_CRATE,
1246 Deny,
1247 "detect public re-exports of private extern crates",
1248 @future_incompatible = FutureIncompatibleInfo {
1249 reason: FutureIncompatibilityReason::FutureReleaseError,
1250 reference: "issue #127909 <https://github.com/rust-lang/rust/issues/127909>",
1251 report_in_deps: true,
1252 };
1253}
1254
1255declare_lint! {
1256 /// The `invalid_type_param_default` lint detects type parameter defaults
1257 /// erroneously allowed in an invalid location.
1258 ///
1259 /// ### Example
1260 ///
1261 /// ```rust,compile_fail
1262 /// fn foo<T=i32>(t: T) {}
1263 /// ```
1264 ///
1265 /// {{produces}}
1266 ///
1267 /// ### Explanation
1268 ///
1269 /// Default type parameters were only intended to be allowed in certain
1270 /// situations, but historically the compiler allowed them everywhere.
1271 /// This is a [future-incompatible] lint to transition this to a hard
1272 /// error in the future. See [issue #36887] for more details.
1273 ///
1274 /// [issue #36887]: https://github.com/rust-lang/rust/issues/36887
1275 /// [future-incompatible]: ../index.md#future-incompatible-lints
1276 pub INVALID_TYPE_PARAM_DEFAULT,
1277 Deny,
1278 "type parameter default erroneously allowed in invalid location",
1279 @future_incompatible = FutureIncompatibleInfo {
1280 reason: FutureIncompatibilityReason::FutureReleaseError,
1281 reference: "issue #36887 <https://github.com/rust-lang/rust/issues/36887>",
1282 report_in_deps: true,
1283 };
1284}
1285
1286declare_lint! {
1287 /// The `renamed_and_removed_lints` lint detects lints that have been
1288 /// renamed or removed.
1289 ///
1290 /// ### Example
1291 ///
1292 /// ```rust
1293 /// #![deny(raw_pointer_derive)]
1294 /// ```
1295 ///
1296 /// {{produces}}
1297 ///
1298 /// ### Explanation
1299 ///
1300 /// To fix this, either remove the lint or use the new name. This can help
1301 /// avoid confusion about lints that are no longer valid, and help
1302 /// maintain consistency for renamed lints.
1303 pub RENAMED_AND_REMOVED_LINTS,
1304 Warn,
1305 "lints that have been renamed or removed"
1306}
1307
1308declare_lint! {
1309 /// The `const_item_mutation` lint detects attempts to mutate a `const`
1310 /// item.
1311 ///
1312 /// ### Example
1313 ///
1314 /// ```rust
1315 /// const FOO: [i32; 1] = [0];
1316 ///
1317 /// fn main() {
1318 /// FOO[0] = 1;
1319 /// // This will print "[0]".
1320 /// println!("{:?}", FOO);
1321 /// }
1322 /// ```
1323 ///
1324 /// {{produces}}
1325 ///
1326 /// ### Explanation
1327 ///
1328 /// Trying to directly mutate a `const` item is almost always a mistake.
1329 /// What is happening in the example above is that a temporary copy of the
1330 /// `const` is mutated, but the original `const` is not. Each time you
1331 /// refer to the `const` by name (such as `FOO` in the example above), a
1332 /// separate copy of the value is inlined at that location.
1333 ///
1334 /// This lint checks for writing directly to a field (`FOO.field =
1335 /// some_value`) or array entry (`FOO[0] = val`), or taking a mutable
1336 /// reference to the const item (`&mut FOO`), including through an
1337 /// autoderef (`FOO.some_mut_self_method()`).
1338 ///
1339 /// There are various alternatives depending on what you are trying to
1340 /// accomplish:
1341 ///
1342 /// * First, always reconsider using mutable globals, as they can be
1343 /// difficult to use correctly, and can make the code more difficult to
1344 /// use or understand.
1345 /// * If you are trying to perform a one-time initialization of a global:
1346 /// * If the value can be computed at compile-time, consider using
1347 /// const-compatible values (see [Constant Evaluation]).
1348 /// * For more complex single-initialization cases, consider using
1349 /// [`std::sync::LazyLock`].
1350 /// * If you truly need a mutable global, consider using a [`static`],
1351 /// which has a variety of options:
1352 /// * Simple data types can be directly defined and mutated with an
1353 /// [`atomic`] type.
1354 /// * More complex types can be placed in a synchronization primitive
1355 /// like a [`Mutex`], which can be initialized with one of the options
1356 /// listed above.
1357 /// * A [mutable `static`] is a low-level primitive, requiring unsafe.
1358 /// Typically This should be avoided in preference of something
1359 /// higher-level like one of the above.
1360 ///
1361 /// [Constant Evaluation]: https://doc.rust-lang.org/reference/const_eval.html
1362 /// [`static`]: https://doc.rust-lang.org/reference/items/static-items.html
1363 /// [mutable `static`]: https://doc.rust-lang.org/reference/items/static-items.html#mutable-statics
1364 /// [`std::sync::LazyLock`]: https://doc.rust-lang.org/stable/std/sync/struct.LazyLock.html
1365 /// [`atomic`]: https://doc.rust-lang.org/std/sync/atomic/index.html
1366 /// [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
1367 pub CONST_ITEM_MUTATION,
1368 Warn,
1369 "detects attempts to mutate a `const` item",
1370}
1371
1372declare_lint! {
1373 /// The `patterns_in_fns_without_body` lint detects `mut` identifier
1374 /// patterns as a parameter in functions without a body.
1375 ///
1376 /// ### Example
1377 ///
1378 /// ```rust,compile_fail
1379 /// trait Trait {
1380 /// fn foo(mut arg: u8);
1381 /// }
1382 /// ```
1383 ///
1384 /// {{produces}}
1385 ///
1386 /// ### Explanation
1387 ///
1388 /// To fix this, remove `mut` from the parameter in the trait definition;
1389 /// it can be used in the implementation. That is, the following is OK:
1390 ///
1391 /// ```rust
1392 /// trait Trait {
1393 /// fn foo(arg: u8); // Removed `mut` here
1394 /// }
1395 ///
1396 /// impl Trait for i32 {
1397 /// fn foo(mut arg: u8) { // `mut` here is OK
1398 ///
1399 /// }
1400 /// }
1401 /// ```
1402 ///
1403 /// Trait definitions can define functions without a body to specify a
1404 /// function that implementors must define. The parameter names in the
1405 /// body-less functions are only allowed to be `_` or an [identifier] for
1406 /// documentation purposes (only the type is relevant). Previous versions
1407 /// of the compiler erroneously allowed [identifier patterns] with the
1408 /// `mut` keyword, but this was not intended to be allowed. This is a
1409 /// [future-incompatible] lint to transition this to a hard error in the
1410 /// future. See [issue #35203] for more details.
1411 ///
1412 /// [identifier]: https://doc.rust-lang.org/reference/identifiers.html
1413 /// [identifier patterns]: https://doc.rust-lang.org/reference/patterns.html#identifier-patterns
1414 /// [issue #35203]: https://github.com/rust-lang/rust/issues/35203
1415 /// [future-incompatible]: ../index.md#future-incompatible-lints
1416 pub PATTERNS_IN_FNS_WITHOUT_BODY,
1417 Deny,
1418 "patterns in functions without body were erroneously allowed",
1419 @future_incompatible = FutureIncompatibleInfo {
1420 reason: FutureIncompatibilityReason::FutureReleaseError,
1421 reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
1422 };
1423}
1424
1425declare_lint! {
1426 /// The `late_bound_lifetime_arguments` lint detects generic lifetime
1427 /// arguments in path segments with late bound lifetime parameters.
1428 ///
1429 /// ### Example
1430 ///
1431 /// ```rust
1432 /// struct S;
1433 ///
1434 /// impl S {
1435 /// fn late(self, _: &u8, _: &u8) {}
1436 /// }
1437 ///
1438 /// fn main() {
1439 /// S.late::<'static>(&0, &0);
1440 /// }
1441 /// ```
1442 ///
1443 /// {{produces}}
1444 ///
1445 /// ### Explanation
1446 ///
1447 /// It is not clear how to provide arguments for early-bound lifetime
1448 /// parameters if they are intermixed with late-bound parameters in the
1449 /// same list. For now, providing any explicit arguments will trigger this
1450 /// lint if late-bound parameters are present, so in the future a solution
1451 /// can be adopted without hitting backward compatibility issues. This is
1452 /// a [future-incompatible] lint to transition this to a hard error in the
1453 /// future. See [issue #42868] for more details, along with a description
1454 /// of the difference between early and late-bound parameters.
1455 ///
1456 /// [issue #42868]: https://github.com/rust-lang/rust/issues/42868
1457 /// [future-incompatible]: ../index.md#future-incompatible-lints
1458 pub LATE_BOUND_LIFETIME_ARGUMENTS,
1459 Warn,
1460 "detects generic lifetime arguments in path segments with late bound lifetime parameters",
1461 @future_incompatible = FutureIncompatibleInfo {
1462 reason: FutureIncompatibilityReason::FutureReleaseError,
1463 reference: "issue #42868 <https://github.com/rust-lang/rust/issues/42868>",
1464 };
1465}
1466
1467declare_lint! {
1468 /// The `coherence_leak_check` lint detects conflicting implementations of
1469 /// a trait that are only distinguished by the old leak-check code.
1470 ///
1471 /// ### Example
1472 ///
1473 /// ```rust
1474 /// trait SomeTrait { }
1475 /// impl SomeTrait for for<'a> fn(&'a u8) { }
1476 /// impl<'a> SomeTrait for fn(&'a u8) { }
1477 /// ```
1478 ///
1479 /// {{produces}}
1480 ///
1481 /// ### Explanation
1482 ///
1483 /// In the past, the compiler would accept trait implementations for
1484 /// identical functions that differed only in where the lifetime binder
1485 /// appeared. Due to a change in the borrow checker implementation to fix
1486 /// several bugs, this is no longer allowed. However, since this affects
1487 /// existing code, this is a [future-incompatible] lint to transition this
1488 /// to a hard error in the future.
1489 ///
1490 /// Code relying on this pattern should introduce "[newtypes]",
1491 /// like `struct Foo(for<'a> fn(&'a u8))`.
1492 ///
1493 /// See [issue #56105] for more details.
1494 ///
1495 /// [issue #56105]: https://github.com/rust-lang/rust/issues/56105
1496 /// [newtypes]: https://doc.rust-lang.org/book/ch19-04-advanced-types.html#using-the-newtype-pattern-for-type-safety-and-abstraction
1497 /// [future-incompatible]: ../index.md#future-incompatible-lints
1498 pub COHERENCE_LEAK_CHECK,
1499 Warn,
1500 "distinct impls distinguished only by the leak-check code",
1501 @future_incompatible = FutureIncompatibleInfo {
1502 reason: FutureIncompatibilityReason::Custom("the behavior may change in a future release"),
1503 reference: "issue #56105 <https://github.com/rust-lang/rust/issues/56105>",
1504 };
1505}
1506
1507declare_lint! {
1508 /// The `deprecated` lint detects use of deprecated items.
1509 ///
1510 /// ### Example
1511 ///
1512 /// ```rust
1513 /// #[deprecated]
1514 /// fn foo() {}
1515 ///
1516 /// fn bar() {
1517 /// foo();
1518 /// }
1519 /// ```
1520 ///
1521 /// {{produces}}
1522 ///
1523 /// ### Explanation
1524 ///
1525 /// Items may be marked "deprecated" with the [`deprecated` attribute] to
1526 /// indicate that they should no longer be used. Usually the attribute
1527 /// should include a note on what to use instead, or check the
1528 /// documentation.
1529 ///
1530 /// [`deprecated` attribute]: https://doc.rust-lang.org/reference/attributes/diagnostics.html#the-deprecated-attribute
1531 pub DEPRECATED,
1532 Warn,
1533 "detects use of deprecated items",
1534 report_in_external_macro
1535}
1536
1537declare_lint! {
1538 /// The `unused_unsafe` lint detects unnecessary use of an `unsafe` block.
1539 ///
1540 /// ### Example
1541 ///
1542 /// ```rust
1543 /// unsafe {}
1544 /// ```
1545 ///
1546 /// {{produces}}
1547 ///
1548 /// ### Explanation
1549 ///
1550 /// If nothing within the block requires `unsafe`, then remove the
1551 /// `unsafe` marker because it is not required and may cause confusion.
1552 pub UNUSED_UNSAFE,
1553 Warn,
1554 "unnecessary use of an `unsafe` block"
1555}
1556
1557declare_lint! {
1558 /// The `unused_mut` lint detects mut variables which don't need to be
1559 /// mutable.
1560 ///
1561 /// ### Example
1562 ///
1563 /// ```rust
1564 /// let mut x = 5;
1565 /// ```
1566 ///
1567 /// {{produces}}
1568 ///
1569 /// ### Explanation
1570 ///
1571 /// The preferred style is to only mark variables as `mut` if it is
1572 /// required.
1573 pub UNUSED_MUT,
1574 Warn,
1575 "detect mut variables which don't need to be mutable"
1576}
1577
1578declare_lint! {
1579 /// The `rust_2024_incompatible_pat` lint
1580 /// detects patterns whose meaning will change in the Rust 2024 edition.
1581 ///
1582 /// ### Example
1583 ///
1584 /// ```rust,edition2021
1585 /// #![warn(rust_2024_incompatible_pat)]
1586 ///
1587 /// if let Some(&a) = &Some(&0u8) {
1588 /// let _: u8 = a;
1589 /// }
1590 /// if let Some(mut _a) = &mut Some(0u8) {
1591 /// _a = 7u8;
1592 /// }
1593 /// ```
1594 ///
1595 /// {{produces}}
1596 ///
1597 /// ### Explanation
1598 ///
1599 /// In Rust 2024 and above, the `mut` keyword does not reset the pattern binding mode,
1600 /// and nor do `&` or `&mut` patterns. The lint will suggest code that
1601 /// has the same meaning in all editions.
1602 pub RUST_2024_INCOMPATIBLE_PAT,
1603 Allow,
1604 "detects patterns whose meaning will change in Rust 2024",
1605 @future_incompatible = FutureIncompatibleInfo {
1606 reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
1607 reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/match-ergonomics.html>",
1608 };
1609}
1610
1611declare_lint! {
1612 /// The `unconditional_recursion` lint detects functions that cannot
1613 /// return without calling themselves.
1614 ///
1615 /// ### Example
1616 ///
1617 /// ```rust
1618 /// fn foo() {
1619 /// foo();
1620 /// }
1621 /// ```
1622 ///
1623 /// {{produces}}
1624 ///
1625 /// ### Explanation
1626 ///
1627 /// It is usually a mistake to have a recursive call that does not have
1628 /// some condition to cause it to terminate. If you really intend to have
1629 /// an infinite loop, using a `loop` expression is recommended.
1630 pub UNCONDITIONAL_RECURSION,
1631 Warn,
1632 "functions that cannot return without calling themselves"
1633}
1634
1635declare_lint! {
1636 /// The `single_use_lifetimes` lint detects lifetimes that are only used
1637 /// once.
1638 ///
1639 /// ### Example
1640 ///
1641 /// ```rust,compile_fail
1642 /// #![deny(single_use_lifetimes)]
1643 ///
1644 /// fn foo<'a>(x: &'a u32) {}
1645 /// ```
1646 ///
1647 /// {{produces}}
1648 ///
1649 /// ### Explanation
1650 ///
1651 /// Specifying an explicit lifetime like `'a` in a function or `impl`
1652 /// should only be used to link together two things. Otherwise, you should
1653 /// just use `'_` to indicate that the lifetime is not linked to anything,
1654 /// or elide the lifetime altogether if possible.
1655 ///
1656 /// This lint is "allow" by default because it was introduced at a time
1657 /// when `'_` and elided lifetimes were first being introduced, and this
1658 /// lint would be too noisy. Also, there are some known false positives
1659 /// that it produces. See [RFC 2115] for historical context, and [issue
1660 /// #44752] for more details.
1661 ///
1662 /// [RFC 2115]: https://github.com/rust-lang/rfcs/blob/master/text/2115-argument-lifetimes.md
1663 /// [issue #44752]: https://github.com/rust-lang/rust/issues/44752
1664 pub SINGLE_USE_LIFETIMES,
1665 Allow,
1666 "detects lifetime parameters that are only used once"
1667}
1668
1669declare_lint! {
1670 /// The `unused_lifetimes` lint detects lifetime parameters that are never
1671 /// used.
1672 ///
1673 /// ### Example
1674 ///
1675 /// ```rust,compile_fail
1676 /// #[deny(unused_lifetimes)]
1677 ///
1678 /// pub fn foo<'a>() {}
1679 /// ```
1680 ///
1681 /// {{produces}}
1682 ///
1683 /// ### Explanation
1684 ///
1685 /// Unused lifetime parameters may signal a mistake or unfinished code.
1686 /// Consider removing the parameter.
1687 pub UNUSED_LIFETIMES,
1688 Allow,
1689 "detects lifetime parameters that are never used"
1690}
1691
1692declare_lint! {
1693 /// The `redundant_lifetimes` lint detects lifetime parameters that are
1694 /// redundant because they are equal to another named lifetime.
1695 ///
1696 /// ### Example
1697 ///
1698 /// ```rust,compile_fail
1699 /// #[deny(redundant_lifetimes)]
1700 ///
1701 /// // `'a = 'static`, so all usages of `'a` can be replaced with `'static`
1702 /// pub fn bar<'a: 'static>() {}
1703 ///
1704 /// // `'a = 'b`, so all usages of `'b` can be replaced with `'a`
1705 /// pub fn bar<'a: 'b, 'b: 'a>() {}
1706 /// ```
1707 ///
1708 /// {{produces}}
1709 ///
1710 /// ### Explanation
1711 ///
1712 /// Unused lifetime parameters may signal a mistake or unfinished code.
1713 /// Consider removing the parameter.
1714 pub REDUNDANT_LIFETIMES,
1715 Allow,
1716 "detects lifetime parameters that are redundant because they are equal to some other named lifetime"
1717}
1718
1719declare_lint! {
1720 /// The `tyvar_behind_raw_pointer` lint detects raw pointer to an
1721 /// inference variable.
1722 ///
1723 /// ### Example
1724 ///
1725 /// ```rust,edition2015
1726 /// // edition 2015
1727 /// let data = std::ptr::null();
1728 /// let _ = &data as *const *const ();
1729 ///
1730 /// if data.is_null() {}
1731 /// ```
1732 ///
1733 /// {{produces}}
1734 ///
1735 /// ### Explanation
1736 ///
1737 /// This kind of inference was previously allowed, but with the future
1738 /// arrival of [arbitrary self types], this can introduce ambiguity. To
1739 /// resolve this, use an explicit type instead of relying on type
1740 /// inference.
1741 ///
1742 /// This is a [future-incompatible] lint to transition this to a hard
1743 /// error in the 2018 edition. See [issue #46906] for more details. This
1744 /// is currently a hard-error on the 2018 edition, and is "warn" by
1745 /// default in the 2015 edition.
1746 ///
1747 /// [arbitrary self types]: https://github.com/rust-lang/rust/issues/44874
1748 /// [issue #46906]: https://github.com/rust-lang/rust/issues/46906
1749 /// [future-incompatible]: ../index.md#future-incompatible-lints
1750 pub TYVAR_BEHIND_RAW_POINTER,
1751 Warn,
1752 "raw pointer to an inference variable",
1753 @future_incompatible = FutureIncompatibleInfo {
1754 reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018),
1755 reference: "issue #46906 <https://github.com/rust-lang/rust/issues/46906>",
1756 };
1757}
1758
1759declare_lint! {
1760 /// The `elided_lifetimes_in_paths` lint detects the use of hidden
1761 /// lifetime parameters.
1762 ///
1763 /// ### Example
1764 ///
1765 /// ```rust,compile_fail
1766 /// #![deny(elided_lifetimes_in_paths)]
1767 /// #![deny(warnings)]
1768 /// struct Foo<'a> {
1769 /// x: &'a u32
1770 /// }
1771 ///
1772 /// fn foo(x: &Foo) {
1773 /// }
1774 /// ```
1775 ///
1776 /// {{produces}}
1777 ///
1778 /// ### Explanation
1779 ///
1780 /// Elided lifetime parameters can make it difficult to see at a glance
1781 /// that borrowing is occurring. This lint ensures that lifetime
1782 /// parameters are always explicitly stated, even if it is the `'_`
1783 /// [placeholder lifetime].
1784 ///
1785 /// This lint is "allow" by default because it has some known issues, and
1786 /// may require a significant transition for old code.
1787 ///
1788 /// [placeholder lifetime]: https://doc.rust-lang.org/reference/lifetime-elision.html#lifetime-elision-in-functions
1789 pub ELIDED_LIFETIMES_IN_PATHS,
1790 Allow,
1791 "hidden lifetime parameters in types are deprecated"
1792}
1793
1794declare_lint! {
1795 /// The `bare_trait_objects` lint suggests using `dyn Trait` for trait
1796 /// objects.
1797 ///
1798 /// ### Example
1799 ///
1800 /// ```rust,edition2018
1801 /// trait Trait { }
1802 ///
1803 /// fn takes_trait_object(_: Box<Trait>) {
1804 /// }
1805 /// ```
1806 ///
1807 /// {{produces}}
1808 ///
1809 /// ### Explanation
1810 ///
1811 /// Without the `dyn` indicator, it can be ambiguous or confusing when
1812 /// reading code as to whether or not you are looking at a trait object.
1813 /// The `dyn` keyword makes it explicit, and adds a symmetry to contrast
1814 /// with [`impl Trait`].
1815 ///
1816 /// [`impl Trait`]: https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters
1817 pub BARE_TRAIT_OBJECTS,
1818 Warn,
1819 "suggest using `dyn Trait` for trait objects",
1820 @future_incompatible = FutureIncompatibleInfo {
1821 reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
1822 reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/warnings-promoted-to-error.html>",
1823 };
1824}
1825
1826declare_lint! {
1827 /// The `absolute_paths_not_starting_with_crate` lint detects fully
1828 /// qualified paths that start with a module name instead of `crate`,
1829 /// `self`, or an extern crate name
1830 ///
1831 /// ### Example
1832 ///
1833 /// ```rust,edition2015,compile_fail
1834 /// #![deny(absolute_paths_not_starting_with_crate)]
1835 ///
1836 /// mod foo {
1837 /// pub fn bar() {}
1838 /// }
1839 ///
1840 /// fn main() {
1841 /// ::foo::bar();
1842 /// }
1843 /// ```
1844 ///
1845 /// {{produces}}
1846 ///
1847 /// ### Explanation
1848 ///
1849 /// Rust [editions] allow the language to evolve without breaking
1850 /// backwards compatibility. This lint catches code that uses absolute
1851 /// paths in the style of the 2015 edition. In the 2015 edition, absolute
1852 /// paths (those starting with `::`) refer to either the crate root or an
1853 /// external crate. In the 2018 edition it was changed so that they only
1854 /// refer to external crates. The path prefix `crate::` should be used
1855 /// instead to reference items from the crate root.
1856 ///
1857 /// If you switch the compiler from the 2015 to 2018 edition without
1858 /// updating the code, then it will fail to compile if the old style paths
1859 /// are used. You can manually change the paths to use the `crate::`
1860 /// prefix to transition to the 2018 edition.
1861 ///
1862 /// This lint solves the problem automatically. It is "allow" by default
1863 /// because the code is perfectly valid in the 2015 edition. The [`cargo
1864 /// fix`] tool with the `--edition` flag will switch this lint to "warn"
1865 /// and automatically apply the suggested fix from the compiler. This
1866 /// provides a completely automated way to update old code to the 2018
1867 /// edition.
1868 ///
1869 /// [editions]: https://doc.rust-lang.org/edition-guide/
1870 /// [`cargo fix`]: https://doc.rust-lang.org/cargo/commands/cargo-fix.html
1871 pub ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
1872 Allow,
1873 "fully qualified paths that start with a module name \
1874 instead of `crate`, `self`, or an extern crate name",
1875 @future_incompatible = FutureIncompatibleInfo {
1876 reason: FutureIncompatibilityReason::EditionError(Edition::Edition2018),
1877 reference: "issue #53130 <https://github.com/rust-lang/rust/issues/53130>",
1878 };
1879}
1880
1881declare_lint! {
1882 /// The `unstable_name_collisions` lint detects that you have used a name
1883 /// that the standard library plans to add in the future.
1884 ///
1885 /// ### Example
1886 ///
1887 /// ```rust
1888 /// trait MyIterator : Iterator {
1889 /// // is_partitioned is an unstable method that already exists on the Iterator trait
1890 /// fn is_partitioned<P>(self, predicate: P) -> bool
1891 /// where
1892 /// Self: Sized,
1893 /// P: FnMut(Self::Item) -> bool,
1894 /// {true}
1895 /// }
1896 ///
1897 /// impl<T: ?Sized> MyIterator for T where T: Iterator { }
1898 ///
1899 /// let x = vec![1, 2, 3];
1900 /// let _ = x.iter().is_partitioned(|_| true);
1901 /// ```
1902 ///
1903 /// {{produces}}
1904 ///
1905 /// ### Explanation
1906 ///
1907 /// When new methods are added to traits in the standard library, they are
1908 /// usually added in an "unstable" form which is only available on the
1909 /// [nightly channel] with a [`feature` attribute]. If there is any
1910 /// preexisting code which extends a trait to have a method with the same
1911 /// name, then the names will collide. In the future, when the method is
1912 /// stabilized, this will cause an error due to the ambiguity. This lint
1913 /// is an early-warning to let you know that there may be a collision in
1914 /// the future. This can be avoided by adding type annotations to
1915 /// disambiguate which trait method you intend to call, such as
1916 /// `MyIterator::is_partitioned(my_iter, my_predicate)` or renaming or removing the method.
1917 ///
1918 /// [nightly channel]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
1919 /// [`feature` attribute]: https://doc.rust-lang.org/nightly/unstable-book/
1920 pub UNSTABLE_NAME_COLLISIONS,
1921 Warn,
1922 "detects name collision with an existing but unstable method",
1923 @future_incompatible = FutureIncompatibleInfo {
1924 reason: FutureIncompatibilityReason::Custom(
1925 "once this associated item is added to the standard library, \
1926 the ambiguity may cause an error or change in behavior!"
1927 ),
1928 reference: "issue #48919 <https://github.com/rust-lang/rust/issues/48919>",
1929 // Note: this item represents future incompatibility of all unstable functions in the
1930 // standard library, and thus should never be removed or changed to an error.
1931 };
1932}
1933
1934declare_lint! {
1935 /// The `irrefutable_let_patterns` lint detects [irrefutable patterns]
1936 /// in [`if let`]s, [`while let`]s, and `if let` guards.
1937 ///
1938 /// ### Example
1939 ///
1940 /// ```rust
1941 /// if let _ = 123 {
1942 /// println!("always runs!");
1943 /// }
1944 /// ```
1945 ///
1946 /// {{produces}}
1947 ///
1948 /// ### Explanation
1949 ///
1950 /// There usually isn't a reason to have an irrefutable pattern in an
1951 /// `if let` or `while let` statement, because the pattern will always match
1952 /// successfully. A [`let`] or [`loop`] statement will suffice. However,
1953 /// when generating code with a macro, forbidding irrefutable patterns
1954 /// would require awkward workarounds in situations where the macro
1955 /// doesn't know if the pattern is refutable or not. This lint allows
1956 /// macros to accept this form, while alerting for a possibly incorrect
1957 /// use in normal code.
1958 ///
1959 /// See [RFC 2086] for more details.
1960 ///
1961 /// [irrefutable patterns]: https://doc.rust-lang.org/reference/patterns.html#refutability
1962 /// [`if let`]: https://doc.rust-lang.org/reference/expressions/if-expr.html#if-let-expressions
1963 /// [`while let`]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#predicate-pattern-loops
1964 /// [`let`]: https://doc.rust-lang.org/reference/statements.html#let-statements
1965 /// [`loop`]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#infinite-loops
1966 /// [RFC 2086]: https://github.com/rust-lang/rfcs/blob/master/text/2086-allow-if-let-irrefutables.md
1967 pub IRREFUTABLE_LET_PATTERNS,
1968 Warn,
1969 "detects irrefutable patterns in `if let` and `while let` statements"
1970}
1971
1972declare_lint! {
1973 /// The `unused_labels` lint detects [labels] that are never used.
1974 ///
1975 /// [labels]: https://doc.rust-lang.org/reference/expressions/loop-expr.html#loop-labels
1976 ///
1977 /// ### Example
1978 ///
1979 /// ```rust,no_run
1980 /// 'unused_label: loop {}
1981 /// ```
1982 ///
1983 /// {{produces}}
1984 ///
1985 /// ### Explanation
1986 ///
1987 /// Unused labels may signal a mistake or unfinished code. To silence the
1988 /// warning for the individual label, prefix it with an underscore such as
1989 /// `'_my_label:`.
1990 pub UNUSED_LABELS,
1991 Warn,
1992 "detects labels that are never used"
1993}
1994
1995declare_lint! {
1996 /// The `proc_macro_derive_resolution_fallback` lint detects proc macro
1997 /// derives using inaccessible names from parent modules.
1998 ///
1999 /// ### Example
2000 ///
2001 /// ```rust,ignore (proc-macro)
2002 /// // foo.rs
2003 /// #![crate_type = "proc-macro"]
2004 ///
2005 /// extern crate proc_macro;
2006 ///
2007 /// use proc_macro::*;
2008 ///
2009 /// #[proc_macro_derive(Foo)]
2010 /// pub fn foo1(a: TokenStream) -> TokenStream {
2011 /// drop(a);
2012 /// "mod __bar { static mut BAR: Option<Something> = None; }".parse().unwrap()
2013 /// }
2014 /// ```
2015 ///
2016 /// ```rust,ignore (needs-dependency)
2017 /// // bar.rs
2018 /// #[macro_use]
2019 /// extern crate foo;
2020 ///
2021 /// struct Something;
2022 ///
2023 /// #[derive(Foo)]
2024 /// struct Another;
2025 ///
2026 /// fn main() {}
2027 /// ```
2028 ///
2029 /// This will produce:
2030 ///
2031 /// ```text
2032 /// warning: cannot find type `Something` in this scope
2033 /// --> src/main.rs:8:10
2034 /// |
2035 /// 8 | #[derive(Foo)]
2036 /// | ^^^ names from parent modules are not accessible without an explicit import
2037 /// |
2038 /// = note: `#[warn(proc_macro_derive_resolution_fallback)]` on by default
2039 /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
2040 /// = note: for more information, see issue #50504 <https://github.com/rust-lang/rust/issues/50504>
2041 /// ```
2042 ///
2043 /// ### Explanation
2044 ///
2045 /// If a proc-macro generates a module, the compiler unintentionally
2046 /// allowed items in that module to refer to items in the crate root
2047 /// without importing them. This is a [future-incompatible] lint to
2048 /// transition this to a hard error in the future. See [issue #50504] for
2049 /// more details.
2050 ///
2051 /// [issue #50504]: https://github.com/rust-lang/rust/issues/50504
2052 /// [future-incompatible]: ../index.md#future-incompatible-lints
2053 pub PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
2054 Deny,
2055 "detects proc macro derives using inaccessible names from parent modules",
2056 @future_incompatible = FutureIncompatibleInfo {
2057 reason: FutureIncompatibilityReason::FutureReleaseError,
2058 reference: "issue #83583 <https://github.com/rust-lang/rust/issues/83583>",
2059 report_in_deps: true,
2060 };
2061}
2062
2063declare_lint! {
2064 /// The `macro_use_extern_crate` lint detects the use of the [`macro_use` attribute].
2065 ///
2066 /// ### Example
2067 ///
2068 /// ```rust,ignore (needs extern crate)
2069 /// #![deny(macro_use_extern_crate)]
2070 ///
2071 /// #[macro_use]
2072 /// extern crate serde_json;
2073 ///
2074 /// fn main() {
2075 /// let _ = json!{{}};
2076 /// }
2077 /// ```
2078 ///
2079 /// This will produce:
2080 ///
2081 /// ```text
2082 /// error: applying the `#[macro_use]` attribute to an `extern crate` item is deprecated
2083 /// --> src/main.rs:3:1
2084 /// |
2085 /// 3 | #[macro_use]
2086 /// | ^^^^^^^^^^^^
2087 /// |
2088 /// = help: remove it and import macros at use sites with a `use` item instead
2089 /// note: the lint level is defined here
2090 /// --> src/main.rs:1:9
2091 /// |
2092 /// 1 | #![deny(macro_use_extern_crate)]
2093 /// | ^^^^^^^^^^^^^^^^^^^^^^
2094 /// ```
2095 ///
2096 /// ### Explanation
2097 ///
2098 /// The [`macro_use` attribute] on an [`extern crate`] item causes
2099 /// macros in that external crate to be brought into the prelude of the
2100 /// crate, making the macros in scope everywhere. As part of the efforts
2101 /// to simplify handling of dependencies in the [2018 edition], the use of
2102 /// `extern crate` is being phased out. To bring macros from extern crates
2103 /// into scope, it is recommended to use a [`use` import].
2104 ///
2105 /// This lint is "allow" by default because this is a stylistic choice
2106 /// that has not been settled, see [issue #52043] for more information.
2107 ///
2108 /// [`macro_use` attribute]: https://doc.rust-lang.org/reference/macros-by-example.html#the-macro_use-attribute
2109 /// [`use` import]: https://doc.rust-lang.org/reference/items/use-declarations.html
2110 /// [issue #52043]: https://github.com/rust-lang/rust/issues/52043
2111 pub MACRO_USE_EXTERN_CRATE,
2112 Allow,
2113 "the `#[macro_use]` attribute is now deprecated in favor of using macros \
2114 via the module system"
2115}
2116
2117declare_lint! {
2118 /// The `macro_expanded_macro_exports_accessed_by_absolute_paths` lint
2119 /// detects macro-expanded [`macro_export`] macros from the current crate
2120 /// that cannot be referred to by absolute paths.
2121 ///
2122 /// [`macro_export`]: https://doc.rust-lang.org/reference/macros-by-example.html#path-based-scope
2123 ///
2124 /// ### Example
2125 ///
2126 /// ```rust,compile_fail
2127 /// macro_rules! define_exported {
2128 /// () => {
2129 /// #[macro_export]
2130 /// macro_rules! exported {
2131 /// () => {};
2132 /// }
2133 /// };
2134 /// }
2135 ///
2136 /// define_exported!();
2137 ///
2138 /// fn main() {
2139 /// crate::exported!();
2140 /// }
2141 /// ```
2142 ///
2143 /// {{produces}}
2144 ///
2145 /// ### Explanation
2146 ///
2147 /// The intent is that all macros marked with the `#[macro_export]`
2148 /// attribute are made available in the root of the crate. However, when a
2149 /// `macro_rules!` definition is generated by another macro, the macro
2150 /// expansion is unable to uphold this rule. This is a
2151 /// [future-incompatible] lint to transition this to a hard error in the
2152 /// future. See [issue #53495] for more details.
2153 ///
2154 /// [issue #53495]: https://github.com/rust-lang/rust/issues/53495
2155 /// [future-incompatible]: ../index.md#future-incompatible-lints
2156 pub MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
2157 Deny,
2158 "macro-expanded `macro_export` macros from the current crate \
2159 cannot be referred to by absolute paths",
2160 @future_incompatible = FutureIncompatibleInfo {
2161 reason: FutureIncompatibilityReason::FutureReleaseError,
2162 reference: "issue #52234 <https://github.com/rust-lang/rust/issues/52234>",
2163 report_in_deps: true,
2164 };
2165 crate_level_only
2166}
2167
2168declare_lint! {
2169 /// The `explicit_outlives_requirements` lint detects unnecessary
2170 /// lifetime bounds that can be inferred.
2171 ///
2172 /// ### Example
2173 ///
2174 /// ```rust,compile_fail
2175 /// # #![allow(unused)]
2176 /// #![deny(explicit_outlives_requirements)]
2177 /// #![deny(warnings)]
2178 ///
2179 /// struct SharedRef<'a, T>
2180 /// where
2181 /// T: 'a,
2182 /// {
2183 /// data: &'a T,
2184 /// }
2185 /// ```
2186 ///
2187 /// {{produces}}
2188 ///
2189 /// ### Explanation
2190 ///
2191 /// If a `struct` contains a reference, such as `&'a T`, the compiler
2192 /// requires that `T` outlives the lifetime `'a`. This historically
2193 /// required writing an explicit lifetime bound to indicate this
2194 /// requirement. However, this can be overly explicit, causing clutter and
2195 /// unnecessary complexity. The language was changed to automatically
2196 /// infer the bound if it is not specified. Specifically, if the struct
2197 /// contains a reference, directly or indirectly, to `T` with lifetime
2198 /// `'x`, then it will infer that `T: 'x` is a requirement.
2199 ///
2200 /// This lint is "allow" by default because it can be noisy for existing
2201 /// code that already had these requirements. This is a stylistic choice,
2202 /// as it is still valid to explicitly state the bound. It also has some
2203 /// false positives that can cause confusion.
2204 ///
2205 /// See [RFC 2093] for more details.
2206 ///
2207 /// [RFC 2093]: https://github.com/rust-lang/rfcs/blob/master/text/2093-infer-outlives.md
2208 pub EXPLICIT_OUTLIVES_REQUIREMENTS,
2209 Allow,
2210 "outlives requirements can be inferred"
2211}
2212
2213declare_lint! {
2214 /// The `deprecated_in_future` lint is internal to rustc and should not be
2215 /// used by user code.
2216 ///
2217 /// This lint is only enabled in the standard library. It works with the
2218 /// use of `#[deprecated]` with a `since` field of a version in the future.
2219 /// This allows something to be marked as deprecated in a future version,
2220 /// and then this lint will ensure that the item is no longer used in the
2221 /// standard library. See the [stability documentation] for more details.
2222 ///
2223 /// [stability documentation]: https://rustc-dev-guide.rust-lang.org/stability.html#deprecated
2224 pub DEPRECATED_IN_FUTURE,
2225 Allow,
2226 "detects use of items that will be deprecated in a future version",
2227 report_in_external_macro
2228}
2229
2230declare_lint! {
2231 /// The `ambiguous_associated_items` lint detects ambiguity between
2232 /// [associated items] and [enum variants].
2233 ///
2234 /// [associated items]: https://doc.rust-lang.org/reference/items/associated-items.html
2235 /// [enum variants]: https://doc.rust-lang.org/reference/items/enumerations.html
2236 ///
2237 /// ### Example
2238 ///
2239 /// ```rust,compile_fail
2240 /// enum E {
2241 /// V
2242 /// }
2243 ///
2244 /// trait Tr {
2245 /// type V;
2246 /// fn foo() -> Self::V;
2247 /// }
2248 ///
2249 /// impl Tr for E {
2250 /// type V = u8;
2251 /// // `Self::V` is ambiguous because it may refer to the associated type or
2252 /// // the enum variant.
2253 /// fn foo() -> Self::V { 0 }
2254 /// }
2255 /// ```
2256 ///
2257 /// {{produces}}
2258 ///
2259 /// ### Explanation
2260 ///
2261 /// Previous versions of Rust did not allow accessing enum variants
2262 /// through [type aliases]. When this ability was added (see [RFC 2338]), this
2263 /// introduced some situations where it can be ambiguous what a type
2264 /// was referring to.
2265 ///
2266 /// To fix this ambiguity, you should use a [qualified path] to explicitly
2267 /// state which type to use. For example, in the above example the
2268 /// function can be written as `fn f() -> <Self as Tr>::V { 0 }` to
2269 /// specifically refer to the associated type.
2270 ///
2271 /// This is a [future-incompatible] lint to transition this to a hard
2272 /// error in the future. See [issue #57644] for more details.
2273 ///
2274 /// [issue #57644]: https://github.com/rust-lang/rust/issues/57644
2275 /// [type aliases]: https://doc.rust-lang.org/reference/items/type-aliases.html#type-aliases
2276 /// [RFC 2338]: https://github.com/rust-lang/rfcs/blob/master/text/2338-type-alias-enum-variants.md
2277 /// [qualified path]: https://doc.rust-lang.org/reference/paths.html#qualified-paths
2278 /// [future-incompatible]: ../index.md#future-incompatible-lints
2279 pub AMBIGUOUS_ASSOCIATED_ITEMS,
2280 Deny,
2281 "ambiguous associated items",
2282 @future_incompatible = FutureIncompatibleInfo {
2283 reason: FutureIncompatibilityReason::FutureReleaseError,
2284 reference: "issue #57644 <https://github.com/rust-lang/rust/issues/57644>",
2285 };
2286}
2287
2288declare_lint! {
2289 /// The `soft_unstable` lint detects unstable features that were unintentionally allowed on
2290 /// stable. This is a [future-incompatible] lint to transition this to a hard error in the
2291 /// future. See [issue #64266] for more details.
2292 ///
2293 /// [issue #64266]: https://github.com/rust-lang/rust/issues/64266
2294 /// [future-incompatible]: ../index.md#future-incompatible-lints
2295 pub SOFT_UNSTABLE,
2296 Deny,
2297 "a feature gate that doesn't break dependent crates",
2298 @future_incompatible = FutureIncompatibleInfo {
2299 reason: FutureIncompatibilityReason::FutureReleaseError,
2300 reference: "issue #64266 <https://github.com/rust-lang/rust/issues/64266>",
2301 report_in_deps: true,
2302 };
2303}
2304
2305declare_lint! {
2306 /// The `inline_no_sanitize` lint detects incompatible use of
2307 /// [`#[inline(always)]`][inline] and [`#[sanitize(xyz = "off")]`][sanitize].
2308 ///
2309 /// [inline]: https://doc.rust-lang.org/reference/attributes/codegen.html#the-inline-attribute
2310 /// [sanitize]: https://doc.rust-lang.org/nightly/unstable-book/language-features/no-sanitize.html
2311 ///
2312 /// ### Example
2313 ///
2314 /// ```rust
2315 /// #![feature(sanitize)]
2316 ///
2317 /// #[inline(always)]
2318 /// #[sanitize(address = "off")]
2319 /// fn x() {}
2320 ///
2321 /// fn main() {
2322 /// x()
2323 /// }
2324 /// ```
2325 ///
2326 /// {{produces}}
2327 ///
2328 /// ### Explanation
2329 ///
2330 /// The use of the [`#[inline(always)]`][inline] attribute prevents the
2331 /// the [`#[sanitize(xyz = "off")]`][sanitize] attribute from working.
2332 /// Consider temporarily removing `inline` attribute.
2333 pub INLINE_NO_SANITIZE,
2334 Warn,
2335 r#"detects incompatible use of `#[inline(always)]` and `#[sanitize(... = "off")]`"#,
2336}
2337
2338declare_lint! {
2339 /// The `rtsan_nonblocking_async` lint detects incompatible use of
2340 /// [`#[sanitize(realtime = "nonblocking")]`][sanitize] on async functions.
2341 ///
2342 /// [sanitize]: https://doc.rust-lang.org/nightly/unstable-book/language-features/no-sanitize.html
2343 /// ### Example
2344 ///
2345 #[cfg_attr(bootstrap, doc = "```ignore")]
2346 #[cfg_attr(not(bootstrap), doc = "```rust,no_run")]
2347 /// #![feature(sanitize)]
2348 ///
2349 /// #[sanitize(realtime = "nonblocking")]
2350 /// async fn x() {}
2351 ///
2352 /// fn main() {
2353 /// x();
2354 /// }
2355 #[cfg_attr(bootstrap, doc = "```")]
2356 #[cfg_attr(not(bootstrap), doc = "```")]
2357 ///
2358 /// {{produces}}
2359 ///
2360 /// ### Explanation
2361 ///
2362 /// The sanitizer only considers the async function body nonblocking. The executor, which runs on
2363 /// every `.await` point can run non-realtime code, without the sanitizer catching it.
2364 pub RTSAN_NONBLOCKING_ASYNC,
2365 Warn,
2366 r#"detects incompatible uses of `#[sanitize(realtime = "nonblocking")]` on async functions"#,
2367}
2368
2369declare_lint! {
2370 /// The `asm_sub_register` lint detects using only a subset of a register
2371 /// for inline asm inputs.
2372 ///
2373 /// ### Example
2374 ///
2375 /// ```rust,ignore (fails on non-x86_64)
2376 /// #[cfg(target_arch="x86_64")]
2377 /// use std::arch::asm;
2378 ///
2379 /// fn main() {
2380 /// #[cfg(target_arch="x86_64")]
2381 /// unsafe {
2382 /// asm!("mov {0}, {0}", in(reg) 0i16);
2383 /// }
2384 /// }
2385 /// ```
2386 ///
2387 /// This will produce:
2388 ///
2389 /// ```text
2390 /// warning: formatting may not be suitable for sub-register argument
2391 /// --> src/main.rs:7:19
2392 /// |
2393 /// 7 | asm!("mov {0}, {0}", in(reg) 0i16);
2394 /// | ^^^ ^^^ ---- for this argument
2395 /// |
2396 /// = note: `#[warn(asm_sub_register)]` on by default
2397 /// = help: use the `x` modifier to have the register formatted as `ax`
2398 /// = help: or use the `r` modifier to keep the default formatting of `rax`
2399 /// ```
2400 ///
2401 /// ### Explanation
2402 ///
2403 /// Registers on some architectures can use different names to refer to a
2404 /// subset of the register. By default, the compiler will use the name for
2405 /// the full register size. To explicitly use a subset of the register,
2406 /// you can override the default by using a modifier on the template
2407 /// string operand to specify when subregister to use. This lint is issued
2408 /// if you pass in a value with a smaller data type than the default
2409 /// register size, to alert you of possibly using the incorrect width. To
2410 /// fix this, add the suggested modifier to the template, or cast the
2411 /// value to the correct size.
2412 ///
2413 /// See [register template modifiers] in the reference for more details.
2414 ///
2415 /// [register template modifiers]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html#template-modifiers
2416 pub ASM_SUB_REGISTER,
2417 Warn,
2418 "using only a subset of a register for inline asm inputs",
2419}
2420
2421declare_lint! {
2422 /// The `bad_asm_style` lint detects the use of the `.intel_syntax` and
2423 /// `.att_syntax` directives.
2424 ///
2425 /// ### Example
2426 ///
2427 /// ```rust,ignore (fails on non-x86_64)
2428 /// #[cfg(target_arch="x86_64")]
2429 /// use std::arch::asm;
2430 ///
2431 /// fn main() {
2432 /// #[cfg(target_arch="x86_64")]
2433 /// unsafe {
2434 /// asm!(
2435 /// ".att_syntax",
2436 /// "movq %{0}, %{0}", in(reg) 0usize
2437 /// );
2438 /// }
2439 /// }
2440 /// ```
2441 ///
2442 /// This will produce:
2443 ///
2444 /// ```text
2445 /// warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
2446 /// --> src/main.rs:8:14
2447 /// |
2448 /// 8 | ".att_syntax",
2449 /// | ^^^^^^^^^^^
2450 /// |
2451 /// = note: `#[warn(bad_asm_style)]` on by default
2452 /// ```
2453 ///
2454 /// ### Explanation
2455 ///
2456 /// On x86, `asm!` uses the intel assembly syntax by default. While this
2457 /// can be switched using assembler directives like `.att_syntax`, using the
2458 /// `att_syntax` option is recommended instead because it will also properly
2459 /// prefix register placeholders with `%` as required by AT&T syntax.
2460 pub BAD_ASM_STYLE,
2461 Warn,
2462 "incorrect use of inline assembly",
2463}
2464
2465declare_lint! {
2466 /// The `unsafe_op_in_unsafe_fn` lint detects unsafe operations in unsafe
2467 /// functions without an explicit unsafe block.
2468 ///
2469 /// ### Example
2470 ///
2471 /// ```rust,compile_fail
2472 /// #![deny(unsafe_op_in_unsafe_fn)]
2473 ///
2474 /// unsafe fn foo() {}
2475 ///
2476 /// unsafe fn bar() {
2477 /// foo();
2478 /// }
2479 ///
2480 /// fn main() {}
2481 /// ```
2482 ///
2483 /// {{produces}}
2484 ///
2485 /// ### Explanation
2486 ///
2487 /// Currently, an [`unsafe fn`] allows any [unsafe] operation within its
2488 /// body. However, this can increase the surface area of code that needs
2489 /// to be scrutinized for proper behavior. The [`unsafe` block] provides a
2490 /// convenient way to make it clear exactly which parts of the code are
2491 /// performing unsafe operations. In the future, it is desired to change
2492 /// it so that unsafe operations cannot be performed in an `unsafe fn`
2493 /// without an `unsafe` block.
2494 ///
2495 /// The fix to this is to wrap the unsafe code in an `unsafe` block.
2496 ///
2497 /// This lint is "allow" by default on editions up to 2021, from 2024 it is
2498 /// "warn" by default; the plan for increasing severity further is
2499 /// still being considered. See [RFC #2585] and [issue #71668] for more
2500 /// details.
2501 ///
2502 /// [`unsafe fn`]: https://doc.rust-lang.org/reference/unsafe-functions.html
2503 /// [`unsafe` block]: https://doc.rust-lang.org/reference/expressions/block-expr.html#unsafe-blocks
2504 /// [unsafe]: https://doc.rust-lang.org/reference/unsafety.html
2505 /// [RFC #2585]: https://github.com/rust-lang/rfcs/blob/master/text/2585-unsafe-block-in-unsafe-fn.md
2506 /// [issue #71668]: https://github.com/rust-lang/rust/issues/71668
2507 pub UNSAFE_OP_IN_UNSAFE_FN,
2508 Allow,
2509 "unsafe operations in unsafe functions without an explicit unsafe block are deprecated",
2510 @future_incompatible = FutureIncompatibleInfo {
2511 reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
2512 reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-op-in-unsafe-fn.html>",
2513 explain_reason: false
2514 };
2515 @edition Edition2024 => Warn;
2516}
2517
2518declare_lint! {
2519 /// The `fuzzy_provenance_casts` lint detects an `as` cast between an integer
2520 /// and a pointer.
2521 ///
2522 /// ### Example
2523 ///
2524 /// ```rust
2525 /// #![feature(strict_provenance_lints)]
2526 /// #![warn(fuzzy_provenance_casts)]
2527 ///
2528 /// fn main() {
2529 /// let _dangling = 16_usize as *const u8;
2530 /// }
2531 /// ```
2532 ///
2533 /// {{produces}}
2534 ///
2535 /// ### Explanation
2536 ///
2537 /// This lint is part of the strict provenance effort, see [issue #95228].
2538 /// Casting an integer to a pointer is considered bad style, as a pointer
2539 /// contains, besides the *address* also a *provenance*, indicating what
2540 /// memory the pointer is allowed to read/write. Casting an integer, which
2541 /// doesn't have provenance, to a pointer requires the compiler to assign
2542 /// (guess) provenance. The compiler assigns "all exposed valid" (see the
2543 /// docs of [`ptr::with_exposed_provenance`] for more information about this
2544 /// "exposing"). This penalizes the optimiser and is not well suited for
2545 /// dynamic analysis/dynamic program verification (e.g. Miri or CHERI
2546 /// platforms).
2547 ///
2548 /// It is much better to use [`ptr::with_addr`] instead to specify the
2549 /// provenance you want. If using this function is not possible because the
2550 /// code relies on exposed provenance then there is as an escape hatch
2551 /// [`ptr::with_exposed_provenance`].
2552 ///
2553 /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
2554 /// [`ptr::with_addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.with_addr
2555 /// [`ptr::with_exposed_provenance`]: https://doc.rust-lang.org/core/ptr/fn.with_exposed_provenance.html
2556 pub FUZZY_PROVENANCE_CASTS,
2557 Allow,
2558 "a fuzzy integer to pointer cast is used",
2559 @feature_gate = strict_provenance_lints;
2560}
2561
2562declare_lint! {
2563 /// The `lossy_provenance_casts` lint detects an `as` cast between a pointer
2564 /// and an integer.
2565 ///
2566 /// ### Example
2567 ///
2568 /// ```rust
2569 /// #![feature(strict_provenance_lints)]
2570 /// #![warn(lossy_provenance_casts)]
2571 ///
2572 /// fn main() {
2573 /// let x: u8 = 37;
2574 /// let _addr: usize = &x as *const u8 as usize;
2575 /// }
2576 /// ```
2577 ///
2578 /// {{produces}}
2579 ///
2580 /// ### Explanation
2581 ///
2582 /// This lint is part of the strict provenance effort, see [issue #95228].
2583 /// Casting a pointer to an integer is a lossy operation, because beyond
2584 /// just an *address* a pointer may be associated with a particular
2585 /// *provenance*. This information is used by the optimiser and for dynamic
2586 /// analysis/dynamic program verification (e.g. Miri or CHERI platforms).
2587 ///
2588 /// Since this cast is lossy, it is considered good style to use the
2589 /// [`ptr::addr`] method instead, which has a similar effect, but doesn't
2590 /// "expose" the pointer provenance. This improves optimisation potential.
2591 /// See the docs of [`ptr::addr`] and [`ptr::expose_provenance`] for more information
2592 /// about exposing pointer provenance.
2593 ///
2594 /// If your code can't comply with strict provenance and needs to expose
2595 /// the provenance, then there is [`ptr::expose_provenance`] as an escape hatch,
2596 /// which preserves the behaviour of `as usize` casts while being explicit
2597 /// about the semantics.
2598 ///
2599 /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
2600 /// [`ptr::addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.addr
2601 /// [`ptr::expose_provenance`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.expose_provenance
2602 pub LOSSY_PROVENANCE_CASTS,
2603 Allow,
2604 "a lossy pointer to integer cast is used",
2605 @feature_gate = strict_provenance_lints;
2606}
2607
2608declare_lint! {
2609 /// The `const_evaluatable_unchecked` lint detects a generic constant used
2610 /// in a type.
2611 ///
2612 /// ### Example
2613 ///
2614 /// ```rust
2615 /// const fn foo<T>() -> usize {
2616 /// if size_of::<*mut T>() < 8 { // size of *mut T does not depend on T
2617 /// 4
2618 /// } else {
2619 /// 8
2620 /// }
2621 /// }
2622 ///
2623 /// fn test<T>() {
2624 /// let _ = [0; foo::<T>()];
2625 /// }
2626 /// ```
2627 ///
2628 /// {{produces}}
2629 ///
2630 /// ### Explanation
2631 ///
2632 /// In the 1.43 release, some uses of generic parameters in array repeat
2633 /// expressions were accidentally allowed. This is a [future-incompatible]
2634 /// lint to transition this to a hard error in the future. See [issue
2635 /// #76200] for a more detailed description and possible fixes.
2636 ///
2637 /// [future-incompatible]: ../index.md#future-incompatible-lints
2638 /// [issue #76200]: https://github.com/rust-lang/rust/issues/76200
2639 pub CONST_EVALUATABLE_UNCHECKED,
2640 Warn,
2641 "detects a generic constant is used in a type without a emitting a warning",
2642 @future_incompatible = FutureIncompatibleInfo {
2643 reason: FutureIncompatibilityReason::FutureReleaseError,
2644 reference: "issue #76200 <https://github.com/rust-lang/rust/issues/76200>",
2645 };
2646}
2647
2648declare_lint! {
2649 /// The `function_item_references` lint detects function references that are
2650 /// formatted with [`fmt::Pointer`] or transmuted.
2651 ///
2652 /// [`fmt::Pointer`]: https://doc.rust-lang.org/std/fmt/trait.Pointer.html
2653 ///
2654 /// ### Example
2655 ///
2656 /// ```rust
2657 /// fn foo() { }
2658 ///
2659 /// fn main() {
2660 /// println!("{:p}", &foo);
2661 /// }
2662 /// ```
2663 ///
2664 /// {{produces}}
2665 ///
2666 /// ### Explanation
2667 ///
2668 /// Taking a reference to a function may be mistaken as a way to obtain a
2669 /// pointer to that function. This can give unexpected results when
2670 /// formatting the reference as a pointer or transmuting it. This lint is
2671 /// issued when function references are formatted as pointers, passed as
2672 /// arguments bound by [`fmt::Pointer`] or transmuted.
2673 pub FUNCTION_ITEM_REFERENCES,
2674 Warn,
2675 "suggest casting to a function pointer when attempting to take references to function items",
2676}
2677
2678declare_lint! {
2679 /// The `uninhabited_static` lint detects uninhabited statics.
2680 ///
2681 /// ### Example
2682 ///
2683 /// ```rust
2684 /// enum Void {}
2685 /// unsafe extern {
2686 /// static EXTERN: Void;
2687 /// }
2688 /// ```
2689 ///
2690 /// {{produces}}
2691 ///
2692 /// ### Explanation
2693 ///
2694 /// Statics with an uninhabited type can never be initialized, so they are impossible to define.
2695 /// However, this can be side-stepped with an `extern static`, leading to problems later in the
2696 /// compiler which assumes that there are no initialized uninhabited places (such as locals or
2697 /// statics). This was accidentally allowed, but is being phased out.
2698 pub UNINHABITED_STATIC,
2699 Warn,
2700 "uninhabited static",
2701 @future_incompatible = FutureIncompatibleInfo {
2702 reason: FutureIncompatibilityReason::FutureReleaseError,
2703 reference: "issue #74840 <https://github.com/rust-lang/rust/issues/74840>",
2704 };
2705}
2706
2707declare_lint! {
2708 /// The `unnameable_test_items` lint detects [`#[test]`][test] functions
2709 /// that are not able to be run by the test harness because they are in a
2710 /// position where they are not nameable.
2711 ///
2712 /// [test]: https://doc.rust-lang.org/reference/attributes/testing.html#the-test-attribute
2713 ///
2714 /// ### Example
2715 ///
2716 /// ```rust,test
2717 /// fn main() {
2718 /// #[test]
2719 /// fn foo() {
2720 /// // This test will not fail because it does not run.
2721 /// assert_eq!(1, 2);
2722 /// }
2723 /// }
2724 /// ```
2725 ///
2726 /// {{produces}}
2727 ///
2728 /// ### Explanation
2729 ///
2730 /// In order for the test harness to run a test, the test function must be
2731 /// located in a position where it can be accessed from the crate root.
2732 /// This generally means it must be defined in a module, and not anywhere
2733 /// else such as inside another function. The compiler previously allowed
2734 /// this without an error, so a lint was added as an alert that a test is
2735 /// not being used. Whether or not this should be allowed has not yet been
2736 /// decided, see [RFC 2471] and [issue #36629].
2737 ///
2738 /// [RFC 2471]: https://github.com/rust-lang/rfcs/pull/2471#issuecomment-397414443
2739 /// [issue #36629]: https://github.com/rust-lang/rust/issues/36629
2740 pub UNNAMEABLE_TEST_ITEMS,
2741 Warn,
2742 "detects an item that cannot be named being marked as `#[test_case]`",
2743 report_in_external_macro
2744}
2745
2746declare_lint! {
2747 /// The `useless_deprecated` lint detects deprecation attributes with no effect.
2748 ///
2749 /// ### Example
2750 ///
2751 /// ```rust,compile_fail
2752 /// struct X;
2753 ///
2754 /// #[deprecated = "message"]
2755 /// impl Default for X {
2756 /// fn default() -> Self {
2757 /// X
2758 /// }
2759 /// }
2760 /// ```
2761 ///
2762 /// {{produces}}
2763 ///
2764 /// ### Explanation
2765 ///
2766 /// Deprecation attributes have no effect on trait implementations.
2767 pub USELESS_DEPRECATED,
2768 Deny,
2769 "detects deprecation attributes with no effect",
2770}
2771
2772declare_lint! {
2773 /// The `ineffective_unstable_trait_impl` lint detects `#[unstable]` attributes which are not used.
2774 ///
2775 /// ### Example
2776 ///
2777 /// ```rust,compile_fail
2778 /// #![feature(staged_api)]
2779 ///
2780 /// #[derive(Clone)]
2781 /// #[stable(feature = "x", since = "1")]
2782 /// struct S {}
2783 ///
2784 /// #[unstable(feature = "y", issue = "none")]
2785 /// impl Copy for S {}
2786 /// ```
2787 ///
2788 /// {{produces}}
2789 ///
2790 /// ### Explanation
2791 ///
2792 /// `staged_api` does not currently support using a stability attribute on `impl` blocks.
2793 /// `impl`s are always stable if both the type and trait are stable, and always unstable otherwise.
2794 pub INEFFECTIVE_UNSTABLE_TRAIT_IMPL,
2795 Deny,
2796 "detects `#[unstable]` on stable trait implementations for stable types"
2797}
2798
2799declare_lint! {
2800 /// The `self_constructor_from_outer_item` lint detects cases where the `Self` constructor
2801 /// was silently allowed due to a bug in the resolver, and which may produce surprising
2802 /// and unintended behavior.
2803 ///
2804 /// Using a `Self` type alias from an outer item was never intended, but was silently allowed.
2805 /// This is deprecated -- and is a hard error when the `Self` type alias references generics
2806 /// that are not in scope.
2807 ///
2808 /// ### Example
2809 ///
2810 /// ```rust,compile_fail
2811 /// #![deny(self_constructor_from_outer_item)]
2812 ///
2813 /// struct S0(usize);
2814 ///
2815 /// impl S0 {
2816 /// fn foo() {
2817 /// const C: S0 = Self(0);
2818 /// fn bar() -> S0 {
2819 /// Self(0)
2820 /// }
2821 /// }
2822 /// }
2823 /// ```
2824 ///
2825 /// {{produces}}
2826 ///
2827 /// ### Explanation
2828 ///
2829 /// The `Self` type alias should not be reachable because nested items are not associated with
2830 /// the scope of the parameters from the parent item.
2831 pub SELF_CONSTRUCTOR_FROM_OUTER_ITEM,
2832 Warn,
2833 "detect unsupported use of `Self` from outer item",
2834 @future_incompatible = FutureIncompatibleInfo {
2835 reason: FutureIncompatibilityReason::FutureReleaseError,
2836 reference: "issue #124186 <https://github.com/rust-lang/rust/issues/124186>",
2837 };
2838}
2839
2840declare_lint! {
2841 /// The `semicolon_in_expressions_from_macros` lint detects trailing semicolons
2842 /// in macro bodies when the macro is invoked in expression position.
2843 /// This was previous accepted, but is being phased out.
2844 ///
2845 /// ### Example
2846 ///
2847 /// ```rust,compile_fail
2848 /// #![deny(semicolon_in_expressions_from_macros)]
2849 /// macro_rules! foo {
2850 /// () => { true; }
2851 /// }
2852 ///
2853 /// fn main() {
2854 /// let val = match true {
2855 /// true => false,
2856 /// _ => foo!()
2857 /// };
2858 /// }
2859 /// ```
2860 ///
2861 /// {{produces}}
2862 ///
2863 /// ### Explanation
2864 ///
2865 /// Previous, Rust ignored trailing semicolon in a macro
2866 /// body when a macro was invoked in expression position.
2867 /// However, this makes the treatment of semicolons in the language
2868 /// inconsistent, and could lead to unexpected runtime behavior
2869 /// in some circumstances (e.g. if the macro author expects
2870 /// a value to be dropped).
2871 ///
2872 /// This is a [future-incompatible] lint to transition this
2873 /// to a hard error in the future. See [issue #79813] for more details.
2874 ///
2875 /// [issue #79813]: https://github.com/rust-lang/rust/issues/79813
2876 /// [future-incompatible]: ../index.md#future-incompatible-lints
2877 pub SEMICOLON_IN_EXPRESSIONS_FROM_MACROS,
2878 Deny,
2879 "trailing semicolon in macro body used as expression",
2880 @future_incompatible = FutureIncompatibleInfo {
2881 reason: FutureIncompatibilityReason::FutureReleaseError,
2882 reference: "issue #79813 <https://github.com/rust-lang/rust/issues/79813>",
2883 report_in_deps: true,
2884 };
2885}
2886
2887declare_lint! {
2888 /// The `legacy_derive_helpers` lint detects derive helper attributes
2889 /// that are used before they are introduced.
2890 ///
2891 /// ### Example
2892 ///
2893 /// ```rust,ignore (needs extern crate)
2894 /// #[serde(rename_all = "camelCase")]
2895 /// #[derive(Deserialize)]
2896 /// struct S { /* fields */ }
2897 /// ```
2898 ///
2899 /// produces:
2900 ///
2901 /// ```text
2902 /// warning: derive helper attribute is used before it is introduced
2903 /// --> $DIR/legacy-derive-helpers.rs:1:3
2904 /// |
2905 /// 1 | #[serde(rename_all = "camelCase")]
2906 /// | ^^^^^
2907 /// ...
2908 /// 2 | #[derive(Deserialize)]
2909 /// | ----------- the attribute is introduced here
2910 /// ```
2911 ///
2912 /// ### Explanation
2913 ///
2914 /// Attributes like this work for historical reasons, but attribute expansion works in
2915 /// left-to-right order in general, so, to resolve `#[serde]`, compiler has to try to "look
2916 /// into the future" at not yet expanded part of the item , but such attempts are not always
2917 /// reliable.
2918 ///
2919 /// To fix the warning place the helper attribute after its corresponding derive.
2920 /// ```rust,ignore (needs extern crate)
2921 /// #[derive(Deserialize)]
2922 /// #[serde(rename_all = "camelCase")]
2923 /// struct S { /* fields */ }
2924 /// ```
2925 pub LEGACY_DERIVE_HELPERS,
2926 Deny,
2927 "detects derive helper attributes that are used before they are introduced",
2928 @future_incompatible = FutureIncompatibleInfo {
2929 reason: FutureIncompatibilityReason::FutureReleaseError,
2930 reference: "issue #79202 <https://github.com/rust-lang/rust/issues/79202>",
2931 report_in_deps: true,
2932 };
2933}
2934
2935declare_lint! {
2936 /// The `large_assignments` lint detects when objects of large
2937 /// types are being moved around.
2938 ///
2939 /// ### Example
2940 ///
2941 /// ```rust,ignore (can crash on some platforms)
2942 /// let x = [0; 50000];
2943 /// let y = x;
2944 /// ```
2945 ///
2946 /// produces:
2947 ///
2948 /// ```text
2949 /// warning: moving a large value
2950 /// --> $DIR/move-large.rs:1:3
2951 /// let y = x;
2952 /// - Copied large value here
2953 /// ```
2954 ///
2955 /// ### Explanation
2956 ///
2957 /// When using a large type in a plain assignment or in a function
2958 /// argument, idiomatic code can be inefficient.
2959 /// Ideally appropriate optimizations would resolve this, but such
2960 /// optimizations are only done in a best-effort manner.
2961 /// This lint will trigger on all sites of large moves and thus allow the
2962 /// user to resolve them in code.
2963 pub LARGE_ASSIGNMENTS,
2964 Warn,
2965 "detects large moves or copies",
2966}
2967
2968declare_lint! {
2969 /// The `unexpected_cfgs` lint detects unexpected conditional compilation conditions.
2970 ///
2971 /// ### Example
2972 ///
2973 /// ```text
2974 /// rustc --check-cfg 'cfg()'
2975 /// ```
2976 ///
2977 /// ```rust,ignore (needs command line option)
2978 /// #[cfg(widnows)]
2979 /// fn foo() {}
2980 /// ```
2981 ///
2982 /// This will produce:
2983 ///
2984 /// ```text
2985 /// warning: unexpected `cfg` condition name: `widnows`
2986 /// --> lint_example.rs:1:7
2987 /// |
2988 /// 1 | #[cfg(widnows)]
2989 /// | ^^^^^^^
2990 /// |
2991 /// = note: `#[warn(unexpected_cfgs)]` on by default
2992 /// ```
2993 ///
2994 /// ### Explanation
2995 ///
2996 /// This lint is only active when [`--check-cfg`][check-cfg] arguments are being
2997 /// passed to the compiler and triggers whenever an unexpected condition name or value is
2998 /// used.
2999 ///
3000 /// See the [Checking Conditional Configurations][check-cfg] section for more
3001 /// details.
3002 ///
3003 /// See the [Cargo Specifics][unexpected_cfgs_lint_config] section for configuring this lint in
3004 /// `Cargo.toml`.
3005 ///
3006 /// [check-cfg]: https://doc.rust-lang.org/nightly/rustc/check-cfg.html
3007 /// [unexpected_cfgs_lint_config]: https://doc.rust-lang.org/nightly/rustc/check-cfg/cargo-specifics.html#check-cfg-in-lintsrust-table
3008 pub UNEXPECTED_CFGS,
3009 Warn,
3010 "detects unexpected names and values in `#[cfg]` conditions",
3011 report_in_external_macro
3012}
3013
3014declare_lint! {
3015 /// The `explicit_builtin_cfgs_in_flags` lint detects builtin cfgs set via the `--cfg` flag.
3016 ///
3017 /// ### Example
3018 ///
3019 /// ```text
3020 /// rustc --cfg unix
3021 /// ```
3022 ///
3023 /// ```rust,ignore (needs command line option)
3024 /// fn main() {}
3025 /// ```
3026 ///
3027 /// This will produce:
3028 ///
3029 /// ```text
3030 /// error: unexpected `--cfg unix` flag
3031 /// |
3032 /// = note: config `unix` is only supposed to be controlled by `--target`
3033 /// = note: manually setting a built-in cfg can and does create incoherent behaviors
3034 /// = note: `#[deny(explicit_builtin_cfgs_in_flags)]` on by default
3035 /// ```
3036 ///
3037 /// ### Explanation
3038 ///
3039 /// Setting builtin cfgs can and does produce incoherent behavior, it's better to the use
3040 /// the appropriate `rustc` flag that controls the config. For example setting the `windows`
3041 /// cfg but on Linux based target.
3042 pub EXPLICIT_BUILTIN_CFGS_IN_FLAGS,
3043 Deny,
3044 "detects builtin cfgs set via the `--cfg`"
3045}
3046
3047declare_lint! {
3048 /// The `repr_transparent_non_zst_fields` lint
3049 /// detects types marked `#[repr(transparent)]` that (transitively)
3050 /// contain a type that is not guaranteed to remain a ZST type under all configurations.
3051 ///
3052 /// ### Example
3053 ///
3054 /// ```rust,ignore (needs external crate)
3055 /// #![deny(repr_transparent_external_private_fields)]
3056 /// use foo::NonExhaustiveZst;
3057 ///
3058 /// #[repr(C)]
3059 /// struct CZst([u8; 0]);
3060 ///
3061 /// #[repr(transparent)]
3062 /// struct Bar(u32, ([u32; 0], NonExhaustiveZst));
3063 /// #[repr(transparent)]
3064 /// struct Baz(u32, CZst);
3065 /// ```
3066 ///
3067 /// This will produce:
3068 ///
3069 /// ```text
3070 /// error: zero-sized fields in repr(transparent) cannot contain external non-exhaustive types
3071 /// --> src/main.rs:5:28
3072 /// |
3073 /// 5 | struct Bar(u32, ([u32; 0], NonExhaustiveZst));
3074 /// | ^^^^^^^^^^^^^^^^
3075 /// |
3076 /// note: the lint level is defined here
3077 /// --> src/main.rs:1:9
3078 /// |
3079 /// 1 | #![deny(repr_transparent_external_private_fields)]
3080 /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3081 /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3082 /// = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
3083 /// = note: this field contains `NonExhaustiveZst`, which is marked with `#[non_exhaustive]`, so it could become non-zero-sized in the future.
3084 ///
3085 /// error: zero-sized fields in repr(transparent) cannot contain `#[repr(C)]` types
3086 /// --> src/main.rs:5:28
3087 /// |
3088 /// 5 | struct Baz(u32, CZst);
3089 /// | ^^^^
3090 /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3091 /// = note: for more information, see issue #78586 <https://github.com/rust-lang/rust/issues/78586>
3092 /// = note: this field contains `CZst`, which is a `#[repr(C)]` type, so it is not guaranteed to be zero-sized on all targets.
3093 /// ```
3094 ///
3095 /// ### Explanation
3096 ///
3097 /// Previous, Rust accepted fields that contain external private zero-sized types, even though
3098 /// those types could gain a non-zero-sized field in a future, semver-compatible update.
3099 ///
3100 /// Rust also accepted fields that contain `repr(C)` zero-sized types, even though those types
3101 /// are not guaranteed to be zero-sized on all targets, and even though those types can
3102 /// make a difference for the ABI (and therefore cannot be ignored by `repr(transparent)`).
3103 ///
3104 /// This is a [future-incompatible] lint to transition this
3105 /// to a hard error in the future. See [issue #78586] for more details.
3106 ///
3107 /// [issue #78586]: https://github.com/rust-lang/rust/issues/78586
3108 /// [future-incompatible]: ../index.md#future-incompatible-lints
3109 pub REPR_TRANSPARENT_NON_ZST_FIELDS,
3110 Deny,
3111 "transparent type contains an external ZST that is marked #[non_exhaustive] or contains private fields",
3112 @future_incompatible = FutureIncompatibleInfo {
3113 reason: FutureIncompatibilityReason::FutureReleaseError,
3114 reference: "issue #78586 <https://github.com/rust-lang/rust/issues/78586>",
3115 report_in_deps: true,
3116 };
3117}
3118
3119declare_lint! {
3120 /// The `unstable_syntax_pre_expansion` lint detects the use of unstable
3121 /// syntax that is discarded during attribute expansion.
3122 ///
3123 /// ### Example
3124 ///
3125 /// ```rust
3126 /// #[cfg(FALSE)]
3127 /// macro foo() {}
3128 /// ```
3129 ///
3130 /// {{produces}}
3131 ///
3132 /// ### Explanation
3133 ///
3134 /// The input to active attributes such as `#[cfg]` or procedural macro
3135 /// attributes is required to be valid syntax. Previously, the compiler only
3136 /// gated the use of unstable syntax features after resolving `#[cfg]` gates
3137 /// and expanding procedural macros.
3138 ///
3139 /// To avoid relying on unstable syntax, move the use of unstable syntax
3140 /// into a position where the compiler does not parse the syntax, such as a
3141 /// functionlike macro.
3142 ///
3143 /// ```rust
3144 /// # #![deny(unstable_syntax_pre_expansion)]
3145 ///
3146 /// macro_rules! identity {
3147 /// ( $($tokens:tt)* ) => { $($tokens)* }
3148 /// }
3149 ///
3150 /// #[cfg(FALSE)]
3151 /// identity! {
3152 /// macro foo() {}
3153 /// }
3154 /// ```
3155 ///
3156 /// This is a [future-incompatible] lint to transition this
3157 /// to a hard error in the future. See [issue #65860] for more details.
3158 ///
3159 /// [issue #65860]: https://github.com/rust-lang/rust/issues/65860
3160 /// [future-incompatible]: ../index.md#future-incompatible-lints
3161 pub UNSTABLE_SYNTAX_PRE_EXPANSION,
3162 Warn,
3163 "unstable syntax can change at any point in the future, causing a hard error!",
3164 @future_incompatible = FutureIncompatibleInfo {
3165 reason: FutureIncompatibilityReason::FutureReleaseError,
3166 reference: "issue #65860 <https://github.com/rust-lang/rust/issues/65860>",
3167 };
3168}
3169
3170declare_lint! {
3171 /// The `ambiguous_glob_reexports` lint detects cases where names re-exported via globs
3172 /// collide. Downstream users trying to use the same name re-exported from multiple globs
3173 /// will receive a warning pointing out redefinition of the same name.
3174 ///
3175 /// ### Example
3176 ///
3177 /// ```rust,compile_fail
3178 /// #![deny(ambiguous_glob_reexports)]
3179 /// pub mod foo {
3180 /// pub type X = u8;
3181 /// }
3182 ///
3183 /// pub mod bar {
3184 /// pub type Y = u8;
3185 /// pub type X = u8;
3186 /// }
3187 ///
3188 /// pub use foo::*;
3189 /// pub use bar::*;
3190 ///
3191 ///
3192 /// pub fn main() {}
3193 /// ```
3194 ///
3195 /// {{produces}}
3196 ///
3197 /// ### Explanation
3198 ///
3199 /// This was previously accepted but it could silently break a crate's downstream users code.
3200 /// For example, if `foo::*` and `bar::*` were re-exported before `bar::X` was added to the
3201 /// re-exports, down stream users could use `this_crate::X` without problems. However, adding
3202 /// `bar::X` would cause compilation errors in downstream crates because `X` is defined
3203 /// multiple times in the same namespace of `this_crate`.
3204 pub AMBIGUOUS_GLOB_REEXPORTS,
3205 Warn,
3206 "ambiguous glob re-exports",
3207}
3208
3209declare_lint! {
3210 /// The `hidden_glob_reexports` lint detects cases where glob re-export items are shadowed by
3211 /// private items.
3212 ///
3213 /// ### Example
3214 ///
3215 /// ```rust,compile_fail
3216 /// #![deny(hidden_glob_reexports)]
3217 ///
3218 /// pub mod upstream {
3219 /// mod inner { pub struct Foo {}; pub struct Bar {}; }
3220 /// pub use self::inner::*;
3221 /// struct Foo {} // private item shadows `inner::Foo`
3222 /// }
3223 ///
3224 /// // mod downstream {
3225 /// // fn test() {
3226 /// // let _ = crate::upstream::Foo; // inaccessible
3227 /// // }
3228 /// // }
3229 ///
3230 /// pub fn main() {}
3231 /// ```
3232 ///
3233 /// {{produces}}
3234 ///
3235 /// ### Explanation
3236 ///
3237 /// This was previously accepted without any errors or warnings but it could silently break a
3238 /// crate's downstream user code. If the `struct Foo` was added, `dep::inner::Foo` would
3239 /// silently become inaccessible and trigger a "`struct `Foo` is private`" visibility error at
3240 /// the downstream use site.
3241 pub HIDDEN_GLOB_REEXPORTS,
3242 Warn,
3243 "name introduced by a private item shadows a name introduced by a public glob re-export",
3244}
3245
3246declare_lint! {
3247 /// The `long_running_const_eval` lint is emitted when const
3248 /// eval is running for a long time to ensure rustc terminates
3249 /// even if you accidentally wrote an infinite loop.
3250 ///
3251 /// ### Example
3252 ///
3253 /// ```rust,compile_fail
3254 /// const FOO: () = loop {};
3255 /// ```
3256 ///
3257 /// {{produces}}
3258 ///
3259 /// ### Explanation
3260 ///
3261 /// Loops allow const evaluation to compute arbitrary code, but may also
3262 /// cause infinite loops or just very long running computations.
3263 /// Users can enable long running computations by allowing the lint
3264 /// on individual constants or for entire crates.
3265 ///
3266 /// ### Unconditional warnings
3267 ///
3268 /// Note that regardless of whether the lint is allowed or set to warn,
3269 /// the compiler will issue warnings if constant evaluation runs significantly
3270 /// longer than this lint's limit. These warnings are also shown to downstream
3271 /// users from crates.io or similar registries. If you are above the lint's limit,
3272 /// both you and downstream users might be exposed to these warnings.
3273 /// They might also appear on compiler updates, as the compiler makes minor changes
3274 /// about how complexity is measured: staying below the limit ensures that there
3275 /// is enough room, and given that the lint is disabled for people who use your
3276 /// dependency it means you will be the only one to get the warning and can put
3277 /// out an update in your own time.
3278 pub LONG_RUNNING_CONST_EVAL,
3279 Deny,
3280 "detects long const eval operations",
3281 report_in_external_macro
3282}
3283
3284declare_lint! {
3285 /// The `unused_associated_type_bounds` lint is emitted when an
3286 /// associated type bound is added to a trait object, but the associated
3287 /// type has a `where Self: Sized` bound, and is thus unavailable on the
3288 /// trait object anyway.
3289 ///
3290 /// ### Example
3291 ///
3292 /// ```rust
3293 /// trait Foo {
3294 /// type Bar where Self: Sized;
3295 /// }
3296 /// type Mop = dyn Foo<Bar = ()>;
3297 /// ```
3298 ///
3299 /// {{produces}}
3300 ///
3301 /// ### Explanation
3302 ///
3303 /// Just like methods with `Self: Sized` bounds are unavailable on trait
3304 /// objects, associated types can be removed from the trait object.
3305 pub UNUSED_ASSOCIATED_TYPE_BOUNDS,
3306 Warn,
3307 "detects unused `Foo = Bar` bounds in `dyn Trait<Foo = Bar>`"
3308}
3309
3310declare_lint! {
3311 /// The `unused_doc_comments` lint detects doc comments that aren't used
3312 /// by `rustdoc`.
3313 ///
3314 /// ### Example
3315 ///
3316 /// ```rust
3317 /// /// docs for x
3318 /// let x = 12;
3319 /// ```
3320 ///
3321 /// {{produces}}
3322 ///
3323 /// ### Explanation
3324 ///
3325 /// `rustdoc` does not use doc comments in all positions, and so the doc
3326 /// comment will be ignored. Try changing it to a normal comment with `//`
3327 /// to avoid the warning.
3328 pub UNUSED_DOC_COMMENTS,
3329 Warn,
3330 "detects doc comments that aren't used by rustdoc"
3331}
3332
3333declare_lint! {
3334 /// The `rust_2021_incompatible_closure_captures` lint detects variables that aren't completely
3335 /// captured in Rust 2021, such that the `Drop` order of their fields may differ between
3336 /// Rust 2018 and 2021.
3337 ///
3338 /// It can also detect when a variable implements a trait like `Send`, but one of its fields does not,
3339 /// and the field is captured by a closure and used with the assumption that said field implements
3340 /// the same trait as the root variable.
3341 ///
3342 /// ### Example of drop reorder
3343 ///
3344 /// ```rust,edition2018,compile_fail
3345 /// #![deny(rust_2021_incompatible_closure_captures)]
3346 /// # #![allow(unused)]
3347 ///
3348 /// struct FancyInteger(i32);
3349 ///
3350 /// impl Drop for FancyInteger {
3351 /// fn drop(&mut self) {
3352 /// println!("Just dropped {}", self.0);
3353 /// }
3354 /// }
3355 ///
3356 /// struct Point { x: FancyInteger, y: FancyInteger }
3357 ///
3358 /// fn main() {
3359 /// let p = Point { x: FancyInteger(10), y: FancyInteger(20) };
3360 ///
3361 /// let c = || {
3362 /// let x = p.x;
3363 /// };
3364 ///
3365 /// c();
3366 ///
3367 /// // ... More code ...
3368 /// }
3369 /// ```
3370 ///
3371 /// {{produces}}
3372 ///
3373 /// ### Explanation
3374 ///
3375 /// In the above example, `p.y` will be dropped at the end of `f` instead of
3376 /// with `c` in Rust 2021.
3377 ///
3378 /// ### Example of auto-trait
3379 ///
3380 /// ```rust,edition2018,compile_fail
3381 /// #![deny(rust_2021_incompatible_closure_captures)]
3382 /// use std::thread;
3383 ///
3384 /// struct Pointer(*mut i32);
3385 /// unsafe impl Send for Pointer {}
3386 ///
3387 /// fn main() {
3388 /// let mut f = 10;
3389 /// let fptr = Pointer(&mut f as *mut i32);
3390 /// thread::spawn(move || unsafe {
3391 /// *fptr.0 = 20;
3392 /// });
3393 /// }
3394 /// ```
3395 ///
3396 /// {{produces}}
3397 ///
3398 /// ### Explanation
3399 ///
3400 /// In the above example, only `fptr.0` is captured in Rust 2021.
3401 /// The field is of type `*mut i32`, which doesn't implement `Send`,
3402 /// making the code invalid as the field cannot be sent between threads safely.
3403 pub RUST_2021_INCOMPATIBLE_CLOSURE_CAPTURES,
3404 Allow,
3405 "detects closures affected by Rust 2021 changes",
3406 @future_incompatible = FutureIncompatibleInfo {
3407 reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2021),
3408 explain_reason: false,
3409 };
3410}
3411
3412declare_lint_pass!(UnusedDocComment => [UNUSED_DOC_COMMENTS]);
3413
3414declare_lint! {
3415 /// The `missing_abi` lint detects cases where the ABI is omitted from
3416 /// `extern` declarations.
3417 ///
3418 /// ### Example
3419 ///
3420 /// ```rust,compile_fail
3421 /// #![deny(missing_abi)]
3422 ///
3423 /// extern fn foo() {}
3424 /// ```
3425 ///
3426 /// {{produces}}
3427 ///
3428 /// ### Explanation
3429 ///
3430 /// For historic reasons, Rust implicitly selects `C` as the default ABI for
3431 /// `extern` declarations. [Other ABIs] like `C-unwind` and `system` have
3432 /// been added since then, and especially with their addition seeing the ABI
3433 /// easily makes code review easier.
3434 ///
3435 /// [Other ABIs]: https://doc.rust-lang.org/reference/items/external-blocks.html#abi
3436 pub MISSING_ABI,
3437 Warn,
3438 "No declared ABI for extern declaration"
3439}
3440
3441declare_lint! {
3442 /// The `invalid_doc_attributes` lint detects when the `#[doc(...)]` is
3443 /// misused.
3444 ///
3445 /// ### Example
3446 ///
3447 /// ```rust,compile_fail
3448 /// #![deny(warnings)]
3449 ///
3450 /// pub mod submodule {
3451 /// #![doc(test(no_crate_inject))]
3452 /// }
3453 /// ```
3454 ///
3455 /// {{produces}}
3456 ///
3457 /// ### Explanation
3458 ///
3459 /// Previously, incorrect usage of the `#[doc(..)]` attribute was not
3460 /// being validated. Usually these should be rejected as a hard error,
3461 /// but this lint was introduced to avoid breaking any existing
3462 /// crates which included them.
3463 pub INVALID_DOC_ATTRIBUTES,
3464 Deny,
3465 "detects invalid `#[doc(...)]` attributes",
3466}
3467
3468declare_lint! {
3469 /// The `rust_2021_incompatible_or_patterns` lint detects usage of old versions of or-patterns.
3470 ///
3471 /// ### Example
3472 ///
3473 /// ```rust,edition2018,compile_fail
3474 /// #![deny(rust_2021_incompatible_or_patterns)]
3475 ///
3476 /// macro_rules! match_any {
3477 /// ( $expr:expr , $( $( $pat:pat )|+ => $expr_arm:expr ),+ ) => {
3478 /// match $expr {
3479 /// $(
3480 /// $( $pat => $expr_arm, )+
3481 /// )+
3482 /// }
3483 /// };
3484 /// }
3485 ///
3486 /// fn main() {
3487 /// let result: Result<i64, i32> = Err(42);
3488 /// let int: i64 = match_any!(result, Ok(i) | Err(i) => i.into());
3489 /// assert_eq!(int, 42);
3490 /// }
3491 /// ```
3492 ///
3493 /// {{produces}}
3494 ///
3495 /// ### Explanation
3496 ///
3497 /// In Rust 2021, the `pat` matcher will match additional patterns, which include the `|` character.
3498 pub RUST_2021_INCOMPATIBLE_OR_PATTERNS,
3499 Allow,
3500 "detects usage of old versions of or-patterns",
3501 @future_incompatible = FutureIncompatibleInfo {
3502 reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
3503 reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/or-patterns-macro-rules.html>",
3504 };
3505}
3506
3507declare_lint! {
3508 /// The `rust_2021_prelude_collisions` lint detects the usage of trait methods which are ambiguous
3509 /// with traits added to the prelude in future editions.
3510 ///
3511 /// ### Example
3512 ///
3513 /// ```rust,edition2018,compile_fail
3514 /// #![deny(rust_2021_prelude_collisions)]
3515 ///
3516 /// trait Foo {
3517 /// fn try_into(self) -> Result<String, !>;
3518 /// }
3519 ///
3520 /// impl Foo for &str {
3521 /// fn try_into(self) -> Result<String, !> {
3522 /// Ok(String::from(self))
3523 /// }
3524 /// }
3525 ///
3526 /// fn main() {
3527 /// let x: String = "3".try_into().unwrap();
3528 /// // ^^^^^^^^
3529 /// // This call to try_into matches both Foo::try_into and TryInto::try_into as
3530 /// // `TryInto` has been added to the Rust prelude in 2021 edition.
3531 /// println!("{x}");
3532 /// }
3533 /// ```
3534 ///
3535 /// {{produces}}
3536 ///
3537 /// ### Explanation
3538 ///
3539 /// In Rust 2021, one of the important introductions is the [prelude changes], which add
3540 /// `TryFrom`, `TryInto`, and `FromIterator` into the standard library's prelude. Since this
3541 /// results in an ambiguity as to which method/function to call when an existing `try_into`
3542 /// method is called via dot-call syntax or a `try_from`/`from_iter` associated function
3543 /// is called directly on a type.
3544 ///
3545 /// [prelude changes]: https://blog.rust-lang.org/inside-rust/2021/03/04/planning-rust-2021.html#prelude-changes
3546 pub RUST_2021_PRELUDE_COLLISIONS,
3547 Allow,
3548 "detects the usage of trait methods which are ambiguous with traits added to the \
3549 prelude in future editions",
3550 @future_incompatible = FutureIncompatibleInfo {
3551 reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
3552 reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/prelude.html>",
3553 };
3554}
3555
3556declare_lint! {
3557 /// The `rust_2024_prelude_collisions` lint detects the usage of trait methods which are ambiguous
3558 /// with traits added to the prelude in future editions.
3559 ///
3560 /// ### Example
3561 ///
3562 /// ```rust,edition2021,compile_fail
3563 /// #![deny(rust_2024_prelude_collisions)]
3564 /// trait Meow {
3565 /// fn poll(&self) {}
3566 /// }
3567 /// impl<T> Meow for T {}
3568 ///
3569 /// fn main() {
3570 /// core::pin::pin!(async {}).poll();
3571 /// // ^^^^^^
3572 /// // This call to try_into matches both Future::poll and Meow::poll as
3573 /// // `Future` has been added to the Rust prelude in 2024 edition.
3574 /// }
3575 /// ```
3576 ///
3577 /// {{produces}}
3578 ///
3579 /// ### Explanation
3580 ///
3581 /// Rust 2024, introduces two new additions to the standard library's prelude:
3582 /// `Future` and `IntoFuture`. This results in an ambiguity as to which method/function
3583 /// to call when an existing `poll`/`into_future` method is called via dot-call syntax or
3584 /// a `poll`/`into_future` associated function is called directly on a type.
3585 ///
3586 pub RUST_2024_PRELUDE_COLLISIONS,
3587 Allow,
3588 "detects the usage of trait methods which are ambiguous with traits added to the \
3589 prelude in future editions",
3590 @future_incompatible = FutureIncompatibleInfo {
3591 reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
3592 reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/prelude.html>",
3593 };
3594}
3595
3596declare_lint! {
3597 /// The `rust_2021_prefixes_incompatible_syntax` lint detects identifiers that will be parsed as a
3598 /// prefix instead in Rust 2021.
3599 ///
3600 /// ### Example
3601 ///
3602 /// ```rust,edition2018,compile_fail
3603 /// #![deny(rust_2021_prefixes_incompatible_syntax)]
3604 ///
3605 /// macro_rules! m {
3606 /// (z $x:expr) => ();
3607 /// }
3608 ///
3609 /// m!(z"hey");
3610 /// ```
3611 ///
3612 /// {{produces}}
3613 ///
3614 /// ### Explanation
3615 ///
3616 /// In Rust 2015 and 2018, `z"hey"` is two tokens: the identifier `z`
3617 /// followed by the string literal `"hey"`. In Rust 2021, the `z` is
3618 /// considered a prefix for `"hey"`.
3619 ///
3620 /// This lint suggests to add whitespace between the `z` and `"hey"` tokens
3621 /// to keep them separated in Rust 2021.
3622 // Allow this lint -- rustdoc doesn't yet support threading edition into this lint's parser.
3623 #[allow(rustdoc::invalid_rust_codeblocks)]
3624 pub RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
3625 Allow,
3626 "identifiers that will be parsed as a prefix in Rust 2021",
3627 @future_incompatible = FutureIncompatibleInfo {
3628 reason: FutureIncompatibilityReason::EditionError(Edition::Edition2021),
3629 reference: "<https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html>",
3630 };
3631 crate_level_only
3632}
3633
3634declare_lint! {
3635 /// The `unsupported_calling_conventions` lint is output whenever there is a use of the
3636 /// `stdcall`, `fastcall`, and `cdecl` calling conventions (or their unwind
3637 /// variants) on targets that cannot meaningfully be supported for the requested target.
3638 ///
3639 /// For example `stdcall` does not make much sense for a x86_64 or, more apparently, powerpc
3640 /// code, because this calling convention was never specified for those targets.
3641 ///
3642 /// Historically MSVC toolchains have fallen back to the regular C calling convention for
3643 /// targets other than x86, but Rust doesn't really see a similar need to introduce a similar
3644 /// hack across many more targets.
3645 ///
3646 /// ### Example
3647 ///
3648 /// ```rust,ignore (needs specific targets)
3649 /// extern "stdcall" fn stdcall() {}
3650 /// ```
3651 ///
3652 /// This will produce:
3653 ///
3654 /// ```text
3655 /// warning: use of calling convention not supported on this target
3656 /// --> $DIR/unsupported.rs:39:1
3657 /// |
3658 /// LL | extern "stdcall" fn stdcall() {}
3659 /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3660 /// |
3661 /// = note: `#[warn(unsupported_calling_conventions)]` on by default
3662 /// = warning: this was previously accepted by the compiler but is being phased out;
3663 /// it will become a hard error in a future release!
3664 /// = note: for more information, see issue ...
3665 /// ```
3666 ///
3667 /// ### Explanation
3668 ///
3669 /// On most of the targets the behaviour of `stdcall` and similar calling conventions is not
3670 /// defined at all, but was previously accepted due to a bug in the implementation of the
3671 /// compiler.
3672 pub UNSUPPORTED_CALLING_CONVENTIONS,
3673 Warn,
3674 "use of unsupported calling convention",
3675 @future_incompatible = FutureIncompatibleInfo {
3676 reason: FutureIncompatibilityReason::FutureReleaseError,
3677 report_in_deps: false,
3678 reference: "issue #137018 <https://github.com/rust-lang/rust/issues/137018>",
3679 };
3680}
3681
3682declare_lint! {
3683 /// The `unsupported_fn_ptr_calling_conventions` lint is output whenever there is a use of
3684 /// a target dependent calling convention on a target that does not support this calling
3685 /// convention on a function pointer.
3686 ///
3687 /// For example `stdcall` does not make much sense for a x86_64 or, more apparently, powerpc
3688 /// code, because this calling convention was never specified for those targets.
3689 ///
3690 /// ### Example
3691 ///
3692 /// ```rust,ignore (needs specific targets)
3693 /// fn stdcall_ptr(f: extern "stdcall" fn ()) {
3694 /// f()
3695 /// }
3696 /// ```
3697 ///
3698 /// This will produce:
3699 ///
3700 /// ```text
3701 /// warning: the calling convention `"stdcall"` is not supported on this target
3702 /// --> $DIR/unsupported.rs:34:15
3703 /// |
3704 /// LL | fn stdcall_ptr(f: extern "stdcall" fn()) {
3705 /// | ^^^^^^^^^^^^^^^^^^^^^^^^
3706 /// |
3707 /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
3708 /// = note: for more information, see issue #130260 <https://github.com/rust-lang/rust/issues/130260>
3709 /// = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
3710 /// ```
3711 ///
3712 /// ### Explanation
3713 ///
3714 /// On most of the targets the behaviour of `stdcall` and similar calling conventions is not
3715 /// defined at all, but was previously accepted due to a bug in the implementation of the
3716 /// compiler.
3717 pub UNSUPPORTED_FN_PTR_CALLING_CONVENTIONS,
3718 Warn,
3719 "use of unsupported calling convention for function pointer",
3720 @future_incompatible = FutureIncompatibleInfo {
3721 reason: FutureIncompatibilityReason::FutureReleaseError,
3722 reference: "issue #130260 <https://github.com/rust-lang/rust/issues/130260>",
3723 report_in_deps: true,
3724 };
3725}
3726
3727declare_lint! {
3728 /// The `break_with_label_and_loop` lint detects labeled `break` expressions with
3729 /// an unlabeled loop as their value expression.
3730 ///
3731 /// ### Example
3732 ///
3733 /// ```rust
3734 /// 'label: loop {
3735 /// break 'label loop { break 42; };
3736 /// };
3737 /// ```
3738 ///
3739 /// {{produces}}
3740 ///
3741 /// ### Explanation
3742 ///
3743 /// In Rust, loops can have a label, and `break` expressions can refer to that label to
3744 /// break out of specific loops (and not necessarily the innermost one). `break` expressions
3745 /// can also carry a value expression, which can be another loop. A labeled `break` with an
3746 /// unlabeled loop as its value expression is easy to confuse with an unlabeled break with
3747 /// a labeled loop and is thus discouraged (but allowed for compatibility); use parentheses
3748 /// around the loop expression to silence this warning. Unlabeled `break` expressions with
3749 /// labeled loops yield a hard error, which can also be silenced by wrapping the expression
3750 /// in parentheses.
3751 pub BREAK_WITH_LABEL_AND_LOOP,
3752 Warn,
3753 "`break` expression with label and unlabeled loop as value expression"
3754}
3755
3756declare_lint! {
3757 /// The `non_exhaustive_omitted_patterns` lint aims to help consumers of a `#[non_exhaustive]`
3758 /// struct or enum who want to match all of its fields/variants explicitly.
3759 ///
3760 /// The `#[non_exhaustive]` annotation forces matches to use wildcards, so exhaustiveness
3761 /// checking cannot be used to ensure that all fields/variants are matched explicitly. To remedy
3762 /// this, this allow-by-default lint warns the user when a match mentions some but not all of
3763 /// the fields/variants of a `#[non_exhaustive]` struct or enum.
3764 ///
3765 /// ### Example
3766 ///
3767 /// ```rust,ignore (needs separate crate)
3768 /// // crate A
3769 /// #[non_exhaustive]
3770 /// pub enum Bar {
3771 /// A,
3772 /// B, // added variant in non breaking change
3773 /// }
3774 ///
3775 /// // in crate B
3776 /// #![feature(non_exhaustive_omitted_patterns_lint)]
3777 /// #[warn(non_exhaustive_omitted_patterns)]
3778 /// match Bar::A {
3779 /// Bar::A => {},
3780 /// _ => {},
3781 /// }
3782 /// ```
3783 ///
3784 /// This will produce:
3785 ///
3786 /// ```text
3787 /// warning: some variants are not matched explicitly
3788 /// --> $DIR/reachable-patterns.rs:70:9
3789 /// |
3790 /// LL | match Bar::A {
3791 /// | ^ pattern `Bar::B` not covered
3792 /// |
3793 /// note: the lint level is defined here
3794 /// --> $DIR/reachable-patterns.rs:69:16
3795 /// |
3796 /// LL | #[warn(non_exhaustive_omitted_patterns)]
3797 /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3798 /// = help: ensure that all variants are matched explicitly by adding the suggested match arms
3799 /// = note: the matched value is of type `Bar` and the `non_exhaustive_omitted_patterns` attribute was found
3800 /// ```
3801 ///
3802 /// Warning: setting this to `deny` will make upstream non-breaking changes (adding fields or
3803 /// variants to a `#[non_exhaustive]` struct or enum) break your crate. This goes against
3804 /// expected semver behavior.
3805 ///
3806 /// ### Explanation
3807 ///
3808 /// Structs and enums tagged with `#[non_exhaustive]` force the user to add a (potentially
3809 /// redundant) wildcard when pattern-matching, to allow for future addition of fields or
3810 /// variants. The `non_exhaustive_omitted_patterns` lint detects when such a wildcard happens to
3811 /// actually catch some fields/variants. In other words, when the match without the wildcard
3812 /// would not be exhaustive. This lets the user be informed if new fields/variants were added.
3813 pub NON_EXHAUSTIVE_OMITTED_PATTERNS,
3814 Allow,
3815 "detect when patterns of types marked `non_exhaustive` are missed",
3816 @feature_gate = non_exhaustive_omitted_patterns_lint;
3817}
3818
3819declare_lint! {
3820 /// The `text_direction_codepoint_in_comment` lint detects Unicode codepoints in comments that
3821 /// change the visual representation of text on screen in a way that does not correspond to
3822 /// their on memory representation.
3823 ///
3824 /// ### Example
3825 ///
3826 /// ```rust,compile_fail
3827 /// #![deny(text_direction_codepoint_in_comment)]
3828 /// fn main() {
3829 #[doc = " println!(\"{:?}\"); // '\u{202E}');"]
3830 /// }
3831 /// ```
3832 ///
3833 /// {{produces}}
3834 ///
3835 /// ### Explanation
3836 ///
3837 /// Unicode allows changing the visual flow of text on screen in order to support scripts that
3838 /// are written right-to-left, but a specially crafted comment can make code that will be
3839 /// compiled appear to be part of a comment, depending on the software used to read the code.
3840 /// To avoid potential problems or confusion, such as in CVE-2021-42574, by default we deny
3841 /// their use.
3842 pub TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
3843 Deny,
3844 "invisible directionality-changing codepoints in comment",
3845 crate_level_only
3846}
3847
3848declare_lint! {
3849 /// The `text_direction_codepoint_in_literal` lint detects Unicode codepoints that change the
3850 /// visual representation of text on screen in a way that does not correspond to their on
3851 /// memory representation.
3852 ///
3853 /// ### Explanation
3854 ///
3855 /// The unicode characters `\u{202A}`, `\u{202B}`, `\u{202D}`, `\u{202E}`, `\u{2066}`,
3856 /// `\u{2067}`, `\u{2068}`, `\u{202C}` and `\u{2069}` make the flow of text on screen change
3857 /// its direction on software that supports these codepoints. This makes the text "abc" display
3858 /// as "cba" on screen. By leveraging software that supports these, people can write specially
3859 /// crafted literals that make the surrounding code seem like it's performing one action, when
3860 /// in reality it is performing another. Because of this, we proactively lint against their
3861 /// presence to avoid surprises.
3862 ///
3863 /// ### Example
3864 ///
3865 /// ```rust,compile_fail
3866 /// #![deny(text_direction_codepoint_in_literal)]
3867 /// fn main() {
3868 // ` - convince tidy that backticks match
3869 #[doc = " println!(\"{:?}\", '\u{202E}');"]
3870 // `
3871 /// }
3872 /// ```
3873 ///
3874 /// {{produces}}
3875 ///
3876 pub TEXT_DIRECTION_CODEPOINT_IN_LITERAL,
3877 Deny,
3878 "detect special Unicode codepoints that affect the visual representation of text on screen, \
3879 changing the direction in which text flows",
3880 crate_level_only
3881}
3882
3883declare_lint! {
3884 /// The `duplicate_macro_attributes` lint detects when a `#[test]`-like built-in macro
3885 /// attribute is duplicated on an item. This lint may trigger on `bench`, `cfg_eval`, `test`
3886 /// and `test_case`.
3887 ///
3888 /// ### Example
3889 ///
3890 /// ```rust,ignore (needs --test)
3891 /// #[test]
3892 /// #[test]
3893 /// fn foo() {}
3894 /// ```
3895 ///
3896 /// This will produce:
3897 ///
3898 /// ```text
3899 /// warning: duplicated attribute
3900 /// --> src/lib.rs:2:1
3901 /// |
3902 /// 2 | #[test]
3903 /// | ^^^^^^^
3904 /// |
3905 /// = note: `#[warn(duplicate_macro_attributes)]` on by default
3906 /// ```
3907 ///
3908 /// ### Explanation
3909 ///
3910 /// A duplicated attribute may erroneously originate from a copy-paste and the effect of it
3911 /// being duplicated may not be obvious or desirable.
3912 ///
3913 /// For instance, doubling the `#[test]` attributes registers the test to be run twice with no
3914 /// change to its environment.
3915 ///
3916 /// [issue #90979]: https://github.com/rust-lang/rust/issues/90979
3917 pub DUPLICATE_MACRO_ATTRIBUTES,
3918 Warn,
3919 "duplicated attribute"
3920}
3921
3922declare_lint! {
3923 /// The `deprecated_where_clause_location` lint detects when a where clause in front of the equals
3924 /// in an associated type.
3925 ///
3926 /// ### Example
3927 ///
3928 /// ```rust
3929 /// trait Trait {
3930 /// type Assoc<'a> where Self: 'a;
3931 /// }
3932 ///
3933 /// impl Trait for () {
3934 /// type Assoc<'a> where Self: 'a = ();
3935 /// }
3936 /// ```
3937 ///
3938 /// {{produces}}
3939 ///
3940 /// ### Explanation
3941 ///
3942 /// The preferred location for where clauses on associated types
3943 /// is after the type. However, for most of generic associated types development,
3944 /// it was only accepted before the equals. To provide a transition period and
3945 /// further evaluate this change, both are currently accepted. At some point in
3946 /// the future, this may be disallowed at an edition boundary; but, that is
3947 /// undecided currently.
3948 pub DEPRECATED_WHERE_CLAUSE_LOCATION,
3949 Warn,
3950 "deprecated where clause location"
3951}
3952
3953declare_lint! {
3954 /// The `test_unstable_lint` lint tests unstable lints and is perma-unstable.
3955 ///
3956 /// ### Example
3957 ///
3958 /// ```rust
3959 /// // This lint is intentionally used to test the compiler's behavior
3960 /// // when an unstable lint is enabled without the corresponding feature gate.
3961 /// #![allow(test_unstable_lint)]
3962 /// ```
3963 ///
3964 /// {{produces}}
3965 ///
3966 /// ### Explanation
3967 ///
3968 /// In order to test the behavior of unstable lints, a permanently-unstable
3969 /// lint is required. This lint can be used to trigger warnings and errors
3970 /// from the compiler related to unstable lints.
3971 pub TEST_UNSTABLE_LINT,
3972 Deny,
3973 "this unstable lint is only for testing",
3974 @feature_gate = test_unstable_lint;
3975}
3976
3977declare_lint! {
3978 /// The `ffi_unwind_calls` lint detects calls to foreign functions or function pointers with
3979 /// `C-unwind` or other FFI-unwind ABIs.
3980 ///
3981 /// ### Example
3982 ///
3983 /// ```rust
3984 /// #![warn(ffi_unwind_calls)]
3985 ///
3986 /// unsafe extern "C-unwind" {
3987 /// fn foo();
3988 /// }
3989 ///
3990 /// fn bar() {
3991 /// unsafe { foo(); }
3992 /// let ptr: unsafe extern "C-unwind" fn() = foo;
3993 /// unsafe { ptr(); }
3994 /// }
3995 /// ```
3996 ///
3997 /// {{produces}}
3998 ///
3999 /// ### Explanation
4000 ///
4001 /// For crates containing such calls, if they are compiled with `-C panic=unwind` then the
4002 /// produced library cannot be linked with crates compiled with `-C panic=abort`. For crates
4003 /// that desire this ability it is therefore necessary to avoid such calls.
4004 pub FFI_UNWIND_CALLS,
4005 Allow,
4006 "call to foreign functions or function pointers with FFI-unwind ABI"
4007}
4008
4009declare_lint! {
4010 /// The `linker_messages` lint forwards warnings from the linker.
4011 ///
4012 /// ### Example
4013 ///
4014 /// ```rust,ignore (needs CLI args, platform-specific)
4015 /// #[warn(linker_messages)]
4016 /// extern "C" {
4017 /// fn foo();
4018 /// }
4019 /// fn main () { unsafe { foo(); } }
4020 /// ```
4021 ///
4022 /// On Linux, using `gcc -Wl,--warn-unresolved-symbols` as a linker, this will produce
4023 ///
4024 /// ```text
4025 /// warning: linker stderr: rust-lld: undefined symbol: foo
4026 /// >>> referenced by rust_out.69edbd30df4ae57d-cgu.0
4027 /// >>> rust_out.rust_out.69edbd30df4ae57d-cgu.0.rcgu.o:(rust_out::main::h3a90094b06757803)
4028 /// |
4029 /// note: the lint level is defined here
4030 /// --> warn.rs:1:9
4031 /// |
4032 /// 1 | #![warn(linker_messages)]
4033 /// | ^^^^^^^^^^^^^^^
4034 /// warning: 1 warning emitted
4035 /// ```
4036 ///
4037 /// ### Explanation
4038 ///
4039 /// Linkers emit platform-specific and program-specific warnings that cannot be predicted in
4040 /// advance by the Rust compiler. Such messages are ignored by default for now. While linker
4041 /// warnings could be very useful they have been ignored for many years by essentially all
4042 /// users, so we need to do a bit more work than just surfacing their text to produce a clear
4043 /// and actionable warning of similar quality to our other diagnostics. See this tracking
4044 /// issue for more details: <https://github.com/rust-lang/rust/issues/136096>.
4045 pub LINKER_MESSAGES,
4046 Allow,
4047 "warnings emitted at runtime by the target-specific linker program"
4048}
4049
4050declare_lint! {
4051 /// The `named_arguments_used_positionally` lint detects cases where named arguments are only
4052 /// used positionally in format strings. This usage is valid but potentially very confusing.
4053 ///
4054 /// ### Example
4055 ///
4056 /// ```rust,compile_fail
4057 /// #![deny(named_arguments_used_positionally)]
4058 /// fn main() {
4059 /// let _x = 5;
4060 /// println!("{}", _x = 1); // Prints 1, will trigger lint
4061 ///
4062 /// println!("{}", _x); // Prints 5, no lint emitted
4063 /// println!("{_x}", _x = _x); // Prints 5, no lint emitted
4064 /// }
4065 /// ```
4066 ///
4067 /// {{produces}}
4068 ///
4069 /// ### Explanation
4070 ///
4071 /// Rust formatting strings can refer to named arguments by their position, but this usage is
4072 /// potentially confusing. In particular, readers can incorrectly assume that the declaration
4073 /// of named arguments is an assignment (which would produce the unit type).
4074 /// For backwards compatibility, this is not a hard error.
4075 pub NAMED_ARGUMENTS_USED_POSITIONALLY,
4076 Warn,
4077 "named arguments in format used positionally"
4078}
4079
4080declare_lint! {
4081 /// The `never_type_fallback_flowing_into_unsafe` lint detects cases where never type fallback
4082 /// affects unsafe function calls.
4083 ///
4084 /// ### Never type fallback
4085 ///
4086 /// When the compiler sees a value of type [`!`] it implicitly inserts a coercion (if possible),
4087 /// to allow type check to infer any type:
4088 ///
4089 /// ```ignore (illustrative-and-has-placeholders)
4090 /// // this
4091 /// let x: u8 = panic!();
4092 ///
4093 /// // is (essentially) turned by the compiler into
4094 /// let x: u8 = absurd(panic!());
4095 ///
4096 /// // where absurd is a function with the following signature
4097 /// // (it's sound, because `!` always marks unreachable code):
4098 /// fn absurd<T>(never: !) -> T { ... }
4099 /// ```
4100 ///
4101 /// While it's convenient to be able to use non-diverging code in one of the branches (like
4102 /// `if a { b } else { return }`) this could lead to compilation errors:
4103 ///
4104 /// ```compile_fail
4105 /// // this
4106 /// { panic!() };
4107 ///
4108 /// // gets turned into this
4109 /// { absurd(panic!()) }; // error: can't infer the type of `absurd`
4110 /// ```
4111 ///
4112 /// To prevent such errors, compiler remembers where it inserted `absurd` calls, and if it
4113 /// can't infer their type, it sets the type to fallback. `{ absurd::<Fallback>(panic!()) };`.
4114 /// This is what is known as "never type fallback".
4115 ///
4116 /// ### Example
4117 ///
4118 /// ```rust,compile_fail
4119 /// fn main() {
4120 /// if true {
4121 /// // return has type `!` which, is some cases, causes never type fallback
4122 /// return
4123 /// } else {
4124 /// // `zeroed` is an unsafe function, which returns an unbounded type
4125 /// unsafe { std::mem::zeroed() }
4126 /// };
4127 /// // depending on the fallback, `zeroed` may create `()` (which is completely sound),
4128 /// // or `!` (which is instant undefined behavior)
4129 /// }
4130 /// ```
4131 ///
4132 /// {{produces}}
4133 ///
4134 /// ### Explanation
4135 ///
4136 /// Due to historic reasons never type fallback was `()`, meaning that `!` got spontaneously
4137 /// coerced to `()`. There are plans to change that, but they may make the code such as above
4138 /// unsound. Instead of depending on the fallback, you should specify the type explicitly:
4139 /// ```
4140 /// if true {
4141 /// return
4142 /// } else {
4143 /// // type is explicitly specified, fallback can't hurt us no more
4144 /// unsafe { std::mem::zeroed::<()>() }
4145 /// };
4146 /// ```
4147 ///
4148 /// See [Tracking Issue for making `!` fall back to `!`](https://github.com/rust-lang/rust/issues/123748).
4149 ///
4150 /// [`!`]: https://doc.rust-lang.org/core/primitive.never.html
4151 /// [`()`]: https://doc.rust-lang.org/core/primitive.unit.html
4152 pub NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
4153 Deny,
4154 "never type fallback affecting unsafe function calls",
4155 @future_incompatible = FutureIncompatibleInfo {
4156 reason: FutureIncompatibilityReason::EditionAndFutureReleaseSemanticsChange(Edition::Edition2024),
4157 reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>",
4158 report_in_deps: true,
4159 };
4160 @edition Edition2024 => Deny;
4161 report_in_external_macro
4162}
4163
4164declare_lint! {
4165 /// The `dependency_on_unit_never_type_fallback` lint detects cases where code compiles with
4166 /// [never type fallback] being [`()`], but will stop compiling with fallback being [`!`].
4167 ///
4168 /// [never type fallback]: https://doc.rust-lang.org/nightly/core/primitive.never.html#never-type-fallback
4169 /// [`!`]: https://doc.rust-lang.org/core/primitive.never.html
4170 /// [`()`]: https://doc.rust-lang.org/core/primitive.unit.html
4171 ///
4172 /// ### Example
4173 ///
4174 /// ```rust,compile_fail,edition2021
4175 /// # #![deny(dependency_on_unit_never_type_fallback)]
4176 /// fn main() {
4177 /// if true {
4178 /// // return has type `!` which, is some cases, causes never type fallback
4179 /// return
4180 /// } else {
4181 /// // the type produced by this call is not specified explicitly,
4182 /// // so it will be inferred from the previous branch
4183 /// Default::default()
4184 /// };
4185 /// // depending on the fallback, this may compile (because `()` implements `Default`),
4186 /// // or it may not (because `!` does not implement `Default`)
4187 /// }
4188 /// ```
4189 ///
4190 /// {{produces}}
4191 ///
4192 /// ### Explanation
4193 ///
4194 /// Due to historic reasons never type fallback was `()`, meaning that `!` got spontaneously
4195 /// coerced to `()`. There are plans to change that, but they may make the code such as above
4196 /// not compile. Instead of depending on the fallback, you should specify the type explicitly:
4197 /// ```
4198 /// if true {
4199 /// return
4200 /// } else {
4201 /// // type is explicitly specified, fallback can't hurt us no more
4202 /// <() as Default>::default()
4203 /// };
4204 /// ```
4205 ///
4206 /// See [Tracking Issue for making `!` fall back to `!`](https://github.com/rust-lang/rust/issues/123748).
4207 pub DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK,
4208 Deny,
4209 "never type fallback affecting unsafe function calls",
4210 @future_incompatible = FutureIncompatibleInfo {
4211 reason: FutureIncompatibilityReason::EditionAndFutureReleaseError(Edition::Edition2024),
4212 reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/never-type-fallback.html>",
4213 report_in_deps: true,
4214 };
4215 report_in_external_macro
4216}
4217
4218declare_lint! {
4219 /// The `invalid_macro_export_arguments` lint detects cases where `#[macro_export]` is being used with invalid arguments.
4220 ///
4221 /// ### Example
4222 ///
4223 /// ```rust,compile_fail
4224 /// #![deny(invalid_macro_export_arguments)]
4225 ///
4226 /// #[macro_export(invalid_parameter)]
4227 /// macro_rules! myMacro {
4228 /// () => {
4229 /// // [...]
4230 /// }
4231 /// }
4232 ///
4233 /// #[macro_export(too, many, items)]
4234 /// ```
4235 ///
4236 /// {{produces}}
4237 ///
4238 /// ### Explanation
4239 ///
4240 /// The only valid argument is `#[macro_export(local_inner_macros)]` or no argument (`#[macro_export]`).
4241 /// You can't have multiple arguments in a `#[macro_export(..)]`, or mention arguments other than `local_inner_macros`.
4242 ///
4243 pub INVALID_MACRO_EXPORT_ARGUMENTS,
4244 Deny,
4245 "\"invalid_parameter\" isn't a valid argument for `#[macro_export]`",
4246 @future_incompatible = FutureIncompatibleInfo {
4247 reason: FutureIncompatibilityReason::FutureReleaseError,
4248 reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
4249 report_in_deps: true,
4250 };
4251}
4252
4253declare_lint! {
4254 /// The `private_interfaces` lint detects types in a primary interface of an item,
4255 /// that are more private than the item itself. Primary interface of an item is all
4256 /// its interface except for bounds on generic parameters and where clauses.
4257 ///
4258 /// ### Example
4259 ///
4260 /// ```rust,compile_fail
4261 /// # #![allow(unused)]
4262 /// #![deny(private_interfaces)]
4263 /// struct SemiPriv;
4264 ///
4265 /// mod m1 {
4266 /// struct Priv;
4267 /// impl crate::SemiPriv {
4268 /// pub fn f(_: Priv) {}
4269 /// }
4270 /// }
4271 ///
4272 /// # fn main() {}
4273 /// ```
4274 ///
4275 /// {{produces}}
4276 ///
4277 /// ### Explanation
4278 ///
4279 /// Having something private in primary interface guarantees that
4280 /// the item will be unusable from outer modules due to type privacy.
4281 pub PRIVATE_INTERFACES,
4282 Warn,
4283 "private type in primary interface of an item",
4284}
4285
4286declare_lint! {
4287 /// The `private_bounds` lint detects types in a secondary interface of an item,
4288 /// that are more private than the item itself. Secondary interface of an item consists of
4289 /// bounds on generic parameters and where clauses, including supertraits for trait items.
4290 ///
4291 /// ### Example
4292 ///
4293 /// ```rust,compile_fail
4294 /// # #![allow(unused)]
4295 /// #![deny(private_bounds)]
4296 ///
4297 /// struct PrivTy;
4298 /// pub struct S
4299 /// where PrivTy:
4300 /// {}
4301 /// # fn main() {}
4302 /// ```
4303 ///
4304 /// {{produces}}
4305 ///
4306 /// ### Explanation
4307 ///
4308 /// Having private types or traits in item bounds makes it less clear what interface
4309 /// the item actually provides.
4310 pub PRIVATE_BOUNDS,
4311 Warn,
4312 "private type in secondary interface of an item",
4313}
4314
4315declare_lint! {
4316 /// The `unnameable_types` lint detects types for which you can get objects of that type,
4317 /// but cannot name the type itself.
4318 ///
4319 /// ### Example
4320 ///
4321 /// ```rust,compile_fail
4322 /// # #![allow(unused)]
4323 /// #![deny(unnameable_types)]
4324 /// mod m {
4325 /// pub struct S;
4326 /// }
4327 ///
4328 /// pub fn get_unnameable() -> m::S { m::S }
4329 /// # fn main() {}
4330 /// ```
4331 ///
4332 /// {{produces}}
4333 ///
4334 /// ### Explanation
4335 ///
4336 /// It is often expected that if you can obtain an object of type `T`, then
4337 /// you can name the type `T` as well; this lint attempts to enforce this rule.
4338 /// The recommended action is to either reexport the type properly to make it nameable,
4339 /// or document that users are not supposed to be able to name it for one reason or another.
4340 ///
4341 /// Besides types, this lint applies to traits because traits can also leak through signatures,
4342 /// and you may obtain objects of their `dyn Trait` or `impl Trait` types.
4343 pub UNNAMEABLE_TYPES,
4344 Allow,
4345 "effective visibility of a type is larger than the area in which it can be named",
4346}
4347
4348declare_lint! {
4349 /// The `malformed_diagnostic_attributes` lint detects malformed diagnostic attributes.
4350 ///
4351 /// ### Example
4352 ///
4353 /// ```rust
4354 /// #[diagnostic::do_not_recommend(message = "message")]
4355 /// trait Trait {}
4356 /// ```
4357 ///
4358 /// {{produces}}
4359 ///
4360 /// ### Explanation
4361 ///
4362 /// It is usually a mistake to use options or syntax that is not supported. Check the spelling,
4363 /// and check the diagnostic attribute listing for the correct name and syntax. Also consider if
4364 /// you are using an old version of the compiler; perhaps the option or syntax is only available
4365 /// in a newer version. See the [reference] for a list of diagnostic attributes and the syntax
4366 /// of each.
4367 ///
4368 /// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4369 pub MALFORMED_DIAGNOSTIC_ATTRIBUTES,
4370 Warn,
4371 "detects malformed diagnostic attributes",
4372}
4373
4374declare_lint! {
4375 /// The `misplaced_diagnostic_attributes` lint detects wrongly placed diagnostic attributes.
4376 ///
4377 /// ### Example
4378 ///
4379 /// ```rust
4380 /// #[diagnostic::do_not_recommend]
4381 /// struct NotUserFacing;
4382 /// ```
4383 ///
4384 /// {{produces}}
4385 ///
4386 /// ### Explanation
4387 ///
4388 /// It is usually a mistake to specify a diagnostic attribute on an item it is not meant for.
4389 /// For example, `#[diagnostic::do_not_recommend]` can only be placed on trait implementations,
4390 /// and does nothing if placed elsewhere. See the [reference] for a list of diagnostic
4391 /// attributes and their correct positions.
4392 ///
4393 /// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4394 pub MISPLACED_DIAGNOSTIC_ATTRIBUTES,
4395 Warn,
4396 "detects diagnostic attributes that are placed on the wrong item",
4397}
4398
4399declare_lint! {
4400 /// The `unknown_diagnostic_attributes` lint detects unknown diagnostic attributes.
4401 ///
4402 /// ### Example
4403 ///
4404 /// ```rust
4405 /// #[diagnostic::does_not_exist]
4406 /// struct Thing;
4407 /// ```
4408 ///
4409 /// {{produces}}
4410 ///
4411 /// ### Explanation
4412 ///
4413 /// It is usually a mistake to specify a diagnostic attribute that does not exist. Check the
4414 /// spelling, and check the diagnostic attribute listing for the correct name. Also consider if
4415 /// you are using an old version of the compiler and the attribute is only available in a newer
4416 /// version. See the [reference] for the list of diagnostic attributes.
4417 ///
4418 /// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4419 pub UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
4420 Warn,
4421 "detects unknown diagnostic attributes",
4422}
4423
4424declare_lint! {
4425 /// The `malformed_diagnostic_format_literals` lint detects malformed diagnostic format
4426 /// literals.
4427 ///
4428 /// ### Example
4429 ///
4430 /// ```rust
4431 /// #[diagnostic::on_unimplemented(message = "{Self}} does not implement `Trait`")]
4432 /// trait Trait {}
4433 /// ```
4434 ///
4435 /// {{produces}}
4436 ///
4437 /// ### Explanation
4438 ///
4439 /// The `#[diagnostic::on_unimplemented]` attribute accepts string literal values that are
4440 /// similar to `format!`'s string literal. See the [reference] for details on what is permitted
4441 /// in this string literal.
4442 ///
4443 /// [reference]: https://doc.rust-lang.org/nightly/reference/attributes/diagnostics.html#the-diagnostic-tool-attribute-namespace
4444 pub MALFORMED_DIAGNOSTIC_FORMAT_LITERALS,
4445 Warn,
4446 "detects diagnostic attribute with malformed diagnostic format literals",
4447}
4448declare_lint! {
4449 /// The `ambiguous_glob_imports` lint detects glob imports that should report ambiguity
4450 /// errors, but previously didn't do that due to rustc bugs.
4451 ///
4452 /// ### Example
4453 ///
4454 /// ```rust,compile_fail
4455 /// #![deny(ambiguous_glob_imports)]
4456 /// pub fn foo() -> u32 {
4457 /// use sub::*;
4458 /// C
4459 /// }
4460 ///
4461 /// mod sub {
4462 /// mod mod1 { pub const C: u32 = 1; }
4463 /// mod mod2 { pub const C: u32 = 2; }
4464 ///
4465 /// pub use mod1::*;
4466 /// pub use mod2::*;
4467 /// }
4468 /// ```
4469 ///
4470 /// {{produces}}
4471 ///
4472 /// ### Explanation
4473 ///
4474 /// Previous versions of Rust compile it successfully because it
4475 /// had lost the ambiguity error when resolve `use sub::mod2::*`.
4476 ///
4477 /// This is a [future-incompatible] lint to transition this to a
4478 /// hard error in the future.
4479 ///
4480 /// [future-incompatible]: ../index.md#future-incompatible-lints
4481 pub AMBIGUOUS_GLOB_IMPORTS,
4482 Deny,
4483 "detects certain glob imports that require reporting an ambiguity error",
4484 @future_incompatible = FutureIncompatibleInfo {
4485 reason: FutureIncompatibilityReason::FutureReleaseError,
4486 reference: "issue #114095 <https://github.com/rust-lang/rust/issues/114095>",
4487 report_in_deps: true,
4488 };
4489}
4490
4491declare_lint! {
4492 /// The `refining_impl_trait_reachable` lint detects `impl Trait` return
4493 /// types in method signatures that are refined by a publically reachable
4494 /// trait implementation, meaning the implementation adds information about
4495 /// the return type that is not present in the trait.
4496 ///
4497 /// ### Example
4498 ///
4499 /// ```rust,compile_fail
4500 /// #![deny(refining_impl_trait)]
4501 ///
4502 /// use std::fmt::Display;
4503 ///
4504 /// pub trait AsDisplay {
4505 /// fn as_display(&self) -> impl Display;
4506 /// }
4507 ///
4508 /// impl<'s> AsDisplay for &'s str {
4509 /// fn as_display(&self) -> Self {
4510 /// *self
4511 /// }
4512 /// }
4513 ///
4514 /// fn main() {
4515 /// // users can observe that the return type of
4516 /// // `<&str as AsDisplay>::as_display()` is `&str`.
4517 /// let _x: &str = "".as_display();
4518 /// }
4519 /// ```
4520 ///
4521 /// {{produces}}
4522 ///
4523 /// ### Explanation
4524 ///
4525 /// Callers of methods for types where the implementation is known are
4526 /// able to observe the types written in the impl signature. This may be
4527 /// intended behavior, but may also lead to implementation details being
4528 /// revealed unintentionally. In particular, it may pose a semver hazard
4529 /// for authors of libraries who do not wish to make stronger guarantees
4530 /// about the types than what is written in the trait signature.
4531 ///
4532 /// `refining_impl_trait` is a lint group composed of two lints:
4533 ///
4534 /// * `refining_impl_trait_reachable`, for refinements that are publically
4535 /// reachable outside a crate, and
4536 /// * `refining_impl_trait_internal`, for refinements that are only visible
4537 /// within a crate.
4538 ///
4539 /// We are seeking feedback on each of these lints; see issue
4540 /// [#121718](https://github.com/rust-lang/rust/issues/121718) for more
4541 /// information.
4542 pub REFINING_IMPL_TRAIT_REACHABLE,
4543 Warn,
4544 "impl trait in impl method signature does not match trait method signature",
4545}
4546
4547declare_lint! {
4548 /// The `refining_impl_trait_internal` lint detects `impl Trait` return
4549 /// types in method signatures that are refined by a trait implementation,
4550 /// meaning the implementation adds information about the return type that
4551 /// is not present in the trait.
4552 ///
4553 /// ### Example
4554 ///
4555 /// ```rust,compile_fail
4556 /// #![deny(refining_impl_trait)]
4557 ///
4558 /// use std::fmt::Display;
4559 ///
4560 /// trait AsDisplay {
4561 /// fn as_display(&self) -> impl Display;
4562 /// }
4563 ///
4564 /// impl<'s> AsDisplay for &'s str {
4565 /// fn as_display(&self) -> Self {
4566 /// *self
4567 /// }
4568 /// }
4569 ///
4570 /// fn main() {
4571 /// // users can observe that the return type of
4572 /// // `<&str as AsDisplay>::as_display()` is `&str`.
4573 /// let _x: &str = "".as_display();
4574 /// }
4575 /// ```
4576 ///
4577 /// {{produces}}
4578 ///
4579 /// ### Explanation
4580 ///
4581 /// Callers of methods for types where the implementation is known are
4582 /// able to observe the types written in the impl signature. This may be
4583 /// intended behavior, but may also lead to implementation details being
4584 /// revealed unintentionally. In particular, it may pose a semver hazard
4585 /// for authors of libraries who do not wish to make stronger guarantees
4586 /// about the types than what is written in the trait signature.
4587 ///
4588 /// `refining_impl_trait` is a lint group composed of two lints:
4589 ///
4590 /// * `refining_impl_trait_reachable`, for refinements that are publically
4591 /// reachable outside a crate, and
4592 /// * `refining_impl_trait_internal`, for refinements that are only visible
4593 /// within a crate.
4594 ///
4595 /// We are seeking feedback on each of these lints; see issue
4596 /// [#121718](https://github.com/rust-lang/rust/issues/121718) for more
4597 /// information.
4598 pub REFINING_IMPL_TRAIT_INTERNAL,
4599 Warn,
4600 "impl trait in impl method signature does not match trait method signature",
4601}
4602
4603declare_lint! {
4604 /// The `elided_lifetimes_in_associated_constant` lint detects elided lifetimes
4605 /// in associated constants when there are other lifetimes in scope. This was
4606 /// accidentally supported, and this lint was later relaxed to allow eliding
4607 /// lifetimes to `'static` when there are no lifetimes in scope.
4608 ///
4609 /// ### Example
4610 ///
4611 /// ```rust,compile_fail
4612 /// #![deny(elided_lifetimes_in_associated_constant)]
4613 ///
4614 /// struct Foo<'a>(&'a ());
4615 ///
4616 /// impl<'a> Foo<'a> {
4617 /// const STR: &str = "hello, world";
4618 /// }
4619 /// ```
4620 ///
4621 /// {{produces}}
4622 ///
4623 /// ### Explanation
4624 ///
4625 /// Previous version of Rust
4626 ///
4627 /// Implicit static-in-const behavior was decided [against] for associated
4628 /// constants because of ambiguity. This, however, regressed and the compiler
4629 /// erroneously treats elided lifetimes in associated constants as lifetime
4630 /// parameters on the impl.
4631 ///
4632 /// This is a [future-incompatible] lint to transition this to a
4633 /// hard error in the future.
4634 ///
4635 /// [against]: https://github.com/rust-lang/rust/issues/38831
4636 /// [future-incompatible]: ../index.md#future-incompatible-lints
4637 pub ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT,
4638 Deny,
4639 "elided lifetimes cannot be used in associated constants in impls",
4640 @future_incompatible = FutureIncompatibleInfo {
4641 reason: FutureIncompatibilityReason::FutureReleaseError,
4642 reference: "issue #115010 <https://github.com/rust-lang/rust/issues/115010>",
4643 };
4644}
4645
4646declare_lint! {
4647 /// The `private_macro_use` lint detects private macros that are imported
4648 /// with `#[macro_use]`.
4649 ///
4650 /// ### Example
4651 ///
4652 /// ```rust,ignore (needs extern crate)
4653 /// // extern_macro.rs
4654 /// macro_rules! foo_ { () => {}; }
4655 /// use foo_ as foo;
4656 ///
4657 /// // code.rs
4658 ///
4659 /// #![deny(private_macro_use)]
4660 ///
4661 /// #[macro_use]
4662 /// extern crate extern_macro;
4663 ///
4664 /// fn main() {
4665 /// foo!();
4666 /// }
4667 /// ```
4668 ///
4669 /// This will produce:
4670 ///
4671 /// ```text
4672 /// error: cannot find macro `foo` in this scope
4673 /// ```
4674 ///
4675 /// ### Explanation
4676 ///
4677 /// This lint arises from overlooking visibility checks for macros
4678 /// in an external crate.
4679 ///
4680 /// This is a [future-incompatible] lint to transition this to a
4681 /// hard error in the future.
4682 ///
4683 /// [future-incompatible]: ../index.md#future-incompatible-lints
4684 pub PRIVATE_MACRO_USE,
4685 Deny,
4686 "detects certain macro bindings that should not be re-exported",
4687 @future_incompatible = FutureIncompatibleInfo {
4688 reason: FutureIncompatibilityReason::FutureReleaseError,
4689 reference: "issue #120192 <https://github.com/rust-lang/rust/issues/120192>",
4690 report_in_deps: true,
4691 };
4692}
4693
4694declare_lint! {
4695 /// The `uncovered_param_in_projection` lint detects a violation of one of Rust's orphan rules for
4696 /// foreign trait implementations that concerns the use of type parameters inside trait associated
4697 /// type paths ("projections") whose output may not be a local type that is mistakenly considered
4698 /// to "cover" said parameters which is **unsound** and which may be rejected by a future version
4699 /// of the compiler.
4700 ///
4701 /// Originally reported in [#99554].
4702 ///
4703 /// [#99554]: https://github.com/rust-lang/rust/issues/99554
4704 ///
4705 /// ### Example
4706 ///
4707 /// ```rust,ignore (dependent)
4708 /// // dependency.rs
4709 /// #![crate_type = "lib"]
4710 ///
4711 /// pub trait Trait<T, U> {}
4712 /// ```
4713 ///
4714 /// ```edition2021,ignore (needs dependency)
4715 /// // dependent.rs
4716 /// trait Identity {
4717 /// type Output;
4718 /// }
4719 ///
4720 /// impl<T> Identity for T {
4721 /// type Output = T;
4722 /// }
4723 ///
4724 /// struct Local;
4725 ///
4726 /// impl<T> dependency::Trait<Local, T> for <T as Identity>::Output {}
4727 ///
4728 /// fn main() {}
4729 /// ```
4730 ///
4731 /// This will produce:
4732 ///
4733 /// ```text
4734 /// warning[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
4735 /// --> dependent.rs:11:6
4736 /// |
4737 /// 11 | impl<T> dependency::Trait<Local, T> for <T as Identity>::Output {}
4738 /// | ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
4739 /// |
4740 /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
4741 /// = note: for more information, see issue #124559 <https://github.com/rust-lang/rust/issues/124559>
4742 /// = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
4743 /// = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
4744 /// = note: `#[warn(uncovered_param_in_projection)]` on by default
4745 /// ```
4746 ///
4747 /// ### Explanation
4748 ///
4749 /// FIXME(fmease): Write explainer.
4750 pub UNCOVERED_PARAM_IN_PROJECTION,
4751 Warn,
4752 "impl contains type parameters that are not covered",
4753 @future_incompatible = FutureIncompatibleInfo {
4754 reason: FutureIncompatibilityReason::FutureReleaseError,
4755 reference: "issue #124559 <https://github.com/rust-lang/rust/issues/124559>",
4756 };
4757}
4758
4759declare_lint! {
4760 /// The `deprecated_safe_2024` lint detects unsafe functions being used as
4761 /// safe functions.
4762 ///
4763 /// ### Example
4764 ///
4765 /// ```rust,edition2021,compile_fail
4766 /// #![deny(deprecated_safe)]
4767 /// // edition 2021
4768 /// use std::env;
4769 /// fn enable_backtrace() {
4770 /// env::set_var("RUST_BACKTRACE", "1");
4771 /// }
4772 /// ```
4773 ///
4774 /// {{produces}}
4775 ///
4776 /// ### Explanation
4777 ///
4778 /// Rust [editions] allow the language to evolve without breaking backward
4779 /// compatibility. This lint catches code that uses `unsafe` functions that
4780 /// were declared as safe (non-`unsafe`) in editions prior to Rust 2024. If
4781 /// you switch the compiler to Rust 2024 without updating the code, then it
4782 /// will fail to compile if you are using a function previously marked as
4783 /// safe.
4784 ///
4785 /// You can audit the code to see if it suffices the preconditions of the
4786 /// `unsafe` code, and if it does, you can wrap it in an `unsafe` block. If
4787 /// you can't fulfill the preconditions, you probably need to switch to a
4788 /// different way of doing what you want to achieve.
4789 ///
4790 /// This lint can automatically wrap the calls in `unsafe` blocks, but this
4791 /// obviously cannot verify that the preconditions of the `unsafe`
4792 /// functions are fulfilled, so that is still up to the user.
4793 ///
4794 /// The lint is currently "allow" by default, but that might change in the
4795 /// future.
4796 ///
4797 /// [editions]: https://doc.rust-lang.org/edition-guide/
4798 pub DEPRECATED_SAFE_2024,
4799 Allow,
4800 "detects unsafe functions being used as safe functions",
4801 @future_incompatible = FutureIncompatibleInfo {
4802 reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
4803 reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/newly-unsafe-functions.html>",
4804 };
4805}
4806
4807declare_lint! {
4808 /// The `missing_unsafe_on_extern` lint detects missing unsafe keyword on extern declarations.
4809 ///
4810 /// ### Example
4811 ///
4812 /// ```rust,edition2021
4813 /// #![warn(missing_unsafe_on_extern)]
4814 /// #![allow(dead_code)]
4815 ///
4816 /// extern "C" {
4817 /// fn foo(_: i32);
4818 /// }
4819 ///
4820 /// fn main() {}
4821 /// ```
4822 ///
4823 /// {{produces}}
4824 ///
4825 /// ### Explanation
4826 ///
4827 /// Declaring extern items, even without ever using them, can cause Undefined Behavior. We
4828 /// should consider all sources of Undefined Behavior to be unsafe.
4829 ///
4830 /// This is a [future-incompatible] lint to transition this to a
4831 /// hard error in the future.
4832 ///
4833 /// [future-incompatible]: ../index.md#future-incompatible-lints
4834 pub MISSING_UNSAFE_ON_EXTERN,
4835 Allow,
4836 "detects missing unsafe keyword on extern declarations",
4837 @future_incompatible = FutureIncompatibleInfo {
4838 reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
4839 reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-extern.html>",
4840 };
4841}
4842
4843declare_lint! {
4844 /// The `unsafe_attr_outside_unsafe` lint detects a missing unsafe keyword
4845 /// on attributes considered unsafe.
4846 ///
4847 /// ### Example
4848 ///
4849 /// ```rust,edition2021
4850 /// #![warn(unsafe_attr_outside_unsafe)]
4851 ///
4852 /// #[no_mangle]
4853 /// extern "C" fn foo() {}
4854 ///
4855 /// fn main() {}
4856 /// ```
4857 ///
4858 /// {{produces}}
4859 ///
4860 /// ### Explanation
4861 ///
4862 /// Some attributes (e.g. `no_mangle`, `export_name`, `link_section` -- see
4863 /// [issue #82499] for a more complete list) are considered "unsafe" attributes.
4864 /// An unsafe attribute must only be used inside unsafe(...).
4865 ///
4866 /// This lint can automatically wrap the attributes in `unsafe(...)` , but this
4867 /// obviously cannot verify that the preconditions of the `unsafe`
4868 /// attributes are fulfilled, so that is still up to the user.
4869 ///
4870 /// The lint is currently "allow" by default, but that might change in the
4871 /// future.
4872 ///
4873 /// [editions]: https://doc.rust-lang.org/edition-guide/
4874 /// [issue #82499]: https://github.com/rust-lang/rust/issues/82499
4875 pub UNSAFE_ATTR_OUTSIDE_UNSAFE,
4876 Allow,
4877 "detects unsafe attributes outside of unsafe",
4878 @future_incompatible = FutureIncompatibleInfo {
4879 reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
4880 reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/unsafe-attributes.html>",
4881 };
4882}
4883
4884declare_lint! {
4885 /// The `out_of_scope_macro_calls` lint detects `macro_rules` called when they are not in scope,
4886 /// above their definition, which may happen in key-value attributes.
4887 ///
4888 /// ### Example
4889 ///
4890 /// ```rust,compile_fail
4891 /// #![doc = in_root!()]
4892 ///
4893 /// macro_rules! in_root { () => { "" } }
4894 ///
4895 /// fn main() {}
4896 /// ```
4897 ///
4898 /// {{produces}}
4899 ///
4900 /// ### Explanation
4901 ///
4902 /// The scope in which a `macro_rules` item is visible starts at that item and continues
4903 /// below it. This is more similar to `let` than to other items, which are in scope both above
4904 /// and below their definition.
4905 /// Due to a bug `macro_rules` were accidentally in scope inside some key-value attributes
4906 /// above their definition. The lint catches such cases.
4907 /// To address the issue turn the `macro_rules` into a regularly scoped item by importing it
4908 /// with `use`.
4909 ///
4910 /// This is a [future-incompatible] lint to transition this to a
4911 /// hard error in the future.
4912 ///
4913 /// [future-incompatible]: ../index.md#future-incompatible-lints
4914 pub OUT_OF_SCOPE_MACRO_CALLS,
4915 Deny,
4916 "detects out of scope calls to `macro_rules` in key-value attributes",
4917 @future_incompatible = FutureIncompatibleInfo {
4918 reason: FutureIncompatibilityReason::FutureReleaseError,
4919 reference: "issue #124535 <https://github.com/rust-lang/rust/issues/124535>",
4920 report_in_deps: true,
4921 };
4922}
4923
4924declare_lint! {
4925 /// The `supertrait_item_shadowing_usage` lint detects when the
4926 /// usage of an item that is provided by both a subtrait and supertrait
4927 /// is shadowed, preferring the subtrait.
4928 ///
4929 /// ### Example
4930 ///
4931 /// ```rust,compile_fail
4932 /// #![feature(supertrait_item_shadowing)]
4933 /// #![deny(supertrait_item_shadowing_usage)]
4934 ///
4935 /// trait Upstream {
4936 /// fn hello(&self) {}
4937 /// }
4938 /// impl<T> Upstream for T {}
4939 ///
4940 /// trait Downstream: Upstream {
4941 /// fn hello(&self) {}
4942 /// }
4943 /// impl<T> Downstream for T {}
4944 ///
4945 /// struct MyType;
4946 /// MyType.hello();
4947 /// ```
4948 ///
4949 /// {{produces}}
4950 ///
4951 /// ### Explanation
4952 ///
4953 /// RFC 3624 specified a heuristic in which a supertrait item would be
4954 /// shadowed by a subtrait item when ambiguity occurs during item
4955 /// selection. In order to mitigate side-effects of this happening
4956 /// silently, this lint detects these cases when users want to deny them
4957 /// or fix the call sites.
4958 pub SUPERTRAIT_ITEM_SHADOWING_USAGE,
4959 // FIXME(supertrait_item_shadowing): It is not decided if this should
4960 // warn by default at the call site.
4961 Allow,
4962 "detects when a supertrait item is shadowed by a subtrait item",
4963 @feature_gate = supertrait_item_shadowing;
4964}
4965
4966declare_lint! {
4967 /// The `supertrait_item_shadowing_definition` lint detects when the
4968 /// definition of an item that is provided by both a subtrait and
4969 /// supertrait is shadowed, preferring the subtrait.
4970 ///
4971 /// ### Example
4972 ///
4973 /// ```rust,compile_fail
4974 /// #![feature(supertrait_item_shadowing)]
4975 /// #![deny(supertrait_item_shadowing_definition)]
4976 ///
4977 /// trait Upstream {
4978 /// fn hello(&self) {}
4979 /// }
4980 /// impl<T> Upstream for T {}
4981 ///
4982 /// trait Downstream: Upstream {
4983 /// fn hello(&self) {}
4984 /// }
4985 /// impl<T> Downstream for T {}
4986 /// ```
4987 ///
4988 /// {{produces}}
4989 ///
4990 /// ### Explanation
4991 ///
4992 /// RFC 3624 specified a heuristic in which a supertrait item would be
4993 /// shadowed by a subtrait item when ambiguity occurs during item
4994 /// selection. In order to mitigate side-effects of this happening
4995 /// silently, this lint detects these cases when users want to deny them
4996 /// or fix their trait definitions.
4997 pub SUPERTRAIT_ITEM_SHADOWING_DEFINITION,
4998 // FIXME(supertrait_item_shadowing): It is not decided if this should
4999 // warn by default at the usage site.
5000 Allow,
5001 "detects when a supertrait item is shadowed by a subtrait item",
5002 @feature_gate = supertrait_item_shadowing;
5003}
5004
5005declare_lint! {
5006 /// The `tail_expr_drop_order` lint looks for those values generated at the tail expression location,
5007 /// that runs a custom `Drop` destructor.
5008 /// Some of them may be dropped earlier in Edition 2024 that they used to in Edition 2021 and prior.
5009 /// This lint detects those cases and provides you information on those values and their custom destructor implementations.
5010 /// Your discretion on this information is required.
5011 ///
5012 /// ### Example
5013 /// ```rust,edition2021
5014 /// #![warn(tail_expr_drop_order)]
5015 /// struct Droppy(i32);
5016 /// impl Droppy {
5017 /// fn get(&self) -> i32 {
5018 /// self.0
5019 /// }
5020 /// }
5021 /// impl Drop for Droppy {
5022 /// fn drop(&mut self) {
5023 /// // This is a custom destructor and it induces side-effects that is observable
5024 /// // especially when the drop order at a tail expression changes.
5025 /// println!("loud drop {}", self.0);
5026 /// }
5027 /// }
5028 /// fn edition_2021() -> i32 {
5029 /// let another_droppy = Droppy(0);
5030 /// Droppy(1).get()
5031 /// }
5032 /// fn main() {
5033 /// edition_2021();
5034 /// }
5035 /// ```
5036 ///
5037 /// {{produces}}
5038 ///
5039 /// ### Explanation
5040 ///
5041 /// In tail expression of blocks or function bodies,
5042 /// values of type with significant `Drop` implementation has an ill-specified drop order
5043 /// before Edition 2024 so that they are dropped only after dropping local variables.
5044 /// Edition 2024 introduces a new rule with drop orders for them,
5045 /// so that they are dropped first before dropping local variables.
5046 ///
5047 /// A significant `Drop::drop` destructor here refers to an explicit, arbitrary
5048 /// implementation of the `Drop` trait on the type, with exceptions including `Vec`,
5049 /// `Box`, `Rc`, `BTreeMap` and `HashMap` that are marked by the compiler otherwise
5050 /// so long that the generic types have no significant destructor recursively.
5051 /// In other words, a type has a significant drop destructor when it has a `Drop` implementation
5052 /// or its destructor invokes a significant destructor on a type.
5053 /// Since we cannot completely reason about the change by just inspecting the existence of
5054 /// a significant destructor, this lint remains only a suggestion and is set to `allow` by default.
5055 ///
5056 /// This lint only points out the issue with `Droppy`, which will be dropped before `another_droppy`
5057 /// does in Edition 2024.
5058 /// No fix will be proposed by this lint.
5059 /// However, the most probable fix is to hoist `Droppy` into its own local variable binding.
5060 /// ```rust
5061 /// struct Droppy(i32);
5062 /// impl Droppy {
5063 /// fn get(&self) -> i32 {
5064 /// self.0
5065 /// }
5066 /// }
5067 /// fn edition_2024() -> i32 {
5068 /// let value = Droppy(0);
5069 /// let another_droppy = Droppy(1);
5070 /// value.get()
5071 /// }
5072 /// ```
5073 pub TAIL_EXPR_DROP_ORDER,
5074 Allow,
5075 "Detect and warn on significant change in drop order in tail expression location",
5076 @future_incompatible = FutureIncompatibleInfo {
5077 reason: FutureIncompatibilityReason::EditionSemanticsChange(Edition::Edition2024),
5078 reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/temporary-tail-expr-scope.html>",
5079 };
5080}
5081
5082declare_lint! {
5083 /// The `rust_2024_guarded_string_incompatible_syntax` lint detects `#` tokens
5084 /// that will be parsed as part of a guarded string literal in Rust 2024.
5085 ///
5086 /// ### Example
5087 ///
5088 /// ```rust,edition2021,compile_fail
5089 /// #![deny(rust_2024_guarded_string_incompatible_syntax)]
5090 ///
5091 /// macro_rules! m {
5092 /// (# $x:expr #) => ();
5093 /// (# $x:expr) => ();
5094 /// }
5095 ///
5096 /// m!(#"hey"#);
5097 /// m!(#"hello");
5098 /// ```
5099 ///
5100 /// {{produces}}
5101 ///
5102 /// ### Explanation
5103 ///
5104 /// Prior to Rust 2024, `#"hey"#` is three tokens: the first `#`
5105 /// followed by the string literal `"hey"` then the final `#`.
5106 /// In Rust 2024, the whole sequence is considered a single token.
5107 ///
5108 /// This lint suggests to add whitespace between the leading `#`
5109 /// and the string to keep them separated in Rust 2024.
5110 // Allow this lint -- rustdoc doesn't yet support threading edition into this lint's parser.
5111 #[allow(rustdoc::invalid_rust_codeblocks)]
5112 pub RUST_2024_GUARDED_STRING_INCOMPATIBLE_SYNTAX,
5113 Allow,
5114 "will be parsed as a guarded string in Rust 2024",
5115 @future_incompatible = FutureIncompatibleInfo {
5116 reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
5117 reference: "<https://doc.rust-lang.org/edition-guide/rust-2024/reserved-syntax.html>",
5118 };
5119 crate_level_only
5120}
5121
5122declare_lint! {
5123 /// The `aarch64_softfloat_neon` lint detects usage of `#[target_feature(enable = "neon")]` on
5124 /// softfloat aarch64 targets. Enabling this target feature causes LLVM to alter the ABI of
5125 /// function calls, making this attribute unsound to use.
5126 ///
5127 /// ### Example
5128 ///
5129 /// ```rust,ignore (needs aarch64-unknown-none-softfloat)
5130 /// #[target_feature(enable = "neon")]
5131 /// fn with_neon() {}
5132 /// ```
5133 ///
5134 /// This will produce:
5135 ///
5136 /// ```text
5137 /// error: enabling the `neon` target feature on the current target is unsound due to ABI issues
5138 /// --> $DIR/abi-incompatible-target-feature-attribute-fcw.rs:11:18
5139 /// |
5140 /// | #[target_feature(enable = "neon")]
5141 /// | ^^^^^^^^^^^^^^^
5142 /// |
5143 /// = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
5144 /// = note: for more information, see issue #134375 <https://github.com/rust-lang/rust/issues/134375>
5145 /// ```
5146 ///
5147 /// ### Explanation
5148 ///
5149 /// If a function like `with_neon` above ends up containing calls to LLVM builtins, those will
5150 /// not use the correct ABI. This is caused by a lack of support in LLVM for mixing code with
5151 /// and without the `neon` target feature. The target feature should never have been stabilized
5152 /// on this target due to this issue, but the problem was not known at the time of
5153 /// stabilization.
5154 pub AARCH64_SOFTFLOAT_NEON,
5155 Warn,
5156 "detects code that could be affected by ABI issues on aarch64 softfloat targets",
5157 @future_incompatible = FutureIncompatibleInfo {
5158 reason: FutureIncompatibilityReason::FutureReleaseError,
5159 reference: "issue #134375 <https://github.com/rust-lang/rust/issues/134375>",
5160 report_in_deps: true,
5161 };
5162}
5163
5164declare_lint! {
5165 /// The `tail_call_track_caller` lint detects usage of `become` attempting to tail call
5166 /// a function marked with `#[track_caller]`.
5167 ///
5168 /// ### Example
5169 ///
5170 /// ```rust
5171 /// #![feature(explicit_tail_calls)]
5172 /// #![expect(incomplete_features)]
5173 ///
5174 /// #[track_caller]
5175 /// fn f() {}
5176 ///
5177 /// fn g() {
5178 /// become f();
5179 /// }
5180 ///
5181 /// g();
5182 /// ```
5183 ///
5184 /// {{produces}}
5185 ///
5186 /// ### Explanation
5187 ///
5188 /// Due to implementation details of tail calls and `#[track_caller]` attribute, calls to
5189 /// functions marked with `#[track_caller]` cannot become tail calls. As such using `become`
5190 /// is no different than a normal call (except for changes in drop order).
5191 pub TAIL_CALL_TRACK_CALLER,
5192 Warn,
5193 "detects tail calls of functions marked with `#[track_caller]`",
5194 @feature_gate = explicit_tail_calls;
5195}
5196declare_lint! {
5197 /// The `inline_always_mismatching_target_features` lint will trigger when a
5198 /// function with the `#[inline(always)]` and `#[target_feature(enable = "...")]`
5199 /// attributes is called and cannot be inlined due to missing target features in the caller.
5200 ///
5201 /// ### Example
5202 ///
5203 /// ```rust,ignore (fails on x86_64)
5204 /// #[inline(always)]
5205 /// #[target_feature(enable = "fp16")]
5206 /// unsafe fn callee() {
5207 /// // operations using fp16 types
5208 /// }
5209 ///
5210 /// // Caller does not enable the required target feature
5211 /// fn caller() {
5212 /// unsafe { callee(); }
5213 /// }
5214 ///
5215 /// fn main() {
5216 /// caller();
5217 /// }
5218 /// ```
5219 ///
5220 /// This will produce:
5221 ///
5222 /// ```text
5223 /// warning: call to `#[inline(always)]`-annotated `callee` requires the same target features. Function will not have `alwaysinline` attribute applied
5224 /// --> $DIR/builtin.rs:5192:14
5225 /// |
5226 /// 10 | unsafe { callee(); }
5227 /// | ^^^^^^^^
5228 /// |
5229 /// note: `fp16` target feature enabled in `callee` here but missing from `caller`
5230 /// --> $DIR/builtin.rs:5185:1
5231 /// |
5232 /// 3 | #[target_feature(enable = "fp16")]
5233 /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
5234 /// 4 | unsafe fn callee() {
5235 /// | ------------------
5236 /// = note: `#[warn(inline_always_mismatching_target_features)]` on by default
5237 /// warning: 1 warning emitted
5238 /// ```
5239 ///
5240 /// ### Explanation
5241 ///
5242 /// Inlining a function with a target feature attribute into a caller that
5243 /// lacks the corresponding target feature can lead to unsound behavior.
5244 /// LLVM may select the wrong instructions or registers, or reorder
5245 /// operations, potentially resulting in runtime errors.
5246 pub INLINE_ALWAYS_MISMATCHING_TARGET_FEATURES,
5247 Warn,
5248 r#"detects when a function annotated with `#[inline(always)]` and `#[target_feature(enable = "..")]` is inlined into a caller without the required target feature"#,
5249}
5250
5251declare_lint! {
5252 /// The `repr_c_enums_larger_than_int` lint detects `repr(C)` enums with discriminant
5253 /// values that do not fit into a C `int` or `unsigned int`.
5254 ///
5255 /// ### Example
5256 ///
5257 /// ```rust,ignore (only errors on 64bit)
5258 /// #[repr(C)]
5259 /// enum E {
5260 /// V = 9223372036854775807, // i64::MAX
5261 /// }
5262 /// ```
5263 ///
5264 /// This will produce:
5265 ///
5266 /// ```text
5267 /// error: `repr(C)` enum discriminant does not fit into C `int` nor into C `unsigned int`
5268 /// --> $DIR/repr-c-big-discriminant1.rs:16:5
5269 /// |
5270 /// LL | A = 9223372036854775807, // i64::MAX
5271 /// | ^
5272 /// |
5273 /// = note: `repr(C)` enums with big discriminants are non-portable, and their size in Rust might not match their size in C
5274 /// = help: use `repr($int_ty)` instead to explicitly set the size of this enum
5275 /// ```
5276 ///
5277 /// ### Explanation
5278 ///
5279 /// In C, enums with discriminants that do not all fit into an `int` or all fit into an
5280 /// `unsigned int` are a portability hazard: such enums are only permitted since C23, and not
5281 /// supported e.g. by MSVC.
5282 ///
5283 /// Furthermore, Rust interprets the discriminant values of `repr(C)` enums as expressions of
5284 /// type `isize`. This makes it impossible to implement the C23 behavior of enums where the enum
5285 /// discriminants have no predefined type and instead the enum uses a type large enough to hold
5286 /// all discriminants.
5287 ///
5288 /// Therefore, `repr(C)` enums in Rust require that either all discriminants to fit into a C
5289 /// `int` or they all fit into an `unsigned int`.
5290 pub REPR_C_ENUMS_LARGER_THAN_INT,
5291 Warn,
5292 "repr(C) enums with discriminant values that do not fit into a C int",
5293 @future_incompatible = FutureIncompatibleInfo {
5294 reason: FutureIncompatibilityReason::FutureReleaseError,
5295 reference: "issue #124403 <https://github.com/rust-lang/rust/issues/124403>",
5296 report_in_deps: false,
5297 };
5298}
5299
5300declare_lint! {
5301 /// The `varargs_without_pattern` lint detects when `...` is used as an argument to a
5302 /// non-foreign function without any pattern being specified.
5303 ///
5304 /// ### Example
5305 ///
5306 /// ```rust
5307 /// // Using `...` in non-foreign function definitions is unstable, however stability is
5308 /// // currently only checked after attributes are expanded, so using `#[cfg(false)]` here will
5309 /// // allow this to compile on stable Rust.
5310 /// #[cfg(false)]
5311 /// fn foo(...) {
5312 ///
5313 /// }
5314 /// ```
5315 ///
5316 /// {{produces}}
5317 ///
5318 /// ### Explanation
5319 ///
5320 /// Patterns are currently required for all non-`...` arguments in function definitions (with
5321 /// some exceptions in the 2015 edition). Requiring `...` arguments to have patterns in
5322 /// non-foreign function definitions makes the language more consistent, and removes a source of
5323 /// confusion for the unstable C variadic feature. `...` arguments without a pattern are already
5324 /// stable and widely used in foreign function definitions; this lint only affects non-foreign
5325 /// function definitions.
5326 ///
5327 /// Using `...` (C varargs) in a non-foreign function definition is currently unstable. However,
5328 /// stability checking for the `...` syntax in non-foreign function definitions is currently
5329 /// implemented after attributes have been expanded, meaning that if the attribute removes the
5330 /// use of the unstable syntax (e.g. `#[cfg(false)]`, or a procedural macro), the code will
5331 /// compile on stable Rust; this is the only situation where this lint affects code that
5332 /// compiles on stable Rust.
5333 ///
5334 /// This is a [future-incompatible] lint to transition this to a hard error in the future.
5335 ///
5336 /// [future-incompatible]: ../index.md#future-incompatible-lints
5337 pub VARARGS_WITHOUT_PATTERN,
5338 Warn,
5339 "detects usage of `...` arguments without a pattern in non-foreign items",
5340 @future_incompatible = FutureIncompatibleInfo {
5341 reason: FutureIncompatibilityReason::FutureReleaseError,
5342 reference: "issue #145544 <https://github.com/rust-lang/rust/issues/145544>",
5343 report_in_deps: false,
5344 };
5345}