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