]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_lint/src/lints.rs
migrate: `ImproperCTypes`
[rust.git] / compiler / rustc_lint / src / lints.rs
1 use rustc_errors::{fluent, AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage};
2 use rustc_hir::def_id::DefId;
3 use rustc_macros::{LintDiagnostic, Subdiagnostic};
4 use rustc_middle::ty::{Predicate, Ty, TyCtxt};
5 use rustc_span::{symbol::Ident, Span, Symbol};
6
7 use crate::{errors::OverruledAttributeSub, LateContext};
8
9 // array_into_iter.rs
10 #[derive(LintDiagnostic)]
11 #[diag(lint_array_into_iter)]
12 pub struct ArrayIntoIterDiag<'a> {
13     pub target: &'a str,
14     #[suggestion(use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
15     pub suggestion: Span,
16     #[subdiagnostic]
17     pub sub: Option<ArrayIntoIterDiagSub>,
18 }
19
20 #[derive(Subdiagnostic)]
21 pub enum ArrayIntoIterDiagSub {
22     #[suggestion(remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
23     RemoveIntoIter {
24         #[primary_span]
25         span: Span,
26     },
27     #[multipart_suggestion(use_explicit_into_iter_suggestion, applicability = "maybe-incorrect")]
28     UseExplicitIntoIter {
29         #[suggestion_part(code = "IntoIterator::into_iter(")]
30         start_span: Span,
31         #[suggestion_part(code = ")")]
32         end_span: Span,
33     },
34 }
35
36 // enum_intrinsics_non_enums.rs
37 #[derive(LintDiagnostic)]
38 #[diag(lint_enum_intrinsics_mem_discriminant)]
39 pub struct EnumIntrinsicsMemDiscriminate<'a> {
40     pub ty_param: Ty<'a>,
41     #[note]
42     pub note: Span,
43 }
44
45 #[derive(LintDiagnostic)]
46 #[diag(lint_enum_intrinsics_mem_variant)]
47 #[note]
48 pub struct EnumIntrinsicsMemVariant<'a> {
49     pub ty_param: Ty<'a>,
50 }
51
52 // let_underscore.rs
53 #[derive(LintDiagnostic)]
54 pub enum NonBindingLet {
55     #[diag(lint_non_binding_let_on_sync_lock)]
56     SyncLock {
57         #[subdiagnostic]
58         sub: NonBindingLetSub,
59     },
60     #[diag(lint_non_binding_let_on_drop_type)]
61     DropType {
62         #[subdiagnostic]
63         sub: NonBindingLetSub,
64     },
65 }
66
67 pub struct NonBindingLetSub {
68     pub suggestion: Span,
69     pub multi_suggestion_start: Span,
70     pub multi_suggestion_end: Span,
71 }
72
73 impl AddToDiagnostic for NonBindingLetSub {
74     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
75     where
76         F: Fn(
77             &mut rustc_errors::Diagnostic,
78             rustc_errors::SubdiagnosticMessage,
79         ) -> rustc_errors::SubdiagnosticMessage,
80     {
81         diag.span_suggestion_verbose(
82             self.suggestion,
83             fluent::lint_non_binding_let_suggestion,
84             "_unused",
85             Applicability::MachineApplicable,
86         );
87         diag.multipart_suggestion(
88             fluent::lint_non_binding_let_multi_suggestion,
89             vec![
90                 (self.multi_suggestion_start, "drop(".to_string()),
91                 (self.multi_suggestion_end, ")".to_string()),
92             ],
93             Applicability::MachineApplicable,
94         );
95     }
96 }
97
98 // levels.rs
99 #[derive(LintDiagnostic)]
100 #[diag(lint_overruled_attribute)]
101 pub struct OverruledAtributeLint<'a> {
102     #[label]
103     pub overruled: Span,
104     pub lint_level: &'a str,
105     pub lint_source: Symbol,
106     #[subdiagnostic]
107     pub sub: OverruledAttributeSub,
108 }
109
110 #[derive(LintDiagnostic)]
111 #[diag(lint_deprecated_lint_name)]
112 pub struct DeprecatedLintName<'a> {
113     pub name: String,
114     #[suggestion(code = "{replace}", applicability = "machine-applicable")]
115     pub suggestion: Span,
116     pub replace: &'a str,
117 }
118
119 pub struct RenamedOrRemovedLint<'a> {
120     pub msg: &'a str,
121     pub suggestion: Span,
122     pub renamed: &'a Option<String>,
123 }
124
125 impl<'a> DecorateLint<'a, ()> for RenamedOrRemovedLint<'_> {
126     fn decorate_lint<'b>(
127         self,
128         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
129     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
130         if let Some(new_name) = self.renamed {
131             diag.span_suggestion(
132                 self.suggestion,
133                 fluent::lint_renamed_or_removed_lint_suggestion,
134                 new_name,
135                 Applicability::MachineApplicable,
136             );
137         };
138         diag
139     }
140
141     fn msg(&self) -> rustc_errors::DiagnosticMessage {
142         rustc_errors::DiagnosticMessage::Str(self.msg.to_string())
143     }
144 }
145
146 pub struct UnknownLint<'a> {
147     pub name: String,
148     pub suggestion: Span,
149     pub replace: &'a Option<Symbol>,
150 }
151
152 impl<'a> DecorateLint<'a, ()> for UnknownLint<'_> {
153     fn decorate_lint<'b>(
154         self,
155         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
156     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
157         diag.set_arg("name", self.name);
158         if let Some(replace) = self.replace {
159             diag.span_suggestion(
160                 self.suggestion,
161                 fluent::suggestion,
162                 replace,
163                 Applicability::MaybeIncorrect,
164             );
165         };
166         diag
167     }
168
169     fn msg(&self) -> rustc_errors::DiagnosticMessage {
170         fluent::lint_unknown_lint
171     }
172 }
173
174 #[derive(LintDiagnostic)]
175 #[diag(lint_ignored_unless_crate_specified)]
176 pub struct IgnoredUnlessCrateSpecified<'a> {
177     pub level: &'a str,
178     pub name: Symbol,
179 }
180
181 // methods.rs
182 #[derive(LintDiagnostic)]
183 #[diag(lint_cstring_ptr)]
184 #[note]
185 #[help]
186 pub struct CStringPtr {
187     #[label(as_ptr_label)]
188     pub as_ptr: Span,
189     #[label(unwrap_label)]
190     pub unwrap: Span,
191 }
192
193 // non_ascii_idents.rs
194 #[derive(LintDiagnostic)]
195 #[diag(lint_identifier_non_ascii_char)]
196 pub struct IdentifierNonAsciiChar;
197
198 #[derive(LintDiagnostic)]
199 #[diag(lint_identifier_uncommon_codepoints)]
200 pub struct IdentifierUncommonCodepoints;
201
202 #[derive(LintDiagnostic)]
203 #[diag(lint_confusable_identifier_pair)]
204 pub struct ConfusableIdentifierPair {
205     pub existing_sym: Symbol,
206     pub sym: Symbol,
207     #[label]
208     pub label: Span,
209 }
210
211 #[derive(LintDiagnostic)]
212 #[diag(lint_mixed_script_confusables)]
213 #[note(includes_note)]
214 #[note]
215 pub struct MixedScriptConfusables {
216     pub set: String,
217     pub includes: String,
218 }
219
220 // non_fmt_panic.rs
221 pub struct NonFmtPanicUnused {
222     pub count: usize,
223     pub suggestion: Option<Span>,
224 }
225
226 impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
227     fn decorate_lint<'b>(
228         self,
229         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
230     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
231         diag.set_arg("count", self.count);
232         diag.note(fluent::note);
233         if let Some(span) = self.suggestion {
234             diag.span_suggestion(
235                 span.shrink_to_hi(),
236                 fluent::add_args_suggestion,
237                 ", ...",
238                 Applicability::HasPlaceholders,
239             );
240             diag.span_suggestion(
241                 span.shrink_to_lo(),
242                 fluent::add_fmt_suggestion,
243                 "\"{}\", ",
244                 Applicability::MachineApplicable,
245             );
246         }
247         diag
248     }
249
250     fn msg(&self) -> rustc_errors::DiagnosticMessage {
251         fluent::lint_non_fmt_panic_unused
252     }
253 }
254
255 #[derive(LintDiagnostic)]
256 #[diag(lint_non_fmt_panic_braces)]
257 #[note]
258 pub struct NonFmtPanicBraces {
259     pub count: usize,
260     #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")]
261     pub suggestion: Option<Span>,
262 }
263
264 // nonstandard_style.rs
265 #[derive(LintDiagnostic)]
266 #[diag(lint_non_camel_case_type)]
267 pub struct NonCamelCaseType<'a> {
268     pub sort: &'a str,
269     pub name: &'a str,
270     #[subdiagnostic]
271     pub sub: NonCamelCaseTypeSub,
272 }
273
274 #[derive(Subdiagnostic)]
275 pub enum NonCamelCaseTypeSub {
276     #[label(label)]
277     Label {
278         #[primary_span]
279         span: Span,
280     },
281     #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
282     Suggestion {
283         #[primary_span]
284         span: Span,
285         replace: String,
286     },
287 }
288
289 #[derive(LintDiagnostic)]
290 #[diag(lint_non_snake_case)]
291 pub struct NonSnakeCaseDiag<'a> {
292     pub sort: &'a str,
293     pub name: &'a str,
294     pub sc: String,
295     #[subdiagnostic]
296     pub sub: NonSnakeCaseDiagSub,
297 }
298
299 pub enum NonSnakeCaseDiagSub {
300     Label { span: Span },
301     Help,
302     RenameOrConvertSuggestion { span: Span, suggestion: Ident },
303     ConvertSuggestion { span: Span, suggestion: String },
304     SuggestionAndNote { span: Span },
305 }
306
307 impl AddToDiagnostic for NonSnakeCaseDiagSub {
308     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
309     where
310         F: Fn(
311             &mut rustc_errors::Diagnostic,
312             rustc_errors::SubdiagnosticMessage,
313         ) -> rustc_errors::SubdiagnosticMessage,
314     {
315         match self {
316             NonSnakeCaseDiagSub::Label { span } => {
317                 diag.span_label(span, fluent::label);
318             }
319             NonSnakeCaseDiagSub::Help => {
320                 diag.help(fluent::help);
321             }
322             NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
323                 diag.span_suggestion(
324                     span,
325                     fluent::convert_suggestion,
326                     suggestion,
327                     Applicability::MaybeIncorrect,
328                 );
329             }
330             NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => {
331                 diag.span_suggestion(
332                     span,
333                     fluent::rename_or_convert_suggestion,
334                     suggestion,
335                     Applicability::MaybeIncorrect,
336                 );
337             }
338             NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
339                 diag.note(fluent::cannot_convert_note);
340                 diag.span_suggestion(
341                     span,
342                     fluent::rename_suggestion,
343                     "",
344                     Applicability::MaybeIncorrect,
345                 );
346             }
347         }
348     }
349 }
350
351 #[derive(LintDiagnostic)]
352 #[diag(lint_non_upper_case_global)]
353 pub struct NonUpperCaseGlobal<'a> {
354     pub sort: &'a str,
355     pub name: &'a str,
356     #[subdiagnostic]
357     pub sub: NonUpperCaseGlobalSub,
358 }
359
360 #[derive(Subdiagnostic)]
361 pub enum NonUpperCaseGlobalSub {
362     #[label(label)]
363     Label {
364         #[primary_span]
365         span: Span,
366     },
367     #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
368     Suggestion {
369         #[primary_span]
370         span: Span,
371         replace: String,
372     },
373 }
374
375 // noop_method_call.rs
376 #[derive(LintDiagnostic)]
377 #[diag(lint_noop_method_call)]
378 #[note]
379 pub struct NoopMethodCallDiag<'a> {
380     pub method: Symbol,
381     pub receiver_ty: Ty<'a>,
382     #[label]
383     pub label: Span,
384 }
385
386 // pass_by_value.rs
387 #[derive(LintDiagnostic)]
388 #[diag(lint_pass_by_value)]
389 pub struct PassByValueDiag {
390     pub ty: String,
391     #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
392     pub suggestion: Span,
393 }
394
395 // redundant_semicolon.rs
396 #[derive(LintDiagnostic)]
397 #[diag(lint_redundant_semicolons)]
398 pub struct RedundantSemicolonsDiag {
399     pub multiple: bool,
400     #[suggestion(code = "", applicability = "maybe-incorrect")]
401     pub suggestion: Span,
402 }
403
404 // traits.rs
405 pub struct DropTraitConstraintsDiag<'a> {
406     pub predicate: Predicate<'a>,
407     pub tcx: TyCtxt<'a>,
408     pub def_id: DefId,
409 }
410
411 impl<'a> DecorateLint<'a, ()> for DropTraitConstraintsDiag<'_> {
412     fn decorate_lint<'b>(
413         self,
414         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
415     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
416         diag.set_arg("predicate", self.predicate);
417         diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
418     }
419
420     fn msg(&self) -> rustc_errors::DiagnosticMessage {
421         fluent::lint_drop_trait_constraints
422     }
423 }
424
425 pub struct DropGlue<'a> {
426     pub tcx: TyCtxt<'a>,
427     pub def_id: DefId,
428 }
429
430 impl<'a> DecorateLint<'a, ()> for DropGlue<'_> {
431     fn decorate_lint<'b>(
432         self,
433         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
434     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
435         diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
436     }
437
438     fn msg(&self) -> rustc_errors::DiagnosticMessage {
439         fluent::lint_drop_glue
440     }
441 }
442
443 // types.rs
444 #[derive(LintDiagnostic)]
445 #[diag(lint_range_endpoint_out_of_range)]
446 pub struct RangeEndpointOutOfRange<'a> {
447     pub ty: &'a str,
448     #[suggestion(code = "{start}..={literal}{suffix}", applicability = "machine-applicable")]
449     pub suggestion: Span,
450     pub start: String,
451     pub literal: u128,
452     pub suffix: &'a str,
453 }
454
455 #[derive(LintDiagnostic)]
456 #[diag(lint_overflowing_bin_hex)]
457 pub struct OverflowingBinHex<'a> {
458     pub ty: &'a str,
459     pub lit: String,
460     pub dec: u128,
461     pub actually: String,
462     #[subdiagnostic]
463     pub sign: OverflowingBinHexSign,
464     #[subdiagnostic]
465     pub sub: Option<OverflowingBinHexSub<'a>>,
466 }
467
468 pub enum OverflowingBinHexSign {
469     Positive,
470     Negative,
471 }
472
473 impl AddToDiagnostic for OverflowingBinHexSign {
474     fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
475     where
476         F: Fn(
477             &mut rustc_errors::Diagnostic,
478             rustc_errors::SubdiagnosticMessage,
479         ) -> rustc_errors::SubdiagnosticMessage,
480     {
481         match self {
482             OverflowingBinHexSign::Positive => {
483                 diag.note(fluent::positive_note);
484             }
485             OverflowingBinHexSign::Negative => {
486                 diag.note(fluent::negative_note);
487                 diag.note(fluent::negative_becomes_note);
488             }
489         }
490     }
491 }
492
493 #[derive(Subdiagnostic)]
494 pub enum OverflowingBinHexSub<'a> {
495     #[suggestion(
496         suggestion,
497         code = "{sans_suffix}{suggestion_ty}",
498         applicability = "machine-applicable"
499     )]
500     Suggestion {
501         #[primary_span]
502         span: Span,
503         suggestion_ty: &'a str,
504         sans_suffix: &'a str,
505     },
506     #[help(help)]
507     Help { suggestion_ty: &'a str },
508 }
509
510 pub struct OverflowingInt<'a> {
511     pub ty: &'a str,
512     pub lit: String,
513     pub min: i128,
514     pub max: u128,
515     pub suggestion_ty: Option<&'a str>,
516 }
517
518 // FIXME: refactor with `Option<&'a str>` in macro
519 impl<'a> DecorateLint<'a, ()> for OverflowingInt<'_> {
520     fn decorate_lint<'b>(
521         self,
522         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
523     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
524         diag.set_arg("ty", self.ty);
525         diag.set_arg("lit", self.lit);
526         diag.set_arg("min", self.min);
527         diag.set_arg("max", self.max);
528         diag.note(fluent::note);
529         if let Some(suggestion_ty) = self.suggestion_ty {
530             diag.set_arg("suggestion_ty", suggestion_ty);
531             diag.help(fluent::help);
532         }
533         diag
534     }
535
536     fn msg(&self) -> rustc_errors::DiagnosticMessage {
537         fluent::lint_overflowing_int
538     }
539 }
540
541 #[derive(LintDiagnostic)]
542 #[diag(lint_only_cast_u8_to_char)]
543 pub struct OnlyCastu8ToChar {
544     #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")]
545     pub span: Span,
546     pub literal: u128,
547 }
548
549 #[derive(LintDiagnostic)]
550 #[diag(lint_overflowing_uint)]
551 #[note]
552 pub struct OverflowingUInt<'a> {
553     pub ty: &'a str,
554     pub lit: String,
555     pub min: u128,
556     pub max: u128,
557 }
558
559 #[derive(LintDiagnostic)]
560 #[diag(lint_overflowing_literal)]
561 #[note]
562 pub struct OverflowingLiteral<'a> {
563     pub ty: &'a str,
564     pub lit: String,
565 }
566
567 #[derive(LintDiagnostic)]
568 #[diag(lint_unused_comparisons)]
569 pub struct UnusedComparisons;
570
571 pub struct ImproperCTypes<'a> {
572     pub ty: Ty<'a>,
573     pub desc: &'a str,
574     pub label: Span,
575     pub help: Option<DiagnosticMessage>,
576     pub note: DiagnosticMessage,
577     pub span_note: Option<Span>,
578 }
579
580 impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> {
581     fn decorate_lint<'b>(
582         self,
583         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
584     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
585         diag.set_arg("ty", self.ty);
586         diag.set_arg("desc", self.desc);
587         diag.span_label(self.label, fluent::label);
588         if let Some(help) = self.help {
589             diag.help(help);
590         }
591         diag.note(self.note);
592         if let Some(note) = self.span_note {
593             diag.span_note(note, fluent::note);
594         }
595         diag
596     }
597
598     fn msg(&self) -> rustc_errors::DiagnosticMessage {
599         fluent::lint_improper_ctypes
600     }
601 }
602
603 #[derive(LintDiagnostic)]
604 #[diag(lint_variant_size_differences)]
605 pub struct VariantSizeDifferencesDiag {
606     pub largest: u64,
607 }
608
609 #[derive(LintDiagnostic)]
610 #[diag(lint_atomic_ordering_load)]
611 #[help]
612 pub struct AtomicOrderingLoad;
613
614 #[derive(LintDiagnostic)]
615 #[diag(lint_atomic_ordering_store)]
616 #[help]
617 pub struct AtomicOrderingStore;
618
619 #[derive(LintDiagnostic)]
620 #[diag(lint_atomic_ordering_fence)]
621 #[help]
622 pub struct AtomicOrderingFence;
623
624 #[derive(LintDiagnostic)]
625 #[diag(lint_atomic_ordering_invalid)]
626 #[help]
627 pub struct InvalidAtomicOrderingDiag {
628     pub method: Symbol,
629     #[label]
630     pub fail_order_arg_span: Span,
631 }
632
633 // unused.rs
634 #[derive(LintDiagnostic)]
635 #[diag(lint_unused_op)]
636 pub struct UnusedOp<'a> {
637     pub op: &'a str,
638     #[label]
639     pub label: Span,
640     #[suggestion(style = "verbose", code = "let _ = ", applicability = "machine-applicable")]
641     pub suggestion: Span,
642 }
643
644 #[derive(LintDiagnostic)]
645 #[diag(lint_unused_result)]
646 pub struct UnusedResult<'a> {
647     pub ty: Ty<'a>,
648 }
649
650 // FIXME(davidtwco): this isn't properly translatable becauses of the
651 // pre/post strings
652 #[derive(LintDiagnostic)]
653 #[diag(lint_unused_closure)]
654 #[note]
655 pub struct UnusedClosure<'a> {
656     pub count: usize,
657     pub pre: &'a str,
658     pub post: &'a str,
659 }
660
661 // FIXME(davidtwco): this isn't properly translatable becauses of the
662 // pre/post strings
663 #[derive(LintDiagnostic)]
664 #[diag(lint_unused_generator)]
665 #[note]
666 pub struct UnusedGenerator<'a> {
667     pub count: usize,
668     pub pre: &'a str,
669     pub post: &'a str,
670 }
671
672 // FIXME(davidtwco): this isn't properly translatable becauses of the pre/post
673 // strings
674 pub struct UnusedDef<'a, 'b> {
675     pub pre: &'a str,
676     pub post: &'a str,
677     pub cx: &'a LateContext<'b>,
678     pub def_id: DefId,
679     pub note: Option<Symbol>,
680 }
681
682 // FIXME: refactor with `Option<String>` in macro
683 impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> {
684     fn decorate_lint<'b>(
685         self,
686         diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
687     ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
688         diag.set_arg("pre", self.pre);
689         diag.set_arg("post", self.post);
690         diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id));
691         // check for #[must_use = "..."]
692         if let Some(note) = self.note {
693             diag.note(note.as_str());
694         }
695         diag
696     }
697
698     fn msg(&self) -> rustc_errors::DiagnosticMessage {
699         fluent::lint_unused_def
700     }
701 }
702
703 #[derive(LintDiagnostic)]
704 #[diag(lint_path_statement_drop)]
705 pub struct PathStatementDrop {
706     #[subdiagnostic]
707     pub sub: PathStatementDropSub,
708 }
709
710 #[derive(Subdiagnostic)]
711 pub enum PathStatementDropSub {
712     #[suggestion(suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
713     Suggestion {
714         #[primary_span]
715         span: Span,
716         snippet: String,
717     },
718     #[help(help)]
719     Help {
720         #[primary_span]
721         span: Span,
722     },
723 }
724
725 #[derive(LintDiagnostic)]
726 #[diag(lint_path_statement_no_effect)]
727 pub struct PathStatementNoEffect;
728
729 #[derive(LintDiagnostic)]
730 #[diag(lint_unused_delim)]
731 pub struct UnusedDelim<'a> {
732     pub delim: &'static str,
733     pub item: &'a str,
734     #[subdiagnostic]
735     pub suggestion: Option<UnusedDelimSuggestion>,
736 }
737
738 #[derive(Subdiagnostic)]
739 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
740 pub struct UnusedDelimSuggestion {
741     #[suggestion_part(code = "{start_replace}")]
742     pub start_span: Span,
743     pub start_replace: &'static str,
744     #[suggestion_part(code = "{end_replace}")]
745     pub end_span: Span,
746     pub end_replace: &'static str,
747 }
748
749 #[derive(LintDiagnostic)]
750 #[diag(lint_unused_import_braces)]
751 pub struct UnusedImportBracesDiag {
752     pub node: Symbol,
753 }
754
755 #[derive(LintDiagnostic)]
756 #[diag(lint_unused_allocation)]
757 pub struct UnusedAllocationDiag;
758
759 #[derive(LintDiagnostic)]
760 #[diag(lint_unused_allocation_mut)]
761 pub struct UnusedAllocationMutDiag;