1 use rustc_errors::{fluent, AddToDiagnostic, Applicability, DecorateLint};
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};
7 use crate::LateContext;
10 #[derive(LintDiagnostic)]
11 #[diag(lint_array_into_iter)]
12 pub struct ArrayIntoIterDiag<'a> {
14 #[suggestion(use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
17 pub sub: Option<ArrayIntoIterDiagSub>,
20 #[derive(Subdiagnostic)]
21 pub enum ArrayIntoIterDiagSub {
22 #[suggestion(remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
27 #[multipart_suggestion(use_explicit_into_iter_suggestion, applicability = "maybe-incorrect")]
29 #[suggestion_part(code = "IntoIterator::into_iter(")]
31 #[suggestion_part(code = ")")]
36 // enum_intrinsics_non_enums.rs
37 #[derive(LintDiagnostic)]
38 #[diag(lint_enum_intrinsics_mem_discriminant)]
39 pub struct EnumIntrinsicsMemDiscriminate<'a> {
45 #[derive(LintDiagnostic)]
46 #[diag(lint_enum_intrinsics_mem_variant)]
48 pub struct EnumIntrinsicsMemVariant<'a> {
53 #[derive(LintDiagnostic)]
54 #[diag(lint::deprecated_lint_name)]
55 pub struct DeprecatedLintName<'a> {
57 #[suggestion(code = "{replace}", applicability = "machine-applicable")]
63 #[derive(LintDiagnostic)]
64 #[diag(lint_cstring_ptr)]
67 pub struct CStringPtr {
68 #[label(as_ptr_label)]
70 #[label(unwrap_label)]
74 // non_ascii_idents.rs
75 #[derive(LintDiagnostic)]
76 #[diag(lint_identifier_non_ascii_char)]
77 pub struct IdentifierNonAsciiChar;
79 #[derive(LintDiagnostic)]
80 #[diag(lint_identifier_uncommon_codepoints)]
81 pub struct IdentifierUncommonCodepoints;
83 #[derive(LintDiagnostic)]
84 #[diag(lint_confusable_identifier_pair)]
85 pub struct ConfusableIdentifierPair {
86 pub existing_sym: Symbol,
92 #[derive(LintDiagnostic)]
93 #[diag(lint_mixed_script_confusables)]
94 #[note(includes_note)]
96 pub struct MixedScriptConfusables {
102 pub struct NonFmtPanicUnused {
104 pub suggestion: Option<Span>,
107 impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
108 fn decorate_lint<'b>(
110 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
111 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
112 diag.set_arg("count", self.count);
113 diag.note(fluent::note);
114 if let Some(span) = self.suggestion {
115 diag.span_suggestion(
117 fluent::add_args_suggestion,
119 Applicability::HasPlaceholders,
121 diag.span_suggestion(
123 fluent::add_fmt_suggestion,
125 Applicability::MachineApplicable,
131 fn msg(&self) -> rustc_errors::DiagnosticMessage {
132 fluent::lint_non_fmt_panic_unused
136 #[derive(LintDiagnostic)]
137 #[diag(lint_non_fmt_panic_braces)]
139 pub struct NonFmtPanicBraces {
141 #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")]
142 pub suggestion: Option<Span>,
145 // nonstandard_style.rs
146 #[derive(LintDiagnostic)]
147 #[diag(lint_non_camel_case_type)]
148 pub struct NonCamelCaseType<'a> {
152 pub sub: NonCamelCaseTypeSub,
155 #[derive(Subdiagnostic)]
156 pub enum NonCamelCaseTypeSub {
162 #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
170 #[derive(LintDiagnostic)]
171 #[diag(lint_non_snake_case)]
172 pub struct NonSnakeCaseDiag<'a> {
177 pub sub: NonSnakeCaseDiagSub,
180 pub enum NonSnakeCaseDiagSub {
181 Label { span: Span },
183 RenameOrConvertSuggestion { span: Span, suggestion: Ident },
184 ConvertSuggestion { span: Span, suggestion: String },
185 SuggestionAndNote { span: Span },
188 impl AddToDiagnostic for NonSnakeCaseDiagSub {
189 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
192 &mut rustc_errors::Diagnostic,
193 rustc_errors::SubdiagnosticMessage,
194 ) -> rustc_errors::SubdiagnosticMessage,
197 NonSnakeCaseDiagSub::Label { span } => {
198 diag.span_label(span, fluent::label);
200 NonSnakeCaseDiagSub::Help => {
201 diag.help(fluent::help);
203 NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
204 diag.span_suggestion(
206 fluent::convert_suggestion,
208 Applicability::MaybeIncorrect,
211 NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => {
212 diag.span_suggestion(
214 fluent::rename_or_convert_suggestion,
216 Applicability::MaybeIncorrect,
219 NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
220 diag.note(fluent::cannot_convert_note);
221 diag.span_suggestion(
223 fluent::rename_suggestion,
225 Applicability::MaybeIncorrect,
232 #[derive(LintDiagnostic)]
233 #[diag(lint_non_upper_case_global)]
234 pub struct NonUpperCaseGlobal<'a> {
238 pub sub: NonUpperCaseGlobalSub,
241 #[derive(Subdiagnostic)]
242 pub enum NonUpperCaseGlobalSub {
248 #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
256 // noop_method_call.rs
257 #[derive(LintDiagnostic)]
258 #[diag(lint_noop_method_call)]
260 pub struct NoopMethodCallDiag<'a> {
262 pub receiver_ty: Ty<'a>,
268 #[derive(LintDiagnostic)]
269 #[diag(lint_pass_by_value)]
270 pub struct PassByValueDiag {
272 #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
273 pub suggestion: Span,
276 // redundant_semicolon.rs
277 #[derive(LintDiagnostic)]
278 #[diag(lint_redundant_semicolons)]
279 pub struct RedundantSemicolonsDiag {
281 #[suggestion(code = "", applicability = "maybe-incorrect")]
282 pub suggestion: Span,
286 pub struct DropTraitConstraintsDiag<'a> {
287 pub predicate: Predicate<'a>,
292 impl<'a> DecorateLint<'a, ()> for DropTraitConstraintsDiag<'_> {
293 fn decorate_lint<'b>(
295 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
296 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
297 diag.set_arg("predicate", self.predicate);
298 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
301 fn msg(&self) -> rustc_errors::DiagnosticMessage {
302 fluent::lint_drop_trait_constraints
306 pub struct DropGlue<'a> {
311 impl<'a> DecorateLint<'a, ()> for DropGlue<'_> {
312 fn decorate_lint<'b>(
314 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
315 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
316 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
319 fn msg(&self) -> rustc_errors::DiagnosticMessage {
320 fluent::lint_drop_glue
325 #[derive(LintDiagnostic)]
326 #[diag(lint_range_endpoint_out_of_range)]
327 pub struct RangeEndpointOutOfRange<'a> {
329 #[suggestion(code = "{start}..={literal}{suffix}", applicability = "machine-applicable")]
330 pub suggestion: Span,
336 #[derive(LintDiagnostic)]
337 #[diag(lint_overflowing_bin_hex)]
338 pub struct OverflowingBinHex<'a> {
342 pub actually: String,
344 pub sign: OverflowingBinHexSign,
346 pub sub: Option<OverflowingBinHexSub<'a>>,
349 pub enum OverflowingBinHexSign {
354 impl AddToDiagnostic for OverflowingBinHexSign {
355 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
358 &mut rustc_errors::Diagnostic,
359 rustc_errors::SubdiagnosticMessage,
360 ) -> rustc_errors::SubdiagnosticMessage,
363 OverflowingBinHexSign::Positive => {
364 diag.note(fluent::positive_note);
366 OverflowingBinHexSign::Negative => {
367 diag.note(fluent::negative_note);
368 diag.note(fluent::negative_becomes_note);
374 #[derive(Subdiagnostic)]
375 pub enum OverflowingBinHexSub<'a> {
378 code = "{sans_suffix}{suggestion_ty}",
379 applicability = "machine-applicable"
384 suggestion_ty: &'a str,
385 sans_suffix: &'a str,
388 Help { suggestion_ty: &'a str },
391 pub struct OverflowingInt<'a> {
396 pub suggestion_ty: Option<&'a str>,
399 // FIXME: refactor with `Option<&'a str>` in macro
400 impl<'a> DecorateLint<'a, ()> for OverflowingInt<'_> {
401 fn decorate_lint<'b>(
403 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
404 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
405 diag.set_arg("ty", self.ty);
406 diag.set_arg("lit", self.lit);
407 diag.set_arg("min", self.min);
408 diag.set_arg("max", self.max);
409 diag.note(fluent::note);
410 if let Some(suggestion_ty) = self.suggestion_ty {
411 diag.set_arg("suggestion_ty", suggestion_ty);
412 diag.help(fluent::help);
417 fn msg(&self) -> rustc_errors::DiagnosticMessage {
418 fluent::lint_overflowing_int
422 #[derive(LintDiagnostic)]
423 #[diag(lint_only_cast_u8_to_char)]
424 pub struct OnlyCastu8ToChar {
425 #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")]
430 #[derive(LintDiagnostic)]
431 #[diag(lint_overflowing_uint)]
433 pub struct OverflowingUInt<'a> {
440 #[derive(LintDiagnostic)]
441 #[diag(lint_overflowing_literal)]
443 pub struct OverflowingLiteral<'a> {
448 #[derive(LintDiagnostic)]
449 #[diag(lint_unused_comparisons)]
450 pub struct UnusedComparisons;
452 #[derive(LintDiagnostic)]
453 #[diag(lint_variant_size_differences)]
454 pub struct VariantSizeDifferencesDiag {
458 #[derive(LintDiagnostic)]
459 #[diag(lint_atomic_ordering_load)]
461 pub struct AtomicOrderingLoad;
463 #[derive(LintDiagnostic)]
464 #[diag(lint_atomic_ordering_store)]
466 pub struct AtomicOrderingStore;
468 #[derive(LintDiagnostic)]
469 #[diag(lint_atomic_ordering_fence)]
471 pub struct AtomicOrderingFence;
473 #[derive(LintDiagnostic)]
474 #[diag(lint_atomic_ordering_invalid)]
476 pub struct InvalidAtomicOrderingDiag {
479 pub fail_order_arg_span: Span,
483 #[derive(LintDiagnostic)]
484 #[diag(lint_unused_op)]
485 pub struct UnusedOp<'a> {
489 #[suggestion(style = "verbose", code = "let _ = ", applicability = "machine-applicable")]
490 pub suggestion: Span,
493 #[derive(LintDiagnostic)]
494 #[diag(lint_unused_result)]
495 pub struct UnusedResult<'a> {
499 // FIXME(davidtwco): this isn't properly translatable becauses of the
501 #[derive(LintDiagnostic)]
502 #[diag(lint_unused_closure)]
504 pub struct UnusedClosure<'a> {
510 // FIXME(davidtwco): this isn't properly translatable becauses of the
512 #[derive(LintDiagnostic)]
513 #[diag(lint_unused_generator)]
515 pub struct UnusedGenerator<'a> {
521 // FIXME(davidtwco): this isn't properly translatable becauses of the pre/post
523 pub struct UnusedDef<'a, 'b> {
526 pub cx: &'a LateContext<'b>,
528 pub note: Option<Symbol>,
531 // FIXME: refactor with `Option<String>` in macro
532 impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> {
533 fn decorate_lint<'b>(
535 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
536 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
537 diag.set_arg("pre", self.pre);
538 diag.set_arg("post", self.post);
539 diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id));
540 // check for #[must_use = "..."]
541 if let Some(note) = self.note {
542 diag.note(note.as_str());
547 fn msg(&self) -> rustc_errors::DiagnosticMessage {
548 fluent::lint_unused_def
552 #[derive(LintDiagnostic)]
553 #[diag(lint_path_statement_drop)]
554 pub struct PathStatementDrop {
556 pub sub: PathStatementDropSub,
559 #[derive(Subdiagnostic)]
560 pub enum PathStatementDropSub {
561 #[suggestion(suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
574 #[derive(LintDiagnostic)]
575 #[diag(lint_path_statement_no_effect)]
576 pub struct PathStatementNoEffect;
578 #[derive(LintDiagnostic)]
579 #[diag(lint_unused_delim)]
580 pub struct UnusedDelim<'a> {
581 pub delim: &'static str,
584 pub suggestion: Option<UnusedDelimSuggestion>,
587 #[derive(Subdiagnostic)]
588 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
589 pub struct UnusedDelimSuggestion {
590 #[suggestion_part(code = "{start_replace}")]
591 pub start_span: Span,
592 pub start_replace: &'static str,
593 #[suggestion_part(code = "{end_replace}")]
595 pub end_replace: &'static str,
598 #[derive(LintDiagnostic)]
599 #[diag(lint_unused_import_braces)]
600 pub struct UnusedImportBracesDiag {
604 #[derive(LintDiagnostic)]
605 #[diag(lint_unused_allocation)]
606 pub struct UnusedAllocationDiag;
608 #[derive(LintDiagnostic)]
609 #[diag(lint_unused_allocation_mut)]
610 pub struct UnusedAllocationMutDiag;