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