• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(rustc::untranslatable_diagnostic)]
2 #![allow(rustc::diagnostic_outside_of_impl)]
3 use std::num::NonZeroU32;
4 
5 use crate::fluent_generated as fluent;
6 use rustc_errors::{
7     AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage, DiagnosticStyledString,
8     SuggestionStyle,
9 };
10 use rustc_hir::def_id::DefId;
11 use rustc_macros::{LintDiagnostic, Subdiagnostic};
12 use rustc_middle::ty::{
13     inhabitedness::InhabitedPredicate, Clause, PolyExistentialTraitRef, Ty, TyCtxt,
14 };
15 use rustc_session::parse::ParseSess;
16 use rustc_span::{edition::Edition, sym, symbol::Ident, Span, Symbol};
17 
18 use crate::{
19     builtin::InitError, builtin::TypeAliasBounds, errors::OverruledAttributeSub, LateContext,
20 };
21 
22 // array_into_iter.rs
23 #[derive(LintDiagnostic)]
24 #[diag(lint_array_into_iter)]
25 pub struct ArrayIntoIterDiag<'a> {
26     pub target: &'a str,
27     #[suggestion(lint_use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
28     pub suggestion: Span,
29     #[subdiagnostic]
30     pub sub: Option<ArrayIntoIterDiagSub>,
31 }
32 
33 #[derive(Subdiagnostic)]
34 pub enum ArrayIntoIterDiagSub {
35     #[suggestion(lint_remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
36     RemoveIntoIter {
37         #[primary_span]
38         span: Span,
39     },
40     #[multipart_suggestion(
41         lint_use_explicit_into_iter_suggestion,
42         applicability = "maybe-incorrect"
43     )]
44     UseExplicitIntoIter {
45         #[suggestion_part(code = "IntoIterator::into_iter(")]
46         start_span: Span,
47         #[suggestion_part(code = ")")]
48         end_span: Span,
49     },
50 }
51 
52 // builtin.rs
53 #[derive(LintDiagnostic)]
54 #[diag(lint_builtin_while_true)]
55 pub struct BuiltinWhileTrue {
56     #[suggestion(style = "short", code = "{replace}", applicability = "machine-applicable")]
57     pub suggestion: Span,
58     pub replace: String,
59 }
60 
61 #[derive(LintDiagnostic)]
62 #[diag(lint_builtin_box_pointers)]
63 pub struct BuiltinBoxPointers<'a> {
64     pub ty: Ty<'a>,
65 }
66 
67 #[derive(LintDiagnostic)]
68 #[diag(lint_builtin_non_shorthand_field_patterns)]
69 pub struct BuiltinNonShorthandFieldPatterns {
70     pub ident: Ident,
71     #[suggestion(code = "{prefix}{ident}", applicability = "machine-applicable")]
72     pub suggestion: Span,
73     pub prefix: &'static str,
74 }
75 
76 #[derive(LintDiagnostic)]
77 pub enum BuiltinUnsafe {
78     #[diag(lint_builtin_allow_internal_unsafe)]
79     AllowInternalUnsafe,
80     #[diag(lint_builtin_unsafe_block)]
81     UnsafeBlock,
82     #[diag(lint_builtin_unsafe_trait)]
83     UnsafeTrait,
84     #[diag(lint_builtin_unsafe_impl)]
85     UnsafeImpl,
86     #[diag(lint_builtin_no_mangle_fn)]
87     #[note(lint_builtin_overridden_symbol_name)]
88     NoMangleFn,
89     #[diag(lint_builtin_export_name_fn)]
90     #[note(lint_builtin_overridden_symbol_name)]
91     ExportNameFn,
92     #[diag(lint_builtin_link_section_fn)]
93     #[note(lint_builtin_overridden_symbol_section)]
94     LinkSectionFn,
95     #[diag(lint_builtin_no_mangle_static)]
96     #[note(lint_builtin_overridden_symbol_name)]
97     NoMangleStatic,
98     #[diag(lint_builtin_export_name_static)]
99     #[note(lint_builtin_overridden_symbol_name)]
100     ExportNameStatic,
101     #[diag(lint_builtin_link_section_static)]
102     #[note(lint_builtin_overridden_symbol_section)]
103     LinkSectionStatic,
104     #[diag(lint_builtin_no_mangle_method)]
105     #[note(lint_builtin_overridden_symbol_name)]
106     NoMangleMethod,
107     #[diag(lint_builtin_export_name_method)]
108     #[note(lint_builtin_overridden_symbol_name)]
109     ExportNameMethod,
110     #[diag(lint_builtin_decl_unsafe_fn)]
111     DeclUnsafeFn,
112     #[diag(lint_builtin_decl_unsafe_method)]
113     DeclUnsafeMethod,
114     #[diag(lint_builtin_impl_unsafe_method)]
115     ImplUnsafeMethod,
116 }
117 
118 #[derive(LintDiagnostic)]
119 #[diag(lint_builtin_missing_doc)]
120 pub struct BuiltinMissingDoc<'a> {
121     pub article: &'a str,
122     pub desc: &'a str,
123 }
124 
125 #[derive(LintDiagnostic)]
126 #[diag(lint_builtin_missing_copy_impl)]
127 pub struct BuiltinMissingCopyImpl;
128 
129 pub struct BuiltinMissingDebugImpl<'a> {
130     pub tcx: TyCtxt<'a>,
131     pub def_id: DefId,
132 }
133 
134 // Needed for def_path_str
135 impl<'a> DecorateLint<'a, ()> for BuiltinMissingDebugImpl<'_> {
decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>136     fn decorate_lint<'b>(
137         self,
138         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
139     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
140         diag.set_arg("debug", self.tcx.def_path_str(self.def_id));
141         diag
142     }
143 
msg(&self) -> DiagnosticMessage144     fn msg(&self) -> DiagnosticMessage {
145         fluent::lint_builtin_missing_debug_impl
146     }
147 }
148 
149 #[derive(LintDiagnostic)]
150 #[diag(lint_builtin_anonymous_params)]
151 pub struct BuiltinAnonymousParams<'a> {
152     #[suggestion(code = "_: {ty_snip}")]
153     pub suggestion: (Span, Applicability),
154     pub ty_snip: &'a str,
155 }
156 
157 // FIXME(davidtwco) translatable deprecated attr
158 #[derive(LintDiagnostic)]
159 #[diag(lint_builtin_deprecated_attr_link)]
160 pub struct BuiltinDeprecatedAttrLink<'a> {
161     pub name: Symbol,
162     pub reason: &'a str,
163     pub link: &'a str,
164     #[subdiagnostic]
165     pub suggestion: BuiltinDeprecatedAttrLinkSuggestion<'a>,
166 }
167 
168 #[derive(Subdiagnostic)]
169 pub enum BuiltinDeprecatedAttrLinkSuggestion<'a> {
170     #[suggestion(lint_msg_suggestion, code = "", applicability = "machine-applicable")]
171     Msg {
172         #[primary_span]
173         suggestion: Span,
174         msg: &'a str,
175     },
176     #[suggestion(lint_default_suggestion, code = "", applicability = "machine-applicable")]
177     Default {
178         #[primary_span]
179         suggestion: Span,
180     },
181 }
182 
183 #[derive(LintDiagnostic)]
184 #[diag(lint_builtin_deprecated_attr_used)]
185 pub struct BuiltinDeprecatedAttrUsed {
186     pub name: String,
187     #[suggestion(
188         lint_builtin_deprecated_attr_default_suggestion,
189         style = "short",
190         code = "",
191         applicability = "machine-applicable"
192     )]
193     pub suggestion: Span,
194 }
195 
196 #[derive(LintDiagnostic)]
197 #[diag(lint_builtin_unused_doc_comment)]
198 pub struct BuiltinUnusedDocComment<'a> {
199     pub kind: &'a str,
200     #[label]
201     pub label: Span,
202     #[subdiagnostic]
203     pub sub: BuiltinUnusedDocCommentSub,
204 }
205 
206 #[derive(Subdiagnostic)]
207 pub enum BuiltinUnusedDocCommentSub {
208     #[help(lint_plain_help)]
209     PlainHelp,
210     #[help(lint_block_help)]
211     BlockHelp,
212 }
213 
214 #[derive(LintDiagnostic)]
215 #[diag(lint_builtin_no_mangle_generic)]
216 pub struct BuiltinNoMangleGeneric {
217     // Use of `#[no_mangle]` suggests FFI intent; correct
218     // fix may be to monomorphize source by hand
219     #[suggestion(style = "short", code = "", applicability = "maybe-incorrect")]
220     pub suggestion: Span,
221 }
222 
223 #[derive(LintDiagnostic)]
224 #[diag(lint_builtin_const_no_mangle)]
225 pub struct BuiltinConstNoMangle {
226     #[suggestion(code = "pub static", applicability = "machine-applicable")]
227     pub suggestion: Span,
228 }
229 
230 #[derive(LintDiagnostic)]
231 #[diag(lint_builtin_mutable_transmutes)]
232 pub struct BuiltinMutablesTransmutes;
233 
234 #[derive(LintDiagnostic)]
235 #[diag(lint_builtin_unstable_features)]
236 pub struct BuiltinUnstableFeatures;
237 
238 // lint_ungated_async_fn_track_caller
239 pub struct BuiltinUngatedAsyncFnTrackCaller<'a> {
240     pub label: Span,
241     pub parse_sess: &'a ParseSess,
242 }
243 
244 impl<'a> DecorateLint<'a, ()> for BuiltinUngatedAsyncFnTrackCaller<'_> {
decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>245     fn decorate_lint<'b>(
246         self,
247         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
248     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
249         diag.span_label(self.label, fluent::lint_label);
250         rustc_session::parse::add_feature_diagnostics(
251             diag,
252             &self.parse_sess,
253             sym::closure_track_caller,
254         );
255         diag
256     }
257 
msg(&self) -> DiagnosticMessage258     fn msg(&self) -> DiagnosticMessage {
259         fluent::lint_ungated_async_fn_track_caller
260     }
261 }
262 
263 #[derive(LintDiagnostic)]
264 #[diag(lint_builtin_unreachable_pub)]
265 pub struct BuiltinUnreachablePub<'a> {
266     pub what: &'a str,
267     #[suggestion(code = "pub(crate)")]
268     pub suggestion: (Span, Applicability),
269     #[help]
270     pub help: Option<()>,
271 }
272 
273 pub struct SuggestChangingAssocTypes<'a, 'b> {
274     pub ty: &'a rustc_hir::Ty<'b>,
275 }
276 
277 impl AddToDiagnostic for SuggestChangingAssocTypes<'_, '_> {
add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,278     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
279     where
280         F: Fn(
281             &mut rustc_errors::Diagnostic,
282             rustc_errors::SubdiagnosticMessage,
283         ) -> rustc_errors::SubdiagnosticMessage,
284     {
285         // Access to associates types should use `<T as Bound>::Assoc`, which does not need a
286         // bound. Let's see if this type does that.
287 
288         // We use a HIR visitor to walk the type.
289         use rustc_hir::intravisit::{self, Visitor};
290         struct WalkAssocTypes<'a> {
291             err: &'a mut rustc_errors::Diagnostic,
292         }
293         impl Visitor<'_> for WalkAssocTypes<'_> {
294             fn visit_qpath(
295                 &mut self,
296                 qpath: &rustc_hir::QPath<'_>,
297                 id: rustc_hir::HirId,
298                 span: Span,
299             ) {
300                 if TypeAliasBounds::is_type_variable_assoc(qpath) {
301                     self.err.span_help(span, fluent::lint_builtin_type_alias_bounds_help);
302                 }
303                 intravisit::walk_qpath(self, qpath, id)
304             }
305         }
306 
307         // Let's go for a walk!
308         let mut visitor = WalkAssocTypes { err: diag };
309         visitor.visit_ty(self.ty);
310     }
311 }
312 
313 #[derive(LintDiagnostic)]
314 #[diag(lint_builtin_type_alias_where_clause)]
315 pub struct BuiltinTypeAliasWhereClause<'a, 'b> {
316     #[suggestion(code = "", applicability = "machine-applicable")]
317     pub suggestion: Span,
318     #[subdiagnostic]
319     pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>,
320 }
321 
322 #[derive(LintDiagnostic)]
323 #[diag(lint_builtin_type_alias_generic_bounds)]
324 pub struct BuiltinTypeAliasGenericBounds<'a, 'b> {
325     #[subdiagnostic]
326     pub suggestion: BuiltinTypeAliasGenericBoundsSuggestion,
327     #[subdiagnostic]
328     pub sub: Option<SuggestChangingAssocTypes<'a, 'b>>,
329 }
330 
331 pub struct BuiltinTypeAliasGenericBoundsSuggestion {
332     pub suggestions: Vec<(Span, String)>,
333 }
334 
335 impl AddToDiagnostic for BuiltinTypeAliasGenericBoundsSuggestion {
add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,336     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
337     where
338         F: Fn(
339             &mut rustc_errors::Diagnostic,
340             rustc_errors::SubdiagnosticMessage,
341         ) -> rustc_errors::SubdiagnosticMessage,
342     {
343         diag.multipart_suggestion(
344             fluent::lint_suggestion,
345             self.suggestions,
346             Applicability::MachineApplicable,
347         );
348     }
349 }
350 
351 #[derive(LintDiagnostic)]
352 #[diag(lint_builtin_trivial_bounds)]
353 pub struct BuiltinTrivialBounds<'a> {
354     pub predicate_kind_name: &'a str,
355     pub predicate: Clause<'a>,
356 }
357 
358 #[derive(LintDiagnostic)]
359 pub enum BuiltinEllipsisInclusiveRangePatternsLint {
360     #[diag(lint_builtin_ellipsis_inclusive_range_patterns)]
361     Parenthesise {
362         #[suggestion(code = "{replace}", applicability = "machine-applicable")]
363         suggestion: Span,
364         replace: String,
365     },
366     #[diag(lint_builtin_ellipsis_inclusive_range_patterns)]
367     NonParenthesise {
368         #[suggestion(style = "short", code = "..=", applicability = "machine-applicable")]
369         suggestion: Span,
370     },
371 }
372 
373 #[derive(LintDiagnostic)]
374 #[diag(lint_builtin_unnameable_test_items)]
375 pub struct BuiltinUnnameableTestItems;
376 
377 #[derive(LintDiagnostic)]
378 #[diag(lint_builtin_keyword_idents)]
379 pub struct BuiltinKeywordIdents {
380     pub kw: Ident,
381     pub next: Edition,
382     #[suggestion(code = "r#{kw}", applicability = "machine-applicable")]
383     pub suggestion: Span,
384 }
385 
386 #[derive(LintDiagnostic)]
387 #[diag(lint_builtin_explicit_outlives)]
388 pub struct BuiltinExplicitOutlives {
389     pub count: usize,
390     #[subdiagnostic]
391     pub suggestion: BuiltinExplicitOutlivesSuggestion,
392 }
393 
394 #[derive(Subdiagnostic)]
395 #[multipart_suggestion(lint_suggestion)]
396 pub struct BuiltinExplicitOutlivesSuggestion {
397     #[suggestion_part(code = "")]
398     pub spans: Vec<Span>,
399     #[applicability]
400     pub applicability: Applicability,
401 }
402 
403 #[derive(LintDiagnostic)]
404 #[diag(lint_builtin_incomplete_features)]
405 pub struct BuiltinIncompleteFeatures {
406     pub name: Symbol,
407     #[subdiagnostic]
408     pub note: Option<BuiltinIncompleteFeaturesNote>,
409     #[subdiagnostic]
410     pub help: Option<BuiltinIncompleteFeaturesHelp>,
411 }
412 
413 #[derive(Subdiagnostic)]
414 #[help(lint_help)]
415 pub struct BuiltinIncompleteFeaturesHelp;
416 
417 #[derive(Subdiagnostic)]
418 #[note(lint_note)]
419 pub struct BuiltinIncompleteFeaturesNote {
420     pub n: NonZeroU32,
421 }
422 
423 pub struct BuiltinUnpermittedTypeInit<'a> {
424     pub msg: DiagnosticMessage,
425     pub ty: Ty<'a>,
426     pub label: Span,
427     pub sub: BuiltinUnpermittedTypeInitSub,
428     pub tcx: TyCtxt<'a>,
429 }
430 
431 impl<'a> DecorateLint<'a, ()> for BuiltinUnpermittedTypeInit<'_> {
decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>432     fn decorate_lint<'b>(
433         self,
434         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
435     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
436         diag.set_arg("ty", self.ty);
437         diag.span_label(self.label, fluent::lint_builtin_unpermitted_type_init_label);
438         if let InhabitedPredicate::True = self.ty.inhabited_predicate(self.tcx) {
439             // Only suggest late `MaybeUninit::assume_init` initialization if the type is inhabited.
440             diag.span_label(
441                 self.label,
442                 fluent::lint_builtin_unpermitted_type_init_label_suggestion,
443             );
444         }
445         self.sub.add_to_diagnostic(diag);
446         diag
447     }
448 
msg(&self) -> rustc_errors::DiagnosticMessage449     fn msg(&self) -> rustc_errors::DiagnosticMessage {
450         self.msg.clone()
451     }
452 }
453 
454 // FIXME(davidtwco): make translatable
455 pub struct BuiltinUnpermittedTypeInitSub {
456     pub err: InitError,
457 }
458 
459 impl AddToDiagnostic for BuiltinUnpermittedTypeInitSub {
add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,460     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
461     where
462         F: Fn(
463             &mut rustc_errors::Diagnostic,
464             rustc_errors::SubdiagnosticMessage,
465         ) -> rustc_errors::SubdiagnosticMessage,
466     {
467         let mut err = self.err;
468         loop {
469             if let Some(span) = err.span {
470                 diag.span_note(span, err.message);
471             } else {
472                 diag.note(err.message);
473             }
474             if let Some(e) = err.nested {
475                 err = *e;
476             } else {
477                 break;
478             }
479         }
480     }
481 }
482 
483 #[derive(LintDiagnostic)]
484 pub enum BuiltinClashingExtern<'a> {
485     #[diag(lint_builtin_clashing_extern_same_name)]
486     SameName {
487         this: Symbol,
488         orig: Symbol,
489         #[label(lint_previous_decl_label)]
490         previous_decl_label: Span,
491         #[label(lint_mismatch_label)]
492         mismatch_label: Span,
493         #[subdiagnostic]
494         sub: BuiltinClashingExternSub<'a>,
495     },
496     #[diag(lint_builtin_clashing_extern_diff_name)]
497     DiffName {
498         this: Symbol,
499         orig: Symbol,
500         #[label(lint_previous_decl_label)]
501         previous_decl_label: Span,
502         #[label(lint_mismatch_label)]
503         mismatch_label: Span,
504         #[subdiagnostic]
505         sub: BuiltinClashingExternSub<'a>,
506     },
507 }
508 
509 // FIXME(davidtwco): translatable expected/found
510 pub struct BuiltinClashingExternSub<'a> {
511     pub tcx: TyCtxt<'a>,
512     pub expected: Ty<'a>,
513     pub found: Ty<'a>,
514 }
515 
516 impl AddToDiagnostic for BuiltinClashingExternSub<'_> {
add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,517     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
518     where
519         F: Fn(
520             &mut rustc_errors::Diagnostic,
521             rustc_errors::SubdiagnosticMessage,
522         ) -> rustc_errors::SubdiagnosticMessage,
523     {
524         let mut expected_str = DiagnosticStyledString::new();
525         expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false);
526         let mut found_str = DiagnosticStyledString::new();
527         found_str.push(self.found.fn_sig(self.tcx).to_string(), true);
528         diag.note_expected_found(&"", expected_str, &"", found_str);
529     }
530 }
531 
532 #[derive(LintDiagnostic)]
533 #[diag(lint_builtin_deref_nullptr)]
534 pub struct BuiltinDerefNullptr {
535     #[label]
536     pub label: Span,
537 }
538 
539 // FIXME: migrate fluent::lint::builtin_asm_labels
540 
541 #[derive(LintDiagnostic)]
542 pub enum BuiltinSpecialModuleNameUsed {
543     #[diag(lint_builtin_special_module_name_used_lib)]
544     #[note]
545     #[help]
546     Lib,
547     #[diag(lint_builtin_special_module_name_used_main)]
548     #[note]
549     Main,
550 }
551 
552 #[derive(LintDiagnostic)]
553 #[diag(lint_builtin_unexpected_cli_config_name)]
554 #[help]
555 pub struct BuiltinUnexpectedCliConfigName {
556     pub name: Symbol,
557 }
558 
559 #[derive(LintDiagnostic)]
560 #[diag(lint_builtin_unexpected_cli_config_value)]
561 #[help]
562 pub struct BuiltinUnexpectedCliConfigValue {
563     pub name: Symbol,
564     pub value: Symbol,
565 }
566 
567 // deref_into_dyn_supertrait.rs
568 #[derive(LintDiagnostic)]
569 #[diag(lint_supertrait_as_deref_target)]
570 pub struct SupertraitAsDerefTarget<'a> {
571     pub t: Ty<'a>,
572     pub target_principal: PolyExistentialTraitRef<'a>,
573     #[subdiagnostic]
574     pub label: Option<SupertraitAsDerefTargetLabel>,
575 }
576 
577 #[derive(Subdiagnostic)]
578 #[label(lint_label)]
579 pub struct SupertraitAsDerefTargetLabel {
580     #[primary_span]
581     pub label: Span,
582 }
583 
584 // enum_intrinsics_non_enums.rs
585 #[derive(LintDiagnostic)]
586 #[diag(lint_enum_intrinsics_mem_discriminant)]
587 pub struct EnumIntrinsicsMemDiscriminate<'a> {
588     pub ty_param: Ty<'a>,
589     #[note]
590     pub note: Span,
591 }
592 
593 #[derive(LintDiagnostic)]
594 #[diag(lint_enum_intrinsics_mem_variant)]
595 #[note]
596 pub struct EnumIntrinsicsMemVariant<'a> {
597     pub ty_param: Ty<'a>,
598 }
599 
600 // expect.rs
601 #[derive(LintDiagnostic)]
602 #[diag(lint_expectation)]
603 pub struct Expectation {
604     #[subdiagnostic]
605     pub rationale: Option<ExpectationNote>,
606     #[note]
607     pub note: Option<()>,
608 }
609 
610 #[derive(Subdiagnostic)]
611 #[note(lint_rationale)]
612 pub struct ExpectationNote {
613     pub rationale: Symbol,
614 }
615 
616 // for_loops_over_fallibles.rs
617 #[derive(LintDiagnostic)]
618 #[diag(lint_for_loops_over_fallibles)]
619 pub struct ForLoopsOverFalliblesDiag<'a> {
620     pub article: &'static str,
621     pub ty: &'static str,
622     #[subdiagnostic]
623     pub sub: ForLoopsOverFalliblesLoopSub<'a>,
624     #[subdiagnostic]
625     pub question_mark: Option<ForLoopsOverFalliblesQuestionMark>,
626     #[subdiagnostic]
627     pub suggestion: ForLoopsOverFalliblesSuggestion<'a>,
628 }
629 
630 #[derive(Subdiagnostic)]
631 pub enum ForLoopsOverFalliblesLoopSub<'a> {
632     #[suggestion(lint_remove_next, code = ".by_ref()", applicability = "maybe-incorrect")]
633     RemoveNext {
634         #[primary_span]
635         suggestion: Span,
636         recv_snip: String,
637     },
638     #[multipart_suggestion(lint_use_while_let, applicability = "maybe-incorrect")]
639     UseWhileLet {
640         #[suggestion_part(code = "while let {var}(")]
641         start_span: Span,
642         #[suggestion_part(code = ") = ")]
643         end_span: Span,
644         var: &'a str,
645     },
646 }
647 
648 #[derive(Subdiagnostic)]
649 #[suggestion(lint_use_question_mark, code = "?", applicability = "maybe-incorrect")]
650 pub struct ForLoopsOverFalliblesQuestionMark {
651     #[primary_span]
652     pub suggestion: Span,
653 }
654 
655 #[derive(Subdiagnostic)]
656 #[multipart_suggestion(lint_suggestion, applicability = "maybe-incorrect")]
657 pub struct ForLoopsOverFalliblesSuggestion<'a> {
658     pub var: &'a str,
659     #[suggestion_part(code = "if let {var}(")]
660     pub start_span: Span,
661     #[suggestion_part(code = ") = ")]
662     pub end_span: Span,
663 }
664 
665 // drop_forget_useless.rs
666 #[derive(LintDiagnostic)]
667 #[diag(lint_dropping_references)]
668 #[note]
669 pub struct DropRefDiag<'a> {
670     pub arg_ty: Ty<'a>,
671     #[label]
672     pub label: Span,
673 }
674 
675 #[derive(LintDiagnostic)]
676 #[diag(lint_dropping_copy_types)]
677 #[note]
678 pub struct DropCopyDiag<'a> {
679     pub arg_ty: Ty<'a>,
680     #[label]
681     pub label: Span,
682 }
683 
684 #[derive(LintDiagnostic)]
685 #[diag(lint_forgetting_references)]
686 #[note]
687 pub struct ForgetRefDiag<'a> {
688     pub arg_ty: Ty<'a>,
689     #[label]
690     pub label: Span,
691 }
692 
693 #[derive(LintDiagnostic)]
694 #[diag(lint_forgetting_copy_types)]
695 #[note]
696 pub struct ForgetCopyDiag<'a> {
697     pub arg_ty: Ty<'a>,
698     #[label]
699     pub label: Span,
700 }
701 
702 #[derive(LintDiagnostic)]
703 #[diag(lint_undropped_manually_drops)]
704 pub struct UndroppedManuallyDropsDiag<'a> {
705     pub arg_ty: Ty<'a>,
706     #[label]
707     pub label: Span,
708     #[subdiagnostic]
709     pub suggestion: UndroppedManuallyDropsSuggestion,
710 }
711 
712 #[derive(Subdiagnostic)]
713 #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
714 pub struct UndroppedManuallyDropsSuggestion {
715     #[suggestion_part(code = "std::mem::ManuallyDrop::into_inner(")]
716     pub start_span: Span,
717     #[suggestion_part(code = ")")]
718     pub end_span: Span,
719 }
720 
721 // invalid_from_utf8.rs
722 #[derive(LintDiagnostic)]
723 pub enum InvalidFromUtf8Diag {
724     #[diag(lint_invalid_from_utf8_unchecked)]
725     Unchecked {
726         method: String,
727         valid_up_to: usize,
728         #[label]
729         label: Span,
730     },
731     #[diag(lint_invalid_from_utf8_checked)]
732     Checked {
733         method: String,
734         valid_up_to: usize,
735         #[label]
736         label: Span,
737     },
738 }
739 
740 // reference_casting.rs
741 #[derive(LintDiagnostic)]
742 #[diag(lint_invalid_reference_casting)]
743 pub struct InvalidReferenceCastingDiag;
744 
745 // hidden_unicode_codepoints.rs
746 #[derive(LintDiagnostic)]
747 #[diag(lint_hidden_unicode_codepoints)]
748 #[note]
749 pub struct HiddenUnicodeCodepointsDiag<'a> {
750     pub label: &'a str,
751     pub count: usize,
752     #[label]
753     pub span_label: Span,
754     #[subdiagnostic]
755     pub labels: Option<HiddenUnicodeCodepointsDiagLabels>,
756     #[subdiagnostic]
757     pub sub: HiddenUnicodeCodepointsDiagSub,
758 }
759 
760 pub struct HiddenUnicodeCodepointsDiagLabels {
761     pub spans: Vec<(char, Span)>,
762 }
763 
764 impl AddToDiagnostic for HiddenUnicodeCodepointsDiagLabels {
add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,765     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
766     where
767         F: Fn(
768             &mut rustc_errors::Diagnostic,
769             rustc_errors::SubdiagnosticMessage,
770         ) -> rustc_errors::SubdiagnosticMessage,
771     {
772         for (c, span) in self.spans {
773             diag.span_label(span, format!("{:?}", c));
774         }
775     }
776 }
777 
778 pub enum HiddenUnicodeCodepointsDiagSub {
779     Escape { spans: Vec<(char, Span)> },
780     NoEscape { spans: Vec<(char, Span)> },
781 }
782 
783 // Used because of multiple multipart_suggestion and note
784 impl AddToDiagnostic for HiddenUnicodeCodepointsDiagSub {
add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,785     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
786     where
787         F: Fn(
788             &mut rustc_errors::Diagnostic,
789             rustc_errors::SubdiagnosticMessage,
790         ) -> rustc_errors::SubdiagnosticMessage,
791     {
792         match self {
793             HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
794                 diag.multipart_suggestion_with_style(
795                     fluent::lint_suggestion_remove,
796                     spans.iter().map(|(_, span)| (*span, "".to_string())).collect(),
797                     Applicability::MachineApplicable,
798                     SuggestionStyle::HideCodeAlways,
799                 );
800                 diag.multipart_suggestion(
801                     fluent::lint_suggestion_escape,
802                     spans
803                         .into_iter()
804                         .map(|(c, span)| {
805                             let c = format!("{:?}", c);
806                             (span, c[1..c.len() - 1].to_string())
807                         })
808                         .collect(),
809                     Applicability::MachineApplicable,
810                 );
811             }
812             HiddenUnicodeCodepointsDiagSub::NoEscape { spans } => {
813                 // FIXME: in other suggestions we've reversed the inner spans of doc comments. We
814                 // should do the same here to provide the same good suggestions as we do for
815                 // literals above.
816                 diag.set_arg(
817                     "escaped",
818                     spans
819                         .into_iter()
820                         .map(|(c, _)| format!("{:?}", c))
821                         .collect::<Vec<String>>()
822                         .join(", "),
823                 );
824                 diag.note(fluent::lint_suggestion_remove);
825                 diag.note(fluent::lint_no_suggestion_note_escape);
826             }
827         }
828     }
829 }
830 
831 // map_unit_fn.rs
832 #[derive(LintDiagnostic)]
833 #[diag(lint_map_unit_fn)]
834 #[note]
835 pub struct MappingToUnit {
836     #[label(lint_function_label)]
837     pub function_label: Span,
838     #[label(lint_argument_label)]
839     pub argument_label: Span,
840     #[label(lint_map_label)]
841     pub map_label: Span,
842     #[suggestion(style = "verbose", code = "{replace}", applicability = "maybe-incorrect")]
843     pub suggestion: Span,
844     pub replace: String,
845 }
846 
847 // internal.rs
848 #[derive(LintDiagnostic)]
849 #[diag(lint_default_hash_types)]
850 #[note]
851 pub struct DefaultHashTypesDiag<'a> {
852     pub preferred: &'a str,
853     pub used: Symbol,
854 }
855 
856 #[derive(LintDiagnostic)]
857 #[diag(lint_query_instability)]
858 #[note]
859 pub struct QueryInstability {
860     pub query: Symbol,
861 }
862 
863 #[derive(LintDiagnostic)]
864 #[diag(lint_tykind_kind)]
865 pub struct TykindKind {
866     #[suggestion(code = "ty", applicability = "maybe-incorrect")]
867     pub suggestion: Span,
868 }
869 
870 #[derive(LintDiagnostic)]
871 #[diag(lint_tykind)]
872 #[help]
873 pub struct TykindDiag;
874 
875 #[derive(LintDiagnostic)]
876 #[diag(lint_ty_qualified)]
877 pub struct TyQualified {
878     pub ty: String,
879     #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
880     pub suggestion: Span,
881 }
882 
883 #[derive(LintDiagnostic)]
884 #[diag(lint_lintpass_by_hand)]
885 #[help]
886 pub struct LintPassByHand;
887 
888 #[derive(LintDiagnostic)]
889 #[diag(lint_non_existent_doc_keyword)]
890 #[help]
891 pub struct NonExistentDocKeyword {
892     pub keyword: Symbol,
893 }
894 
895 #[derive(LintDiagnostic)]
896 #[diag(lint_diag_out_of_impl)]
897 pub struct DiagOutOfImpl;
898 
899 #[derive(LintDiagnostic)]
900 #[diag(lint_untranslatable_diag)]
901 pub struct UntranslatableDiag;
902 
903 #[derive(LintDiagnostic)]
904 #[diag(lint_trivial_untranslatable_diag)]
905 pub struct UntranslatableDiagnosticTrivial;
906 
907 #[derive(LintDiagnostic)]
908 #[diag(lint_bad_opt_access)]
909 pub struct BadOptAccessDiag<'a> {
910     pub msg: &'a str,
911 }
912 
913 // let_underscore.rs
914 #[derive(LintDiagnostic)]
915 pub enum NonBindingLet {
916     #[diag(lint_non_binding_let_on_sync_lock)]
917     SyncLock {
918         #[subdiagnostic]
919         sub: NonBindingLetSub,
920     },
921     #[diag(lint_non_binding_let_on_drop_type)]
922     DropType {
923         #[subdiagnostic]
924         sub: NonBindingLetSub,
925     },
926 }
927 
928 pub struct NonBindingLetSub {
929     pub suggestion: Span,
930     pub multi_suggestion_start: Span,
931     pub multi_suggestion_end: Span,
932 }
933 
934 impl AddToDiagnostic for NonBindingLetSub {
add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,935     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
936     where
937         F: Fn(
938             &mut rustc_errors::Diagnostic,
939             rustc_errors::SubdiagnosticMessage,
940         ) -> rustc_errors::SubdiagnosticMessage,
941     {
942         diag.span_suggestion_verbose(
943             self.suggestion,
944             fluent::lint_non_binding_let_suggestion,
945             "_unused",
946             Applicability::MachineApplicable,
947         );
948         diag.multipart_suggestion(
949             fluent::lint_non_binding_let_multi_suggestion,
950             vec![
951                 (self.multi_suggestion_start, "drop(".to_string()),
952                 (self.multi_suggestion_end, ")".to_string()),
953             ],
954             Applicability::MachineApplicable,
955         );
956     }
957 }
958 
959 // levels.rs
960 #[derive(LintDiagnostic)]
961 #[diag(lint_overruled_attribute)]
962 pub struct OverruledAttributeLint<'a> {
963     #[label]
964     pub overruled: Span,
965     pub lint_level: &'a str,
966     pub lint_source: Symbol,
967     #[subdiagnostic]
968     pub sub: OverruledAttributeSub,
969 }
970 
971 #[derive(LintDiagnostic)]
972 #[diag(lint_deprecated_lint_name)]
973 pub struct DeprecatedLintName<'a> {
974     pub name: String,
975     #[suggestion(code = "{replace}", applicability = "machine-applicable")]
976     pub suggestion: Span,
977     pub replace: &'a str,
978 }
979 
980 // FIXME: Non-translatable msg
981 #[derive(LintDiagnostic)]
982 #[diag(lint_renamed_or_removed_lint)]
983 pub struct RenamedOrRemovedLint<'a> {
984     pub msg: &'a str,
985     #[subdiagnostic]
986     pub suggestion: Option<RenamedOrRemovedLintSuggestion<'a>>,
987 }
988 
989 #[derive(Subdiagnostic)]
990 #[suggestion(lint_suggestion, code = "{replace}", applicability = "machine-applicable")]
991 pub struct RenamedOrRemovedLintSuggestion<'a> {
992     #[primary_span]
993     pub suggestion: Span,
994     pub replace: &'a str,
995 }
996 
997 #[derive(LintDiagnostic)]
998 #[diag(lint_unknown_lint)]
999 pub struct UnknownLint {
1000     pub name: String,
1001     #[subdiagnostic]
1002     pub suggestion: Option<UnknownLintSuggestion>,
1003 }
1004 
1005 #[derive(Subdiagnostic)]
1006 #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
1007 pub struct UnknownLintSuggestion {
1008     #[primary_span]
1009     pub suggestion: Span,
1010     pub replace: Symbol,
1011 }
1012 
1013 #[derive(LintDiagnostic)]
1014 #[diag(lint_ignored_unless_crate_specified)]
1015 pub struct IgnoredUnlessCrateSpecified<'a> {
1016     pub level: &'a str,
1017     pub name: Symbol,
1018 }
1019 
1020 // methods.rs
1021 #[derive(LintDiagnostic)]
1022 #[diag(lint_cstring_ptr)]
1023 #[note]
1024 #[help]
1025 pub struct CStringPtr {
1026     #[label(lint_as_ptr_label)]
1027     pub as_ptr: Span,
1028     #[label(lint_unwrap_label)]
1029     pub unwrap: Span,
1030 }
1031 
1032 // multiple_supertrait_upcastable.rs
1033 #[derive(LintDiagnostic)]
1034 #[diag(lint_multiple_supertrait_upcastable)]
1035 pub struct MultipleSupertraitUpcastable {
1036     pub ident: Ident,
1037 }
1038 
1039 // non_ascii_idents.rs
1040 #[derive(LintDiagnostic)]
1041 #[diag(lint_identifier_non_ascii_char)]
1042 pub struct IdentifierNonAsciiChar;
1043 
1044 #[derive(LintDiagnostic)]
1045 #[diag(lint_identifier_uncommon_codepoints)]
1046 pub struct IdentifierUncommonCodepoints;
1047 
1048 #[derive(LintDiagnostic)]
1049 #[diag(lint_confusable_identifier_pair)]
1050 pub struct ConfusableIdentifierPair {
1051     pub existing_sym: Symbol,
1052     pub sym: Symbol,
1053     #[label]
1054     pub label: Span,
1055 }
1056 
1057 #[derive(LintDiagnostic)]
1058 #[diag(lint_mixed_script_confusables)]
1059 #[note(lint_includes_note)]
1060 #[note]
1061 pub struct MixedScriptConfusables {
1062     pub set: String,
1063     pub includes: String,
1064 }
1065 
1066 // non_fmt_panic.rs
1067 pub struct NonFmtPanicUnused {
1068     pub count: usize,
1069     pub suggestion: Option<Span>,
1070 }
1071 
1072 // Used because of two suggestions based on one Option<Span>
1073 impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>1074     fn decorate_lint<'b>(
1075         self,
1076         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
1077     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
1078         diag.set_arg("count", self.count);
1079         diag.note(fluent::lint_note);
1080         if let Some(span) = self.suggestion {
1081             diag.span_suggestion(
1082                 span.shrink_to_hi(),
1083                 fluent::lint_add_args_suggestion,
1084                 ", ...",
1085                 Applicability::HasPlaceholders,
1086             );
1087             diag.span_suggestion(
1088                 span.shrink_to_lo(),
1089                 fluent::lint_add_fmt_suggestion,
1090                 "\"{}\", ",
1091                 Applicability::MachineApplicable,
1092             );
1093         }
1094         diag
1095     }
1096 
msg(&self) -> rustc_errors::DiagnosticMessage1097     fn msg(&self) -> rustc_errors::DiagnosticMessage {
1098         fluent::lint_non_fmt_panic_unused
1099     }
1100 }
1101 
1102 #[derive(LintDiagnostic)]
1103 #[diag(lint_non_fmt_panic_braces)]
1104 #[note]
1105 pub struct NonFmtPanicBraces {
1106     pub count: usize,
1107     #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")]
1108     pub suggestion: Option<Span>,
1109 }
1110 
1111 // nonstandard_style.rs
1112 #[derive(LintDiagnostic)]
1113 #[diag(lint_non_camel_case_type)]
1114 pub struct NonCamelCaseType<'a> {
1115     pub sort: &'a str,
1116     pub name: &'a str,
1117     #[subdiagnostic]
1118     pub sub: NonCamelCaseTypeSub,
1119 }
1120 
1121 #[derive(Subdiagnostic)]
1122 pub enum NonCamelCaseTypeSub {
1123     #[label(lint_label)]
1124     Label {
1125         #[primary_span]
1126         span: Span,
1127     },
1128     #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
1129     Suggestion {
1130         #[primary_span]
1131         span: Span,
1132         replace: String,
1133     },
1134 }
1135 
1136 #[derive(LintDiagnostic)]
1137 #[diag(lint_non_snake_case)]
1138 pub struct NonSnakeCaseDiag<'a> {
1139     pub sort: &'a str,
1140     pub name: &'a str,
1141     pub sc: String,
1142     #[subdiagnostic]
1143     pub sub: NonSnakeCaseDiagSub,
1144 }
1145 
1146 pub enum NonSnakeCaseDiagSub {
1147     Label { span: Span },
1148     Help,
1149     RenameOrConvertSuggestion { span: Span, suggestion: Ident },
1150     ConvertSuggestion { span: Span, suggestion: String },
1151     SuggestionAndNote { span: Span },
1152 }
1153 
1154 impl AddToDiagnostic for NonSnakeCaseDiagSub {
add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,1155     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
1156     where
1157         F: Fn(
1158             &mut rustc_errors::Diagnostic,
1159             rustc_errors::SubdiagnosticMessage,
1160         ) -> rustc_errors::SubdiagnosticMessage,
1161     {
1162         match self {
1163             NonSnakeCaseDiagSub::Label { span } => {
1164                 diag.span_label(span, fluent::lint_label);
1165             }
1166             NonSnakeCaseDiagSub::Help => {
1167                 diag.help(fluent::lint_help);
1168             }
1169             NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
1170                 diag.span_suggestion(
1171                     span,
1172                     fluent::lint_convert_suggestion,
1173                     suggestion,
1174                     Applicability::MaybeIncorrect,
1175                 );
1176             }
1177             NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => {
1178                 diag.span_suggestion(
1179                     span,
1180                     fluent::lint_rename_or_convert_suggestion,
1181                     suggestion,
1182                     Applicability::MaybeIncorrect,
1183                 );
1184             }
1185             NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
1186                 diag.note(fluent::lint_cannot_convert_note);
1187                 diag.span_suggestion(
1188                     span,
1189                     fluent::lint_rename_suggestion,
1190                     "",
1191                     Applicability::MaybeIncorrect,
1192                 );
1193             }
1194         }
1195     }
1196 }
1197 
1198 #[derive(LintDiagnostic)]
1199 #[diag(lint_non_upper_case_global)]
1200 pub struct NonUpperCaseGlobal<'a> {
1201     pub sort: &'a str,
1202     pub name: &'a str,
1203     #[subdiagnostic]
1204     pub sub: NonUpperCaseGlobalSub,
1205 }
1206 
1207 #[derive(Subdiagnostic)]
1208 pub enum NonUpperCaseGlobalSub {
1209     #[label(lint_label)]
1210     Label {
1211         #[primary_span]
1212         span: Span,
1213     },
1214     #[suggestion(lint_suggestion, code = "{replace}", applicability = "maybe-incorrect")]
1215     Suggestion {
1216         #[primary_span]
1217         span: Span,
1218         replace: String,
1219     },
1220 }
1221 
1222 // noop_method_call.rs
1223 #[derive(LintDiagnostic)]
1224 #[diag(lint_noop_method_call)]
1225 #[note]
1226 pub struct NoopMethodCallDiag<'a> {
1227     pub method: Symbol,
1228     pub receiver_ty: Ty<'a>,
1229     #[label]
1230     pub label: Span,
1231 }
1232 
1233 #[derive(LintDiagnostic)]
1234 #[diag(lint_suspicious_double_ref_deref)]
1235 pub struct SuspiciousDoubleRefDerefDiag<'a> {
1236     pub ty: Ty<'a>,
1237 }
1238 
1239 #[derive(LintDiagnostic)]
1240 #[diag(lint_suspicious_double_ref_clone)]
1241 pub struct SuspiciousDoubleRefCloneDiag<'a> {
1242     pub ty: Ty<'a>,
1243 }
1244 
1245 // pass_by_value.rs
1246 #[derive(LintDiagnostic)]
1247 #[diag(lint_pass_by_value)]
1248 pub struct PassByValueDiag {
1249     pub ty: String,
1250     #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
1251     pub suggestion: Span,
1252 }
1253 
1254 // redundant_semicolon.rs
1255 #[derive(LintDiagnostic)]
1256 #[diag(lint_redundant_semicolons)]
1257 pub struct RedundantSemicolonsDiag {
1258     pub multiple: bool,
1259     #[suggestion(code = "", applicability = "maybe-incorrect")]
1260     pub suggestion: Span,
1261 }
1262 
1263 // traits.rs
1264 pub struct DropTraitConstraintsDiag<'a> {
1265     pub predicate: Clause<'a>,
1266     pub tcx: TyCtxt<'a>,
1267     pub def_id: DefId,
1268 }
1269 
1270 // Needed for def_path_str
1271 impl<'a> DecorateLint<'a, ()> for DropTraitConstraintsDiag<'_> {
decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>1272     fn decorate_lint<'b>(
1273         self,
1274         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
1275     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
1276         diag.set_arg("predicate", self.predicate);
1277         diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
1278     }
1279 
msg(&self) -> rustc_errors::DiagnosticMessage1280     fn msg(&self) -> rustc_errors::DiagnosticMessage {
1281         fluent::lint_drop_trait_constraints
1282     }
1283 }
1284 
1285 pub struct DropGlue<'a> {
1286     pub tcx: TyCtxt<'a>,
1287     pub def_id: DefId,
1288 }
1289 
1290 // Needed for def_path_str
1291 impl<'a> DecorateLint<'a, ()> for DropGlue<'_> {
decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>1292     fn decorate_lint<'b>(
1293         self,
1294         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
1295     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
1296         diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
1297     }
1298 
msg(&self) -> rustc_errors::DiagnosticMessage1299     fn msg(&self) -> rustc_errors::DiagnosticMessage {
1300         fluent::lint_drop_glue
1301     }
1302 }
1303 
1304 // types.rs
1305 #[derive(LintDiagnostic)]
1306 #[diag(lint_range_endpoint_out_of_range)]
1307 pub struct RangeEndpointOutOfRange<'a> {
1308     pub ty: &'a str,
1309     #[subdiagnostic]
1310     pub sub: UseInclusiveRange<'a>,
1311 }
1312 
1313 #[derive(Subdiagnostic)]
1314 pub enum UseInclusiveRange<'a> {
1315     #[suggestion(
1316         lint_range_use_inclusive_range,
1317         code = "{start}..={literal}{suffix}",
1318         applicability = "machine-applicable"
1319     )]
1320     WithoutParen {
1321         #[primary_span]
1322         sugg: Span,
1323         start: String,
1324         literal: u128,
1325         suffix: &'a str,
1326     },
1327     #[multipart_suggestion(lint_range_use_inclusive_range, applicability = "machine-applicable")]
1328     WithParen {
1329         #[suggestion_part(code = "=")]
1330         eq_sugg: Span,
1331         #[suggestion_part(code = "{literal}{suffix}")]
1332         lit_sugg: Span,
1333         literal: u128,
1334         suffix: &'a str,
1335     },
1336 }
1337 
1338 #[derive(LintDiagnostic)]
1339 #[diag(lint_overflowing_bin_hex)]
1340 pub struct OverflowingBinHex<'a> {
1341     pub ty: &'a str,
1342     pub lit: String,
1343     pub dec: u128,
1344     pub actually: String,
1345     #[subdiagnostic]
1346     pub sign: OverflowingBinHexSign,
1347     #[subdiagnostic]
1348     pub sub: Option<OverflowingBinHexSub<'a>>,
1349     #[subdiagnostic]
1350     pub sign_bit_sub: Option<OverflowingBinHexSignBitSub<'a>>,
1351 }
1352 
1353 pub enum OverflowingBinHexSign {
1354     Positive,
1355     Negative,
1356 }
1357 
1358 impl AddToDiagnostic for OverflowingBinHexSign {
add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F) where F: Fn( &mut rustc_errors::Diagnostic, rustc_errors::SubdiagnosticMessage, ) -> rustc_errors::SubdiagnosticMessage,1359     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
1360     where
1361         F: Fn(
1362             &mut rustc_errors::Diagnostic,
1363             rustc_errors::SubdiagnosticMessage,
1364         ) -> rustc_errors::SubdiagnosticMessage,
1365     {
1366         match self {
1367             OverflowingBinHexSign::Positive => {
1368                 diag.note(fluent::lint_positive_note);
1369             }
1370             OverflowingBinHexSign::Negative => {
1371                 diag.note(fluent::lint_negative_note);
1372                 diag.note(fluent::lint_negative_becomes_note);
1373             }
1374         }
1375     }
1376 }
1377 
1378 #[derive(Subdiagnostic)]
1379 pub enum OverflowingBinHexSub<'a> {
1380     #[suggestion(
1381         lint_suggestion,
1382         code = "{sans_suffix}{suggestion_ty}",
1383         applicability = "machine-applicable"
1384     )]
1385     Suggestion {
1386         #[primary_span]
1387         span: Span,
1388         suggestion_ty: &'a str,
1389         sans_suffix: &'a str,
1390     },
1391     #[help(lint_help)]
1392     Help { suggestion_ty: &'a str },
1393 }
1394 
1395 #[derive(Subdiagnostic)]
1396 #[suggestion(
1397     lint_sign_bit_suggestion,
1398     code = "{lit_no_suffix}{uint_ty} as {int_ty}",
1399     applicability = "maybe-incorrect"
1400 )]
1401 pub struct OverflowingBinHexSignBitSub<'a> {
1402     #[primary_span]
1403     pub span: Span,
1404     pub lit_no_suffix: &'a str,
1405     pub negative_val: String,
1406     pub uint_ty: &'a str,
1407     pub int_ty: &'a str,
1408 }
1409 
1410 #[derive(LintDiagnostic)]
1411 #[diag(lint_overflowing_int)]
1412 #[note]
1413 pub struct OverflowingInt<'a> {
1414     pub ty: &'a str,
1415     pub lit: String,
1416     pub min: i128,
1417     pub max: u128,
1418     #[subdiagnostic]
1419     pub help: Option<OverflowingIntHelp<'a>>,
1420 }
1421 
1422 #[derive(Subdiagnostic)]
1423 #[help(lint_help)]
1424 pub struct OverflowingIntHelp<'a> {
1425     pub suggestion_ty: &'a str,
1426 }
1427 
1428 #[derive(LintDiagnostic)]
1429 #[diag(lint_only_cast_u8_to_char)]
1430 pub struct OnlyCastu8ToChar {
1431     #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")]
1432     pub span: Span,
1433     pub literal: u128,
1434 }
1435 
1436 #[derive(LintDiagnostic)]
1437 #[diag(lint_overflowing_uint)]
1438 #[note]
1439 pub struct OverflowingUInt<'a> {
1440     pub ty: &'a str,
1441     pub lit: String,
1442     pub min: u128,
1443     pub max: u128,
1444 }
1445 
1446 #[derive(LintDiagnostic)]
1447 #[diag(lint_overflowing_literal)]
1448 #[note]
1449 pub struct OverflowingLiteral<'a> {
1450     pub ty: &'a str,
1451     pub lit: String,
1452 }
1453 
1454 #[derive(LintDiagnostic)]
1455 #[diag(lint_unused_comparisons)]
1456 pub struct UnusedComparisons;
1457 
1458 #[derive(LintDiagnostic)]
1459 pub enum InvalidNanComparisons {
1460     #[diag(lint_invalid_nan_comparisons_eq_ne)]
1461     EqNe {
1462         #[subdiagnostic]
1463         suggestion: InvalidNanComparisonsSuggestion,
1464     },
1465     #[diag(lint_invalid_nan_comparisons_lt_le_gt_ge)]
1466     LtLeGtGe,
1467 }
1468 
1469 #[derive(Subdiagnostic)]
1470 pub enum InvalidNanComparisonsSuggestion {
1471     #[multipart_suggestion(
1472         lint_suggestion,
1473         style = "verbose",
1474         applicability = "machine-applicable"
1475     )]
1476     Spanful {
1477         #[suggestion_part(code = "!")]
1478         neg: Option<Span>,
1479         #[suggestion_part(code = ".is_nan()")]
1480         float: Span,
1481         #[suggestion_part(code = "")]
1482         nan_plus_binop: Span,
1483     },
1484     #[help(lint_suggestion)]
1485     Spanless,
1486 }
1487 
1488 pub struct ImproperCTypes<'a> {
1489     pub ty: Ty<'a>,
1490     pub desc: &'a str,
1491     pub label: Span,
1492     pub help: Option<DiagnosticMessage>,
1493     pub note: DiagnosticMessage,
1494     pub span_note: Option<Span>,
1495 }
1496 
1497 // Used because of the complexity of Option<DiagnosticMessage>, DiagnosticMessage, and Option<Span>
1498 impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> {
decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>1499     fn decorate_lint<'b>(
1500         self,
1501         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
1502     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
1503         diag.set_arg("ty", self.ty);
1504         diag.set_arg("desc", self.desc);
1505         diag.span_label(self.label, fluent::lint_label);
1506         if let Some(help) = self.help {
1507             diag.help(help);
1508         }
1509         diag.note(self.note);
1510         if let Some(note) = self.span_note {
1511             diag.span_note(note, fluent::lint_note);
1512         }
1513         diag
1514     }
1515 
msg(&self) -> rustc_errors::DiagnosticMessage1516     fn msg(&self) -> rustc_errors::DiagnosticMessage {
1517         fluent::lint_improper_ctypes
1518     }
1519 }
1520 
1521 #[derive(LintDiagnostic)]
1522 #[diag(lint_variant_size_differences)]
1523 pub struct VariantSizeDifferencesDiag {
1524     pub largest: u64,
1525 }
1526 
1527 #[derive(LintDiagnostic)]
1528 #[diag(lint_atomic_ordering_load)]
1529 #[help]
1530 pub struct AtomicOrderingLoad;
1531 
1532 #[derive(LintDiagnostic)]
1533 #[diag(lint_atomic_ordering_store)]
1534 #[help]
1535 pub struct AtomicOrderingStore;
1536 
1537 #[derive(LintDiagnostic)]
1538 #[diag(lint_atomic_ordering_fence)]
1539 #[help]
1540 pub struct AtomicOrderingFence;
1541 
1542 #[derive(LintDiagnostic)]
1543 #[diag(lint_atomic_ordering_invalid)]
1544 #[help]
1545 pub struct InvalidAtomicOrderingDiag {
1546     pub method: Symbol,
1547     #[label]
1548     pub fail_order_arg_span: Span,
1549 }
1550 
1551 // unused.rs
1552 #[derive(LintDiagnostic)]
1553 #[diag(lint_unused_op)]
1554 pub struct UnusedOp<'a> {
1555     pub op: &'a str,
1556     #[label]
1557     pub label: Span,
1558     #[subdiagnostic]
1559     pub suggestion: UnusedOpSuggestion,
1560 }
1561 
1562 #[derive(Subdiagnostic)]
1563 pub enum UnusedOpSuggestion {
1564     #[suggestion(
1565         lint_suggestion,
1566         style = "verbose",
1567         code = "let _ = ",
1568         applicability = "maybe-incorrect"
1569     )]
1570     NormalExpr {
1571         #[primary_span]
1572         span: Span,
1573     },
1574     #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
1575     BlockTailExpr {
1576         #[suggestion_part(code = "let _ = ")]
1577         before_span: Span,
1578         #[suggestion_part(code = ";")]
1579         after_span: Span,
1580     },
1581 }
1582 
1583 #[derive(LintDiagnostic)]
1584 #[diag(lint_unused_result)]
1585 pub struct UnusedResult<'a> {
1586     pub ty: Ty<'a>,
1587 }
1588 
1589 // FIXME(davidtwco): this isn't properly translatable because of the
1590 // pre/post strings
1591 #[derive(LintDiagnostic)]
1592 #[diag(lint_unused_closure)]
1593 #[note]
1594 pub struct UnusedClosure<'a> {
1595     pub count: usize,
1596     pub pre: &'a str,
1597     pub post: &'a str,
1598 }
1599 
1600 // FIXME(davidtwco): this isn't properly translatable because of the
1601 // pre/post strings
1602 #[derive(LintDiagnostic)]
1603 #[diag(lint_unused_generator)]
1604 #[note]
1605 pub struct UnusedGenerator<'a> {
1606     pub count: usize,
1607     pub pre: &'a str,
1608     pub post: &'a str,
1609 }
1610 
1611 // FIXME(davidtwco): this isn't properly translatable because of the pre/post
1612 // strings
1613 pub struct UnusedDef<'a, 'b> {
1614     pub pre: &'a str,
1615     pub post: &'a str,
1616     pub cx: &'a LateContext<'b>,
1617     pub def_id: DefId,
1618     pub note: Option<Symbol>,
1619     pub suggestion: Option<UnusedDefSuggestion>,
1620 }
1621 
1622 #[derive(Subdiagnostic)]
1623 
1624 pub enum UnusedDefSuggestion {
1625     #[suggestion(
1626         lint_suggestion,
1627         style = "verbose",
1628         code = "let _ = ",
1629         applicability = "maybe-incorrect"
1630     )]
1631     NormalExpr {
1632         #[primary_span]
1633         span: Span,
1634     },
1635     #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
1636     BlockTailExpr {
1637         #[suggestion_part(code = "let _ = ")]
1638         before_span: Span,
1639         #[suggestion_part(code = ";")]
1640         after_span: Span,
1641     },
1642 }
1643 
1644 // Needed because of def_path_str
1645 impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> {
decorate_lint<'b>( self, diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()>1646     fn decorate_lint<'b>(
1647         self,
1648         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
1649     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
1650         diag.set_arg("pre", self.pre);
1651         diag.set_arg("post", self.post);
1652         diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id));
1653         // check for #[must_use = "..."]
1654         if let Some(note) = self.note {
1655             diag.note(note.to_string());
1656         }
1657         if let Some(sugg) = self.suggestion {
1658             diag.subdiagnostic(sugg);
1659         }
1660         diag
1661     }
1662 
msg(&self) -> rustc_errors::DiagnosticMessage1663     fn msg(&self) -> rustc_errors::DiagnosticMessage {
1664         fluent::lint_unused_def
1665     }
1666 }
1667 
1668 #[derive(LintDiagnostic)]
1669 #[diag(lint_path_statement_drop)]
1670 pub struct PathStatementDrop {
1671     #[subdiagnostic]
1672     pub sub: PathStatementDropSub,
1673 }
1674 
1675 #[derive(Subdiagnostic)]
1676 pub enum PathStatementDropSub {
1677     #[suggestion(lint_suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
1678     Suggestion {
1679         #[primary_span]
1680         span: Span,
1681         snippet: String,
1682     },
1683     #[help(lint_help)]
1684     Help {
1685         #[primary_span]
1686         span: Span,
1687     },
1688 }
1689 
1690 #[derive(LintDiagnostic)]
1691 #[diag(lint_path_statement_no_effect)]
1692 pub struct PathStatementNoEffect;
1693 
1694 #[derive(LintDiagnostic)]
1695 #[diag(lint_unused_delim)]
1696 pub struct UnusedDelim<'a> {
1697     pub delim: &'static str,
1698     pub item: &'a str,
1699     #[subdiagnostic]
1700     pub suggestion: Option<UnusedDelimSuggestion>,
1701 }
1702 
1703 #[derive(Subdiagnostic)]
1704 #[multipart_suggestion(lint_suggestion, applicability = "machine-applicable")]
1705 pub struct UnusedDelimSuggestion {
1706     #[suggestion_part(code = "{start_replace}")]
1707     pub start_span: Span,
1708     pub start_replace: &'static str,
1709     #[suggestion_part(code = "{end_replace}")]
1710     pub end_span: Span,
1711     pub end_replace: &'static str,
1712 }
1713 
1714 #[derive(LintDiagnostic)]
1715 #[diag(lint_unused_import_braces)]
1716 pub struct UnusedImportBracesDiag {
1717     pub node: Symbol,
1718 }
1719 
1720 #[derive(LintDiagnostic)]
1721 #[diag(lint_unused_allocation)]
1722 pub struct UnusedAllocationDiag;
1723 
1724 #[derive(LintDiagnostic)]
1725 #[diag(lint_unused_allocation_mut)]
1726 pub struct UnusedAllocationMutDiag;
1727