rustc_lint/
lints.rs

1#![allow(rustc::diagnostic_outside_of_impl)]
2#![allow(rustc::untranslatable_diagnostic)]
3use std::num::NonZero;
4
5use rustc_abi::ExternAbi;
6use rustc_errors::codes::*;
7use rustc_errors::{
8    Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString, ElidedLifetimeInPathSubdiag,
9    EmissionGuarantee, LintDiagnostic, MultiSpan, Subdiagnostic, SuggestionStyle,
10};
11use rustc_hir::def::Namespace;
12use rustc_hir::def_id::DefId;
13use rustc_hir::intravisit::VisitorExt;
14use rustc_hir::{self as hir, MissingLifetimeKind};
15use rustc_macros::{LintDiagnostic, Subdiagnostic};
16use rustc_middle::ty::inhabitedness::InhabitedPredicate;
17use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt};
18use rustc_session::Session;
19use rustc_session::lint::AmbiguityErrorDiag;
20use rustc_span::edition::Edition;
21use rustc_span::{Ident, MacroRulesNormalizedIdent, Span, Symbol, kw, sym};
22
23use crate::builtin::{InitError, ShorthandAssocTyCollector, TypeAliasBounds};
24use crate::errors::{OverruledAttributeSub, RequestedLevel};
25use crate::{LateContext, fluent_generated as fluent};
26
27// array_into_iter.rs
28#[derive(LintDiagnostic)]
29#[diag(lint_shadowed_into_iter)]
30pub(crate) struct ShadowedIntoIterDiag {
31    pub target: &'static str,
32    pub edition: &'static str,
33    #[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
34    pub suggestion: Span,
35    #[subdiagnostic]
36    pub sub: Option<ShadowedIntoIterDiagSub>,
37}
38
39#[derive(Subdiagnostic)]
40pub(crate) enum ShadowedIntoIterDiagSub {
41    #[suggestion(lint_remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
42    RemoveIntoIter {
43        #[primary_span]
44        span: Span,
45    },
46    #[multipart_suggestion(
47        lint_use_explicit_into_iter_suggestion,
48        applicability = "maybe-incorrect"
49    )]
50    UseExplicitIntoIter {
51        #[suggestion_part(code = "IntoIterator::into_iter(")]
52        start_span: Span,
53        #[suggestion_part(code = ")")]
54        end_span: Span,
55    },
56}
57
58// autorefs.rs
59#[derive(LintDiagnostic)]
60#[diag(lint_implicit_unsafe_autorefs)]
61#[note]
62pub(crate) struct ImplicitUnsafeAutorefsDiag<'a> {
63    #[label(lint_raw_ptr)]
64    pub raw_ptr_span: Span,
65    pub raw_ptr_ty: Ty<'a>,
66    #[subdiagnostic]
67    pub origin: ImplicitUnsafeAutorefsOrigin<'a>,
68    #[subdiagnostic]
69    pub method: Option<ImplicitUnsafeAutorefsMethodNote>,
70    #[subdiagnostic]
71    pub suggestion: ImplicitUnsafeAutorefsSuggestion,
72}
73
74#[derive(Subdiagnostic)]
75pub(crate) enum ImplicitUnsafeAutorefsOrigin<'a> {
76    #[note(lint_autoref)]
77    Autoref {
78        #[primary_span]
79        autoref_span: Span,
80        autoref_ty: Ty<'a>,
81    },
82    #[note(lint_overloaded_deref)]
83    OverloadedDeref,
84}
85
86#[derive(Subdiagnostic)]
87#[note(lint_method_def)]
88pub(crate) struct ImplicitUnsafeAutorefsMethodNote {
89    #[primary_span]
90    pub def_span: Span,
91    pub method_name: Symbol,
92}
93
94#[derive(Subdiagnostic)]
95#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
96pub(crate) struct ImplicitUnsafeAutorefsSuggestion {
97    pub mutbl: &'static str,
98    pub deref: &'static str,
99    #[suggestion_part(code = "({mutbl}{deref}")]
100    pub start_span: Span,
101    #[suggestion_part(code = ")")]
102    pub end_span: Span,
103}
104
105// builtin.rs
106#[derive(LintDiagnostic)]
107#[diag(lint_builtin_while_true)]
108pub(crate) struct BuiltinWhileTrue {
109    #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")]
110    pub suggestion: Span,
111    pub replace: String,
112}
113
114#[derive(LintDiagnostic)]
115#[diag(lint_builtin_non_shorthand_field_patterns)]
116pub(crate) struct BuiltinNonShorthandFieldPatterns {
117    pub ident: Ident,
118    #[suggestion(code = "{prefix}{ident}", applicability = "machine-applicable")]
119    pub suggestion: Span,
120    pub prefix: &'static str,
121}
122
123#[derive(LintDiagnostic)]
124pub(crate) enum BuiltinUnsafe {
125    #[diag(lint_builtin_allow_internal_unsafe)]
126    AllowInternalUnsafe,
127    #[diag(lint_builtin_unsafe_block)]
128    UnsafeBlock,
129    #[diag(lint_builtin_unsafe_extern_block)]
130    UnsafeExternBlock,
131    #[diag(lint_builtin_unsafe_trait)]
132    UnsafeTrait,
133    #[diag(lint_builtin_unsafe_impl)]
134    UnsafeImpl,
135    #[diag(lint_builtin_no_mangle_fn)]
136    #[note(lint_builtin_overridden_symbol_name)]
137    NoMangleFn,
138    #[diag(lint_builtin_export_name_fn)]
139    #[note(lint_builtin_overridden_symbol_name)]
140    ExportNameFn,
141    #[diag(lint_builtin_link_section_fn)]
142    #[note(lint_builtin_overridden_symbol_section)]
143    LinkSectionFn,
144    #[diag(lint_builtin_no_mangle_static)]
145    #[note(lint_builtin_overridden_symbol_name)]
146    NoMangleStatic,
147    #[diag(lint_builtin_export_name_static)]
148    #[note(lint_builtin_overridden_symbol_name)]
149    ExportNameStatic,
150    #[diag(lint_builtin_link_section_static)]
151    #[note(lint_builtin_overridden_symbol_section)]
152    LinkSectionStatic,
153    #[diag(lint_builtin_no_mangle_method)]
154    #[note(lint_builtin_overridden_symbol_name)]
155    NoMangleMethod,
156    #[diag(lint_builtin_export_name_method)]
157    #[note(lint_builtin_overridden_symbol_name)]
158    ExportNameMethod,
159    #[diag(lint_builtin_decl_unsafe_fn)]
160    DeclUnsafeFn,
161    #[diag(lint_builtin_decl_unsafe_method)]
162    DeclUnsafeMethod,
163    #[diag(lint_builtin_impl_unsafe_method)]
164    ImplUnsafeMethod,
165    #[diag(lint_builtin_global_asm)]
166    #[note(lint_builtin_global_macro_unsafety)]
167    GlobalAsm,
168}
169
170#[derive(LintDiagnostic)]
171#[diag(lint_builtin_missing_doc)]
172pub(crate) struct BuiltinMissingDoc<'a> {
173    pub article: &'a str,
174    pub desc: &'a str,
175}
176
177#[derive(LintDiagnostic)]
178#[diag(lint_builtin_missing_copy_impl)]
179pub(crate) struct BuiltinMissingCopyImpl;
180
181pub(crate) struct BuiltinMissingDebugImpl<'a> {
182    pub tcx: TyCtxt<'a>,
183    pub def_id: DefId,
184}
185
186// Needed for def_path_str
187impl<'a> LintDiagnostic<'a, ()> for BuiltinMissingDebugImpl<'_> {
188    fn decorate_lint<'b>(self, diag: &'b mut rustc_errors::Diag<'a, ()>) {
189        diag.primary_message(fluent::lint_builtin_missing_debug_impl);
190        diag.arg("debug", self.tcx.def_path_str(self.def_id));
191    }
192}
193
194#[derive(LintDiagnostic)]
195#[diag(lint_builtin_anonymous_params)]
196pub(crate) struct BuiltinAnonymousParams<'a> {
197    #[suggestion(code = "_: {ty_snip}")]
198    pub suggestion: (Span, Applicability),
199    pub ty_snip: &'a str,
200}
201
202// FIXME(davidtwco) translatable deprecated attr
203#[derive(LintDiagnostic)]
204#[diag(lint_builtin_deprecated_attr_link)]
205pub(crate) struct BuiltinDeprecatedAttrLink<'a> {
206    pub name: Symbol,
207    pub reason: &'a str,
208    pub link: &'a str,
209    #[subdiagnostic]
210    pub suggestion: BuiltinDeprecatedAttrLinkSuggestion<'a>,
211}
212
213#[derive(Subdiagnostic)]
214pub(crate) enum BuiltinDeprecatedAttrLinkSuggestion<'a> {
215    #[suggestion(lint_msg_suggestion, code = "", applicability = "machine-applicable")]
216    Msg {
217        #[primary_span]
218        suggestion: Span,
219        msg: &'a str,
220    },
221    #[suggestion(lint_default_suggestion, code = "", applicability = "machine-applicable")]
222    Default {
223        #[primary_span]
224        suggestion: Span,
225    },
226}
227
228#[derive(LintDiagnostic)]
229#[diag(lint_builtin_unused_doc_comment)]
230pub(crate) struct BuiltinUnusedDocComment<'a> {
231    pub kind: &'a str,
232    #[label]
233    pub label: Span,
234    #[subdiagnostic]
235    pub sub: BuiltinUnusedDocCommentSub,
236}
237
238#[derive(Subdiagnostic)]
239pub(crate) enum BuiltinUnusedDocCommentSub {
240    #[help(lint_plain_help)]
241    PlainHelp,
242    #[help(lint_block_help)]
243    BlockHelp,
244}
245
246#[derive(LintDiagnostic)]
247#[diag(lint_builtin_no_mangle_generic)]
248pub(crate) struct BuiltinNoMangleGeneric {
249    // Use of `#[no_mangle]` suggests FFI intent; correct
250    // fix may be to monomorphize source by hand
251    #[suggestion(style = "short", code = "", applicability = "maybe-incorrect")]
252    pub suggestion: Span,
253}
254
255#[derive(LintDiagnostic)]
256#[diag(lint_builtin_const_no_mangle)]
257pub(crate) struct BuiltinConstNoMangle {
258    #[suggestion(code = "pub static", applicability = "machine-applicable")]
259    pub suggestion: Span,
260}
261
262#[derive(LintDiagnostic)]
263#[diag(lint_builtin_mutable_transmutes)]
264pub(crate) struct BuiltinMutablesTransmutes;
265
266#[derive(LintDiagnostic)]
267#[diag(lint_builtin_unstable_features)]
268pub(crate) struct BuiltinUnstableFeatures;
269
270// lint_ungated_async_fn_track_caller
271pub(crate) struct BuiltinUngatedAsyncFnTrackCaller<'a> {
272    pub label: Span,
273    pub session: &'a Session,
274}
275
276impl<'a> LintDiagnostic<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
277    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
278        diag.primary_message(fluent::lint_ungated_async_fn_track_caller);
279        diag.span_label(self.label, fluent::lint_label);
280        rustc_session::parse::add_feature_diagnostics(
281            diag,
282            self.session,
283            sym::async_fn_track_caller,
284        );
285    }
286}
287
288#[derive(LintDiagnostic)]
289#[diag(lint_builtin_unreachable_pub)]
290pub(crate) struct BuiltinUnreachablePub<'a> {
291    pub what: &'a str,
292    pub new_vis: &'a str,
293    #[suggestion(code = "{new_vis}")]
294    pub suggestion: (Span, Applicability),
295    #[help]
296    pub help: bool,
297}
298
299#[derive(LintDiagnostic)]
300#[diag(lint_macro_expr_fragment_specifier_2024_migration)]
301pub(crate) struct MacroExprFragment2024 {
302    #[suggestion(code = "expr_2021", applicability = "machine-applicable")]
303    pub suggestion: Span,
304}
305
306pub(crate) struct BuiltinTypeAliasBounds<'hir> {
307    pub in_where_clause: bool,
308    pub label: Span,
309    pub enable_feat_help: bool,
310    pub suggestions: Vec<(Span, String)>,
311    pub preds: &'hir [hir::WherePredicate<'hir>],
312    pub ty: Option<&'hir hir::Ty<'hir>>,
313}
314
315impl<'a> LintDiagnostic<'a, ()> for BuiltinTypeAliasBounds<'_> {
316    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
317        diag.primary_message(if self.in_where_clause {
318            fluent::lint_builtin_type_alias_bounds_where_clause
319        } else {
320            fluent::lint_builtin_type_alias_bounds_param_bounds
321        });
322        diag.span_label(self.label, fluent::lint_builtin_type_alias_bounds_label);
323        diag.note(fluent::lint_builtin_type_alias_bounds_limitation_note);
324        if self.enable_feat_help {
325            diag.help(fluent::lint_builtin_type_alias_bounds_enable_feat_help);
326        }
327
328        // We perform the walk in here instead of in `<TypeAliasBounds as LateLintPass>` to
329        // avoid doing throwaway work in case the lint ends up getting suppressed.
330        let mut collector = ShorthandAssocTyCollector { qselves: Vec::new() };
331        if let Some(ty) = self.ty {
332            collector.visit_ty_unambig(ty);
333        }
334
335        let affect_object_lifetime_defaults = self
336            .preds
337            .iter()
338            .filter(|pred| pred.kind.in_where_clause() == self.in_where_clause)
339            .any(|pred| TypeAliasBounds::affects_object_lifetime_defaults(pred));
340
341        // If there are any shorthand assoc tys, then the bounds can't be removed automatically.
342        // The user first needs to fully qualify the assoc tys.
343        let applicability = if !collector.qselves.is_empty() || affect_object_lifetime_defaults {
344            Applicability::MaybeIncorrect
345        } else {
346            Applicability::MachineApplicable
347        };
348
349        diag.arg("count", self.suggestions.len());
350        diag.multipart_suggestion(fluent::lint_suggestion, self.suggestions, applicability);
351
352        // Suggest fully qualifying paths of the form `T::Assoc` with `T` type param via
353        // `<T as /* Trait */>::Assoc` to remove their reliance on any type param bounds.
354        //
355        // Instead of attempting to figure out the necessary trait ref, just use a
356        // placeholder. Since we don't record type-dependent resolutions for non-body
357        // items like type aliases, we can't simply deduce the corresp. trait from
358        // the HIR path alone without rerunning parts of HIR ty lowering here
359        // (namely `probe_single_ty_param_bound_for_assoc_ty`) which is infeasible.
360        //
361        // (We could employ some simple heuristics but that's likely not worth it).
362        for qself in collector.qselves {
363            diag.multipart_suggestion(
364                fluent::lint_builtin_type_alias_bounds_qualify_assoc_tys_sugg,
365                vec![
366                    (qself.shrink_to_lo(), "<".into()),
367                    (qself.shrink_to_hi(), " as /* Trait */>".into()),
368                ],
369                Applicability::HasPlaceholders,
370            );
371        }
372    }
373}
374
375#[derive(LintDiagnostic)]
376#[diag(lint_builtin_trivial_bounds)]
377pub(crate) struct BuiltinTrivialBounds<'a> {
378    pub predicate_kind_name: &'a str,
379    pub predicate: Clause<'a>,
380}
381
382#[derive(LintDiagnostic)]
383#[diag(lint_builtin_double_negations)]
384#[note(lint_note)]
385#[note(lint_note_decrement)]
386pub(crate) struct BuiltinDoubleNegations {
387    #[subdiagnostic]
388    pub add_parens: BuiltinDoubleNegationsAddParens,
389}
390
391#[derive(Subdiagnostic)]
392#[multipart_suggestion(lint_add_parens_suggestion, applicability = "maybe-incorrect")]
393pub(crate) struct BuiltinDoubleNegationsAddParens {
394    #[suggestion_part(code = "(")]
395    pub start_span: Span,
396    #[suggestion_part(code = ")")]
397    pub end_span: Span,
398}
399
400#[derive(LintDiagnostic)]
401pub(crate) enum BuiltinEllipsisInclusiveRangePatternsLint {
402    #[diag(lint_builtin_ellipsis_inclusive_range_patterns)]
403    Parenthesise {
404        #[suggestion(code = "{replace}", applicability = "machine-applicable")]
405        suggestion: Span,
406        replace: String,
407    },
408    #[diag(lint_builtin_ellipsis_inclusive_range_patterns)]
409    NonParenthesise {
410        #[suggestion(style = "short", code = "..=", applicability = "machine-applicable")]
411        suggestion: Span,
412    },
413}
414
415#[derive(LintDiagnostic)]
416#[diag(lint_builtin_keyword_idents)]
417pub(crate) struct BuiltinKeywordIdents {
418    pub kw: Ident,
419    pub next: Edition,
420    #[suggestion(code = "{prefix}r#{kw}", applicability = "machine-applicable")]
421    pub suggestion: Span,
422    pub prefix: &'static str,
423}
424
425#[derive(LintDiagnostic)]
426#[diag(lint_builtin_explicit_outlives)]
427pub(crate) struct BuiltinExplicitOutlives {
428    pub count: usize,
429    #[subdiagnostic]
430    pub suggestion: BuiltinExplicitOutlivesSuggestion,
431}
432
433#[derive(Subdiagnostic)]
434#[multipart_suggestion(lint_suggestion)]
435pub(crate) struct BuiltinExplicitOutlivesSuggestion {
436    #[suggestion_part(code = "")]
437    pub spans: Vec<Span>,
438    #[applicability]
439    pub applicability: Applicability,
440}
441
442#[derive(LintDiagnostic)]
443#[diag(lint_builtin_incomplete_features)]
444pub(crate) struct BuiltinIncompleteFeatures {
445    pub name: Symbol,
446    #[subdiagnostic]
447    pub note: Option<BuiltinFeatureIssueNote>,
448    #[subdiagnostic]
449    pub help: Option<BuiltinIncompleteFeaturesHelp>,
450}
451
452#[derive(LintDiagnostic)]
453#[diag(lint_builtin_internal_features)]
454#[note]
455pub(crate) struct BuiltinInternalFeatures {
456    pub name: Symbol,
457}
458
459#[derive(Subdiagnostic)]
460#[help(lint_help)]
461pub(crate) struct BuiltinIncompleteFeaturesHelp;
462
463#[derive(Subdiagnostic)]
464#[note(lint_note)]
465pub(crate) struct BuiltinFeatureIssueNote {
466    pub n: NonZero<u32>,
467}
468
469pub(crate) struct BuiltinUnpermittedTypeInit<'a> {
470    pub msg: DiagMessage,
471    pub ty: Ty<'a>,
472    pub label: Span,
473    pub sub: BuiltinUnpermittedTypeInitSub,
474    pub tcx: TyCtxt<'a>,
475}
476
477impl<'a> LintDiagnostic<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
478    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
479        diag.primary_message(self.msg);
480        diag.arg("ty", self.ty);
481        diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label);
482        if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) {
483            // Only suggest late `MaybeUninit::assume_init` initialization if the type is inhabited.
484            diag.span_label(
485                self.label,
486                fluent::lint_builtin_unpermitted_type_init_label_suggestion,
487            );
488        }
489        self.sub.add_to_diag(diag);
490    }
491}
492
493// FIXME(davidtwco): make translatable
494pub(crate) struct BuiltinUnpermittedTypeInitSub {
495    pub err: InitError,
496}
497
498impl Subdiagnostic for BuiltinUnpermittedTypeInitSub {
499    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
500        let mut err = self.err;
501        loop {
502            if let Some(span) = err.span {
503                diag.span_note(span, err.message);
504            } else {
505                diag.note(err.message);
506            }
507            if let Some(e) = err.nested {
508                err = *e;
509            } else {
510                break;
511            }
512        }
513    }
514}
515
516#[derive(LintDiagnostic)]
517pub(crate) enum BuiltinClashingExtern<'a> {
518    #[diag(lint_builtin_clashing_extern_same_name)]
519    SameName {
520        this: Symbol,
521        orig: Symbol,
522        #[label(lint_previous_decl_label)]
523        previous_decl_label: Span,
524        #[label(lint_mismatch_label)]
525        mismatch_label: Span,
526        #[subdiagnostic]
527        sub: BuiltinClashingExternSub<'a>,
528    },
529    #[diag(lint_builtin_clashing_extern_diff_name)]
530    DiffName {
531        this: Symbol,
532        orig: Symbol,
533        #[label(lint_previous_decl_label)]
534        previous_decl_label: Span,
535        #[label(lint_mismatch_label)]
536        mismatch_label: Span,
537        #[subdiagnostic]
538        sub: BuiltinClashingExternSub<'a>,
539    },
540}
541
542// FIXME(davidtwco): translatable expected/found
543pub(crate) struct BuiltinClashingExternSub<'a> {
544    pub tcx: TyCtxt<'a>,
545    pub expected: Ty<'a>,
546    pub found: Ty<'a>,
547}
548
549impl Subdiagnostic for BuiltinClashingExternSub<'_> {
550    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
551        let mut expected_str = DiagStyledString::new();
552        expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false);
553        let mut found_str = DiagStyledString::new();
554        found_str.push(self.found.fn_sig(self.tcx).to_string(), true);
555        diag.note_expected_found("", expected_str, "", found_str);
556    }
557}
558
559#[derive(LintDiagnostic)]
560#[diag(lint_builtin_deref_nullptr)]
561pub(crate) struct BuiltinDerefNullptr {
562    #[label]
563    pub label: Span,
564}
565
566// FIXME: migrate fluent::lint::builtin_asm_labels
567
568#[derive(LintDiagnostic)]
569pub(crate) enum BuiltinSpecialModuleNameUsed {
570    #[diag(lint_builtin_special_module_name_used_lib)]
571    #[note]
572    #[help]
573    Lib,
574    #[diag(lint_builtin_special_module_name_used_main)]
575    #[note]
576    Main,
577}
578
579// deref_into_dyn_supertrait.rs
580#[derive(LintDiagnostic)]
581#[diag(lint_supertrait_as_deref_target)]
582pub(crate) struct SupertraitAsDerefTarget<'a> {
583    pub self_ty: Ty<'a>,
584    pub supertrait_principal: PolyExistentialTraitRef<'a>,
585    pub target_principal: PolyExistentialTraitRef<'a>,
586    #[label]
587    pub label: Span,
588    #[subdiagnostic]
589    pub label2: Option<SupertraitAsDerefTargetLabel>,
590}
591
592#[derive(Subdiagnostic)]
593#[label(lint_label2)]
594pub(crate) struct SupertraitAsDerefTargetLabel {
595    #[primary_span]
596    pub label: Span,
597}
598
599// enum_intrinsics_non_enums.rs
600#[derive(LintDiagnostic)]
601#[diag(lint_enum_intrinsics_mem_discriminant)]
602pub(crate) struct EnumIntrinsicsMemDiscriminate<'a> {
603    pub ty_param: Ty<'a>,
604    #[note]
605    pub note: Span,
606}
607
608#[derive(LintDiagnostic)]
609#[diag(lint_enum_intrinsics_mem_variant)]
610#[note]
611pub(crate) struct EnumIntrinsicsMemVariant<'a> {
612    pub ty_param: Ty<'a>,
613}
614
615// expect.rs
616#[derive(LintDiagnostic)]
617#[diag(lint_expectation)]
618pub(crate) struct Expectation {
619    #[subdiagnostic]
620    pub rationale: Option<ExpectationNote>,
621    #[note]
622    pub note: bool,
623}
624
625#[derive(Subdiagnostic)]
626#[note(lint_rationale)]
627pub(crate) struct ExpectationNote {
628    pub rationale: Symbol,
629}
630
631// ptr_nulls.rs
632#[derive(LintDiagnostic)]
633pub(crate) enum UselessPtrNullChecksDiag<'a> {
634    #[diag(lint_useless_ptr_null_checks_fn_ptr)]
635    #[help]
636    FnPtr {
637        orig_ty: Ty<'a>,
638        #[label]
639        label: Span,
640    },
641    #[diag(lint_useless_ptr_null_checks_ref)]
642    Ref {
643        orig_ty: Ty<'a>,
644        #[label]
645        label: Span,
646    },
647    #[diag(lint_useless_ptr_null_checks_fn_ret)]
648    FnRet { fn_name: Ident },
649}
650
651#[derive(LintDiagnostic)]
652pub(crate) enum InvalidNullArgumentsDiag {
653    #[diag(lint_invalid_null_arguments)]
654    #[help(lint_doc)]
655    NullPtrInline {
656        #[label(lint_origin)]
657        null_span: Span,
658    },
659    #[diag(lint_invalid_null_arguments)]
660    #[help(lint_doc)]
661    NullPtrThroughBinding {
662        #[note(lint_origin)]
663        null_span: Span,
664    },
665}
666
667// for_loops_over_fallibles.rs
668#[derive(LintDiagnostic)]
669#[diag(lint_for_loops_over_fallibles)]
670pub(crate) struct ForLoopsOverFalliblesDiag<'a> {
671    pub article: &'static str,
672    pub ref_prefix: &'static str,
673    pub ty: &'static str,
674    #[subdiagnostic]
675    pub sub: ForLoopsOverFalliblesLoopSub<'a>,
676    #[subdiagnostic]
677    pub question_mark: Option<ForLoopsOverFalliblesQuestionMark>,
678    #[subdiagnostic]
679    pub suggestion: ForLoopsOverFalliblesSuggestion<'a>,
680}
681
682#[derive(Subdiagnostic)]
683pub(crate) enum ForLoopsOverFalliblesLoopSub<'a> {
684    #[suggestion(lint_remove_next, code = ".by_ref()", applicability = "maybe-incorrect")]
685    RemoveNext {
686        #[primary_span]
687        suggestion: Span,
688        recv_snip: String,
689    },
690    #[multipart_suggestion(lint_use_while_let, applicability = "maybe-incorrect")]
691    UseWhileLet {
692        #[suggestion_part(code = "while let {var}(")]
693        start_span: Span,
694        #[suggestion_part(code = ") = ")]
695        end_span: Span,
696        var: &'a str,
697    },
698}
699
700#[derive(Subdiagnostic)]
701#[suggestion(lint_use_question_mark, code = "?", applicability = "maybe-incorrect")]
702pub(crate) struct ForLoopsOverFalliblesQuestionMark {
703    #[primary_span]
704    pub suggestion: Span,
705}
706
707#[derive(Subdiagnostic)]
708#[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
709pub(crate) struct ForLoopsOverFalliblesSuggestion<'a> {
710    pub var: &'a str,
711    #[suggestion_part(code = "if let {var}(")]
712    pub start_span: Span,
713    #[suggestion_part(code = ") = ")]
714    pub end_span: Span,
715}
716
717#[derive(Subdiagnostic)]
718pub(crate) enum UseLetUnderscoreIgnoreSuggestion {
719    #[note(lint_use_let_underscore_ignore_suggestion)]
720    Note,
721    #[multipart_suggestion(
722        lint_use_let_underscore_ignore_suggestion,
723        style = "verbose",
724        applicability = "maybe-incorrect"
725    )]
726    Suggestion {
727        #[suggestion_part(code = "let _ = ")]
728        start_span: Span,
729        #[suggestion_part(code = "")]
730        end_span: Span,
731    },
732}
733
734// drop_forget_useless.rs
735#[derive(LintDiagnostic)]
736#[diag(lint_dropping_references)]
737pub(crate) struct DropRefDiag<'a> {
738    pub arg_ty: Ty<'a>,
739    #[label]
740    pub label: Span,
741    #[subdiagnostic]
742    pub sugg: UseLetUnderscoreIgnoreSuggestion,
743}
744
745#[derive(LintDiagnostic)]
746#[diag(lint_dropping_copy_types)]
747pub(crate) struct DropCopyDiag<'a> {
748    pub arg_ty: Ty<'a>,
749    #[label]
750    pub label: Span,
751    #[subdiagnostic]
752    pub sugg: UseLetUnderscoreIgnoreSuggestion,
753}
754
755#[derive(LintDiagnostic)]
756#[diag(lint_forgetting_references)]
757pub(crate) struct ForgetRefDiag<'a> {
758    pub arg_ty: Ty<'a>,
759    #[label]
760    pub label: Span,
761    #[subdiagnostic]
762    pub sugg: UseLetUnderscoreIgnoreSuggestion,
763}
764
765#[derive(LintDiagnostic)]
766#[diag(lint_forgetting_copy_types)]
767pub(crate) struct ForgetCopyDiag<'a> {
768    pub arg_ty: Ty<'a>,
769    #[label]
770    pub label: Span,
771    #[subdiagnostic]
772    pub sugg: UseLetUnderscoreIgnoreSuggestion,
773}
774
775#[derive(LintDiagnostic)]
776#[diag(lint_undropped_manually_drops)]
777pub(crate) struct UndroppedManuallyDropsDiag<'a> {
778    pub arg_ty: Ty<'a>,
779    #[label]
780    pub label: Span,
781    #[subdiagnostic]
782    pub suggestion: UndroppedManuallyDropsSuggestion,
783}
784
785#[derive(Subdiagnostic)]
786#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
787pub(crate) struct UndroppedManuallyDropsSuggestion {
788    #[suggestion_part(code = "std::mem::ManuallyDrop::into_inner(")]
789    pub start_span: Span,
790    #[suggestion_part(code = ")")]
791    pub end_span: Span,
792}
793
794// invalid_from_utf8.rs
795#[derive(LintDiagnostic)]
796pub(crate) enum InvalidFromUtf8Diag {
797    #[diag(lint_invalid_from_utf8_unchecked)]
798    Unchecked {
799        method: String,
800        valid_up_to: usize,
801        #[label]
802        label: Span,
803    },
804    #[diag(lint_invalid_from_utf8_checked)]
805    Checked {
806        method: String,
807        valid_up_to: usize,
808        #[label]
809        label: Span,
810    },
811}
812
813// reference_casting.rs
814#[derive(LintDiagnostic)]
815pub(crate) enum InvalidReferenceCastingDiag<'tcx> {
816    #[diag(lint_invalid_reference_casting_borrow_as_mut)]
817    #[note(lint_invalid_reference_casting_note_book)]
818    BorrowAsMut {
819        #[label]
820        orig_cast: Option<Span>,
821        #[note(lint_invalid_reference_casting_note_ty_has_interior_mutability)]
822        ty_has_interior_mutability: bool,
823    },
824    #[diag(lint_invalid_reference_casting_assign_to_ref)]
825    #[note(lint_invalid_reference_casting_note_book)]
826    AssignToRef {
827        #[label]
828        orig_cast: Option<Span>,
829        #[note(lint_invalid_reference_casting_note_ty_has_interior_mutability)]
830        ty_has_interior_mutability: bool,
831    },
832    #[diag(lint_invalid_reference_casting_bigger_layout)]
833    #[note(lint_layout)]
834    BiggerLayout {
835        #[label]
836        orig_cast: Option<Span>,
837        #[label(lint_alloc)]
838        alloc: Span,
839        from_ty: Ty<'tcx>,
840        from_size: u64,
841        to_ty: Ty<'tcx>,
842        to_size: u64,
843    },
844}
845
846// hidden_unicode_codepoints.rs
847#[derive(LintDiagnostic)]
848#[diag(lint_hidden_unicode_codepoints)]
849#[note]
850pub(crate) struct HiddenUnicodeCodepointsDiag<'a> {
851    pub label: &'a str,
852    pub count: usize,
853    #[label]
854    pub span_label: Span,
855    #[subdiagnostic]
856    pub labels: Option<HiddenUnicodeCodepointsDiagLabels>,
857    #[subdiagnostic]
858    pub sub: HiddenUnicodeCodepointsDiagSub,
859}
860
861pub(crate) struct HiddenUnicodeCodepointsDiagLabels {
862    pub spans: Vec<(char, Span)>,
863}
864
865impl Subdiagnostic for HiddenUnicodeCodepointsDiagLabels {
866    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
867        for (c, span) in self.spans {
868            diag.span_label(span, format!("{c:?}"));
869        }
870    }
871}
872
873pub(crate) enum HiddenUnicodeCodepointsDiagSub {
874    Escape { spans: Vec<(char, Span)> },
875    NoEscape { spans: Vec<(char, Span)> },
876}
877
878// Used because of multiple multipart_suggestion and note
879impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub {
880    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
881        match self {
882            HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
883                diag.multipart_suggestion_with_style(
884                    fluent::lint_suggestion_remove,
885                    spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
886                    Applicability::MachineApplicable,
887                    SuggestionStyle::HideCodeAlways,
888                );
889                diag.multipart_suggestion(
890                    fluent::lint_suggestion_escape,
891                    spans
892                        .into_iter()
893                        .map(|(c, span)| {
894                            let c = format!("{c:?}");
895                            (span, c[1..c.len() - 1].to_string())
896                        })
897                        .collect(),
898                    Applicability::MachineApplicable,
899                );
900            }
901            HiddenUnicodeCodepointsDiagSub::NoEscape { spans } => {
902                // FIXME: in other suggestions we've reversed the inner spans of doc comments. We
903                // should do the same here to provide the same good suggestions as we do for
904                // literals above.
905                diag.arg(
906                    "escaped",
907                    spans
908                        .into_iter()
909                        .map(|(c, _)| format!("{c:?}"))
910                        .collect::<Vec<String>>()
911                        .join(", "),
912                );
913                diag.note(fluent::lint_suggestion_remove);
914                diag.note(fluent::lint_no_suggestion_note_escape);
915            }
916        }
917    }
918}
919
920// map_unit_fn.rs
921#[derive(LintDiagnostic)]
922#[diag(lint_map_unit_fn)]
923#[note]
924pub(crate) struct MappingToUnit {
925    #[label(lint_function_label)]
926    pub function_label: Span,
927    #[label(lint_argument_label)]
928    pub argument_label: Span,
929    #[label(lint_map_label)]
930    pub map_label: Span,
931    #[suggestion(style = "verbose", code = "{replace}", applicability = "maybe-incorrect")]
932    pub suggestion: Span,
933    pub replace: String,
934}
935
936// internal.rs
937#[derive(LintDiagnostic)]
938#[diag(lint_default_hash_types)]
939#[note]
940pub(crate) struct DefaultHashTypesDiag<'a> {
941    pub preferred: &'a str,
942    pub used: Symbol,
943}
944
945#[derive(LintDiagnostic)]
946#[diag(lint_query_instability)]
947#[note]
948pub(crate) struct QueryInstability {
949    pub query: Symbol,
950}
951
952#[derive(LintDiagnostic)]
953#[diag(lint_query_untracked)]
954#[note]
955pub(crate) struct QueryUntracked {
956    pub method: Symbol,
957}
958
959#[derive(LintDiagnostic)]
960#[diag(lint_span_use_eq_ctxt)]
961pub(crate) struct SpanUseEqCtxtDiag;
962
963#[derive(LintDiagnostic)]
964#[diag(lint_symbol_intern_string_literal)]
965#[help]
966pub(crate) struct SymbolInternStringLiteralDiag;
967
968#[derive(LintDiagnostic)]
969#[diag(lint_tykind_kind)]
970pub(crate) struct TykindKind {
971    #[suggestion(code = "ty", applicability = "maybe-incorrect")]
972    pub suggestion: Span,
973}
974
975#[derive(LintDiagnostic)]
976#[diag(lint_tykind)]
977#[help]
978pub(crate) struct TykindDiag;
979
980#[derive(LintDiagnostic)]
981#[diag(lint_ty_qualified)]
982pub(crate) struct TyQualified {
983    pub ty: String,
984    #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
985    pub suggestion: Span,
986}
987
988#[derive(LintDiagnostic)]
989#[diag(lint_type_ir_inherent_usage)]
990#[note]
991pub(crate) struct TypeIrInherentUsage;
992
993#[derive(LintDiagnostic)]
994#[diag(lint_type_ir_trait_usage)]
995#[note]
996pub(crate) struct TypeIrTraitUsage;
997
998#[derive(LintDiagnostic)]
999#[diag(lint_non_glob_import_type_ir_inherent)]
1000pub(crate) struct NonGlobImportTypeIrInherent {
1001    #[suggestion(code = "{snippet}", applicability = "maybe-incorrect")]
1002    pub suggestion: Option<Span>,
1003    pub snippet: &'static str,
1004}
1005
1006#[derive(LintDiagnostic)]
1007#[diag(lint_lintpass_by_hand)]
1008#[help]
1009pub(crate) struct LintPassByHand;
1010
1011#[derive(LintDiagnostic)]
1012#[diag(lint_diag_out_of_impl)]
1013pub(crate) struct DiagOutOfImpl;
1014
1015#[derive(LintDiagnostic)]
1016#[diag(lint_untranslatable_diag)]
1017pub(crate) struct UntranslatableDiag;
1018
1019#[derive(LintDiagnostic)]
1020#[diag(lint_bad_opt_access)]
1021pub(crate) struct BadOptAccessDiag<'a> {
1022    pub msg: &'a str,
1023}
1024
1025// let_underscore.rs
1026#[derive(LintDiagnostic)]
1027pub(crate) enum NonBindingLet {
1028    #[diag(lint_non_binding_let_on_sync_lock)]
1029    SyncLock {
1030        #[label]
1031        pat: Span,
1032        #[subdiagnostic]
1033        sub: NonBindingLetSub,
1034    },
1035    #[diag(lint_non_binding_let_on_drop_type)]
1036    DropType {
1037        #[subdiagnostic]
1038        sub: NonBindingLetSub,
1039    },
1040}
1041
1042pub(crate) struct NonBindingLetSub {
1043    pub suggestion: Span,
1044    pub drop_fn_start_end: Option<(Span, Span)>,
1045    pub is_assign_desugar: bool,
1046}
1047
1048impl Subdiagnostic for NonBindingLetSub {
1049    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1050        let can_suggest_binding = self.drop_fn_start_end.is_some() || !self.is_assign_desugar;
1051
1052        if can_suggest_binding {
1053            let prefix = if self.is_assign_desugar { "let " } else { "" };
1054            diag.span_suggestion_verbose(
1055                self.suggestion,
1056                fluent::lint_non_binding_let_suggestion,
1057                format!("{prefix}_unused"),
1058                Applicability::MachineApplicable,
1059            );
1060        } else {
1061            diag.span_help(self.suggestion, fluent::lint_non_binding_let_suggestion);
1062        }
1063        if let Some(drop_fn_start_end) = self.drop_fn_start_end {
1064            diag.multipart_suggestion(
1065                fluent::lint_non_binding_let_multi_suggestion,
1066                vec![
1067                    (drop_fn_start_end.0, "drop(".to_string()),
1068                    (drop_fn_start_end.1, ")".to_string()),
1069                ],
1070                Applicability::MachineApplicable,
1071            );
1072        } else {
1073            diag.help(fluent::lint_non_binding_let_multi_drop_fn);
1074        }
1075    }
1076}
1077
1078// levels.rs
1079#[derive(LintDiagnostic)]
1080#[diag(lint_overruled_attribute)]
1081pub(crate) struct OverruledAttributeLint<'a> {
1082    #[label]
1083    pub overruled: Span,
1084    pub lint_level: &'a str,
1085    pub lint_source: Symbol,
1086    #[subdiagnostic]
1087    pub sub: OverruledAttributeSub,
1088}
1089
1090#[derive(LintDiagnostic)]
1091#[diag(lint_deprecated_lint_name)]
1092pub(crate) struct DeprecatedLintName<'a> {
1093    pub name: String,
1094    #[suggestion(code = "{replace}", applicability = "machine-applicable")]
1095    pub suggestion: Span,
1096    pub replace: &'a str,
1097}
1098
1099#[derive(LintDiagnostic)]
1100#[diag(lint_deprecated_lint_name)]
1101#[help]
1102pub(crate) struct DeprecatedLintNameFromCommandLine<'a> {
1103    pub name: String,
1104    pub replace: &'a str,
1105    #[subdiagnostic]
1106    pub requested_level: RequestedLevel<'a>,
1107}
1108
1109#[derive(LintDiagnostic)]
1110#[diag(lint_renamed_lint)]
1111pub(crate) struct RenamedLint<'a> {
1112    pub name: &'a str,
1113    #[subdiagnostic]
1114    pub suggestion: RenamedLintSuggestion<'a>,
1115}
1116
1117#[derive(Subdiagnostic)]
1118pub(crate) enum RenamedLintSuggestion<'a> {
1119    #[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")]
1120    WithSpan {
1121        #[primary_span]
1122        suggestion: Span,
1123        replace: &'a str,
1124    },
1125    #[help(lint_help)]
1126    WithoutSpan { replace: &'a str },
1127}
1128
1129#[derive(LintDiagnostic)]
1130#[diag(lint_renamed_lint)]
1131pub(crate) struct RenamedLintFromCommandLine<'a> {
1132    pub name: &'a str,
1133    #[subdiagnostic]
1134    pub suggestion: RenamedLintSuggestion<'a>,
1135    #[subdiagnostic]
1136    pub requested_level: RequestedLevel<'a>,
1137}
1138
1139#[derive(LintDiagnostic)]
1140#[diag(lint_removed_lint)]
1141pub(crate) struct RemovedLint<'a> {
1142    pub name: &'a str,
1143    pub reason: &'a str,
1144}
1145
1146#[derive(LintDiagnostic)]
1147#[diag(lint_removed_lint)]
1148pub(crate) struct RemovedLintFromCommandLine<'a> {
1149    pub name: &'a str,
1150    pub reason: &'a str,
1151    #[subdiagnostic]
1152    pub requested_level: RequestedLevel<'a>,
1153}
1154
1155#[derive(LintDiagnostic)]
1156#[diag(lint_unknown_lint)]
1157pub(crate) struct UnknownLint {
1158    pub name: String,
1159    #[subdiagnostic]
1160    pub suggestion: Option<UnknownLintSuggestion>,
1161}
1162
1163#[derive(Subdiagnostic)]
1164pub(crate) enum UnknownLintSuggestion {
1165    #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
1166    WithSpan {
1167        #[primary_span]
1168        suggestion: Span,
1169        replace: Symbol,
1170        from_rustc: bool,
1171    },
1172    #[help(lint_help)]
1173    WithoutSpan { replace: Symbol, from_rustc: bool },
1174}
1175
1176#[derive(LintDiagnostic)]
1177#[diag(lint_unknown_lint, code = E0602)]
1178pub(crate) struct UnknownLintFromCommandLine<'a> {
1179    pub name: String,
1180    #[subdiagnostic]
1181    pub suggestion: Option<UnknownLintSuggestion>,
1182    #[subdiagnostic]
1183    pub requested_level: RequestedLevel<'a>,
1184}
1185
1186#[derive(LintDiagnostic)]
1187#[diag(lint_ignored_unless_crate_specified)]
1188pub(crate) struct IgnoredUnlessCrateSpecified<'a> {
1189    pub level: &'a str,
1190    pub name: Symbol,
1191}
1192
1193// dangling.rs
1194#[derive(LintDiagnostic)]
1195#[diag(lint_dangling_pointers_from_temporaries)]
1196#[note]
1197#[help(lint_help_bind)]
1198#[help(lint_help_returned)]
1199#[help(lint_help_visit)]
1200// FIXME: put #[primary_span] on `ptr_span` once it does not cause conflicts
1201pub(crate) struct DanglingPointersFromTemporaries<'tcx> {
1202    pub callee: Ident,
1203    pub ty: Ty<'tcx>,
1204    #[label(lint_label_ptr)]
1205    pub ptr_span: Span,
1206    #[label(lint_label_temporary)]
1207    pub temporary_span: Span,
1208}
1209
1210// multiple_supertrait_upcastable.rs
1211#[derive(LintDiagnostic)]
1212#[diag(lint_multiple_supertrait_upcastable)]
1213pub(crate) struct MultipleSupertraitUpcastable {
1214    pub ident: Ident,
1215}
1216
1217// non_ascii_idents.rs
1218#[derive(LintDiagnostic)]
1219#[diag(lint_identifier_non_ascii_char)]
1220pub(crate) struct IdentifierNonAsciiChar;
1221
1222#[derive(LintDiagnostic)]
1223#[diag(lint_identifier_uncommon_codepoints)]
1224#[note]
1225pub(crate) struct IdentifierUncommonCodepoints {
1226    pub codepoints: Vec<char>,
1227    pub codepoints_len: usize,
1228    pub identifier_type: &'static str,
1229}
1230
1231#[derive(LintDiagnostic)]
1232#[diag(lint_confusable_identifier_pair)]
1233pub(crate) struct ConfusableIdentifierPair {
1234    pub existing_sym: Symbol,
1235    pub sym: Symbol,
1236    #[label(lint_other_use)]
1237    pub label: Span,
1238    #[label(lint_current_use)]
1239    pub main_label: Span,
1240}
1241
1242#[derive(LintDiagnostic)]
1243#[diag(lint_mixed_script_confusables)]
1244#[note(lint_includes_note)]
1245#[note]
1246pub(crate) struct MixedScriptConfusables {
1247    pub set: String,
1248    pub includes: String,
1249}
1250
1251// non_fmt_panic.rs
1252pub(crate) struct NonFmtPanicUnused {
1253    pub count: usize,
1254    pub suggestion: Option<Span>,
1255}
1256
1257// Used because of two suggestions based on one Option<Span>
1258impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused {
1259    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
1260        diag.primary_message(fluent::lint_non_fmt_panic_unused);
1261        diag.arg("count", self.count);
1262        diag.note(fluent::lint_note);
1263        if let Some(span) = self.suggestion {
1264            diag.span_suggestion(
1265                span.shrink_to_hi(),
1266                fluent::lint_add_args_suggestion,
1267                ", ...",
1268                Applicability::HasPlaceholders,
1269            );
1270            diag.span_suggestion(
1271                span.shrink_to_lo(),
1272                fluent::lint_add_fmt_suggestion,
1273                "\"{}\", ",
1274                Applicability::MachineApplicable,
1275            );
1276        }
1277    }
1278}
1279
1280#[derive(LintDiagnostic)]
1281#[diag(lint_non_fmt_panic_braces)]
1282#[note]
1283pub(crate) struct NonFmtPanicBraces {
1284    pub count: usize,
1285    #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")]
1286    pub suggestion: Option<Span>,
1287}
1288
1289// nonstandard_style.rs
1290#[derive(LintDiagnostic)]
1291#[diag(lint_non_camel_case_type)]
1292pub(crate) struct NonCamelCaseType<'a> {
1293    pub sort: &'a str,
1294    pub name: &'a str,
1295    #[subdiagnostic]
1296    pub sub: NonCamelCaseTypeSub,
1297}
1298
1299#[derive(Subdiagnostic)]
1300pub(crate) enum NonCamelCaseTypeSub {
1301    #[label(lint_label)]
1302    Label {
1303        #[primary_span]
1304        span: Span,
1305    },
1306    #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
1307    Suggestion {
1308        #[primary_span]
1309        span: Span,
1310        replace: String,
1311    },
1312}
1313
1314#[derive(LintDiagnostic)]
1315#[diag(lint_non_snake_case)]
1316pub(crate) struct NonSnakeCaseDiag<'a> {
1317    pub sort: &'a str,
1318    pub name: &'a str,
1319    pub sc: String,
1320    #[subdiagnostic]
1321    pub sub: NonSnakeCaseDiagSub,
1322}
1323
1324pub(crate) enum NonSnakeCaseDiagSub {
1325    Label { span: Span },
1326    Help,
1327    RenameOrConvertSuggestion { span: Span, suggestion: Ident },
1328    ConvertSuggestion { span: Span, suggestion: String },
1329    SuggestionAndNote { span: Span },
1330}
1331
1332impl Subdiagnostic for NonSnakeCaseDiagSub {
1333    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1334        match self {
1335            NonSnakeCaseDiagSub::Label { span } => {
1336                diag.span_label(span, fluent::lint_label);
1337            }
1338            NonSnakeCaseDiagSub::Help => {
1339                diag.help(fluent::lint_help);
1340            }
1341            NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
1342                diag.span_suggestion(
1343                    span,
1344                    fluent::lint_convert_suggestion,
1345                    suggestion,
1346                    Applicability::MaybeIncorrect,
1347                );
1348            }
1349            NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => {
1350                diag.span_suggestion(
1351                    span,
1352                    fluent::lint_rename_or_convert_suggestion,
1353                    suggestion,
1354                    Applicability::MaybeIncorrect,
1355                );
1356            }
1357            NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
1358                diag.note(fluent::lint_cannot_convert_note);
1359                diag.span_suggestion(
1360                    span,
1361                    fluent::lint_rename_suggestion,
1362                    "",
1363                    Applicability::MaybeIncorrect,
1364                );
1365            }
1366        }
1367    }
1368}
1369
1370#[derive(LintDiagnostic)]
1371#[diag(lint_non_upper_case_global)]
1372pub(crate) struct NonUpperCaseGlobal<'a> {
1373    pub sort: &'a str,
1374    pub name: &'a str,
1375    #[subdiagnostic]
1376    pub sub: NonUpperCaseGlobalSub,
1377}
1378
1379#[derive(Subdiagnostic)]
1380pub(crate) enum NonUpperCaseGlobalSub {
1381    #[label(lint_label)]
1382    Label {
1383        #[primary_span]
1384        span: Span,
1385    },
1386    #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
1387    Suggestion {
1388        #[primary_span]
1389        span: Span,
1390        replace: String,
1391    },
1392}
1393
1394// noop_method_call.rs
1395#[derive(LintDiagnostic)]
1396#[diag(lint_noop_method_call)]
1397#[note]
1398pub(crate) struct NoopMethodCallDiag<'a> {
1399    pub method: Ident,
1400    pub orig_ty: Ty<'a>,
1401    pub trait_: Symbol,
1402    #[suggestion(code = "", applicability = "machine-applicable")]
1403    pub label: Span,
1404    #[suggestion(
1405        lint_derive_suggestion,
1406        code = "#[derive(Clone)]\n",
1407        applicability = "maybe-incorrect"
1408    )]
1409    pub suggest_derive: Option<Span>,
1410}
1411
1412#[derive(LintDiagnostic)]
1413#[diag(lint_suspicious_double_ref_deref)]
1414pub(crate) struct SuspiciousDoubleRefDerefDiag<'a> {
1415    pub ty: Ty<'a>,
1416}
1417
1418#[derive(LintDiagnostic)]
1419#[diag(lint_suspicious_double_ref_clone)]
1420pub(crate) struct SuspiciousDoubleRefCloneDiag<'a> {
1421    pub ty: Ty<'a>,
1422}
1423
1424// non_local_defs.rs
1425pub(crate) enum NonLocalDefinitionsDiag {
1426    Impl {
1427        depth: u32,
1428        body_kind_descr: &'static str,
1429        body_name: String,
1430        cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
1431        const_anon: Option<Option<Span>>,
1432        doctest: bool,
1433        macro_to_change: Option<(String, &'static str)>,
1434    },
1435    MacroRules {
1436        depth: u32,
1437        body_kind_descr: &'static str,
1438        body_name: String,
1439        doctest: bool,
1440        cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
1441    },
1442}
1443
1444impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
1445    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
1446        match self {
1447            NonLocalDefinitionsDiag::Impl {
1448                depth,
1449                body_kind_descr,
1450                body_name,
1451                cargo_update,
1452                const_anon,
1453                doctest,
1454                macro_to_change,
1455            } => {
1456                diag.primary_message(fluent::lint_non_local_definitions_impl);
1457                diag.arg("depth", depth);
1458                diag.arg("body_kind_descr", body_kind_descr);
1459                diag.arg("body_name", body_name);
1460
1461                if let Some((macro_to_change, macro_kind)) = macro_to_change {
1462                    diag.arg("macro_to_change", macro_to_change);
1463                    diag.arg("macro_kind", macro_kind);
1464                    diag.note(fluent::lint_macro_to_change);
1465                }
1466                if let Some(cargo_update) = cargo_update {
1467                    diag.subdiagnostic(cargo_update);
1468                }
1469
1470                diag.note(fluent::lint_non_local);
1471
1472                if doctest {
1473                    diag.help(fluent::lint_doctest);
1474                }
1475
1476                if let Some(const_anon) = const_anon {
1477                    diag.note(fluent::lint_exception);
1478                    if let Some(const_anon) = const_anon {
1479                        diag.span_suggestion(
1480                            const_anon,
1481                            fluent::lint_const_anon,
1482                            "_",
1483                            Applicability::MachineApplicable,
1484                        );
1485                    }
1486                }
1487            }
1488            NonLocalDefinitionsDiag::MacroRules {
1489                depth,
1490                body_kind_descr,
1491                body_name,
1492                doctest,
1493                cargo_update,
1494            } => {
1495                diag.primary_message(fluent::lint_non_local_definitions_macro_rules);
1496                diag.arg("depth", depth);
1497                diag.arg("body_kind_descr", body_kind_descr);
1498                diag.arg("body_name", body_name);
1499
1500                if doctest {
1501                    diag.help(fluent::lint_help_doctest);
1502                } else {
1503                    diag.help(fluent::lint_help);
1504                }
1505
1506                diag.note(fluent::lint_non_local);
1507
1508                if let Some(cargo_update) = cargo_update {
1509                    diag.subdiagnostic(cargo_update);
1510                }
1511            }
1512        }
1513    }
1514}
1515
1516#[derive(Subdiagnostic)]
1517#[note(lint_non_local_definitions_cargo_update)]
1518pub(crate) struct NonLocalDefinitionsCargoUpdateNote {
1519    pub macro_kind: &'static str,
1520    pub macro_name: Symbol,
1521    pub crate_name: Symbol,
1522}
1523
1524// precedence.rs
1525#[derive(LintDiagnostic)]
1526#[diag(lint_ambiguous_negative_literals)]
1527#[note(lint_example)]
1528pub(crate) struct AmbiguousNegativeLiteralsDiag {
1529    #[subdiagnostic]
1530    pub negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion,
1531    #[subdiagnostic]
1532    pub current_behavior: AmbiguousNegativeLiteralsCurrentBehaviorSuggestion,
1533}
1534
1535#[derive(Subdiagnostic)]
1536#[multipart_suggestion(lint_negative_literal, applicability = "maybe-incorrect")]
1537pub(crate) struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion {
1538    #[suggestion_part(code = "(")]
1539    pub start_span: Span,
1540    #[suggestion_part(code = ")")]
1541    pub end_span: Span,
1542}
1543
1544#[derive(Subdiagnostic)]
1545#[multipart_suggestion(lint_current_behavior, applicability = "maybe-incorrect")]
1546pub(crate) struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion {
1547    #[suggestion_part(code = "(")]
1548    pub start_span: Span,
1549    #[suggestion_part(code = ")")]
1550    pub end_span: Span,
1551}
1552
1553// pass_by_value.rs
1554#[derive(LintDiagnostic)]
1555#[diag(lint_pass_by_value)]
1556pub(crate) struct PassByValueDiag {
1557    pub ty: String,
1558    #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
1559    pub suggestion: Span,
1560}
1561
1562// redundant_semicolon.rs
1563#[derive(LintDiagnostic)]
1564#[diag(lint_redundant_semicolons)]
1565pub(crate) struct RedundantSemicolonsDiag {
1566    pub multiple: bool,
1567    #[suggestion(code = "", applicability = "maybe-incorrect")]
1568    pub suggestion: Span,
1569}
1570
1571// traits.rs
1572pub(crate) struct DropTraitConstraintsDiag<'a> {
1573    pub predicate: Clause<'a>,
1574    pub tcx: TyCtxt<'a>,
1575    pub def_id: DefId,
1576}
1577
1578// Needed for def_path_str
1579impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> {
1580    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
1581        diag.primary_message(fluent::lint_drop_trait_constraints);
1582        diag.arg("predicate", self.predicate);
1583        diag.arg("needs_drop", self.tcx.def_path_str(self.def_id));
1584    }
1585}
1586
1587pub(crate) struct DropGlue<'a> {
1588    pub tcx: TyCtxt<'a>,
1589    pub def_id: DefId,
1590}
1591
1592// Needed for def_path_str
1593impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> {
1594    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
1595        diag.primary_message(fluent::lint_drop_glue);
1596        diag.arg("needs_drop", self.tcx.def_path_str(self.def_id));
1597    }
1598}
1599
1600// types.rs
1601#[derive(LintDiagnostic)]
1602#[diag(lint_range_endpoint_out_of_range)]
1603pub(crate) struct RangeEndpointOutOfRange<'a> {
1604    pub ty: &'a str,
1605    #[subdiagnostic]
1606    pub sub: UseInclusiveRange<'a>,
1607}
1608
1609#[derive(Subdiagnostic)]
1610pub(crate) enum UseInclusiveRange<'a> {
1611    #[suggestion(
1612        lint_range_use_inclusive_range,
1613        code = "{start}..={literal}{suffix}",
1614        applicability = "machine-applicable"
1615    )]
1616    WithoutParen {
1617        #[primary_span]
1618        sugg: Span,
1619        start: String,
1620        literal: u128,
1621        suffix: &'a str,
1622    },
1623    #[multipart_suggestion(lint_range_use_inclusive_range, applicability = "machine-applicable")]
1624    WithParen {
1625        #[suggestion_part(code = "=")]
1626        eq_sugg: Span,
1627        #[suggestion_part(code = "{literal}{suffix}")]
1628        lit_sugg: Span,
1629        literal: u128,
1630        suffix: &'a str,
1631    },
1632}
1633
1634#[derive(LintDiagnostic)]
1635#[diag(lint_overflowing_bin_hex)]
1636pub(crate) struct OverflowingBinHex<'a> {
1637    pub ty: &'a str,
1638    pub lit: String,
1639    pub dec: u128,
1640    pub actually: String,
1641    #[subdiagnostic]
1642    pub sign: OverflowingBinHexSign,
1643    #[subdiagnostic]
1644    pub sub: Option<OverflowingBinHexSub<'a>>,
1645    #[subdiagnostic]
1646    pub sign_bit_sub: Option<OverflowingBinHexSignBitSub<'a>>,
1647}
1648
1649pub(crate) enum OverflowingBinHexSign {
1650    Positive,
1651    Negative,
1652}
1653
1654impl Subdiagnostic for OverflowingBinHexSign {
1655    fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1656        match self {
1657            OverflowingBinHexSign::Positive => {
1658                diag.note(fluent::lint_positive_note);
1659            }
1660            OverflowingBinHexSign::Negative => {
1661                diag.note(fluent::lint_negative_note);
1662                diag.note(fluent::lint_negative_becomes_note);
1663            }
1664        }
1665    }
1666}
1667
1668#[derive(Subdiagnostic)]
1669pub(crate) enum OverflowingBinHexSub<'a> {
1670    #[suggestion(
1671        lint_suggestion,
1672        code = "{sans_suffix}{suggestion_ty}",
1673        applicability = "machine-applicable"
1674    )]
1675    Suggestion {
1676        #[primary_span]
1677        span: Span,
1678        suggestion_ty: &'a str,
1679        sans_suffix: &'a str,
1680    },
1681    #[help(lint_help)]
1682    Help { suggestion_ty: &'a str },
1683}
1684
1685#[derive(Subdiagnostic)]
1686#[suggestion(
1687    lint_sign_bit_suggestion,
1688    code = "{lit_no_suffix}{uint_ty} as {int_ty}",
1689    applicability = "maybe-incorrect"
1690)]
1691pub(crate) struct OverflowingBinHexSignBitSub<'a> {
1692    #[primary_span]
1693    pub span: Span,
1694    pub lit_no_suffix: &'a str,
1695    pub negative_val: String,
1696    pub uint_ty: &'a str,
1697    pub int_ty: &'a str,
1698}
1699
1700#[derive(LintDiagnostic)]
1701#[diag(lint_overflowing_int)]
1702#[note]
1703pub(crate) struct OverflowingInt<'a> {
1704    pub ty: &'a str,
1705    pub lit: String,
1706    pub min: i128,
1707    pub max: u128,
1708    #[subdiagnostic]
1709    pub help: Option<OverflowingIntHelp<'a>>,
1710}
1711
1712#[derive(Subdiagnostic)]
1713#[help(lint_help)]
1714pub(crate) struct OverflowingIntHelp<'a> {
1715    pub suggestion_ty: &'a str,
1716}
1717
1718#[derive(LintDiagnostic)]
1719#[diag(lint_only_cast_u8_to_char)]
1720pub(crate) struct OnlyCastu8ToChar {
1721    #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")]
1722    pub span: Span,
1723    pub literal: u128,
1724}
1725
1726#[derive(LintDiagnostic)]
1727#[diag(lint_overflowing_uint)]
1728#[note]
1729pub(crate) struct OverflowingUInt<'a> {
1730    pub ty: &'a str,
1731    pub lit: String,
1732    pub min: u128,
1733    pub max: u128,
1734}
1735
1736#[derive(LintDiagnostic)]
1737#[diag(lint_overflowing_literal)]
1738#[note]
1739pub(crate) struct OverflowingLiteral<'a> {
1740    pub ty: &'a str,
1741    pub lit: String,
1742}
1743
1744#[derive(LintDiagnostic)]
1745#[diag(lint_uses_power_alignment)]
1746pub(crate) struct UsesPowerAlignment;
1747
1748#[derive(LintDiagnostic)]
1749#[diag(lint_unused_comparisons)]
1750pub(crate) struct UnusedComparisons;
1751
1752#[derive(LintDiagnostic)]
1753pub(crate) enum InvalidNanComparisons {
1754    #[diag(lint_invalid_nan_comparisons_eq_ne)]
1755    EqNe {
1756        #[subdiagnostic]
1757        suggestion: InvalidNanComparisonsSuggestion,
1758    },
1759    #[diag(lint_invalid_nan_comparisons_lt_le_gt_ge)]
1760    LtLeGtGe,
1761}
1762
1763#[derive(Subdiagnostic)]
1764pub(crate) enum InvalidNanComparisonsSuggestion {
1765    #[multipart_suggestion(
1766        lint_suggestion,
1767        style = "verbose",
1768        applicability = "machine-applicable"
1769    )]
1770    Spanful {
1771        #[suggestion_part(code = "!")]
1772        neg: Option<Span>,
1773        #[suggestion_part(code = ".is_nan()")]
1774        float: Span,
1775        #[suggestion_part(code = "")]
1776        nan_plus_binop: Span,
1777    },
1778    #[help(lint_suggestion)]
1779    Spanless,
1780}
1781
1782#[derive(LintDiagnostic)]
1783pub(crate) enum AmbiguousWidePointerComparisons<'a> {
1784    #[diag(lint_ambiguous_wide_pointer_comparisons)]
1785    SpanfulEq {
1786        #[subdiagnostic]
1787        addr_suggestion: AmbiguousWidePointerComparisonsAddrSuggestion<'a>,
1788        #[subdiagnostic]
1789        addr_metadata_suggestion: Option<AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a>>,
1790    },
1791    #[diag(lint_ambiguous_wide_pointer_comparisons)]
1792    SpanfulCmp {
1793        #[subdiagnostic]
1794        cast_suggestion: AmbiguousWidePointerComparisonsCastSuggestion<'a>,
1795        #[subdiagnostic]
1796        expect_suggestion: AmbiguousWidePointerComparisonsExpectSuggestion<'a>,
1797    },
1798    #[diag(lint_ambiguous_wide_pointer_comparisons)]
1799    #[help(lint_addr_metadata_suggestion)]
1800    #[help(lint_addr_suggestion)]
1801    Spanless,
1802}
1803
1804#[derive(Subdiagnostic)]
1805#[multipart_suggestion(
1806    lint_addr_metadata_suggestion,
1807    style = "verbose",
1808    // FIXME(#53934): make machine-applicable again
1809    applicability = "maybe-incorrect"
1810)]
1811pub(crate) struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> {
1812    pub ne: &'a str,
1813    pub deref_left: &'a str,
1814    pub deref_right: &'a str,
1815    pub l_modifiers: &'a str,
1816    pub r_modifiers: &'a str,
1817    #[suggestion_part(code = "{ne}std::ptr::eq({deref_left}")]
1818    pub left: Span,
1819    #[suggestion_part(code = "{l_modifiers}, {deref_right}")]
1820    pub middle: Span,
1821    #[suggestion_part(code = "{r_modifiers})")]
1822    pub right: Span,
1823}
1824
1825#[derive(Subdiagnostic)]
1826#[multipart_suggestion(
1827    lint_addr_suggestion,
1828    style = "verbose",
1829    // FIXME(#53934): make machine-applicable again
1830    applicability = "maybe-incorrect"
1831)]
1832pub(crate) struct AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
1833    pub(crate) ne: &'a str,
1834    pub(crate) deref_left: &'a str,
1835    pub(crate) deref_right: &'a str,
1836    pub(crate) l_modifiers: &'a str,
1837    pub(crate) r_modifiers: &'a str,
1838    #[suggestion_part(code = "{ne}std::ptr::addr_eq({deref_left}")]
1839    pub(crate) left: Span,
1840    #[suggestion_part(code = "{l_modifiers}, {deref_right}")]
1841    pub(crate) middle: Span,
1842    #[suggestion_part(code = "{r_modifiers})")]
1843    pub(crate) right: Span,
1844}
1845
1846#[derive(Subdiagnostic)]
1847#[multipart_suggestion(
1848    lint_cast_suggestion,
1849    style = "verbose",
1850    // FIXME(#53934): make machine-applicable again
1851    applicability = "maybe-incorrect"
1852)]
1853pub(crate) struct AmbiguousWidePointerComparisonsCastSuggestion<'a> {
1854    pub(crate) deref_left: &'a str,
1855    pub(crate) deref_right: &'a str,
1856    pub(crate) paren_left: &'a str,
1857    pub(crate) paren_right: &'a str,
1858    pub(crate) l_modifiers: &'a str,
1859    pub(crate) r_modifiers: &'a str,
1860    #[suggestion_part(code = "({deref_left}")]
1861    pub(crate) left_before: Option<Span>,
1862    #[suggestion_part(code = "{l_modifiers}{paren_left}.cast::<()>()")]
1863    pub(crate) left_after: Span,
1864    #[suggestion_part(code = "({deref_right}")]
1865    pub(crate) right_before: Option<Span>,
1866    #[suggestion_part(code = "{r_modifiers}{paren_right}.cast::<()>()")]
1867    pub(crate) right_after: Span,
1868}
1869
1870#[derive(Subdiagnostic)]
1871#[multipart_suggestion(
1872    lint_expect_suggestion,
1873    style = "verbose",
1874    // FIXME(#53934): make machine-applicable again
1875    applicability = "maybe-incorrect"
1876)]
1877pub(crate) struct AmbiguousWidePointerComparisonsExpectSuggestion<'a> {
1878    pub(crate) paren_left: &'a str,
1879    pub(crate) paren_right: &'a str,
1880    // FIXME(#127436): Adjust once resolved
1881    #[suggestion_part(
1882        code = r#"{{ #[expect(ambiguous_wide_pointer_comparisons, reason = "...")] {paren_left}"#
1883    )]
1884    pub(crate) before: Span,
1885    #[suggestion_part(code = "{paren_right} }}")]
1886    pub(crate) after: Span,
1887}
1888
1889#[derive(LintDiagnostic)]
1890pub(crate) enum UnpredictableFunctionPointerComparisons<'a, 'tcx> {
1891    #[diag(lint_unpredictable_fn_pointer_comparisons)]
1892    #[note(lint_note_duplicated_fn)]
1893    #[note(lint_note_deduplicated_fn)]
1894    #[note(lint_note_visit_fn_addr_eq)]
1895    Suggestion {
1896        #[subdiagnostic]
1897        sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx>,
1898    },
1899    #[diag(lint_unpredictable_fn_pointer_comparisons)]
1900    #[note(lint_note_duplicated_fn)]
1901    #[note(lint_note_deduplicated_fn)]
1902    #[note(lint_note_visit_fn_addr_eq)]
1903    Warn,
1904}
1905
1906#[derive(Subdiagnostic)]
1907pub(crate) enum UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx> {
1908    #[multipart_suggestion(
1909        lint_fn_addr_eq_suggestion,
1910        style = "verbose",
1911        applicability = "maybe-incorrect"
1912    )]
1913    FnAddrEq {
1914        ne: &'a str,
1915        deref_left: &'a str,
1916        deref_right: &'a str,
1917        #[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
1918        left: Span,
1919        #[suggestion_part(code = ", {deref_right}")]
1920        middle: Span,
1921        #[suggestion_part(code = ")")]
1922        right: Span,
1923    },
1924    #[multipart_suggestion(
1925        lint_fn_addr_eq_suggestion,
1926        style = "verbose",
1927        applicability = "maybe-incorrect"
1928    )]
1929    FnAddrEqWithCast {
1930        ne: &'a str,
1931        deref_left: &'a str,
1932        deref_right: &'a str,
1933        fn_sig: rustc_middle::ty::PolyFnSig<'tcx>,
1934        #[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
1935        left: Span,
1936        #[suggestion_part(code = ", {deref_right}")]
1937        middle: Span,
1938        #[suggestion_part(code = " as {fn_sig})")]
1939        right: Span,
1940    },
1941}
1942
1943pub(crate) struct ImproperCTypes<'a> {
1944    pub ty: Ty<'a>,
1945    pub desc: &'a str,
1946    pub label: Span,
1947    pub help: Option<DiagMessage>,
1948    pub note: DiagMessage,
1949    pub span_note: Option<Span>,
1950}
1951
1952// Used because of the complexity of Option<DiagMessage>, DiagMessage, and Option<Span>
1953impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
1954    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
1955        diag.primary_message(fluent::lint_improper_ctypes);
1956        diag.arg("ty", self.ty);
1957        diag.arg("desc", self.desc);
1958        diag.span_label(self.label, fluent::lint_label);
1959        if let Some(help) = self.help {
1960            diag.help(help);
1961        }
1962        diag.note(self.note);
1963        if let Some(note) = self.span_note {
1964            diag.span_note(note, fluent::lint_note);
1965        }
1966    }
1967}
1968
1969#[derive(LintDiagnostic)]
1970#[diag(lint_variant_size_differences)]
1971pub(crate) struct VariantSizeDifferencesDiag {
1972    pub largest: u64,
1973}
1974
1975#[derive(LintDiagnostic)]
1976#[diag(lint_atomic_ordering_load)]
1977#[help]
1978pub(crate) struct AtomicOrderingLoad;
1979
1980#[derive(LintDiagnostic)]
1981#[diag(lint_atomic_ordering_store)]
1982#[help]
1983pub(crate) struct AtomicOrderingStore;
1984
1985#[derive(LintDiagnostic)]
1986#[diag(lint_atomic_ordering_fence)]
1987#[help]
1988pub(crate) struct AtomicOrderingFence;
1989
1990#[derive(LintDiagnostic)]
1991#[diag(lint_atomic_ordering_invalid)]
1992#[help]
1993pub(crate) struct InvalidAtomicOrderingDiag {
1994    pub method: Symbol,
1995    #[label]
1996    pub fail_order_arg_span: Span,
1997}
1998
1999// unused.rs
2000#[derive(LintDiagnostic)]
2001#[diag(lint_unused_op)]
2002pub(crate) struct UnusedOp<'a> {
2003    pub op: &'a str,
2004    #[label]
2005    pub label: Span,
2006    #[subdiagnostic]
2007    pub suggestion: UnusedOpSuggestion,
2008}
2009
2010#[derive(Subdiagnostic)]
2011pub(crate) enum UnusedOpSuggestion {
2012    #[suggestion(
2013        lint_suggestion,
2014        style = "verbose",
2015        code = "let _ = ",
2016        applicability = "maybe-incorrect"
2017    )]
2018    NormalExpr {
2019        #[primary_span]
2020        span: Span,
2021    },
2022    #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
2023    BlockTailExpr {
2024        #[suggestion_part(code = "let _ = ")]
2025        before_span: Span,
2026        #[suggestion_part(code = ";")]
2027        after_span: Span,
2028    },
2029}
2030
2031#[derive(LintDiagnostic)]
2032#[diag(lint_unused_result)]
2033pub(crate) struct UnusedResult<'a> {
2034    pub ty: Ty<'a>,
2035}
2036
2037// FIXME(davidtwco): this isn't properly translatable because of the
2038// pre/post strings
2039#[derive(LintDiagnostic)]
2040#[diag(lint_unused_closure)]
2041#[note]
2042pub(crate) struct UnusedClosure<'a> {
2043    pub count: usize,
2044    pub pre: &'a str,
2045    pub post: &'a str,
2046}
2047
2048// FIXME(davidtwco): this isn't properly translatable because of the
2049// pre/post strings
2050#[derive(LintDiagnostic)]
2051#[diag(lint_unused_coroutine)]
2052#[note]
2053pub(crate) struct UnusedCoroutine<'a> {
2054    pub count: usize,
2055    pub pre: &'a str,
2056    pub post: &'a str,
2057}
2058
2059// FIXME(davidtwco): this isn't properly translatable because of the pre/post
2060// strings
2061pub(crate) struct UnusedDef<'a, 'b> {
2062    pub pre: &'a str,
2063    pub post: &'a str,
2064    pub cx: &'a LateContext<'b>,
2065    pub def_id: DefId,
2066    pub note: Option<Symbol>,
2067    pub suggestion: Option<UnusedDefSuggestion>,
2068}
2069
2070#[derive(Subdiagnostic)]
2071
2072pub(crate) enum UnusedDefSuggestion {
2073    #[suggestion(
2074        lint_suggestion,
2075        style = "verbose",
2076        code = "let _ = ",
2077        applicability = "maybe-incorrect"
2078    )]
2079    NormalExpr {
2080        #[primary_span]
2081        span: Span,
2082    },
2083    #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
2084    BlockTailExpr {
2085        #[suggestion_part(code = "let _ = ")]
2086        before_span: Span,
2087        #[suggestion_part(code = ";")]
2088        after_span: Span,
2089    },
2090}
2091
2092// Needed because of def_path_str
2093impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> {
2094    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
2095        diag.primary_message(fluent::lint_unused_def);
2096        diag.arg("pre", self.pre);
2097        diag.arg("post", self.post);
2098        diag.arg("def", self.cx.tcx.def_path_str(self.def_id));
2099        // check for #[must_use = "..."]
2100        if let Some(note) = self.note {
2101            diag.note(note.to_string());
2102        }
2103        if let Some(sugg) = self.suggestion {
2104            diag.subdiagnostic(sugg);
2105        }
2106    }
2107}
2108
2109#[derive(LintDiagnostic)]
2110#[diag(lint_path_statement_drop)]
2111pub(crate) struct PathStatementDrop {
2112    #[subdiagnostic]
2113    pub sub: PathStatementDropSub,
2114}
2115
2116#[derive(Subdiagnostic)]
2117pub(crate) enum PathStatementDropSub {
2118    #[suggestion(lint_suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
2119    Suggestion {
2120        #[primary_span]
2121        span: Span,
2122        snippet: String,
2123    },
2124    #[help(lint_help)]
2125    Help {
2126        #[primary_span]
2127        span: Span,
2128    },
2129}
2130
2131#[derive(LintDiagnostic)]
2132#[diag(lint_path_statement_no_effect)]
2133pub(crate) struct PathStatementNoEffect;
2134
2135#[derive(LintDiagnostic)]
2136#[diag(lint_unused_delim)]
2137pub(crate) struct UnusedDelim<'a> {
2138    pub delim: &'static str,
2139    pub item: &'a str,
2140    #[subdiagnostic]
2141    pub suggestion: Option<UnusedDelimSuggestion>,
2142}
2143
2144#[derive(Subdiagnostic)]
2145#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
2146pub(crate) struct UnusedDelimSuggestion {
2147    #[suggestion_part(code = "{start_replace}")]
2148    pub start_span: Span,
2149    pub start_replace: &'static str,
2150    #[suggestion_part(code = "{end_replace}")]
2151    pub end_span: Span,
2152    pub end_replace: &'static str,
2153}
2154
2155#[derive(LintDiagnostic)]
2156#[diag(lint_unused_import_braces)]
2157pub(crate) struct UnusedImportBracesDiag {
2158    pub node: Symbol,
2159}
2160
2161#[derive(LintDiagnostic)]
2162#[diag(lint_unused_allocation)]
2163pub(crate) struct UnusedAllocationDiag;
2164
2165#[derive(LintDiagnostic)]
2166#[diag(lint_unused_allocation_mut)]
2167pub(crate) struct UnusedAllocationMutDiag;
2168
2169pub(crate) struct AsyncFnInTraitDiag {
2170    pub sugg: Option<Vec<(Span, String)>>,
2171}
2172
2173impl<'a> LintDiagnostic<'a, ()> for AsyncFnInTraitDiag {
2174    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
2175        diag.primary_message(fluent::lint_async_fn_in_trait);
2176        diag.note(fluent::lint_note);
2177        if let Some(sugg) = self.sugg {
2178            diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect);
2179        }
2180    }
2181}
2182
2183#[derive(LintDiagnostic)]
2184#[diag(lint_unit_bindings)]
2185pub(crate) struct UnitBindingsDiag {
2186    #[label]
2187    pub label: Span,
2188}
2189
2190#[derive(LintDiagnostic)]
2191pub(crate) enum InvalidAsmLabel {
2192    #[diag(lint_invalid_asm_label_named)]
2193    #[help]
2194    #[note]
2195    Named {
2196        #[note(lint_invalid_asm_label_no_span)]
2197        missing_precise_span: bool,
2198    },
2199    #[diag(lint_invalid_asm_label_format_arg)]
2200    #[help]
2201    #[note(lint_note1)]
2202    #[note(lint_note2)]
2203    FormatArg {
2204        #[note(lint_invalid_asm_label_no_span)]
2205        missing_precise_span: bool,
2206    },
2207    #[diag(lint_invalid_asm_label_binary)]
2208    #[help]
2209    #[note(lint_note1)]
2210    #[note(lint_note2)]
2211    Binary {
2212        #[note(lint_invalid_asm_label_no_span)]
2213        missing_precise_span: bool,
2214        // hack to get a label on the whole span, must match the emitted span
2215        #[label]
2216        span: Span,
2217    },
2218}
2219
2220#[derive(Subdiagnostic)]
2221pub(crate) enum UnexpectedCfgCargoHelp {
2222    #[help(lint_unexpected_cfg_add_cargo_feature)]
2223    #[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)]
2224    LintCfg { cargo_toml_lint_cfg: String },
2225    #[help(lint_unexpected_cfg_add_cargo_feature)]
2226    #[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)]
2227    #[help(lint_unexpected_cfg_add_build_rs_println)]
2228    LintCfgAndBuildRs { cargo_toml_lint_cfg: String, build_rs_println: String },
2229}
2230
2231impl UnexpectedCfgCargoHelp {
2232    fn cargo_toml_lint_cfg(unescaped: &str) -> String {
2233        format!(
2234            "\n [lints.rust]\n unexpected_cfgs = {{ level = \"warn\", check-cfg = ['{unescaped}'] }}"
2235        )
2236    }
2237
2238    pub(crate) fn lint_cfg(unescaped: &str) -> Self {
2239        UnexpectedCfgCargoHelp::LintCfg {
2240            cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped),
2241        }
2242    }
2243
2244    pub(crate) fn lint_cfg_and_build_rs(unescaped: &str, escaped: &str) -> Self {
2245        UnexpectedCfgCargoHelp::LintCfgAndBuildRs {
2246            cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped),
2247            build_rs_println: format!("println!(\"cargo::rustc-check-cfg={escaped}\");"),
2248        }
2249    }
2250}
2251
2252#[derive(Subdiagnostic)]
2253#[help(lint_unexpected_cfg_add_cmdline_arg)]
2254pub(crate) struct UnexpectedCfgRustcHelp {
2255    pub cmdline_arg: String,
2256}
2257
2258impl UnexpectedCfgRustcHelp {
2259    pub(crate) fn new(unescaped: &str) -> Self {
2260        Self { cmdline_arg: format!("--check-cfg={unescaped}") }
2261    }
2262}
2263
2264#[derive(Subdiagnostic)]
2265#[note(lint_unexpected_cfg_from_external_macro_origin)]
2266#[help(lint_unexpected_cfg_from_external_macro_refer)]
2267pub(crate) struct UnexpectedCfgRustcMacroHelp {
2268    pub macro_kind: &'static str,
2269    pub macro_name: Symbol,
2270}
2271
2272#[derive(Subdiagnostic)]
2273#[note(lint_unexpected_cfg_from_external_macro_origin)]
2274#[help(lint_unexpected_cfg_from_external_macro_refer)]
2275#[help(lint_unexpected_cfg_cargo_update)]
2276pub(crate) struct UnexpectedCfgCargoMacroHelp {
2277    pub macro_kind: &'static str,
2278    pub macro_name: Symbol,
2279    pub crate_name: Symbol,
2280}
2281
2282#[derive(LintDiagnostic)]
2283#[diag(lint_unexpected_cfg_name)]
2284pub(crate) struct UnexpectedCfgName {
2285    #[subdiagnostic]
2286    pub code_sugg: unexpected_cfg_name::CodeSuggestion,
2287    #[subdiagnostic]
2288    pub invocation_help: unexpected_cfg_name::InvocationHelp,
2289
2290    pub name: Symbol,
2291}
2292
2293pub(crate) mod unexpected_cfg_name {
2294    use rustc_errors::DiagSymbolList;
2295    use rustc_macros::Subdiagnostic;
2296    use rustc_span::{Ident, Span, Symbol};
2297
2298    #[derive(Subdiagnostic)]
2299    pub(crate) enum CodeSuggestion {
2300        #[help(lint_unexpected_cfg_define_features)]
2301        DefineFeatures,
2302        #[multipart_suggestion(
2303            lint_unexpected_cfg_name_version_syntax,
2304            applicability = "machine-applicable"
2305        )]
2306        VersionSyntax {
2307            #[suggestion_part(code = "(")]
2308            between_name_and_value: Span,
2309            #[suggestion_part(code = ")")]
2310            after_value: Span,
2311        },
2312        #[suggestion(
2313            lint_unexpected_cfg_name_similar_name_value,
2314            applicability = "maybe-incorrect",
2315            code = "{code}"
2316        )]
2317        SimilarNameAndValue {
2318            #[primary_span]
2319            span: Span,
2320            code: String,
2321        },
2322        #[suggestion(
2323            lint_unexpected_cfg_name_similar_name_no_value,
2324            applicability = "maybe-incorrect",
2325            code = "{code}"
2326        )]
2327        SimilarNameNoValue {
2328            #[primary_span]
2329            span: Span,
2330            code: String,
2331        },
2332        #[suggestion(
2333            lint_unexpected_cfg_name_similar_name_different_values,
2334            applicability = "maybe-incorrect",
2335            code = "{code}"
2336        )]
2337        SimilarNameDifferentValues {
2338            #[primary_span]
2339            span: Span,
2340            code: String,
2341            #[subdiagnostic]
2342            expected: Option<ExpectedValues>,
2343        },
2344        #[suggestion(
2345            lint_unexpected_cfg_name_similar_name,
2346            applicability = "maybe-incorrect",
2347            code = "{code}"
2348        )]
2349        SimilarName {
2350            #[primary_span]
2351            span: Span,
2352            code: String,
2353            #[subdiagnostic]
2354            expected: Option<ExpectedValues>,
2355        },
2356        SimilarValues {
2357            #[subdiagnostic]
2358            with_similar_values: Vec<FoundWithSimilarValue>,
2359            #[subdiagnostic]
2360            expected_names: Option<ExpectedNames>,
2361        },
2362    }
2363
2364    #[derive(Subdiagnostic)]
2365    #[help(lint_unexpected_cfg_name_expected_values)]
2366    pub(crate) struct ExpectedValues {
2367        pub best_match: Symbol,
2368        pub possibilities: DiagSymbolList,
2369    }
2370
2371    #[derive(Subdiagnostic)]
2372    #[suggestion(
2373        lint_unexpected_cfg_name_with_similar_value,
2374        applicability = "maybe-incorrect",
2375        code = "{code}"
2376    )]
2377    pub(crate) struct FoundWithSimilarValue {
2378        #[primary_span]
2379        pub span: Span,
2380        pub code: String,
2381    }
2382
2383    #[derive(Subdiagnostic)]
2384    #[help_once(lint_unexpected_cfg_name_expected_names)]
2385    pub(crate) struct ExpectedNames {
2386        pub possibilities: DiagSymbolList<Ident>,
2387        pub and_more: usize,
2388    }
2389
2390    #[derive(Subdiagnostic)]
2391    pub(crate) enum InvocationHelp {
2392        #[note(lint_unexpected_cfg_doc_cargo)]
2393        Cargo {
2394            #[subdiagnostic]
2395            macro_help: Option<super::UnexpectedCfgCargoMacroHelp>,
2396            #[subdiagnostic]
2397            help: Option<super::UnexpectedCfgCargoHelp>,
2398        },
2399        #[note(lint_unexpected_cfg_doc_rustc)]
2400        Rustc {
2401            #[subdiagnostic]
2402            macro_help: Option<super::UnexpectedCfgRustcMacroHelp>,
2403            #[subdiagnostic]
2404            help: super::UnexpectedCfgRustcHelp,
2405        },
2406    }
2407}
2408
2409#[derive(LintDiagnostic)]
2410#[diag(lint_unexpected_cfg_value)]
2411pub(crate) struct UnexpectedCfgValue {
2412    #[subdiagnostic]
2413    pub code_sugg: unexpected_cfg_value::CodeSuggestion,
2414    #[subdiagnostic]
2415    pub invocation_help: unexpected_cfg_value::InvocationHelp,
2416
2417    pub has_value: bool,
2418    pub value: String,
2419}
2420
2421pub(crate) mod unexpected_cfg_value {
2422    use rustc_errors::DiagSymbolList;
2423    use rustc_macros::Subdiagnostic;
2424    use rustc_span::{Span, Symbol};
2425
2426    #[derive(Subdiagnostic)]
2427    pub(crate) enum CodeSuggestion {
2428        ChangeValue {
2429            #[subdiagnostic]
2430            expected_values: ExpectedValues,
2431            #[subdiagnostic]
2432            suggestion: Option<ChangeValueSuggestion>,
2433        },
2434        #[note(lint_unexpected_cfg_value_no_expected_value)]
2435        RemoveValue {
2436            #[subdiagnostic]
2437            suggestion: Option<RemoveValueSuggestion>,
2438
2439            name: Symbol,
2440        },
2441        #[note(lint_unexpected_cfg_value_no_expected_values)]
2442        RemoveCondition {
2443            #[subdiagnostic]
2444            suggestion: RemoveConditionSuggestion,
2445
2446            name: Symbol,
2447        },
2448    }
2449
2450    #[derive(Subdiagnostic)]
2451    pub(crate) enum ChangeValueSuggestion {
2452        #[suggestion(
2453            lint_unexpected_cfg_value_similar_name,
2454            code = r#""{best_match}""#,
2455            applicability = "maybe-incorrect"
2456        )]
2457        SimilarName {
2458            #[primary_span]
2459            span: Span,
2460            best_match: Symbol,
2461        },
2462        #[suggestion(
2463            lint_unexpected_cfg_value_specify_value,
2464            code = r#" = "{first_possibility}""#,
2465            applicability = "maybe-incorrect"
2466        )]
2467        SpecifyValue {
2468            #[primary_span]
2469            span: Span,
2470            first_possibility: Symbol,
2471        },
2472    }
2473
2474    #[derive(Subdiagnostic)]
2475    #[suggestion(
2476        lint_unexpected_cfg_value_remove_value,
2477        code = "",
2478        applicability = "maybe-incorrect"
2479    )]
2480    pub(crate) struct RemoveValueSuggestion {
2481        #[primary_span]
2482        pub span: Span,
2483    }
2484
2485    #[derive(Subdiagnostic)]
2486    #[suggestion(
2487        lint_unexpected_cfg_value_remove_condition,
2488        code = "",
2489        applicability = "maybe-incorrect"
2490    )]
2491    pub(crate) struct RemoveConditionSuggestion {
2492        #[primary_span]
2493        pub span: Span,
2494    }
2495
2496    #[derive(Subdiagnostic)]
2497    #[note(lint_unexpected_cfg_value_expected_values)]
2498    pub(crate) struct ExpectedValues {
2499        pub name: Symbol,
2500        pub have_none_possibility: bool,
2501        pub possibilities: DiagSymbolList,
2502        pub and_more: usize,
2503    }
2504
2505    #[derive(Subdiagnostic)]
2506    pub(crate) enum InvocationHelp {
2507        #[note(lint_unexpected_cfg_doc_cargo)]
2508        Cargo {
2509            #[subdiagnostic]
2510            help: Option<CargoHelp>,
2511            #[subdiagnostic]
2512            macro_help: Option<super::UnexpectedCfgCargoMacroHelp>,
2513        },
2514        #[note(lint_unexpected_cfg_doc_rustc)]
2515        Rustc {
2516            #[subdiagnostic]
2517            help: Option<super::UnexpectedCfgRustcHelp>,
2518            #[subdiagnostic]
2519            macro_help: Option<super::UnexpectedCfgRustcMacroHelp>,
2520        },
2521    }
2522
2523    #[derive(Subdiagnostic)]
2524    pub(crate) enum CargoHelp {
2525        #[help(lint_unexpected_cfg_value_add_feature)]
2526        AddFeature {
2527            value: Symbol,
2528        },
2529        #[help(lint_unexpected_cfg_define_features)]
2530        DefineFeatures,
2531        Other(#[subdiagnostic] super::UnexpectedCfgCargoHelp),
2532    }
2533}
2534
2535#[derive(LintDiagnostic)]
2536#[diag(lint_unexpected_builtin_cfg)]
2537#[note(lint_controlled_by)]
2538#[note(lint_incoherent)]
2539pub(crate) struct UnexpectedBuiltinCfg {
2540    pub(crate) cfg: String,
2541    pub(crate) cfg_name: Symbol,
2542    pub(crate) controlled_by: &'static str,
2543}
2544
2545#[derive(LintDiagnostic)]
2546#[diag(lint_macro_use_deprecated)]
2547#[help]
2548pub(crate) struct MacroUseDeprecated;
2549
2550#[derive(LintDiagnostic)]
2551#[diag(lint_unused_macro_use)]
2552pub(crate) struct UnusedMacroUse;
2553
2554#[derive(LintDiagnostic)]
2555#[diag(lint_private_extern_crate_reexport, code = E0365)]
2556pub(crate) struct PrivateExternCrateReexport {
2557    pub ident: Ident,
2558    #[suggestion(code = "pub ", style = "verbose", applicability = "maybe-incorrect")]
2559    pub sugg: Span,
2560}
2561
2562#[derive(LintDiagnostic)]
2563#[diag(lint_unused_label)]
2564pub(crate) struct UnusedLabel;
2565
2566#[derive(LintDiagnostic)]
2567#[diag(lint_macro_is_private)]
2568pub(crate) struct MacroIsPrivate {
2569    pub ident: Ident,
2570}
2571
2572#[derive(LintDiagnostic)]
2573#[diag(lint_unused_macro_definition)]
2574pub(crate) struct UnusedMacroDefinition {
2575    pub name: Symbol,
2576}
2577
2578#[derive(LintDiagnostic)]
2579#[diag(lint_macro_rule_never_used)]
2580pub(crate) struct MacroRuleNeverUsed {
2581    pub n: usize,
2582    pub name: Symbol,
2583}
2584
2585pub(crate) struct UnstableFeature {
2586    pub msg: DiagMessage,
2587}
2588
2589impl<'a> LintDiagnostic<'a, ()> for UnstableFeature {
2590    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
2591        diag.primary_message(self.msg);
2592    }
2593}
2594
2595#[derive(LintDiagnostic)]
2596#[diag(lint_avoid_intel_syntax)]
2597pub(crate) struct AvoidIntelSyntax;
2598
2599#[derive(LintDiagnostic)]
2600#[diag(lint_avoid_att_syntax)]
2601pub(crate) struct AvoidAttSyntax;
2602
2603#[derive(LintDiagnostic)]
2604#[diag(lint_incomplete_include)]
2605pub(crate) struct IncompleteInclude;
2606
2607#[derive(LintDiagnostic)]
2608#[diag(lint_unnameable_test_items)]
2609pub(crate) struct UnnameableTestItems;
2610
2611#[derive(LintDiagnostic)]
2612#[diag(lint_duplicate_macro_attribute)]
2613pub(crate) struct DuplicateMacroAttribute;
2614
2615#[derive(LintDiagnostic)]
2616#[diag(lint_cfg_attr_no_attributes)]
2617pub(crate) struct CfgAttrNoAttributes;
2618
2619#[derive(LintDiagnostic)]
2620#[diag(lint_missing_fragment_specifier)]
2621pub(crate) struct MissingFragmentSpecifier;
2622
2623#[derive(LintDiagnostic)]
2624#[diag(lint_metavariable_still_repeating)]
2625pub(crate) struct MetaVariableStillRepeating {
2626    pub name: MacroRulesNormalizedIdent,
2627}
2628
2629#[derive(LintDiagnostic)]
2630#[diag(lint_metavariable_wrong_operator)]
2631pub(crate) struct MetaVariableWrongOperator;
2632
2633#[derive(LintDiagnostic)]
2634#[diag(lint_duplicate_matcher_binding)]
2635pub(crate) struct DuplicateMatcherBinding;
2636
2637#[derive(LintDiagnostic)]
2638#[diag(lint_unknown_macro_variable)]
2639pub(crate) struct UnknownMacroVariable {
2640    pub name: MacroRulesNormalizedIdent,
2641}
2642
2643#[derive(LintDiagnostic)]
2644#[diag(lint_unused_crate_dependency)]
2645#[help]
2646pub(crate) struct UnusedCrateDependency {
2647    pub extern_crate: Symbol,
2648    pub local_crate: Symbol,
2649}
2650
2651#[derive(LintDiagnostic)]
2652#[diag(lint_ill_formed_attribute_input)]
2653pub(crate) struct IllFormedAttributeInput {
2654    pub num_suggestions: usize,
2655    pub suggestions: DiagArgValue,
2656}
2657
2658#[derive(LintDiagnostic)]
2659pub(crate) enum InnerAttributeUnstable {
2660    #[diag(lint_inner_macro_attribute_unstable)]
2661    InnerMacroAttribute,
2662    #[diag(lint_custom_inner_attribute_unstable)]
2663    CustomInnerAttribute,
2664}
2665
2666#[derive(LintDiagnostic)]
2667#[diag(lint_unknown_diagnostic_attribute)]
2668pub(crate) struct UnknownDiagnosticAttribute {
2669    #[subdiagnostic]
2670    pub typo: Option<UnknownDiagnosticAttributeTypoSugg>,
2671}
2672
2673#[derive(Subdiagnostic)]
2674#[suggestion(
2675    lint_unknown_diagnostic_attribute_typo_sugg,
2676    style = "verbose",
2677    code = "{typo_name}",
2678    applicability = "machine-applicable"
2679)]
2680pub(crate) struct UnknownDiagnosticAttributeTypoSugg {
2681    #[primary_span]
2682    pub span: Span,
2683    pub typo_name: Symbol,
2684}
2685
2686#[derive(LintDiagnostic)]
2687#[diag(lint_unicode_text_flow)]
2688#[note]
2689pub(crate) struct UnicodeTextFlow {
2690    #[label]
2691    pub comment_span: Span,
2692    #[subdiagnostic]
2693    pub characters: Vec<UnicodeCharNoteSub>,
2694    #[subdiagnostic]
2695    pub suggestions: Option<UnicodeTextFlowSuggestion>,
2696
2697    pub num_codepoints: usize,
2698}
2699
2700#[derive(Subdiagnostic)]
2701#[label(lint_label_comment_char)]
2702pub(crate) struct UnicodeCharNoteSub {
2703    #[primary_span]
2704    pub span: Span,
2705    pub c_debug: String,
2706}
2707
2708#[derive(Subdiagnostic)]
2709#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable", style = "hidden")]
2710pub(crate) struct UnicodeTextFlowSuggestion {
2711    #[suggestion_part(code = "")]
2712    pub spans: Vec<Span>,
2713}
2714
2715#[derive(LintDiagnostic)]
2716#[diag(lint_abs_path_with_module)]
2717pub(crate) struct AbsPathWithModule {
2718    #[subdiagnostic]
2719    pub sugg: AbsPathWithModuleSugg,
2720}
2721
2722#[derive(Subdiagnostic)]
2723#[suggestion(lint_suggestion, code = "{replacement}")]
2724pub(crate) struct AbsPathWithModuleSugg {
2725    #[primary_span]
2726    pub span: Span,
2727    #[applicability]
2728    pub applicability: Applicability,
2729    pub replacement: String,
2730}
2731
2732#[derive(LintDiagnostic)]
2733#[diag(lint_proc_macro_derive_resolution_fallback)]
2734pub(crate) struct ProcMacroDeriveResolutionFallback {
2735    #[label]
2736    pub span: Span,
2737    pub ns: Namespace,
2738    pub ident: Ident,
2739}
2740
2741#[derive(LintDiagnostic)]
2742#[diag(lint_macro_expanded_macro_exports_accessed_by_absolute_paths)]
2743pub(crate) struct MacroExpandedMacroExportsAccessedByAbsolutePaths {
2744    #[note]
2745    pub definition: Span,
2746}
2747
2748#[derive(LintDiagnostic)]
2749#[diag(lint_hidden_lifetime_parameters)]
2750pub(crate) struct ElidedLifetimesInPaths {
2751    #[subdiagnostic]
2752    pub subdiag: ElidedLifetimeInPathSubdiag,
2753}
2754
2755pub(crate) struct ElidedNamedLifetime {
2756    pub span: Span,
2757    pub kind: MissingLifetimeKind,
2758    pub name: Symbol,
2759    pub declaration: Option<Span>,
2760}
2761
2762impl<G: EmissionGuarantee> LintDiagnostic<'_, G> for ElidedNamedLifetime {
2763    fn decorate_lint(self, diag: &mut rustc_errors::Diag<'_, G>) {
2764        let Self { span, kind, name, declaration } = self;
2765        diag.primary_message(fluent::lint_elided_named_lifetime);
2766        diag.arg("name", name);
2767        diag.span_label(span, fluent::lint_label_elided);
2768        if let Some(declaration) = declaration {
2769            diag.span_label(declaration, fluent::lint_label_named);
2770        }
2771        // FIXME(GrigorenkoPV): this `if` and `return` should be removed,
2772        //  but currently this lint's suggestions can conflict with those of `clippy::needless_lifetimes`:
2773        //  https://github.com/rust-lang/rust/pull/129840#issuecomment-2323349119
2774        // HACK: `'static` suggestions will never sonflict, emit only those for now.
2775        if name != kw::StaticLifetime {
2776            return;
2777        }
2778        match kind {
2779            MissingLifetimeKind::Underscore => diag.span_suggestion_verbose(
2780                span,
2781                fluent::lint_suggestion,
2782                format!("{name}"),
2783                Applicability::MachineApplicable,
2784            ),
2785            MissingLifetimeKind::Ampersand => diag.span_suggestion_verbose(
2786                span.shrink_to_hi(),
2787                fluent::lint_suggestion,
2788                format!("{name} "),
2789                Applicability::MachineApplicable,
2790            ),
2791            MissingLifetimeKind::Comma => diag.span_suggestion_verbose(
2792                span.shrink_to_hi(),
2793                fluent::lint_suggestion,
2794                format!("{name}, "),
2795                Applicability::MachineApplicable,
2796            ),
2797            MissingLifetimeKind::Brackets => diag.span_suggestion_verbose(
2798                span.shrink_to_hi(),
2799                fluent::lint_suggestion,
2800                format!("<{name}>"),
2801                Applicability::MachineApplicable,
2802            ),
2803        };
2804    }
2805}
2806
2807#[derive(LintDiagnostic)]
2808#[diag(lint_invalid_crate_type_value)]
2809pub(crate) struct UnknownCrateTypes {
2810    #[subdiagnostic]
2811    pub sugg: Option<UnknownCrateTypesSub>,
2812}
2813
2814#[derive(Subdiagnostic)]
2815#[suggestion(lint_suggestion, code = r#""{candidate}""#, applicability = "maybe-incorrect")]
2816pub(crate) struct UnknownCrateTypesSub {
2817    #[primary_span]
2818    pub span: Span,
2819    pub candidate: Symbol,
2820}
2821
2822#[derive(LintDiagnostic)]
2823#[diag(lint_unused_imports)]
2824pub(crate) struct UnusedImports {
2825    #[subdiagnostic]
2826    pub sugg: UnusedImportsSugg,
2827    #[help]
2828    pub test_module_span: Option<Span>,
2829
2830    pub span_snippets: DiagArgValue,
2831    pub num_snippets: usize,
2832}
2833
2834#[derive(Subdiagnostic)]
2835pub(crate) enum UnusedImportsSugg {
2836    #[suggestion(
2837        lint_suggestion_remove_whole_use,
2838        applicability = "machine-applicable",
2839        code = "",
2840        style = "tool-only"
2841    )]
2842    RemoveWholeUse {
2843        #[primary_span]
2844        span: Span,
2845    },
2846    #[multipart_suggestion(
2847        lint_suggestion_remove_imports,
2848        applicability = "machine-applicable",
2849        style = "tool-only"
2850    )]
2851    RemoveImports {
2852        #[suggestion_part(code = "")]
2853        remove_spans: Vec<Span>,
2854        num_to_remove: usize,
2855    },
2856}
2857
2858#[derive(LintDiagnostic)]
2859#[diag(lint_redundant_import)]
2860pub(crate) struct RedundantImport {
2861    #[subdiagnostic]
2862    pub subs: Vec<RedundantImportSub>,
2863
2864    pub ident: Ident,
2865}
2866
2867#[derive(Subdiagnostic)]
2868pub(crate) enum RedundantImportSub {
2869    #[label(lint_label_imported_here)]
2870    ImportedHere(#[primary_span] Span),
2871    #[label(lint_label_defined_here)]
2872    DefinedHere(#[primary_span] Span),
2873    #[label(lint_label_imported_prelude)]
2874    ImportedPrelude(#[primary_span] Span),
2875    #[label(lint_label_defined_prelude)]
2876    DefinedPrelude(#[primary_span] Span),
2877}
2878
2879#[derive(LintDiagnostic)]
2880#[diag(lint_unused_doc_comment)]
2881#[help]
2882pub(crate) struct UnusedDocComment {
2883    #[label]
2884    pub span: Span,
2885}
2886
2887#[derive(LintDiagnostic)]
2888pub(crate) enum PatternsInFnsWithoutBody {
2889    #[diag(lint_pattern_in_foreign)]
2890    Foreign {
2891        #[subdiagnostic]
2892        sub: PatternsInFnsWithoutBodySub,
2893    },
2894    #[diag(lint_pattern_in_bodiless)]
2895    Bodiless {
2896        #[subdiagnostic]
2897        sub: PatternsInFnsWithoutBodySub,
2898    },
2899}
2900
2901#[derive(Subdiagnostic)]
2902#[suggestion(lint_remove_mut_from_pattern, code = "{ident}", applicability = "machine-applicable")]
2903pub(crate) struct PatternsInFnsWithoutBodySub {
2904    #[primary_span]
2905    pub span: Span,
2906
2907    pub ident: Ident,
2908}
2909
2910#[derive(LintDiagnostic)]
2911#[diag(lint_extern_without_abi)]
2912pub(crate) struct MissingAbi {
2913    #[suggestion(code = "extern {default_abi}", applicability = "machine-applicable")]
2914    pub span: Span,
2915    pub default_abi: ExternAbi,
2916}
2917
2918#[derive(LintDiagnostic)]
2919#[diag(lint_legacy_derive_helpers)]
2920pub(crate) struct LegacyDeriveHelpers {
2921    #[label]
2922    pub span: Span,
2923}
2924
2925#[derive(LintDiagnostic)]
2926#[diag(lint_or_patterns_back_compat)]
2927pub(crate) struct OrPatternsBackCompat {
2928    #[suggestion(code = "{suggestion}", applicability = "machine-applicable")]
2929    pub span: Span,
2930    pub suggestion: String,
2931}
2932
2933#[derive(LintDiagnostic)]
2934#[diag(lint_reserved_prefix)]
2935pub(crate) struct ReservedPrefix {
2936    #[label]
2937    pub label: Span,
2938    #[suggestion(code = " ", applicability = "machine-applicable")]
2939    pub suggestion: Span,
2940
2941    pub prefix: String,
2942}
2943
2944#[derive(LintDiagnostic)]
2945#[diag(lint_raw_prefix)]
2946pub(crate) struct RawPrefix {
2947    #[label]
2948    pub label: Span,
2949    #[suggestion(code = " ", applicability = "machine-applicable")]
2950    pub suggestion: Span,
2951}
2952
2953#[derive(LintDiagnostic)]
2954#[diag(lint_unused_builtin_attribute)]
2955pub(crate) struct UnusedBuiltinAttribute {
2956    #[note]
2957    pub invoc_span: Span,
2958
2959    pub attr_name: Symbol,
2960    pub macro_name: String,
2961}
2962
2963#[derive(LintDiagnostic)]
2964#[diag(lint_trailing_semi_macro)]
2965pub(crate) struct TrailingMacro {
2966    #[note(lint_note1)]
2967    #[note(lint_note2)]
2968    pub is_trailing: bool,
2969
2970    pub name: Ident,
2971}
2972
2973#[derive(LintDiagnostic)]
2974#[diag(lint_break_with_label_and_loop)]
2975pub(crate) struct BreakWithLabelAndLoop {
2976    #[subdiagnostic]
2977    pub sub: BreakWithLabelAndLoopSub,
2978}
2979
2980#[derive(Subdiagnostic)]
2981#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
2982pub(crate) struct BreakWithLabelAndLoopSub {
2983    #[suggestion_part(code = "(")]
2984    pub left: Span,
2985    #[suggestion_part(code = ")")]
2986    pub right: Span,
2987}
2988
2989#[derive(LintDiagnostic)]
2990#[diag(lint_deprecated_where_clause_location)]
2991#[note]
2992pub(crate) struct DeprecatedWhereClauseLocation {
2993    #[subdiagnostic]
2994    pub suggestion: DeprecatedWhereClauseLocationSugg,
2995}
2996
2997#[derive(Subdiagnostic)]
2998pub(crate) enum DeprecatedWhereClauseLocationSugg {
2999    #[multipart_suggestion(lint_suggestion_move_to_end, applicability = "machine-applicable")]
3000    MoveToEnd {
3001        #[suggestion_part(code = "")]
3002        left: Span,
3003        #[suggestion_part(code = "{sugg}")]
3004        right: Span,
3005
3006        sugg: String,
3007    },
3008    #[suggestion(lint_suggestion_remove_where, code = "", applicability = "machine-applicable")]
3009    RemoveWhere {
3010        #[primary_span]
3011        span: Span,
3012    },
3013}
3014
3015#[derive(LintDiagnostic)]
3016#[diag(lint_missing_unsafe_on_extern)]
3017pub(crate) struct MissingUnsafeOnExtern {
3018    #[suggestion(code = "unsafe ", applicability = "machine-applicable")]
3019    pub suggestion: Span,
3020}
3021
3022#[derive(LintDiagnostic)]
3023#[diag(lint_single_use_lifetime)]
3024pub(crate) struct SingleUseLifetime {
3025    #[label(lint_label_param)]
3026    pub param_span: Span,
3027    #[label(lint_label_use)]
3028    pub use_span: Span,
3029    #[subdiagnostic]
3030    pub suggestion: Option<SingleUseLifetimeSugg>,
3031
3032    pub ident: Ident,
3033}
3034
3035#[derive(Subdiagnostic)]
3036#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
3037pub(crate) struct SingleUseLifetimeSugg {
3038    #[suggestion_part(code = "")]
3039    pub deletion_span: Option<Span>,
3040    #[suggestion_part(code = "{replace_lt}")]
3041    pub use_span: Span,
3042
3043    pub replace_lt: String,
3044}
3045
3046#[derive(LintDiagnostic)]
3047#[diag(lint_unused_lifetime)]
3048pub(crate) struct UnusedLifetime {
3049    #[suggestion(code = "", applicability = "machine-applicable")]
3050    pub deletion_span: Option<Span>,
3051
3052    pub ident: Ident,
3053}
3054
3055#[derive(LintDiagnostic)]
3056#[diag(lint_named_argument_used_positionally)]
3057pub(crate) struct NamedArgumentUsedPositionally {
3058    #[label(lint_label_named_arg)]
3059    pub named_arg_sp: Span,
3060    #[label(lint_label_position_arg)]
3061    pub position_label_sp: Option<Span>,
3062    #[suggestion(style = "verbose", code = "{name}", applicability = "maybe-incorrect")]
3063    pub suggestion: Option<Span>,
3064
3065    pub name: String,
3066    pub named_arg_name: String,
3067}
3068
3069#[derive(LintDiagnostic)]
3070#[diag(lint_byte_slice_in_packed_struct_with_derive)]
3071#[help]
3072pub(crate) struct ByteSliceInPackedStructWithDerive {
3073    // FIXME: make this translatable
3074    pub ty: String,
3075}
3076
3077#[derive(LintDiagnostic)]
3078#[diag(lint_unused_extern_crate)]
3079pub(crate) struct UnusedExternCrate {
3080    #[label]
3081    pub span: Span,
3082    #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
3083    pub removal_span: Span,
3084}
3085
3086#[derive(LintDiagnostic)]
3087#[diag(lint_extern_crate_not_idiomatic)]
3088pub(crate) struct ExternCrateNotIdiomatic {
3089    #[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")]
3090    pub span: Span,
3091
3092    pub code: &'static str,
3093}
3094
3095// FIXME: make this translatable
3096pub(crate) struct AmbiguousGlobImports {
3097    pub ambiguity: AmbiguityErrorDiag,
3098}
3099
3100impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports {
3101    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
3102        diag.primary_message(self.ambiguity.msg.clone());
3103        rustc_errors::report_ambiguity_error(diag, self.ambiguity);
3104    }
3105}
3106
3107#[derive(LintDiagnostic)]
3108#[diag(lint_ambiguous_glob_reexport)]
3109pub(crate) struct AmbiguousGlobReexports {
3110    #[label(lint_label_first_reexport)]
3111    pub first_reexport: Span,
3112    #[label(lint_label_duplicate_reexport)]
3113    pub duplicate_reexport: Span,
3114
3115    pub name: String,
3116    // FIXME: make this translatable
3117    pub namespace: String,
3118}
3119
3120#[derive(LintDiagnostic)]
3121#[diag(lint_hidden_glob_reexport)]
3122pub(crate) struct HiddenGlobReexports {
3123    #[note(lint_note_glob_reexport)]
3124    pub glob_reexport: Span,
3125    #[note(lint_note_private_item)]
3126    pub private_item: Span,
3127
3128    pub name: String,
3129    // FIXME: make this translatable
3130    pub namespace: String,
3131}
3132
3133#[derive(LintDiagnostic)]
3134#[diag(lint_unnecessary_qualification)]
3135pub(crate) struct UnusedQualifications {
3136    #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
3137    pub removal_span: Span,
3138}
3139
3140#[derive(LintDiagnostic)]
3141#[diag(lint_associated_const_elided_lifetime)]
3142pub(crate) struct AssociatedConstElidedLifetime {
3143    #[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")]
3144    pub span: Span,
3145
3146    pub code: &'static str,
3147    pub elided: bool,
3148    #[note]
3149    pub lifetimes_in_scope: MultiSpan,
3150}
3151
3152#[derive(LintDiagnostic)]
3153#[diag(lint_redundant_import_visibility)]
3154pub(crate) struct RedundantImportVisibility {
3155    #[note]
3156    pub span: Span,
3157    #[help]
3158    pub help: (),
3159
3160    pub import_vis: String,
3161    pub max_vis: String,
3162}
3163
3164#[derive(LintDiagnostic)]
3165#[diag(lint_unsafe_attr_outside_unsafe)]
3166pub(crate) struct UnsafeAttrOutsideUnsafe {
3167    #[label]
3168    pub span: Span,
3169    #[subdiagnostic]
3170    pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
3171}
3172
3173#[derive(Subdiagnostic)]
3174#[multipart_suggestion(
3175    lint_unsafe_attr_outside_unsafe_suggestion,
3176    applicability = "machine-applicable"
3177)]
3178pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion {
3179    #[suggestion_part(code = "unsafe(")]
3180    pub left: Span,
3181    #[suggestion_part(code = ")")]
3182    pub right: Span,
3183}
3184
3185#[derive(LintDiagnostic)]
3186#[diag(lint_out_of_scope_macro_calls)]
3187#[help]
3188pub(crate) struct OutOfScopeMacroCalls {
3189    #[label]
3190    pub span: Span,
3191    pub path: String,
3192    pub location: String,
3193}
3194
3195#[derive(LintDiagnostic)]
3196#[diag(lint_static_mut_refs_lint)]
3197pub(crate) struct RefOfMutStatic<'a> {
3198    #[label]
3199    pub span: Span,
3200    #[subdiagnostic]
3201    pub sugg: Option<MutRefSugg>,
3202    pub shared_label: &'a str,
3203    #[note(lint_shared_note)]
3204    pub shared_note: bool,
3205    #[note(lint_mut_note)]
3206    pub mut_note: bool,
3207}
3208
3209#[derive(Subdiagnostic)]
3210pub(crate) enum MutRefSugg {
3211    #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
3212    Shared {
3213        #[suggestion_part(code = "&raw const ")]
3214        span: Span,
3215    },
3216    #[multipart_suggestion(
3217        lint_suggestion_mut,
3218        style = "verbose",
3219        applicability = "maybe-incorrect"
3220    )]
3221    Mut {
3222        #[suggestion_part(code = "&raw mut ")]
3223        span: Span,
3224    },
3225}
3226
3227#[derive(LintDiagnostic)]
3228#[diag(lint_unqualified_local_imports)]
3229pub(crate) struct UnqualifiedLocalImportsDiag {}
3230
3231#[derive(LintDiagnostic)]
3232#[diag(lint_reserved_string)]
3233pub(crate) struct ReservedString {
3234    #[suggestion(code = " ", applicability = "machine-applicable")]
3235    pub suggestion: Span,
3236}
3237
3238#[derive(LintDiagnostic)]
3239#[diag(lint_reserved_multihash)]
3240pub(crate) struct ReservedMultihash {
3241    #[suggestion(code = " ", applicability = "machine-applicable")]
3242    pub suggestion: Span,
3243}