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