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