1#![allow(rustc::untranslatable_diagnostic)]
2use std::num::NonZero;
3
4use rustc_abi::ExternAbi;
5use rustc_errors::codes::*;
6use rustc_errors::{
7 Applicability, Diag, DiagArgValue, DiagMessage, DiagStyledString, ElidedLifetimeInPathSubdiag,
8 EmissionGuarantee, LintDiagnostic, MultiSpan, Subdiagnostic, SuggestionStyle,
9};
10use rustc_hir as hir;
11use rustc_hir::def::Namespace;
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, MacroRulesNormalizedIdent, 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_hidden_unicode_codepoints)]
823#[note]
824pub(crate) struct HiddenUnicodeCodepointsDiag<'a> {
825 pub label: &'a str,
826 pub count: usize,
827 #[label]
828 pub span_label: Span,
829 #[subdiagnostic]
830 pub labels: Option<HiddenUnicodeCodepointsDiagLabels>,
831 #[subdiagnostic]
832 pub sub: HiddenUnicodeCodepointsDiagSub,
833}
834
835pub(crate) struct HiddenUnicodeCodepointsDiagLabels {
836 pub spans: Vec<(char, Span)>,
837}
838
839impl Subdiagnostic for HiddenUnicodeCodepointsDiagLabels {
840 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
841 for (c, span) in self.spans {
842 diag.span_label(span, format!("{c:?}"));
843 }
844 }
845}
846
847pub(crate) enum HiddenUnicodeCodepointsDiagSub {
848 Escape { spans: Vec<(char, Span)> },
849 NoEscape { spans: Vec<(char, Span)> },
850}
851
852impl Subdiagnostic for HiddenUnicodeCodepointsDiagSub {
854 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
855 match self {
856 HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
857 diag.multipart_suggestion_with_style(
858 fluent::lint_suggestion_remove,
859 spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
860 Applicability::MachineApplicable,
861 SuggestionStyle::HideCodeAlways,
862 );
863 diag.multipart_suggestion(
864 fluent::lint_suggestion_escape,
865 spans
866 .into_iter()
867 .map(|(c, span)| {
868 let c = format!("{c:?}");
869 (span, c[1..c.len() - 1].to_string())
870 })
871 .collect(),
872 Applicability::MachineApplicable,
873 );
874 }
875 HiddenUnicodeCodepointsDiagSub::NoEscape { spans } => {
876 diag.arg(
880 "escaped",
881 spans
882 .into_iter()
883 .map(|(c, _)| format!("{c:?}"))
884 .collect::<Vec<String>>()
885 .join(", "),
886 );
887 diag.note(fluent::lint_suggestion_remove);
888 diag.note(fluent::lint_no_suggestion_note_escape);
889 }
890 }
891 }
892}
893
894#[derive(LintDiagnostic)]
896#[diag(lint_map_unit_fn)]
897#[note]
898pub(crate) struct MappingToUnit {
899 #[label(lint_function_label)]
900 pub function_label: Span,
901 #[label(lint_argument_label)]
902 pub argument_label: Span,
903 #[label(lint_map_label)]
904 pub map_label: Span,
905 #[suggestion(style = "verbose", code = "{replace}", applicability = "maybe-incorrect")]
906 pub suggestion: Span,
907 pub replace: String,
908}
909
910#[derive(LintDiagnostic)]
912#[diag(lint_default_hash_types)]
913#[note]
914pub(crate) struct DefaultHashTypesDiag<'a> {
915 pub preferred: &'a str,
916 pub used: Symbol,
917}
918
919#[derive(LintDiagnostic)]
920#[diag(lint_query_instability)]
921#[note]
922pub(crate) struct QueryInstability {
923 pub query: Symbol,
924}
925
926#[derive(LintDiagnostic)]
927#[diag(lint_query_untracked)]
928#[note]
929pub(crate) struct QueryUntracked {
930 pub method: Symbol,
931}
932
933#[derive(LintDiagnostic)]
934#[diag(lint_span_use_eq_ctxt)]
935pub(crate) struct SpanUseEqCtxtDiag;
936
937#[derive(LintDiagnostic)]
938#[diag(lint_symbol_intern_string_literal)]
939#[help]
940pub(crate) struct SymbolInternStringLiteralDiag;
941
942#[derive(LintDiagnostic)]
943#[diag(lint_tykind_kind)]
944pub(crate) struct TykindKind {
945 #[suggestion(code = "ty", applicability = "maybe-incorrect")]
946 pub suggestion: Span,
947}
948
949#[derive(LintDiagnostic)]
950#[diag(lint_tykind)]
951#[help]
952pub(crate) struct TykindDiag;
953
954#[derive(LintDiagnostic)]
955#[diag(lint_ty_qualified)]
956pub(crate) struct TyQualified {
957 pub ty: String,
958 #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
959 pub suggestion: Span,
960}
961
962#[derive(LintDiagnostic)]
963#[diag(lint_type_ir_inherent_usage)]
964#[note]
965pub(crate) struct TypeIrInherentUsage;
966
967#[derive(LintDiagnostic)]
968#[diag(lint_type_ir_trait_usage)]
969#[note]
970pub(crate) struct TypeIrTraitUsage;
971
972#[derive(LintDiagnostic)]
973#[diag(lint_type_ir_direct_use)]
974#[note]
975pub(crate) struct TypeIrDirectUse;
976
977#[derive(LintDiagnostic)]
978#[diag(lint_non_glob_import_type_ir_inherent)]
979pub(crate) struct NonGlobImportTypeIrInherent {
980 #[suggestion(code = "{snippet}", applicability = "maybe-incorrect")]
981 pub suggestion: Option<Span>,
982 pub snippet: &'static str,
983}
984
985#[derive(LintDiagnostic)]
986#[diag(lint_lintpass_by_hand)]
987#[help]
988pub(crate) struct LintPassByHand;
989
990#[derive(LintDiagnostic)]
991#[diag(lint_diag_out_of_impl)]
992pub(crate) struct DiagOutOfImpl;
993
994#[derive(LintDiagnostic)]
995#[diag(lint_untranslatable_diag)]
996pub(crate) struct UntranslatableDiag;
997
998#[derive(LintDiagnostic)]
999#[diag(lint_bad_opt_access)]
1000pub(crate) struct BadOptAccessDiag<'a> {
1001 pub msg: &'a str,
1002}
1003
1004#[derive(LintDiagnostic)]
1006pub(crate) enum NonBindingLet {
1007 #[diag(lint_non_binding_let_on_sync_lock)]
1008 SyncLock {
1009 #[label]
1010 pat: Span,
1011 #[subdiagnostic]
1012 sub: NonBindingLetSub,
1013 },
1014 #[diag(lint_non_binding_let_on_drop_type)]
1015 DropType {
1016 #[subdiagnostic]
1017 sub: NonBindingLetSub,
1018 },
1019}
1020
1021pub(crate) struct NonBindingLetSub {
1022 pub suggestion: Span,
1023 pub drop_fn_start_end: Option<(Span, Span)>,
1024 pub is_assign_desugar: bool,
1025}
1026
1027impl Subdiagnostic for NonBindingLetSub {
1028 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1029 let can_suggest_binding = self.drop_fn_start_end.is_some() || !self.is_assign_desugar;
1030
1031 if can_suggest_binding {
1032 let prefix = if self.is_assign_desugar { "let " } else { "" };
1033 diag.span_suggestion_verbose(
1034 self.suggestion,
1035 fluent::lint_non_binding_let_suggestion,
1036 format!("{prefix}_unused"),
1037 Applicability::MachineApplicable,
1038 );
1039 } else {
1040 diag.span_help(self.suggestion, fluent::lint_non_binding_let_suggestion);
1041 }
1042 if let Some(drop_fn_start_end) = self.drop_fn_start_end {
1043 diag.multipart_suggestion(
1044 fluent::lint_non_binding_let_multi_suggestion,
1045 vec![
1046 (drop_fn_start_end.0, "drop(".to_string()),
1047 (drop_fn_start_end.1, ")".to_string()),
1048 ],
1049 Applicability::MachineApplicable,
1050 );
1051 } else {
1052 diag.help(fluent::lint_non_binding_let_multi_drop_fn);
1053 }
1054 }
1055}
1056
1057#[derive(LintDiagnostic)]
1059#[diag(lint_overruled_attribute)]
1060pub(crate) struct OverruledAttributeLint<'a> {
1061 #[label]
1062 pub overruled: Span,
1063 pub lint_level: &'a str,
1064 pub lint_source: Symbol,
1065 #[subdiagnostic]
1066 pub sub: OverruledAttributeSub,
1067}
1068
1069#[derive(LintDiagnostic)]
1070#[diag(lint_deprecated_lint_name)]
1071pub(crate) struct DeprecatedLintName<'a> {
1072 pub name: String,
1073 #[suggestion(code = "{replace}", applicability = "machine-applicable")]
1074 pub suggestion: Span,
1075 pub replace: &'a str,
1076}
1077
1078#[derive(LintDiagnostic)]
1079#[diag(lint_deprecated_lint_name)]
1080#[help]
1081pub(crate) struct DeprecatedLintNameFromCommandLine<'a> {
1082 pub name: String,
1083 pub replace: &'a str,
1084 #[subdiagnostic]
1085 pub requested_level: RequestedLevel<'a>,
1086}
1087
1088#[derive(LintDiagnostic)]
1089#[diag(lint_renamed_lint)]
1090pub(crate) struct RenamedLint<'a> {
1091 pub name: &'a str,
1092 pub replace: &'a str,
1093 #[subdiagnostic]
1094 pub suggestion: RenamedLintSuggestion<'a>,
1095}
1096
1097#[derive(Subdiagnostic)]
1098pub(crate) enum RenamedLintSuggestion<'a> {
1099 #[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")]
1100 WithSpan {
1101 #[primary_span]
1102 suggestion: Span,
1103 replace: &'a str,
1104 },
1105 #[help(lint_help)]
1106 WithoutSpan { replace: &'a str },
1107}
1108
1109#[derive(LintDiagnostic)]
1110#[diag(lint_renamed_lint)]
1111pub(crate) struct RenamedLintFromCommandLine<'a> {
1112 pub name: &'a str,
1113 pub replace: &'a str,
1114 #[subdiagnostic]
1115 pub suggestion: RenamedLintSuggestion<'a>,
1116 #[subdiagnostic]
1117 pub requested_level: RequestedLevel<'a>,
1118}
1119
1120#[derive(LintDiagnostic)]
1121#[diag(lint_removed_lint)]
1122pub(crate) struct RemovedLint<'a> {
1123 pub name: &'a str,
1124 pub reason: &'a str,
1125}
1126
1127#[derive(LintDiagnostic)]
1128#[diag(lint_removed_lint)]
1129pub(crate) struct RemovedLintFromCommandLine<'a> {
1130 pub name: &'a str,
1131 pub reason: &'a str,
1132 #[subdiagnostic]
1133 pub requested_level: RequestedLevel<'a>,
1134}
1135
1136#[derive(LintDiagnostic)]
1137#[diag(lint_unknown_lint)]
1138pub(crate) struct UnknownLint {
1139 pub name: String,
1140 #[subdiagnostic]
1141 pub suggestion: Option<UnknownLintSuggestion>,
1142}
1143
1144#[derive(Subdiagnostic)]
1145pub(crate) enum UnknownLintSuggestion {
1146 #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
1147 WithSpan {
1148 #[primary_span]
1149 suggestion: Span,
1150 replace: Symbol,
1151 from_rustc: bool,
1152 },
1153 #[help(lint_help)]
1154 WithoutSpan { replace: Symbol, from_rustc: bool },
1155}
1156
1157#[derive(LintDiagnostic)]
1158#[diag(lint_unknown_lint, code = E0602)]
1159pub(crate) struct UnknownLintFromCommandLine<'a> {
1160 pub name: String,
1161 #[subdiagnostic]
1162 pub suggestion: Option<UnknownLintSuggestion>,
1163 #[subdiagnostic]
1164 pub requested_level: RequestedLevel<'a>,
1165}
1166
1167#[derive(LintDiagnostic)]
1168#[diag(lint_ignored_unless_crate_specified)]
1169pub(crate) struct IgnoredUnlessCrateSpecified<'a> {
1170 pub level: &'a str,
1171 pub name: Symbol,
1172}
1173
1174#[derive(LintDiagnostic)]
1176#[diag(lint_dangling_pointers_from_temporaries)]
1177#[note]
1178#[help(lint_help_bind)]
1179#[help(lint_help_returned)]
1180#[help(lint_help_visit)]
1181pub(crate) struct DanglingPointersFromTemporaries<'tcx> {
1183 pub callee: Ident,
1184 pub ty: Ty<'tcx>,
1185 #[label(lint_label_ptr)]
1186 pub ptr_span: Span,
1187 #[label(lint_label_temporary)]
1188 pub temporary_span: Span,
1189}
1190
1191#[derive(LintDiagnostic)]
1193#[diag(lint_multiple_supertrait_upcastable)]
1194pub(crate) struct MultipleSupertraitUpcastable {
1195 pub ident: Ident,
1196}
1197
1198#[derive(LintDiagnostic)]
1200#[diag(lint_identifier_non_ascii_char)]
1201pub(crate) struct IdentifierNonAsciiChar;
1202
1203#[derive(LintDiagnostic)]
1204#[diag(lint_identifier_uncommon_codepoints)]
1205#[note]
1206pub(crate) struct IdentifierUncommonCodepoints {
1207 pub codepoints: Vec<char>,
1208 pub codepoints_len: usize,
1209 pub identifier_type: &'static str,
1210}
1211
1212#[derive(LintDiagnostic)]
1213#[diag(lint_confusable_identifier_pair)]
1214pub(crate) struct ConfusableIdentifierPair {
1215 pub existing_sym: Symbol,
1216 pub sym: Symbol,
1217 #[label(lint_other_use)]
1218 pub label: Span,
1219 #[label(lint_current_use)]
1220 pub main_label: Span,
1221}
1222
1223#[derive(LintDiagnostic)]
1224#[diag(lint_mixed_script_confusables)]
1225#[note(lint_includes_note)]
1226#[note]
1227pub(crate) struct MixedScriptConfusables {
1228 pub set: String,
1229 pub includes: String,
1230}
1231
1232pub(crate) struct NonFmtPanicUnused {
1234 pub count: usize,
1235 pub suggestion: Option<Span>,
1236}
1237
1238impl<'a> LintDiagnostic<'a, ()> for NonFmtPanicUnused {
1240 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
1241 diag.primary_message(fluent::lint_non_fmt_panic_unused);
1242 diag.arg("count", self.count);
1243 diag.note(fluent::lint_note);
1244 if let Some(span) = self.suggestion {
1245 diag.span_suggestion(
1246 span.shrink_to_hi(),
1247 fluent::lint_add_args_suggestion,
1248 ", ...",
1249 Applicability::HasPlaceholders,
1250 );
1251 diag.span_suggestion(
1252 span.shrink_to_lo(),
1253 fluent::lint_add_fmt_suggestion,
1254 "\"{}\", ",
1255 Applicability::MachineApplicable,
1256 );
1257 }
1258 }
1259}
1260
1261#[derive(LintDiagnostic)]
1262#[diag(lint_non_fmt_panic_braces)]
1263#[note]
1264pub(crate) struct NonFmtPanicBraces {
1265 pub count: usize,
1266 #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")]
1267 pub suggestion: Option<Span>,
1268}
1269
1270#[derive(LintDiagnostic)]
1272#[diag(lint_non_camel_case_type)]
1273pub(crate) struct NonCamelCaseType<'a> {
1274 pub sort: &'a str,
1275 pub name: &'a str,
1276 #[subdiagnostic]
1277 pub sub: NonCamelCaseTypeSub,
1278}
1279
1280#[derive(Subdiagnostic)]
1281pub(crate) enum NonCamelCaseTypeSub {
1282 #[label(lint_label)]
1283 Label {
1284 #[primary_span]
1285 span: Span,
1286 },
1287 #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
1288 Suggestion {
1289 #[primary_span]
1290 span: Span,
1291 replace: String,
1292 },
1293}
1294
1295#[derive(LintDiagnostic)]
1296#[diag(lint_non_snake_case)]
1297pub(crate) struct NonSnakeCaseDiag<'a> {
1298 pub sort: &'a str,
1299 pub name: &'a str,
1300 pub sc: String,
1301 #[subdiagnostic]
1302 pub sub: NonSnakeCaseDiagSub,
1303}
1304
1305pub(crate) enum NonSnakeCaseDiagSub {
1306 Label { span: Span },
1307 Help,
1308 RenameOrConvertSuggestion { span: Span, suggestion: Ident },
1309 ConvertSuggestion { span: Span, suggestion: String },
1310 SuggestionAndNote { span: Span },
1311}
1312
1313impl Subdiagnostic for NonSnakeCaseDiagSub {
1314 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1315 match self {
1316 NonSnakeCaseDiagSub::Label { span } => {
1317 diag.span_label(span, fluent::lint_label);
1318 }
1319 NonSnakeCaseDiagSub::Help => {
1320 diag.help(fluent::lint_help);
1321 }
1322 NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
1323 diag.span_suggestion(
1324 span,
1325 fluent::lint_convert_suggestion,
1326 suggestion,
1327 Applicability::MaybeIncorrect,
1328 );
1329 }
1330 NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => {
1331 diag.span_suggestion(
1332 span,
1333 fluent::lint_rename_or_convert_suggestion,
1334 suggestion,
1335 Applicability::MaybeIncorrect,
1336 );
1337 }
1338 NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
1339 diag.note(fluent::lint_cannot_convert_note);
1340 diag.span_suggestion(
1341 span,
1342 fluent::lint_rename_suggestion,
1343 "",
1344 Applicability::MaybeIncorrect,
1345 );
1346 }
1347 }
1348 }
1349}
1350
1351#[derive(LintDiagnostic)]
1352#[diag(lint_non_upper_case_global)]
1353pub(crate) struct NonUpperCaseGlobal<'a> {
1354 pub sort: &'a str,
1355 pub name: &'a str,
1356 #[subdiagnostic]
1357 pub sub: NonUpperCaseGlobalSub,
1358 #[subdiagnostic]
1359 pub usages: Vec<NonUpperCaseGlobalSubTool>,
1360}
1361
1362#[derive(Subdiagnostic)]
1363pub(crate) enum NonUpperCaseGlobalSub {
1364 #[label(lint_label)]
1365 Label {
1366 #[primary_span]
1367 span: Span,
1368 },
1369 #[suggestion(lint_suggestion, code = "{replace}")]
1370 Suggestion {
1371 #[primary_span]
1372 span: Span,
1373 #[applicability]
1374 applicability: Applicability,
1375 replace: String,
1376 },
1377}
1378
1379#[derive(Subdiagnostic)]
1380#[suggestion(
1381 lint_suggestion,
1382 code = "{replace}",
1383 applicability = "machine-applicable",
1384 style = "tool-only"
1385)]
1386pub(crate) struct NonUpperCaseGlobalSubTool {
1387 #[primary_span]
1388 pub(crate) span: Span,
1389 pub(crate) replace: String,
1390}
1391
1392#[derive(LintDiagnostic)]
1394#[diag(lint_noop_method_call)]
1395#[note]
1396pub(crate) struct NoopMethodCallDiag<'a> {
1397 pub method: Ident,
1398 pub orig_ty: Ty<'a>,
1399 pub trait_: Symbol,
1400 #[suggestion(code = "", applicability = "machine-applicable")]
1401 pub label: Span,
1402 #[suggestion(
1403 lint_derive_suggestion,
1404 code = "#[derive(Clone)]\n",
1405 applicability = "maybe-incorrect"
1406 )]
1407 pub suggest_derive: Option<Span>,
1408}
1409
1410#[derive(LintDiagnostic)]
1411#[diag(lint_suspicious_double_ref_deref)]
1412pub(crate) struct SuspiciousDoubleRefDerefDiag<'a> {
1413 pub ty: Ty<'a>,
1414}
1415
1416#[derive(LintDiagnostic)]
1417#[diag(lint_suspicious_double_ref_clone)]
1418pub(crate) struct SuspiciousDoubleRefCloneDiag<'a> {
1419 pub ty: Ty<'a>,
1420}
1421
1422pub(crate) enum NonLocalDefinitionsDiag {
1424 Impl {
1425 depth: u32,
1426 body_kind_descr: &'static str,
1427 body_name: String,
1428 cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
1429 const_anon: Option<Option<Span>>,
1430 doctest: bool,
1431 macro_to_change: Option<(String, &'static str)>,
1432 },
1433 MacroRules {
1434 depth: u32,
1435 body_kind_descr: &'static str,
1436 body_name: String,
1437 doctest: bool,
1438 cargo_update: Option<NonLocalDefinitionsCargoUpdateNote>,
1439 },
1440}
1441
1442impl<'a> LintDiagnostic<'a, ()> for NonLocalDefinitionsDiag {
1443 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
1444 match self {
1445 NonLocalDefinitionsDiag::Impl {
1446 depth,
1447 body_kind_descr,
1448 body_name,
1449 cargo_update,
1450 const_anon,
1451 doctest,
1452 macro_to_change,
1453 } => {
1454 diag.primary_message(fluent::lint_non_local_definitions_impl);
1455 diag.arg("depth", depth);
1456 diag.arg("body_kind_descr", body_kind_descr);
1457 diag.arg("body_name", body_name);
1458
1459 if let Some((macro_to_change, macro_kind)) = macro_to_change {
1460 diag.arg("macro_to_change", macro_to_change);
1461 diag.arg("macro_kind", macro_kind);
1462 diag.note(fluent::lint_macro_to_change);
1463 }
1464 if let Some(cargo_update) = cargo_update {
1465 diag.subdiagnostic(cargo_update);
1466 }
1467
1468 diag.note(fluent::lint_non_local);
1469
1470 if doctest {
1471 diag.help(fluent::lint_doctest);
1472 }
1473
1474 if let Some(const_anon) = const_anon {
1475 diag.note(fluent::lint_exception);
1476 if let Some(const_anon) = const_anon {
1477 diag.span_suggestion(
1478 const_anon,
1479 fluent::lint_const_anon,
1480 "_",
1481 Applicability::MachineApplicable,
1482 );
1483 }
1484 }
1485 }
1486 NonLocalDefinitionsDiag::MacroRules {
1487 depth,
1488 body_kind_descr,
1489 body_name,
1490 doctest,
1491 cargo_update,
1492 } => {
1493 diag.primary_message(fluent::lint_non_local_definitions_macro_rules);
1494 diag.arg("depth", depth);
1495 diag.arg("body_kind_descr", body_kind_descr);
1496 diag.arg("body_name", body_name);
1497
1498 if doctest {
1499 diag.help(fluent::lint_help_doctest);
1500 } else {
1501 diag.help(fluent::lint_help);
1502 }
1503
1504 diag.note(fluent::lint_non_local);
1505
1506 if let Some(cargo_update) = cargo_update {
1507 diag.subdiagnostic(cargo_update);
1508 }
1509 }
1510 }
1511 }
1512}
1513
1514#[derive(Subdiagnostic)]
1515#[note(lint_non_local_definitions_cargo_update)]
1516pub(crate) struct NonLocalDefinitionsCargoUpdateNote {
1517 pub macro_kind: &'static str,
1518 pub macro_name: Symbol,
1519 pub crate_name: Symbol,
1520}
1521
1522#[derive(LintDiagnostic)]
1524#[diag(lint_ambiguous_negative_literals)]
1525#[note(lint_example)]
1526pub(crate) struct AmbiguousNegativeLiteralsDiag {
1527 #[subdiagnostic]
1528 pub negative_literal: AmbiguousNegativeLiteralsNegativeLiteralSuggestion,
1529 #[subdiagnostic]
1530 pub current_behavior: AmbiguousNegativeLiteralsCurrentBehaviorSuggestion,
1531}
1532
1533#[derive(Subdiagnostic)]
1534#[multipart_suggestion(lint_negative_literal, applicability = "maybe-incorrect")]
1535pub(crate) struct AmbiguousNegativeLiteralsNegativeLiteralSuggestion {
1536 #[suggestion_part(code = "(")]
1537 pub start_span: Span,
1538 #[suggestion_part(code = ")")]
1539 pub end_span: Span,
1540}
1541
1542#[derive(Subdiagnostic)]
1543#[multipart_suggestion(lint_current_behavior, applicability = "maybe-incorrect")]
1544pub(crate) struct AmbiguousNegativeLiteralsCurrentBehaviorSuggestion {
1545 #[suggestion_part(code = "(")]
1546 pub start_span: Span,
1547 #[suggestion_part(code = ")")]
1548 pub end_span: Span,
1549}
1550
1551#[derive(LintDiagnostic)]
1553#[diag(lint_pass_by_value)]
1554pub(crate) struct PassByValueDiag {
1555 pub ty: String,
1556 #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
1557 pub suggestion: Span,
1558}
1559
1560#[derive(LintDiagnostic)]
1562#[diag(lint_redundant_semicolons)]
1563pub(crate) struct RedundantSemicolonsDiag {
1564 pub multiple: bool,
1565 #[subdiagnostic]
1566 pub suggestion: Option<RedundantSemicolonsSuggestion>,
1567}
1568
1569#[derive(Subdiagnostic)]
1570#[suggestion(lint_redundant_semicolons_suggestion, code = "", applicability = "maybe-incorrect")]
1571pub(crate) struct RedundantSemicolonsSuggestion {
1572 pub multiple_semicolons: bool,
1573 #[primary_span]
1574 pub span: Span,
1575}
1576
1577pub(crate) struct DropTraitConstraintsDiag<'a> {
1579 pub predicate: Clause<'a>,
1580 pub tcx: TyCtxt<'a>,
1581 pub def_id: DefId,
1582}
1583
1584impl<'a> LintDiagnostic<'a, ()> for DropTraitConstraintsDiag<'_> {
1586 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
1587 diag.primary_message(fluent::lint_drop_trait_constraints);
1588 diag.arg("predicate", self.predicate);
1589 diag.arg("needs_drop", self.tcx.def_path_str(self.def_id));
1590 }
1591}
1592
1593pub(crate) struct DropGlue<'a> {
1594 pub tcx: TyCtxt<'a>,
1595 pub def_id: DefId,
1596}
1597
1598impl<'a> LintDiagnostic<'a, ()> for DropGlue<'_> {
1600 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
1601 diag.primary_message(fluent::lint_drop_glue);
1602 diag.arg("needs_drop", self.tcx.def_path_str(self.def_id));
1603 }
1604}
1605
1606#[derive(LintDiagnostic)]
1608#[diag(lint_range_endpoint_out_of_range)]
1609pub(crate) struct RangeEndpointOutOfRange<'a> {
1610 pub ty: &'a str,
1611 #[subdiagnostic]
1612 pub sub: UseInclusiveRange<'a>,
1613}
1614
1615#[derive(Subdiagnostic)]
1616pub(crate) enum UseInclusiveRange<'a> {
1617 #[suggestion(
1618 lint_range_use_inclusive_range,
1619 code = "{start}..={literal}{suffix}",
1620 applicability = "machine-applicable"
1621 )]
1622 WithoutParen {
1623 #[primary_span]
1624 sugg: Span,
1625 start: String,
1626 literal: u128,
1627 suffix: &'a str,
1628 },
1629 #[multipart_suggestion(lint_range_use_inclusive_range, applicability = "machine-applicable")]
1630 WithParen {
1631 #[suggestion_part(code = "=")]
1632 eq_sugg: Span,
1633 #[suggestion_part(code = "{literal}{suffix}")]
1634 lit_sugg: Span,
1635 literal: u128,
1636 suffix: &'a str,
1637 },
1638}
1639
1640#[derive(LintDiagnostic)]
1641#[diag(lint_overflowing_bin_hex)]
1642pub(crate) struct OverflowingBinHex<'a> {
1643 pub ty: &'a str,
1644 pub lit: String,
1645 pub dec: u128,
1646 pub actually: String,
1647 #[subdiagnostic]
1648 pub sign: OverflowingBinHexSign,
1649 #[subdiagnostic]
1650 pub sub: Option<OverflowingBinHexSub<'a>>,
1651 #[subdiagnostic]
1652 pub sign_bit_sub: Option<OverflowingBinHexSignBitSub<'a>>,
1653}
1654
1655pub(crate) enum OverflowingBinHexSign {
1656 Positive,
1657 Negative,
1658}
1659
1660impl Subdiagnostic for OverflowingBinHexSign {
1661 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
1662 match self {
1663 OverflowingBinHexSign::Positive => {
1664 diag.note(fluent::lint_positive_note);
1665 }
1666 OverflowingBinHexSign::Negative => {
1667 diag.note(fluent::lint_negative_note);
1668 diag.note(fluent::lint_negative_becomes_note);
1669 }
1670 }
1671 }
1672}
1673
1674#[derive(Subdiagnostic)]
1675pub(crate) enum OverflowingBinHexSub<'a> {
1676 #[suggestion(
1677 lint_suggestion,
1678 code = "{sans_suffix}{suggestion_ty}",
1679 applicability = "machine-applicable"
1680 )]
1681 Suggestion {
1682 #[primary_span]
1683 span: Span,
1684 suggestion_ty: &'a str,
1685 sans_suffix: &'a str,
1686 },
1687 #[help(lint_help)]
1688 Help { suggestion_ty: &'a str },
1689}
1690
1691#[derive(Subdiagnostic)]
1692#[suggestion(
1693 lint_sign_bit_suggestion,
1694 code = "{lit_no_suffix}{uint_ty} as {int_ty}",
1695 applicability = "maybe-incorrect"
1696)]
1697pub(crate) struct OverflowingBinHexSignBitSub<'a> {
1698 #[primary_span]
1699 pub span: Span,
1700 pub lit_no_suffix: &'a str,
1701 pub negative_val: String,
1702 pub uint_ty: &'a str,
1703 pub int_ty: &'a str,
1704}
1705
1706#[derive(LintDiagnostic)]
1707#[diag(lint_overflowing_int)]
1708#[note]
1709pub(crate) struct OverflowingInt<'a> {
1710 pub ty: &'a str,
1711 pub lit: String,
1712 pub min: i128,
1713 pub max: u128,
1714 #[subdiagnostic]
1715 pub help: Option<OverflowingIntHelp<'a>>,
1716}
1717
1718#[derive(Subdiagnostic)]
1719#[help(lint_help)]
1720pub(crate) struct OverflowingIntHelp<'a> {
1721 pub suggestion_ty: &'a str,
1722}
1723
1724#[derive(LintDiagnostic)]
1725#[diag(lint_only_cast_u8_to_char)]
1726pub(crate) struct OnlyCastu8ToChar {
1727 #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")]
1728 pub span: Span,
1729 pub literal: u128,
1730}
1731
1732#[derive(LintDiagnostic)]
1733#[diag(lint_overflowing_uint)]
1734#[note]
1735pub(crate) struct OverflowingUInt<'a> {
1736 pub ty: &'a str,
1737 pub lit: String,
1738 pub min: u128,
1739 pub max: u128,
1740}
1741
1742#[derive(LintDiagnostic)]
1743#[diag(lint_overflowing_literal)]
1744#[note]
1745pub(crate) struct OverflowingLiteral<'a> {
1746 pub ty: &'a str,
1747 pub lit: String,
1748}
1749
1750#[derive(LintDiagnostic)]
1751#[diag(lint_surrogate_char_cast)]
1752#[note]
1753pub(crate) struct SurrogateCharCast {
1754 pub literal: u128,
1755}
1756
1757#[derive(LintDiagnostic)]
1758#[diag(lint_too_large_char_cast)]
1759#[note]
1760pub(crate) struct TooLargeCharCast {
1761 pub literal: u128,
1762}
1763
1764#[derive(LintDiagnostic)]
1765#[diag(lint_uses_power_alignment)]
1766pub(crate) struct UsesPowerAlignment;
1767
1768#[derive(LintDiagnostic)]
1769#[diag(lint_unused_comparisons)]
1770pub(crate) struct UnusedComparisons;
1771
1772#[derive(LintDiagnostic)]
1773pub(crate) enum InvalidNanComparisons {
1774 #[diag(lint_invalid_nan_comparisons_eq_ne)]
1775 EqNe {
1776 #[subdiagnostic]
1777 suggestion: InvalidNanComparisonsSuggestion,
1778 },
1779 #[diag(lint_invalid_nan_comparisons_lt_le_gt_ge)]
1780 LtLeGtGe,
1781}
1782
1783#[derive(Subdiagnostic)]
1784pub(crate) enum InvalidNanComparisonsSuggestion {
1785 #[multipart_suggestion(
1786 lint_suggestion,
1787 style = "verbose",
1788 applicability = "machine-applicable"
1789 )]
1790 Spanful {
1791 #[suggestion_part(code = "!")]
1792 neg: Option<Span>,
1793 #[suggestion_part(code = ".is_nan()")]
1794 float: Span,
1795 #[suggestion_part(code = "")]
1796 nan_plus_binop: Span,
1797 },
1798 #[help(lint_suggestion)]
1799 Spanless,
1800}
1801
1802#[derive(LintDiagnostic)]
1803pub(crate) enum AmbiguousWidePointerComparisons<'a> {
1804 #[diag(lint_ambiguous_wide_pointer_comparisons)]
1805 SpanfulEq {
1806 #[subdiagnostic]
1807 addr_suggestion: AmbiguousWidePointerComparisonsAddrSuggestion<'a>,
1808 #[subdiagnostic]
1809 addr_metadata_suggestion: Option<AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a>>,
1810 },
1811 #[diag(lint_ambiguous_wide_pointer_comparisons)]
1812 SpanfulCmp {
1813 #[subdiagnostic]
1814 cast_suggestion: AmbiguousWidePointerComparisonsCastSuggestion<'a>,
1815 #[subdiagnostic]
1816 expect_suggestion: AmbiguousWidePointerComparisonsExpectSuggestion<'a>,
1817 },
1818 #[diag(lint_ambiguous_wide_pointer_comparisons)]
1819 #[help(lint_addr_metadata_suggestion)]
1820 #[help(lint_addr_suggestion)]
1821 Spanless,
1822}
1823
1824#[derive(Subdiagnostic)]
1825#[multipart_suggestion(
1826 lint_addr_metadata_suggestion,
1827 style = "verbose",
1828 applicability = "maybe-incorrect"
1830)]
1831pub(crate) struct AmbiguousWidePointerComparisonsAddrMetadataSuggestion<'a> {
1832 pub ne: &'a str,
1833 pub deref_left: &'a str,
1834 pub deref_right: &'a str,
1835 pub l_modifiers: &'a str,
1836 pub r_modifiers: &'a str,
1837 #[suggestion_part(code = "{ne}std::ptr::eq({deref_left}")]
1838 pub left: Span,
1839 #[suggestion_part(code = "{l_modifiers}, {deref_right}")]
1840 pub middle: Span,
1841 #[suggestion_part(code = "{r_modifiers})")]
1842 pub right: Span,
1843}
1844
1845#[derive(Subdiagnostic)]
1846#[multipart_suggestion(
1847 lint_addr_suggestion,
1848 style = "verbose",
1849 applicability = "maybe-incorrect"
1851)]
1852pub(crate) struct AmbiguousWidePointerComparisonsAddrSuggestion<'a> {
1853 pub(crate) ne: &'a str,
1854 pub(crate) deref_left: &'a str,
1855 pub(crate) deref_right: &'a str,
1856 pub(crate) l_modifiers: &'a str,
1857 pub(crate) r_modifiers: &'a str,
1858 #[suggestion_part(code = "{ne}std::ptr::addr_eq({deref_left}")]
1859 pub(crate) left: Span,
1860 #[suggestion_part(code = "{l_modifiers}, {deref_right}")]
1861 pub(crate) middle: Span,
1862 #[suggestion_part(code = "{r_modifiers})")]
1863 pub(crate) right: Span,
1864}
1865
1866#[derive(Subdiagnostic)]
1867#[multipart_suggestion(
1868 lint_cast_suggestion,
1869 style = "verbose",
1870 applicability = "maybe-incorrect"
1872)]
1873pub(crate) struct AmbiguousWidePointerComparisonsCastSuggestion<'a> {
1874 pub(crate) deref_left: &'a str,
1875 pub(crate) deref_right: &'a str,
1876 pub(crate) paren_left: &'a str,
1877 pub(crate) paren_right: &'a str,
1878 pub(crate) l_modifiers: &'a str,
1879 pub(crate) r_modifiers: &'a str,
1880 #[suggestion_part(code = "({deref_left}")]
1881 pub(crate) left_before: Option<Span>,
1882 #[suggestion_part(code = "{l_modifiers}{paren_left}.cast::<()>()")]
1883 pub(crate) left_after: Span,
1884 #[suggestion_part(code = "({deref_right}")]
1885 pub(crate) right_before: Option<Span>,
1886 #[suggestion_part(code = "{r_modifiers}{paren_right}.cast::<()>()")]
1887 pub(crate) right_after: Span,
1888}
1889
1890#[derive(Subdiagnostic)]
1891#[multipart_suggestion(
1892 lint_expect_suggestion,
1893 style = "verbose",
1894 applicability = "maybe-incorrect"
1896)]
1897pub(crate) struct AmbiguousWidePointerComparisonsExpectSuggestion<'a> {
1898 pub(crate) paren_left: &'a str,
1899 pub(crate) paren_right: &'a str,
1900 #[suggestion_part(
1902 code = r#"{{ #[expect(ambiguous_wide_pointer_comparisons, reason = "...")] {paren_left}"#
1903 )]
1904 pub(crate) before: Span,
1905 #[suggestion_part(code = "{paren_right} }}")]
1906 pub(crate) after: Span,
1907}
1908
1909#[derive(LintDiagnostic)]
1910pub(crate) enum UnpredictableFunctionPointerComparisons<'a, 'tcx> {
1911 #[diag(lint_unpredictable_fn_pointer_comparisons)]
1912 #[note(lint_note_duplicated_fn)]
1913 #[note(lint_note_deduplicated_fn)]
1914 #[note(lint_note_visit_fn_addr_eq)]
1915 Suggestion {
1916 #[subdiagnostic]
1917 sugg: UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx>,
1918 },
1919 #[diag(lint_unpredictable_fn_pointer_comparisons)]
1920 #[note(lint_note_duplicated_fn)]
1921 #[note(lint_note_deduplicated_fn)]
1922 #[note(lint_note_visit_fn_addr_eq)]
1923 Warn,
1924}
1925
1926#[derive(Subdiagnostic)]
1927pub(crate) enum UnpredictableFunctionPointerComparisonsSuggestion<'a, 'tcx> {
1928 #[multipart_suggestion(
1929 lint_fn_addr_eq_suggestion,
1930 style = "verbose",
1931 applicability = "maybe-incorrect"
1932 )]
1933 FnAddrEq {
1934 ne: &'a str,
1935 deref_left: &'a str,
1936 deref_right: &'a str,
1937 #[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
1938 left: Span,
1939 #[suggestion_part(code = ", {deref_right}")]
1940 middle: Span,
1941 #[suggestion_part(code = ")")]
1942 right: Span,
1943 },
1944 #[multipart_suggestion(
1945 lint_fn_addr_eq_suggestion,
1946 style = "verbose",
1947 applicability = "maybe-incorrect"
1948 )]
1949 FnAddrEqWithCast {
1950 ne: &'a str,
1951 deref_left: &'a str,
1952 deref_right: &'a str,
1953 fn_sig: rustc_middle::ty::PolyFnSig<'tcx>,
1954 #[suggestion_part(code = "{ne}std::ptr::fn_addr_eq({deref_left}")]
1955 left: Span,
1956 #[suggestion_part(code = ", {deref_right}")]
1957 middle: Span,
1958 #[suggestion_part(code = " as {fn_sig})")]
1959 right: Span,
1960 },
1961}
1962
1963pub(crate) struct ImproperCTypes<'a> {
1964 pub ty: Ty<'a>,
1965 pub desc: &'a str,
1966 pub label: Span,
1967 pub help: Option<DiagMessage>,
1968 pub note: DiagMessage,
1969 pub span_note: Option<Span>,
1970}
1971
1972impl<'a> LintDiagnostic<'a, ()> for ImproperCTypes<'_> {
1974 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
1975 diag.primary_message(fluent::lint_improper_ctypes);
1976 diag.arg("ty", self.ty);
1977 diag.arg("desc", self.desc);
1978 diag.span_label(self.label, fluent::lint_label);
1979 if let Some(help) = self.help {
1980 diag.help(help);
1981 }
1982 diag.note(self.note);
1983 if let Some(note) = self.span_note {
1984 diag.span_note(note, fluent::lint_note);
1985 }
1986 }
1987}
1988
1989#[derive(LintDiagnostic)]
1990#[diag(lint_variant_size_differences)]
1991pub(crate) struct VariantSizeDifferencesDiag {
1992 pub largest: u64,
1993}
1994
1995#[derive(LintDiagnostic)]
1996#[diag(lint_atomic_ordering_load)]
1997#[help]
1998pub(crate) struct AtomicOrderingLoad;
1999
2000#[derive(LintDiagnostic)]
2001#[diag(lint_atomic_ordering_store)]
2002#[help]
2003pub(crate) struct AtomicOrderingStore;
2004
2005#[derive(LintDiagnostic)]
2006#[diag(lint_atomic_ordering_fence)]
2007#[help]
2008pub(crate) struct AtomicOrderingFence;
2009
2010#[derive(LintDiagnostic)]
2011#[diag(lint_atomic_ordering_invalid)]
2012#[help]
2013pub(crate) struct InvalidAtomicOrderingDiag {
2014 pub method: Symbol,
2015 #[label]
2016 pub fail_order_arg_span: Span,
2017}
2018
2019#[derive(LintDiagnostic)]
2021#[diag(lint_unused_op)]
2022pub(crate) struct UnusedOp<'a> {
2023 pub op: &'a str,
2024 #[label]
2025 pub label: Span,
2026 #[subdiagnostic]
2027 pub suggestion: UnusedOpSuggestion,
2028}
2029
2030#[derive(Subdiagnostic)]
2031pub(crate) enum UnusedOpSuggestion {
2032 #[suggestion(
2033 lint_suggestion,
2034 style = "verbose",
2035 code = "let _ = ",
2036 applicability = "maybe-incorrect"
2037 )]
2038 NormalExpr {
2039 #[primary_span]
2040 span: Span,
2041 },
2042 #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
2043 BlockTailExpr {
2044 #[suggestion_part(code = "let _ = ")]
2045 before_span: Span,
2046 #[suggestion_part(code = ";")]
2047 after_span: Span,
2048 },
2049}
2050
2051#[derive(LintDiagnostic)]
2052#[diag(lint_unused_result)]
2053pub(crate) struct UnusedResult<'a> {
2054 pub ty: Ty<'a>,
2055}
2056
2057#[derive(LintDiagnostic)]
2060#[diag(lint_unused_closure)]
2061#[note]
2062pub(crate) struct UnusedClosure<'a> {
2063 pub count: usize,
2064 pub pre: &'a str,
2065 pub post: &'a str,
2066}
2067
2068#[derive(LintDiagnostic)]
2071#[diag(lint_unused_coroutine)]
2072#[note]
2073pub(crate) struct UnusedCoroutine<'a> {
2074 pub count: usize,
2075 pub pre: &'a str,
2076 pub post: &'a str,
2077}
2078
2079pub(crate) struct UnusedDef<'a, 'b> {
2082 pub pre: &'a str,
2083 pub post: &'a str,
2084 pub cx: &'a LateContext<'b>,
2085 pub def_id: DefId,
2086 pub note: Option<Symbol>,
2087 pub suggestion: Option<UnusedDefSuggestion>,
2088}
2089
2090#[derive(Subdiagnostic)]
2091
2092pub(crate) enum UnusedDefSuggestion {
2093 #[suggestion(
2094 lint_suggestion,
2095 style = "verbose",
2096 code = "let _ = ",
2097 applicability = "maybe-incorrect"
2098 )]
2099 NormalExpr {
2100 #[primary_span]
2101 span: Span,
2102 },
2103 #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
2104 BlockTailExpr {
2105 #[suggestion_part(code = "let _ = ")]
2106 before_span: Span,
2107 #[suggestion_part(code = ";")]
2108 after_span: Span,
2109 },
2110}
2111
2112impl<'a> LintDiagnostic<'a, ()> for UnusedDef<'_, '_> {
2114 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
2115 diag.primary_message(fluent::lint_unused_def);
2116 diag.arg("pre", self.pre);
2117 diag.arg("post", self.post);
2118 diag.arg("def", self.cx.tcx.def_path_str(self.def_id));
2119 if let Some(note) = self.note {
2121 diag.note(note.to_string());
2122 }
2123 if let Some(sugg) = self.suggestion {
2124 diag.subdiagnostic(sugg);
2125 }
2126 }
2127}
2128
2129#[derive(LintDiagnostic)]
2130#[diag(lint_path_statement_drop)]
2131pub(crate) struct PathStatementDrop {
2132 #[subdiagnostic]
2133 pub sub: PathStatementDropSub,
2134}
2135
2136#[derive(Subdiagnostic)]
2137pub(crate) enum PathStatementDropSub {
2138 #[suggestion(lint_suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
2139 Suggestion {
2140 #[primary_span]
2141 span: Span,
2142 snippet: String,
2143 },
2144 #[help(lint_help)]
2145 Help {
2146 #[primary_span]
2147 span: Span,
2148 },
2149}
2150
2151#[derive(LintDiagnostic)]
2152#[diag(lint_path_statement_no_effect)]
2153pub(crate) struct PathStatementNoEffect;
2154
2155#[derive(LintDiagnostic)]
2156#[diag(lint_unused_delim)]
2157pub(crate) struct UnusedDelim<'a> {
2158 pub delim: &'static str,
2159 pub item: &'a str,
2160 #[subdiagnostic]
2161 pub suggestion: Option<UnusedDelimSuggestion>,
2162}
2163
2164#[derive(Subdiagnostic)]
2165#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
2166pub(crate) struct UnusedDelimSuggestion {
2167 #[suggestion_part(code = "{start_replace}")]
2168 pub start_span: Span,
2169 pub start_replace: &'static str,
2170 #[suggestion_part(code = "{end_replace}")]
2171 pub end_span: Span,
2172 pub end_replace: &'static str,
2173}
2174
2175#[derive(LintDiagnostic)]
2176#[diag(lint_unused_import_braces)]
2177pub(crate) struct UnusedImportBracesDiag {
2178 pub node: Symbol,
2179}
2180
2181#[derive(LintDiagnostic)]
2182#[diag(lint_unused_allocation)]
2183pub(crate) struct UnusedAllocationDiag;
2184
2185#[derive(LintDiagnostic)]
2186#[diag(lint_unused_allocation_mut)]
2187pub(crate) struct UnusedAllocationMutDiag;
2188
2189pub(crate) struct AsyncFnInTraitDiag {
2190 pub sugg: Option<Vec<(Span, String)>>,
2191}
2192
2193impl<'a> LintDiagnostic<'a, ()> for AsyncFnInTraitDiag {
2194 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
2195 diag.primary_message(fluent::lint_async_fn_in_trait);
2196 diag.note(fluent::lint_note);
2197 if let Some(sugg) = self.sugg {
2198 diag.multipart_suggestion(fluent::lint_suggestion, sugg, Applicability::MaybeIncorrect);
2199 }
2200 }
2201}
2202
2203#[derive(LintDiagnostic)]
2204#[diag(lint_unit_bindings)]
2205pub(crate) struct UnitBindingsDiag {
2206 #[label]
2207 pub label: Span,
2208}
2209
2210#[derive(LintDiagnostic)]
2211pub(crate) enum InvalidAsmLabel {
2212 #[diag(lint_invalid_asm_label_named)]
2213 #[help]
2214 #[note]
2215 Named {
2216 #[note(lint_invalid_asm_label_no_span)]
2217 missing_precise_span: bool,
2218 },
2219 #[diag(lint_invalid_asm_label_format_arg)]
2220 #[help]
2221 #[note(lint_note1)]
2222 #[note(lint_note2)]
2223 FormatArg {
2224 #[note(lint_invalid_asm_label_no_span)]
2225 missing_precise_span: bool,
2226 },
2227 #[diag(lint_invalid_asm_label_binary)]
2228 #[help]
2229 #[note(lint_note1)]
2230 #[note(lint_note2)]
2231 Binary {
2232 #[note(lint_invalid_asm_label_no_span)]
2233 missing_precise_span: bool,
2234 #[label]
2236 span: Span,
2237 },
2238}
2239
2240#[derive(Subdiagnostic)]
2241pub(crate) enum UnexpectedCfgCargoHelp {
2242 #[help(lint_unexpected_cfg_add_cargo_feature)]
2243 #[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)]
2244 LintCfg { cargo_toml_lint_cfg: String },
2245 #[help(lint_unexpected_cfg_add_cargo_feature)]
2246 #[help(lint_unexpected_cfg_add_cargo_toml_lint_cfg)]
2247 #[help(lint_unexpected_cfg_add_build_rs_println)]
2248 LintCfgAndBuildRs { cargo_toml_lint_cfg: String, build_rs_println: String },
2249}
2250
2251impl UnexpectedCfgCargoHelp {
2252 fn cargo_toml_lint_cfg(unescaped: &str) -> String {
2253 format!(
2254 "\n [lints.rust]\n unexpected_cfgs = {{ level = \"warn\", check-cfg = ['{unescaped}'] }}"
2255 )
2256 }
2257
2258 pub(crate) fn lint_cfg(unescaped: &str) -> Self {
2259 UnexpectedCfgCargoHelp::LintCfg {
2260 cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped),
2261 }
2262 }
2263
2264 pub(crate) fn lint_cfg_and_build_rs(unescaped: &str, escaped: &str) -> Self {
2265 UnexpectedCfgCargoHelp::LintCfgAndBuildRs {
2266 cargo_toml_lint_cfg: Self::cargo_toml_lint_cfg(unescaped),
2267 build_rs_println: format!("println!(\"cargo::rustc-check-cfg={escaped}\");"),
2268 }
2269 }
2270}
2271
2272#[derive(Subdiagnostic)]
2273#[help(lint_unexpected_cfg_add_cmdline_arg)]
2274pub(crate) struct UnexpectedCfgRustcHelp {
2275 pub cmdline_arg: String,
2276}
2277
2278impl UnexpectedCfgRustcHelp {
2279 pub(crate) fn new(unescaped: &str) -> Self {
2280 Self { cmdline_arg: format!("--check-cfg={unescaped}") }
2281 }
2282}
2283
2284#[derive(Subdiagnostic)]
2285#[note(lint_unexpected_cfg_from_external_macro_origin)]
2286#[help(lint_unexpected_cfg_from_external_macro_refer)]
2287pub(crate) struct UnexpectedCfgRustcMacroHelp {
2288 pub macro_kind: &'static str,
2289 pub macro_name: Symbol,
2290}
2291
2292#[derive(Subdiagnostic)]
2293#[note(lint_unexpected_cfg_from_external_macro_origin)]
2294#[help(lint_unexpected_cfg_from_external_macro_refer)]
2295#[help(lint_unexpected_cfg_cargo_update)]
2296pub(crate) struct UnexpectedCfgCargoMacroHelp {
2297 pub macro_kind: &'static str,
2298 pub macro_name: Symbol,
2299 pub crate_name: Symbol,
2300}
2301
2302#[derive(LintDiagnostic)]
2303#[diag(lint_unexpected_cfg_name)]
2304pub(crate) struct UnexpectedCfgName {
2305 #[subdiagnostic]
2306 pub code_sugg: unexpected_cfg_name::CodeSuggestion,
2307 #[subdiagnostic]
2308 pub invocation_help: unexpected_cfg_name::InvocationHelp,
2309
2310 pub name: Symbol,
2311}
2312
2313pub(crate) mod unexpected_cfg_name {
2314 use rustc_errors::DiagSymbolList;
2315 use rustc_macros::Subdiagnostic;
2316 use rustc_span::{Ident, Span, Symbol};
2317
2318 #[derive(Subdiagnostic)]
2319 pub(crate) enum CodeSuggestion {
2320 #[help(lint_unexpected_cfg_define_features)]
2321 DefineFeatures,
2322 #[multipart_suggestion(
2323 lint_unexpected_cfg_name_version_syntax,
2324 applicability = "machine-applicable"
2325 )]
2326 VersionSyntax {
2327 #[suggestion_part(code = "(")]
2328 between_name_and_value: Span,
2329 #[suggestion_part(code = ")")]
2330 after_value: Span,
2331 },
2332 #[suggestion(
2333 lint_unexpected_cfg_name_similar_name_value,
2334 applicability = "maybe-incorrect",
2335 code = "{code}"
2336 )]
2337 SimilarNameAndValue {
2338 #[primary_span]
2339 span: Span,
2340 code: String,
2341 },
2342 #[suggestion(
2343 lint_unexpected_cfg_name_similar_name_no_value,
2344 applicability = "maybe-incorrect",
2345 code = "{code}"
2346 )]
2347 SimilarNameNoValue {
2348 #[primary_span]
2349 span: Span,
2350 code: String,
2351 },
2352 #[suggestion(
2353 lint_unexpected_cfg_name_similar_name_different_values,
2354 applicability = "maybe-incorrect",
2355 code = "{code}"
2356 )]
2357 SimilarNameDifferentValues {
2358 #[primary_span]
2359 span: Span,
2360 code: String,
2361 #[subdiagnostic]
2362 expected: Option<ExpectedValues>,
2363 },
2364 #[suggestion(
2365 lint_unexpected_cfg_name_similar_name,
2366 applicability = "maybe-incorrect",
2367 code = "{code}"
2368 )]
2369 SimilarName {
2370 #[primary_span]
2371 span: Span,
2372 code: String,
2373 #[subdiagnostic]
2374 expected: Option<ExpectedValues>,
2375 },
2376 SimilarValues {
2377 #[subdiagnostic]
2378 with_similar_values: Vec<FoundWithSimilarValue>,
2379 #[subdiagnostic]
2380 expected_names: Option<ExpectedNames>,
2381 },
2382 }
2383
2384 #[derive(Subdiagnostic)]
2385 #[help(lint_unexpected_cfg_name_expected_values)]
2386 pub(crate) struct ExpectedValues {
2387 pub best_match: Symbol,
2388 pub possibilities: DiagSymbolList,
2389 }
2390
2391 #[derive(Subdiagnostic)]
2392 #[suggestion(
2393 lint_unexpected_cfg_name_with_similar_value,
2394 applicability = "maybe-incorrect",
2395 code = "{code}"
2396 )]
2397 pub(crate) struct FoundWithSimilarValue {
2398 #[primary_span]
2399 pub span: Span,
2400 pub code: String,
2401 }
2402
2403 #[derive(Subdiagnostic)]
2404 #[help_once(lint_unexpected_cfg_name_expected_names)]
2405 pub(crate) struct ExpectedNames {
2406 pub possibilities: DiagSymbolList<Ident>,
2407 pub and_more: usize,
2408 }
2409
2410 #[derive(Subdiagnostic)]
2411 pub(crate) enum InvocationHelp {
2412 #[note(lint_unexpected_cfg_doc_cargo)]
2413 Cargo {
2414 #[subdiagnostic]
2415 macro_help: Option<super::UnexpectedCfgCargoMacroHelp>,
2416 #[subdiagnostic]
2417 help: Option<super::UnexpectedCfgCargoHelp>,
2418 },
2419 #[note(lint_unexpected_cfg_doc_rustc)]
2420 Rustc {
2421 #[subdiagnostic]
2422 macro_help: Option<super::UnexpectedCfgRustcMacroHelp>,
2423 #[subdiagnostic]
2424 help: super::UnexpectedCfgRustcHelp,
2425 },
2426 }
2427}
2428
2429#[derive(LintDiagnostic)]
2430#[diag(lint_unexpected_cfg_value)]
2431pub(crate) struct UnexpectedCfgValue {
2432 #[subdiagnostic]
2433 pub code_sugg: unexpected_cfg_value::CodeSuggestion,
2434 #[subdiagnostic]
2435 pub invocation_help: unexpected_cfg_value::InvocationHelp,
2436
2437 pub has_value: bool,
2438 pub value: String,
2439}
2440
2441pub(crate) mod unexpected_cfg_value {
2442 use rustc_errors::DiagSymbolList;
2443 use rustc_macros::Subdiagnostic;
2444 use rustc_span::{Span, Symbol};
2445
2446 #[derive(Subdiagnostic)]
2447 pub(crate) enum CodeSuggestion {
2448 ChangeValue {
2449 #[subdiagnostic]
2450 expected_values: ExpectedValues,
2451 #[subdiagnostic]
2452 suggestion: Option<ChangeValueSuggestion>,
2453 },
2454 #[note(lint_unexpected_cfg_value_no_expected_value)]
2455 RemoveValue {
2456 #[subdiagnostic]
2457 suggestion: Option<RemoveValueSuggestion>,
2458
2459 name: Symbol,
2460 },
2461 #[note(lint_unexpected_cfg_value_no_expected_values)]
2462 RemoveCondition {
2463 #[subdiagnostic]
2464 suggestion: RemoveConditionSuggestion,
2465
2466 name: Symbol,
2467 },
2468 }
2469
2470 #[derive(Subdiagnostic)]
2471 pub(crate) enum ChangeValueSuggestion {
2472 #[suggestion(
2473 lint_unexpected_cfg_value_similar_name,
2474 code = r#""{best_match}""#,
2475 applicability = "maybe-incorrect"
2476 )]
2477 SimilarName {
2478 #[primary_span]
2479 span: Span,
2480 best_match: Symbol,
2481 },
2482 #[suggestion(
2483 lint_unexpected_cfg_value_specify_value,
2484 code = r#" = "{first_possibility}""#,
2485 applicability = "maybe-incorrect"
2486 )]
2487 SpecifyValue {
2488 #[primary_span]
2489 span: Span,
2490 first_possibility: Symbol,
2491 },
2492 }
2493
2494 #[derive(Subdiagnostic)]
2495 #[suggestion(
2496 lint_unexpected_cfg_value_remove_value,
2497 code = "",
2498 applicability = "maybe-incorrect"
2499 )]
2500 pub(crate) struct RemoveValueSuggestion {
2501 #[primary_span]
2502 pub span: Span,
2503 }
2504
2505 #[derive(Subdiagnostic)]
2506 #[suggestion(
2507 lint_unexpected_cfg_value_remove_condition,
2508 code = "",
2509 applicability = "maybe-incorrect"
2510 )]
2511 pub(crate) struct RemoveConditionSuggestion {
2512 #[primary_span]
2513 pub span: Span,
2514 }
2515
2516 #[derive(Subdiagnostic)]
2517 #[note(lint_unexpected_cfg_value_expected_values)]
2518 pub(crate) struct ExpectedValues {
2519 pub name: Symbol,
2520 pub have_none_possibility: bool,
2521 pub possibilities: DiagSymbolList,
2522 pub and_more: usize,
2523 }
2524
2525 #[derive(Subdiagnostic)]
2526 pub(crate) enum InvocationHelp {
2527 #[note(lint_unexpected_cfg_doc_cargo)]
2528 Cargo {
2529 #[subdiagnostic]
2530 help: Option<CargoHelp>,
2531 #[subdiagnostic]
2532 macro_help: Option<super::UnexpectedCfgCargoMacroHelp>,
2533 },
2534 #[note(lint_unexpected_cfg_doc_rustc)]
2535 Rustc {
2536 #[subdiagnostic]
2537 help: Option<super::UnexpectedCfgRustcHelp>,
2538 #[subdiagnostic]
2539 macro_help: Option<super::UnexpectedCfgRustcMacroHelp>,
2540 },
2541 }
2542
2543 #[derive(Subdiagnostic)]
2544 pub(crate) enum CargoHelp {
2545 #[help(lint_unexpected_cfg_value_add_feature)]
2546 AddFeature {
2547 value: Symbol,
2548 },
2549 #[help(lint_unexpected_cfg_define_features)]
2550 DefineFeatures,
2551 Other(#[subdiagnostic] super::UnexpectedCfgCargoHelp),
2552 }
2553}
2554
2555#[derive(LintDiagnostic)]
2556#[diag(lint_unexpected_builtin_cfg)]
2557#[note(lint_controlled_by)]
2558#[note(lint_incoherent)]
2559pub(crate) struct UnexpectedBuiltinCfg {
2560 pub(crate) cfg: String,
2561 pub(crate) cfg_name: Symbol,
2562 pub(crate) controlled_by: &'static str,
2563}
2564
2565#[derive(LintDiagnostic)]
2566#[diag(lint_macro_use_deprecated)]
2567#[help]
2568pub(crate) struct MacroUseDeprecated;
2569
2570#[derive(LintDiagnostic)]
2571#[diag(lint_unused_macro_use)]
2572pub(crate) struct UnusedMacroUse;
2573
2574#[derive(LintDiagnostic)]
2575#[diag(lint_private_extern_crate_reexport, code = E0365)]
2576pub(crate) struct PrivateExternCrateReexport {
2577 pub ident: Ident,
2578 #[suggestion(code = "pub ", style = "verbose", applicability = "maybe-incorrect")]
2579 pub sugg: Span,
2580}
2581
2582#[derive(LintDiagnostic)]
2583#[diag(lint_unused_label)]
2584pub(crate) struct UnusedLabel;
2585
2586#[derive(LintDiagnostic)]
2587#[diag(lint_macro_is_private)]
2588pub(crate) struct MacroIsPrivate {
2589 pub ident: Ident,
2590}
2591
2592#[derive(LintDiagnostic)]
2593#[diag(lint_unused_macro_definition)]
2594pub(crate) struct UnusedMacroDefinition {
2595 pub name: Symbol,
2596}
2597
2598#[derive(LintDiagnostic)]
2599#[diag(lint_macro_rule_never_used)]
2600pub(crate) struct MacroRuleNeverUsed {
2601 pub n: usize,
2602 pub name: Symbol,
2603}
2604
2605pub(crate) struct UnstableFeature {
2606 pub msg: DiagMessage,
2607}
2608
2609impl<'a> LintDiagnostic<'a, ()> for UnstableFeature {
2610 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
2611 diag.primary_message(self.msg);
2612 }
2613}
2614
2615#[derive(LintDiagnostic)]
2616#[diag(lint_avoid_intel_syntax)]
2617pub(crate) struct AvoidIntelSyntax;
2618
2619#[derive(LintDiagnostic)]
2620#[diag(lint_avoid_att_syntax)]
2621pub(crate) struct AvoidAttSyntax;
2622
2623#[derive(LintDiagnostic)]
2624#[diag(lint_incomplete_include)]
2625pub(crate) struct IncompleteInclude;
2626
2627#[derive(LintDiagnostic)]
2628#[diag(lint_unnameable_test_items)]
2629pub(crate) struct UnnameableTestItems;
2630
2631#[derive(LintDiagnostic)]
2632#[diag(lint_duplicate_macro_attribute)]
2633pub(crate) struct DuplicateMacroAttribute;
2634
2635#[derive(LintDiagnostic)]
2636#[diag(lint_cfg_attr_no_attributes)]
2637pub(crate) struct CfgAttrNoAttributes;
2638
2639#[derive(LintDiagnostic)]
2640#[diag(lint_metavariable_still_repeating)]
2641pub(crate) struct MetaVariableStillRepeating {
2642 pub name: MacroRulesNormalizedIdent,
2643}
2644
2645#[derive(LintDiagnostic)]
2646#[diag(lint_metavariable_wrong_operator)]
2647pub(crate) struct MetaVariableWrongOperator;
2648
2649#[derive(LintDiagnostic)]
2650#[diag(lint_duplicate_matcher_binding)]
2651pub(crate) struct DuplicateMatcherBinding;
2652
2653#[derive(LintDiagnostic)]
2654#[diag(lint_unknown_macro_variable)]
2655pub(crate) struct UnknownMacroVariable {
2656 pub name: MacroRulesNormalizedIdent,
2657}
2658
2659#[derive(LintDiagnostic)]
2660#[diag(lint_unused_crate_dependency)]
2661#[help]
2662pub(crate) struct UnusedCrateDependency {
2663 pub extern_crate: Symbol,
2664 pub local_crate: Symbol,
2665}
2666
2667#[derive(LintDiagnostic)]
2669#[diag(lint_ill_formed_attribute_input)]
2670pub(crate) struct IllFormedAttributeInput {
2671 pub num_suggestions: usize,
2672 pub suggestions: DiagArgValue,
2673}
2674
2675#[derive(LintDiagnostic)]
2676pub(crate) enum InnerAttributeUnstable {
2677 #[diag(lint_inner_macro_attribute_unstable)]
2678 InnerMacroAttribute,
2679 #[diag(lint_custom_inner_attribute_unstable)]
2680 CustomInnerAttribute,
2681}
2682
2683#[derive(LintDiagnostic)]
2684#[diag(lint_unknown_diagnostic_attribute)]
2685pub(crate) struct UnknownDiagnosticAttribute {
2686 #[subdiagnostic]
2687 pub typo: Option<UnknownDiagnosticAttributeTypoSugg>,
2688}
2689
2690#[derive(Subdiagnostic)]
2691#[suggestion(
2692 lint_unknown_diagnostic_attribute_typo_sugg,
2693 style = "verbose",
2694 code = "{typo_name}",
2695 applicability = "machine-applicable"
2696)]
2697pub(crate) struct UnknownDiagnosticAttributeTypoSugg {
2698 #[primary_span]
2699 pub span: Span,
2700 pub typo_name: Symbol,
2701}
2702
2703#[derive(LintDiagnostic)]
2704#[diag(lint_unicode_text_flow)]
2705#[note]
2706pub(crate) struct UnicodeTextFlow {
2707 #[label]
2708 pub comment_span: Span,
2709 #[subdiagnostic]
2710 pub characters: Vec<UnicodeCharNoteSub>,
2711 #[subdiagnostic]
2712 pub suggestions: Option<UnicodeTextFlowSuggestion>,
2713
2714 pub num_codepoints: usize,
2715}
2716
2717#[derive(Subdiagnostic)]
2718#[label(lint_label_comment_char)]
2719pub(crate) struct UnicodeCharNoteSub {
2720 #[primary_span]
2721 pub span: Span,
2722 pub c_debug: String,
2723}
2724
2725#[derive(Subdiagnostic)]
2726#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable", style = "hidden")]
2727pub(crate) struct UnicodeTextFlowSuggestion {
2728 #[suggestion_part(code = "")]
2729 pub spans: Vec<Span>,
2730}
2731
2732#[derive(LintDiagnostic)]
2733#[diag(lint_abs_path_with_module)]
2734pub(crate) struct AbsPathWithModule {
2735 #[subdiagnostic]
2736 pub sugg: AbsPathWithModuleSugg,
2737}
2738
2739#[derive(Subdiagnostic)]
2740#[suggestion(lint_suggestion, code = "{replacement}")]
2741pub(crate) struct AbsPathWithModuleSugg {
2742 #[primary_span]
2743 pub span: Span,
2744 #[applicability]
2745 pub applicability: Applicability,
2746 pub replacement: String,
2747}
2748
2749#[derive(LintDiagnostic)]
2750#[diag(lint_proc_macro_derive_resolution_fallback)]
2751pub(crate) struct ProcMacroDeriveResolutionFallback {
2752 #[label]
2753 pub span: Span,
2754 pub ns: Namespace,
2755 pub ident: Ident,
2756}
2757
2758#[derive(LintDiagnostic)]
2759#[diag(lint_macro_expanded_macro_exports_accessed_by_absolute_paths)]
2760pub(crate) struct MacroExpandedMacroExportsAccessedByAbsolutePaths {
2761 #[note]
2762 pub definition: Span,
2763}
2764
2765#[derive(LintDiagnostic)]
2766#[diag(lint_hidden_lifetime_parameters)]
2767pub(crate) struct ElidedLifetimesInPaths {
2768 #[subdiagnostic]
2769 pub subdiag: ElidedLifetimeInPathSubdiag,
2770}
2771
2772#[derive(LintDiagnostic)]
2773#[diag(lint_invalid_crate_type_value)]
2774pub(crate) struct UnknownCrateTypes {
2775 #[subdiagnostic]
2776 pub sugg: Option<UnknownCrateTypesSub>,
2777}
2778
2779#[derive(Subdiagnostic)]
2780#[suggestion(lint_suggestion, code = r#""{candidate}""#, applicability = "maybe-incorrect")]
2781pub(crate) struct UnknownCrateTypesSub {
2782 #[primary_span]
2783 pub span: Span,
2784 pub candidate: Symbol,
2785}
2786
2787#[derive(LintDiagnostic)]
2788#[diag(lint_unused_imports)]
2789pub(crate) struct UnusedImports {
2790 #[subdiagnostic]
2791 pub sugg: UnusedImportsSugg,
2792 #[help]
2793 pub test_module_span: Option<Span>,
2794
2795 pub span_snippets: DiagArgValue,
2796 pub num_snippets: usize,
2797}
2798
2799#[derive(Subdiagnostic)]
2800pub(crate) enum UnusedImportsSugg {
2801 #[suggestion(
2802 lint_suggestion_remove_whole_use,
2803 applicability = "machine-applicable",
2804 code = "",
2805 style = "tool-only"
2806 )]
2807 RemoveWholeUse {
2808 #[primary_span]
2809 span: Span,
2810 },
2811 #[multipart_suggestion(
2812 lint_suggestion_remove_imports,
2813 applicability = "machine-applicable",
2814 style = "tool-only"
2815 )]
2816 RemoveImports {
2817 #[suggestion_part(code = "")]
2818 remove_spans: Vec<Span>,
2819 num_to_remove: usize,
2820 },
2821}
2822
2823#[derive(LintDiagnostic)]
2824#[diag(lint_redundant_import)]
2825pub(crate) struct RedundantImport {
2826 #[subdiagnostic]
2827 pub subs: Vec<RedundantImportSub>,
2828
2829 pub ident: Ident,
2830}
2831
2832#[derive(Subdiagnostic)]
2833pub(crate) enum RedundantImportSub {
2834 #[label(lint_label_imported_here)]
2835 ImportedHere(#[primary_span] Span),
2836 #[label(lint_label_defined_here)]
2837 DefinedHere(#[primary_span] Span),
2838 #[label(lint_label_imported_prelude)]
2839 ImportedPrelude(#[primary_span] Span),
2840 #[label(lint_label_defined_prelude)]
2841 DefinedPrelude(#[primary_span] Span),
2842}
2843
2844#[derive(LintDiagnostic)]
2845#[diag(lint_unused_doc_comment)]
2846#[help]
2847pub(crate) struct UnusedDocComment {
2848 #[label]
2849 pub span: Span,
2850}
2851
2852#[derive(LintDiagnostic)]
2853pub(crate) enum PatternsInFnsWithoutBody {
2854 #[diag(lint_pattern_in_foreign)]
2855 Foreign {
2856 #[subdiagnostic]
2857 sub: PatternsInFnsWithoutBodySub,
2858 },
2859 #[diag(lint_pattern_in_bodiless)]
2860 Bodiless {
2861 #[subdiagnostic]
2862 sub: PatternsInFnsWithoutBodySub,
2863 },
2864}
2865
2866#[derive(Subdiagnostic)]
2867#[suggestion(lint_remove_mut_from_pattern, code = "{ident}", applicability = "machine-applicable")]
2868pub(crate) struct PatternsInFnsWithoutBodySub {
2869 #[primary_span]
2870 pub span: Span,
2871
2872 pub ident: Ident,
2873}
2874
2875#[derive(LintDiagnostic)]
2876#[diag(lint_extern_without_abi)]
2877pub(crate) struct MissingAbi {
2878 #[suggestion(code = "extern {default_abi}", applicability = "machine-applicable")]
2879 pub span: Span,
2880 pub default_abi: ExternAbi,
2881}
2882
2883#[derive(LintDiagnostic)]
2884#[diag(lint_legacy_derive_helpers)]
2885pub(crate) struct LegacyDeriveHelpers {
2886 #[label]
2887 pub span: Span,
2888}
2889
2890#[derive(LintDiagnostic)]
2891#[diag(lint_or_patterns_back_compat)]
2892pub(crate) struct OrPatternsBackCompat {
2893 #[suggestion(code = "{suggestion}", applicability = "machine-applicable")]
2894 pub span: Span,
2895 pub suggestion: String,
2896}
2897
2898#[derive(LintDiagnostic)]
2899#[diag(lint_reserved_prefix)]
2900pub(crate) struct ReservedPrefix {
2901 #[label]
2902 pub label: Span,
2903 #[suggestion(code = " ", applicability = "machine-applicable")]
2904 pub suggestion: Span,
2905
2906 pub prefix: String,
2907}
2908
2909#[derive(LintDiagnostic)]
2910#[diag(lint_raw_prefix)]
2911pub(crate) struct RawPrefix {
2912 #[label]
2913 pub label: Span,
2914 #[suggestion(code = " ", applicability = "machine-applicable")]
2915 pub suggestion: Span,
2916}
2917
2918#[derive(LintDiagnostic)]
2919#[diag(lint_unused_builtin_attribute)]
2920pub(crate) struct UnusedBuiltinAttribute {
2921 #[note]
2922 pub invoc_span: Span,
2923
2924 pub attr_name: Symbol,
2925 pub macro_name: String,
2926}
2927
2928#[derive(LintDiagnostic)]
2929#[diag(lint_trailing_semi_macro)]
2930pub(crate) struct TrailingMacro {
2931 #[note(lint_note1)]
2932 #[note(lint_note2)]
2933 pub is_trailing: bool,
2934
2935 pub name: Ident,
2936}
2937
2938#[derive(LintDiagnostic)]
2939#[diag(lint_break_with_label_and_loop)]
2940pub(crate) struct BreakWithLabelAndLoop {
2941 #[subdiagnostic]
2942 pub sub: BreakWithLabelAndLoopSub,
2943}
2944
2945#[derive(Subdiagnostic)]
2946#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
2947pub(crate) struct BreakWithLabelAndLoopSub {
2948 #[suggestion_part(code = "(")]
2949 pub left: Span,
2950 #[suggestion_part(code = ")")]
2951 pub right: Span,
2952}
2953
2954#[derive(LintDiagnostic)]
2955#[diag(lint_deprecated_where_clause_location)]
2956#[note]
2957pub(crate) struct DeprecatedWhereClauseLocation {
2958 #[subdiagnostic]
2959 pub suggestion: DeprecatedWhereClauseLocationSugg,
2960}
2961
2962#[derive(Subdiagnostic)]
2963pub(crate) enum DeprecatedWhereClauseLocationSugg {
2964 #[multipart_suggestion(lint_suggestion_move_to_end, applicability = "machine-applicable")]
2965 MoveToEnd {
2966 #[suggestion_part(code = "")]
2967 left: Span,
2968 #[suggestion_part(code = "{sugg}")]
2969 right: Span,
2970
2971 sugg: String,
2972 },
2973 #[suggestion(lint_suggestion_remove_where, code = "", applicability = "machine-applicable")]
2974 RemoveWhere {
2975 #[primary_span]
2976 span: Span,
2977 },
2978}
2979
2980#[derive(LintDiagnostic)]
2981#[diag(lint_missing_unsafe_on_extern)]
2982pub(crate) struct MissingUnsafeOnExtern {
2983 #[suggestion(code = "unsafe ", applicability = "machine-applicable")]
2984 pub suggestion: Span,
2985}
2986
2987#[derive(LintDiagnostic)]
2988#[diag(lint_single_use_lifetime)]
2989pub(crate) struct SingleUseLifetime {
2990 #[label(lint_label_param)]
2991 pub param_span: Span,
2992 #[label(lint_label_use)]
2993 pub use_span: Span,
2994 #[subdiagnostic]
2995 pub suggestion: Option<SingleUseLifetimeSugg>,
2996
2997 pub ident: Ident,
2998}
2999
3000#[derive(Subdiagnostic)]
3001#[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
3002pub(crate) struct SingleUseLifetimeSugg {
3003 #[suggestion_part(code = "")]
3004 pub deletion_span: Option<Span>,
3005 #[suggestion_part(code = "{replace_lt}")]
3006 pub use_span: Span,
3007
3008 pub replace_lt: String,
3009}
3010
3011#[derive(LintDiagnostic)]
3012#[diag(lint_unused_lifetime)]
3013pub(crate) struct UnusedLifetime {
3014 #[suggestion(code = "", applicability = "machine-applicable")]
3015 pub deletion_span: Option<Span>,
3016
3017 pub ident: Ident,
3018}
3019
3020#[derive(LintDiagnostic)]
3021#[diag(lint_named_argument_used_positionally)]
3022pub(crate) struct NamedArgumentUsedPositionally {
3023 #[label(lint_label_named_arg)]
3024 pub named_arg_sp: Span,
3025 #[label(lint_label_position_arg)]
3026 pub position_label_sp: Option<Span>,
3027 #[suggestion(style = "verbose", code = "{name}", applicability = "maybe-incorrect")]
3028 pub suggestion: Option<Span>,
3029
3030 pub name: String,
3031 pub named_arg_name: String,
3032}
3033
3034#[derive(LintDiagnostic)]
3035#[diag(lint_byte_slice_in_packed_struct_with_derive)]
3036#[help]
3037pub(crate) struct ByteSliceInPackedStructWithDerive {
3038 pub ty: String,
3040}
3041
3042#[derive(LintDiagnostic)]
3043#[diag(lint_unused_extern_crate)]
3044pub(crate) struct UnusedExternCrate {
3045 #[label]
3046 pub span: Span,
3047 #[suggestion(code = "", applicability = "machine-applicable", style = "verbose")]
3048 pub removal_span: Span,
3049}
3050
3051#[derive(LintDiagnostic)]
3052#[diag(lint_extern_crate_not_idiomatic)]
3053pub(crate) struct ExternCrateNotIdiomatic {
3054 #[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")]
3055 pub span: Span,
3056
3057 pub code: &'static str,
3058}
3059
3060pub(crate) struct AmbiguousGlobImports {
3062 pub ambiguity: AmbiguityErrorDiag,
3063}
3064
3065impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports {
3066 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
3067 diag.primary_message(self.ambiguity.msg.clone());
3068 rustc_errors::report_ambiguity_error(diag, self.ambiguity);
3069 }
3070}
3071
3072#[derive(LintDiagnostic)]
3073#[diag(lint_ambiguous_glob_reexport)]
3074pub(crate) struct AmbiguousGlobReexports {
3075 #[label(lint_label_first_reexport)]
3076 pub first_reexport: Span,
3077 #[label(lint_label_duplicate_reexport)]
3078 pub duplicate_reexport: Span,
3079
3080 pub name: String,
3081 pub namespace: String,
3083}
3084
3085#[derive(LintDiagnostic)]
3086#[diag(lint_hidden_glob_reexport)]
3087pub(crate) struct HiddenGlobReexports {
3088 #[note(lint_note_glob_reexport)]
3089 pub glob_reexport: Span,
3090 #[note(lint_note_private_item)]
3091 pub private_item: Span,
3092
3093 pub name: String,
3094 pub namespace: String,
3096}
3097
3098#[derive(LintDiagnostic)]
3099#[diag(lint_reexport_private_dependency)]
3100pub(crate) struct ReexportPrivateDependency {
3101 pub name: String,
3102 pub kind: String,
3103 pub krate: Symbol,
3104}
3105
3106#[derive(LintDiagnostic)]
3107#[diag(lint_unnecessary_qualification)]
3108pub(crate) struct UnusedQualifications {
3109 #[suggestion(style = "verbose", code = "", applicability = "machine-applicable")]
3110 pub removal_span: Span,
3111}
3112
3113#[derive(LintDiagnostic)]
3114#[diag(lint_associated_const_elided_lifetime)]
3115pub(crate) struct AssociatedConstElidedLifetime {
3116 #[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")]
3117 pub span: Span,
3118
3119 pub code: &'static str,
3120 pub elided: bool,
3121 #[note]
3122 pub lifetimes_in_scope: MultiSpan,
3123}
3124
3125#[derive(LintDiagnostic)]
3126#[diag(lint_redundant_import_visibility)]
3127pub(crate) struct RedundantImportVisibility {
3128 #[note]
3129 pub span: Span,
3130 #[help]
3131 pub help: (),
3132
3133 pub import_vis: String,
3134 pub max_vis: String,
3135}
3136
3137#[derive(LintDiagnostic)]
3138#[diag(lint_unsafe_attr_outside_unsafe)]
3139pub(crate) struct UnsafeAttrOutsideUnsafe {
3140 #[label]
3141 pub span: Span,
3142 #[subdiagnostic]
3143 pub suggestion: UnsafeAttrOutsideUnsafeSuggestion,
3144}
3145
3146#[derive(Subdiagnostic)]
3147#[multipart_suggestion(
3148 lint_unsafe_attr_outside_unsafe_suggestion,
3149 applicability = "machine-applicable"
3150)]
3151pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion {
3152 #[suggestion_part(code = "unsafe(")]
3153 pub left: Span,
3154 #[suggestion_part(code = ")")]
3155 pub right: Span,
3156}
3157
3158#[derive(LintDiagnostic)]
3159#[diag(lint_out_of_scope_macro_calls)]
3160#[help]
3161pub(crate) struct OutOfScopeMacroCalls {
3162 #[label]
3163 pub span: Span,
3164 pub path: String,
3165 pub location: String,
3166}
3167
3168#[derive(LintDiagnostic)]
3169#[diag(lint_static_mut_refs_lint)]
3170pub(crate) struct RefOfMutStatic<'a> {
3171 #[label]
3172 pub span: Span,
3173 #[subdiagnostic]
3174 pub sugg: Option<MutRefSugg>,
3175 pub shared_label: &'a str,
3176 #[note(lint_shared_note)]
3177 pub shared_note: bool,
3178 #[note(lint_mut_note)]
3179 pub mut_note: bool,
3180}
3181
3182#[derive(Subdiagnostic)]
3183pub(crate) enum MutRefSugg {
3184 #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
3185 Shared {
3186 #[suggestion_part(code = "&raw const ")]
3187 span: Span,
3188 },
3189 #[multipart_suggestion(
3190 lint_suggestion_mut,
3191 style = "verbose",
3192 applicability = "maybe-incorrect"
3193 )]
3194 Mut {
3195 #[suggestion_part(code = "&raw mut ")]
3196 span: Span,
3197 },
3198}
3199
3200#[derive(LintDiagnostic)]
3201#[diag(lint_unqualified_local_imports)]
3202pub(crate) struct UnqualifiedLocalImportsDiag {}
3203
3204#[derive(LintDiagnostic)]
3205#[diag(lint_reserved_string)]
3206pub(crate) struct ReservedString {
3207 #[suggestion(code = " ", applicability = "machine-applicable")]
3208 pub suggestion: Span,
3209}
3210
3211#[derive(LintDiagnostic)]
3212#[diag(lint_reserved_multihash)]
3213pub(crate) struct ReservedMultihash {
3214 #[suggestion(code = " ", applicability = "machine-applicable")]
3215 pub suggestion: Span,
3216}
3217
3218#[derive(Debug)]
3219pub(crate) struct MismatchedLifetimeSyntaxes {
3220 pub inputs: LifetimeSyntaxCategories<Vec<Span>>,
3221 pub outputs: LifetimeSyntaxCategories<Vec<Span>>,
3222
3223 pub suggestions: Vec<MismatchedLifetimeSyntaxesSuggestion>,
3224}
3225
3226impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for MismatchedLifetimeSyntaxes {
3227 fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
3228 let counts = self.inputs.len() + self.outputs.len();
3229 let message = match counts {
3230 LifetimeSyntaxCategories { hidden: 0, elided: 0, named: 0 } => {
3231 panic!("No lifetime mismatch detected")
3232 }
3233
3234 LifetimeSyntaxCategories { hidden: _, elided: _, named: 0 } => {
3235 fluent::lint_mismatched_lifetime_syntaxes_hiding_while_elided
3236 }
3237
3238 LifetimeSyntaxCategories { hidden: _, elided: 0, named: _ } => {
3239 fluent::lint_mismatched_lifetime_syntaxes_hiding_while_named
3240 }
3241
3242 LifetimeSyntaxCategories { hidden: 0, elided: _, named: _ } => {
3243 fluent::lint_mismatched_lifetime_syntaxes_eliding_while_named
3244 }
3245
3246 LifetimeSyntaxCategories { hidden: _, elided: _, named: _ } => {
3247 fluent::lint_mismatched_lifetime_syntaxes_hiding_and_eliding_while_named
3248 }
3249 };
3250 diag.primary_message(message);
3251
3252 for s in self.inputs.hidden {
3253 diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_input_hidden);
3254 }
3255 for s in self.inputs.elided {
3256 diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_input_elided);
3257 }
3258 for s in self.inputs.named {
3259 diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_input_named);
3260 }
3261
3262 for s in self.outputs.hidden {
3263 diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_output_hidden);
3264 }
3265 for s in self.outputs.elided {
3266 diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_output_elided);
3267 }
3268 for s in self.outputs.named {
3269 diag.span_label(s, fluent::lint_mismatched_lifetime_syntaxes_output_named);
3270 }
3271
3272 diag.help(fluent::lint_mismatched_lifetime_syntaxes_help);
3273
3274 let mut suggestions = self.suggestions.into_iter();
3275 if let Some(s) = suggestions.next() {
3276 diag.subdiagnostic(s);
3277
3278 for mut s in suggestions {
3279 s.make_tool_only();
3280 diag.subdiagnostic(s);
3281 }
3282 }
3283 }
3284}
3285
3286#[derive(Debug)]
3287pub(crate) enum MismatchedLifetimeSyntaxesSuggestion {
3288 Implicit {
3289 suggestions: Vec<Span>,
3290 tool_only: bool,
3291 },
3292
3293 Mixed {
3294 implicit_suggestions: Vec<Span>,
3295 explicit_anonymous_suggestions: Vec<(Span, String)>,
3296 tool_only: bool,
3297 },
3298
3299 Explicit {
3300 lifetime_name: String,
3301 suggestions: Vec<(Span, String)>,
3302 tool_only: bool,
3303 },
3304}
3305
3306impl MismatchedLifetimeSyntaxesSuggestion {
3307 fn make_tool_only(&mut self) {
3308 use MismatchedLifetimeSyntaxesSuggestion::*;
3309
3310 let tool_only = match self {
3311 Implicit { tool_only, .. } | Mixed { tool_only, .. } | Explicit { tool_only, .. } => {
3312 tool_only
3313 }
3314 };
3315
3316 *tool_only = true;
3317 }
3318}
3319
3320impl Subdiagnostic for MismatchedLifetimeSyntaxesSuggestion {
3321 fn add_to_diag<G: EmissionGuarantee>(self, diag: &mut Diag<'_, G>) {
3322 use MismatchedLifetimeSyntaxesSuggestion::*;
3323
3324 let style = |tool_only| {
3325 if tool_only { SuggestionStyle::CompletelyHidden } else { SuggestionStyle::ShowAlways }
3326 };
3327
3328 match self {
3329 Implicit { suggestions, tool_only } => {
3330 let suggestions = suggestions.into_iter().map(|s| (s, String::new())).collect();
3331 diag.multipart_suggestion_with_style(
3332 fluent::lint_mismatched_lifetime_syntaxes_suggestion_implicit,
3333 suggestions,
3334 Applicability::MaybeIncorrect,
3335 style(tool_only),
3336 );
3337 }
3338
3339 Mixed { implicit_suggestions, explicit_anonymous_suggestions, tool_only } => {
3340 let message = if implicit_suggestions.is_empty() {
3341 fluent::lint_mismatched_lifetime_syntaxes_suggestion_mixed_only_paths
3342 } else {
3343 fluent::lint_mismatched_lifetime_syntaxes_suggestion_mixed
3344 };
3345
3346 let implicit_suggestions =
3347 implicit_suggestions.into_iter().map(|s| (s, String::new()));
3348
3349 let suggestions =
3350 implicit_suggestions.chain(explicit_anonymous_suggestions).collect();
3351
3352 diag.multipart_suggestion_with_style(
3353 message,
3354 suggestions,
3355 Applicability::MaybeIncorrect,
3356 style(tool_only),
3357 );
3358 }
3359
3360 Explicit { lifetime_name, suggestions, tool_only } => {
3361 diag.arg("lifetime_name", lifetime_name);
3362 let msg = diag.eagerly_translate(
3363 fluent::lint_mismatched_lifetime_syntaxes_suggestion_explicit,
3364 );
3365 diag.remove_arg("lifetime_name");
3366 diag.multipart_suggestion_with_style(
3367 msg,
3368 suggestions,
3369 Applicability::MaybeIncorrect,
3370 style(tool_only),
3371 );
3372 }
3373 }
3374 }
3375}