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_cstring_ptr)]
57 pub struct CStringPtr {
58 #[label(as_ptr_label)]
60 #[label(unwrap_label)]
64 // non_ascii_idents.rs
65 #[derive(LintDiagnostic)]
66 #[diag(lint_identifier_non_ascii_char)]
67 pub struct IdentifierNonAsciiChar;
69 #[derive(LintDiagnostic)]
70 #[diag(lint_identifier_uncommon_codepoints)]
71 pub struct IdentifierUncommonCodepoints;
73 #[derive(LintDiagnostic)]
74 #[diag(lint_confusable_identifier_pair)]
75 pub struct ConfusableIdentifierPair {
76 pub existing_sym: Symbol,
82 #[derive(LintDiagnostic)]
83 #[diag(lint_mixed_script_confusables)]
84 #[note(includes_note)]
86 pub struct MixedScriptConfusables {
92 pub struct NonFmtPanicUnused {
94 pub suggestion: Option<Span>,
97 impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
100 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
101 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
102 diag.set_arg("count", self.count);
103 diag.note(fluent::note);
104 if let Some(span) = self.suggestion {
105 diag.span_suggestion(
107 fluent::add_args_suggestion,
109 Applicability::HasPlaceholders,
111 diag.span_suggestion(
113 fluent::add_fmt_suggestion,
115 Applicability::MachineApplicable,
121 fn msg(&self) -> rustc_errors::DiagnosticMessage {
122 fluent::lint_non_fmt_panic_unused
126 #[derive(LintDiagnostic)]
127 #[diag(lint_non_fmt_panic_braces)]
129 pub struct NonFmtPanicBraces {
131 #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")]
132 pub suggestion: Option<Span>,
135 // nonstandard_style.rs
136 #[derive(LintDiagnostic)]
137 #[diag(lint_non_camel_case_type)]
138 pub struct NonCamelCaseType<'a> {
142 pub sub: NonCamelCaseTypeSub,
145 #[derive(Subdiagnostic)]
146 pub enum NonCamelCaseTypeSub {
152 #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
160 #[derive(LintDiagnostic)]
161 #[diag(lint_non_snake_case)]
162 pub struct NonSnakeCaseDiag<'a> {
167 pub sub: NonSnakeCaseDiagSub,
170 pub enum NonSnakeCaseDiagSub {
171 Label { span: Span },
173 RenameOrConvertSuggestion { span: Span, suggestion: Ident },
174 ConvertSuggestion { span: Span, suggestion: String },
175 SuggestionAndNote { span: Span },
178 impl AddToDiagnostic for NonSnakeCaseDiagSub {
179 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
182 &mut rustc_errors::Diagnostic,
183 rustc_errors::SubdiagnosticMessage,
184 ) -> rustc_errors::SubdiagnosticMessage,
187 NonSnakeCaseDiagSub::Label { span } => {
188 diag.span_label(span, fluent::label);
190 NonSnakeCaseDiagSub::Help => {
191 diag.help(fluent::help);
193 NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
194 diag.span_suggestion(
196 fluent::convert_suggestion,
198 Applicability::MaybeIncorrect,
201 NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => {
202 diag.span_suggestion(
204 fluent::rename_or_convert_suggestion,
206 Applicability::MaybeIncorrect,
209 NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
210 diag.note(fluent::cannot_convert_note);
211 diag.span_suggestion(
213 fluent::rename_suggestion,
215 Applicability::MaybeIncorrect,
222 #[derive(LintDiagnostic)]
223 #[diag(lint_non_upper_case_global)]
224 pub struct NonUpperCaseGlobal<'a> {
228 pub sub: NonUpperCaseGlobalSub,
231 #[derive(Subdiagnostic)]
232 pub enum NonUpperCaseGlobalSub {
238 #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
246 // noop_method_call.rs
247 #[derive(LintDiagnostic)]
248 #[diag(lint_noop_method_call)]
250 pub struct NoopMethodCallDiag<'a> {
252 pub receiver_ty: Ty<'a>,
258 #[derive(LintDiagnostic)]
259 #[diag(lint_pass_by_value)]
260 pub struct PassByValueDiag {
262 #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
263 pub suggestion: Span,
266 // redundant_semicolon.rs
267 #[derive(LintDiagnostic)]
268 #[diag(lint_redundant_semicolons)]
269 pub struct RedundantSemicolonsDiag {
271 #[suggestion(code = "", applicability = "maybe-incorrect")]
272 pub suggestion: Span,
276 pub struct DropTraitConstraintsDiag<'a> {
277 pub predicate: Predicate<'a>,
282 impl<'a> DecorateLint<'a, ()> for DropTraitConstraintsDiag<'_> {
283 fn decorate_lint<'b>(
285 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
286 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
287 diag.set_arg("predicate", self.predicate);
288 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
291 fn msg(&self) -> rustc_errors::DiagnosticMessage {
292 fluent::lint_drop_trait_constraints
296 pub struct DropGlue<'a> {
301 impl<'a> DecorateLint<'a, ()> for DropGlue<'_> {
302 fn decorate_lint<'b>(
304 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
305 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
306 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id))
309 fn msg(&self) -> rustc_errors::DiagnosticMessage {
310 fluent::lint_drop_glue
315 #[derive(LintDiagnostic)]
316 #[diag(lint_range_endpoint_out_of_range)]
317 pub struct RangeEndpointOutOfRange<'a> {
319 #[suggestion(code = "{start}..={literal}{suffix}", applicability = "machine-applicable")]
320 pub suggestion: Span,
326 #[derive(LintDiagnostic)]
327 #[diag(lint_overflowing_bin_hex)]
328 pub struct OverflowingBinHex<'a> {
332 pub actually: String,
334 pub sign: OverflowingBinHexSign,
336 pub sub: Option<OverflowingBinHexSub<'a>>,
339 pub enum OverflowingBinHexSign {
344 impl AddToDiagnostic for OverflowingBinHexSign {
345 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
348 &mut rustc_errors::Diagnostic,
349 rustc_errors::SubdiagnosticMessage,
350 ) -> rustc_errors::SubdiagnosticMessage,
353 OverflowingBinHexSign::Positive => {
354 diag.note(fluent::positive_note);
356 OverflowingBinHexSign::Negative => {
357 diag.note(fluent::negative_note);
358 diag.note(fluent::negative_becomes_note);
364 #[derive(Subdiagnostic)]
365 pub enum OverflowingBinHexSub<'a> {
368 code = "{sans_suffix}{suggestion_ty}",
369 applicability = "machine-applicable"
374 suggestion_ty: &'a str,
375 sans_suffix: &'a str,
378 Help { suggestion_ty: &'a str },
381 pub struct OverflowingInt<'a> {
386 pub suggestion_ty: Option<&'a str>,
389 // FIXME: refactor with `Option<&'a str>` in macro
390 impl<'a> DecorateLint<'a, ()> for OverflowingInt<'_> {
391 fn decorate_lint<'b>(
393 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
394 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
395 diag.set_arg("ty", self.ty);
396 diag.set_arg("lit", self.lit);
397 diag.set_arg("min", self.min);
398 diag.set_arg("max", self.max);
399 diag.note(fluent::note);
400 if let Some(suggestion_ty) = self.suggestion_ty {
401 diag.set_arg("suggestion_ty", suggestion_ty);
402 diag.help(fluent::help);
407 fn msg(&self) -> rustc_errors::DiagnosticMessage {
408 fluent::lint_overflowing_int
412 #[derive(LintDiagnostic)]
413 #[diag(lint_only_cast_u8_to_char)]
414 pub struct OnlyCastu8ToChar {
415 #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")]
420 #[derive(LintDiagnostic)]
421 #[diag(lint_overflowing_uint)]
423 pub struct OverflowingUInt<'a> {
430 #[derive(LintDiagnostic)]
431 #[diag(lint_overflowing_literal)]
433 pub struct OverflowingLiteral<'a> {
438 #[derive(LintDiagnostic)]
439 #[diag(lint_unused_comparisons)]
440 pub struct UnusedComparisons;
442 #[derive(LintDiagnostic)]
443 #[diag(lint_variant_size_differences)]
444 pub struct VariantSizeDifferencesDiag {
448 #[derive(LintDiagnostic)]
449 #[diag(lint_atomic_ordering_load)]
451 pub struct AtomicOrderingLoad;
453 #[derive(LintDiagnostic)]
454 #[diag(lint_atomic_ordering_store)]
456 pub struct AtomicOrderingStore;
458 #[derive(LintDiagnostic)]
459 #[diag(lint_atomic_ordering_fence)]
461 pub struct AtomicOrderingFence;
463 #[derive(LintDiagnostic)]
464 #[diag(lint_atomic_ordering_invalid)]
466 pub struct InvalidAtomicOrderingDiag {
469 pub fail_order_arg_span: Span,
473 #[derive(LintDiagnostic)]
474 #[diag(lint_unused_op)]
475 pub struct UnusedOp<'a> {
479 #[suggestion(style = "verbose", code = "let _ = ", applicability = "machine-applicable")]
480 pub suggestion: Span,
483 #[derive(LintDiagnostic)]
484 #[diag(lint_unused_result)]
485 pub struct UnusedResult<'a> {
489 // FIXME(davidtwco): this isn't properly translatable becauses of the
491 #[derive(LintDiagnostic)]
492 #[diag(lint_unused_closure)]
494 pub struct UnusedClosure<'a> {
500 // FIXME(davidtwco): this isn't properly translatable becauses of the
502 #[derive(LintDiagnostic)]
503 #[diag(lint_unused_generator)]
505 pub struct UnusedGenerator<'a> {
511 // FIXME(davidtwco): this isn't properly translatable becauses of the pre/post
513 pub struct UnusedDef<'a, 'b> {
516 pub cx: &'a LateContext<'b>,
518 pub note: Option<Symbol>,
521 // FIXME: refactor with `Option<String>` in macro
522 impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> {
523 fn decorate_lint<'b>(
525 diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
526 ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
527 diag.set_arg("pre", self.pre);
528 diag.set_arg("post", self.post);
529 diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id));
530 // check for #[must_use = "..."]
531 if let Some(note) = self.note {
532 diag.note(note.as_str());
537 fn msg(&self) -> rustc_errors::DiagnosticMessage {
538 fluent::lint_unused_def
542 #[derive(LintDiagnostic)]
543 #[diag(lint_path_statement_drop)]
544 pub struct PathStatementDrop {
546 pub sub: PathStatementDropSub,
549 #[derive(Subdiagnostic)]
550 pub enum PathStatementDropSub {
551 #[suggestion(suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
564 #[derive(LintDiagnostic)]
565 #[diag(lint_path_statement_no_effect)]
566 pub struct PathStatementNoEffect;
568 #[derive(LintDiagnostic)]
569 #[diag(lint_unused_delim)]
570 pub struct UnusedDelim<'a> {
571 pub delim: &'static str,
574 pub suggestion: Option<UnusedDelimSuggestion>,
577 #[derive(Subdiagnostic)]
578 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
579 pub struct UnusedDelimSuggestion {
580 #[suggestion_part(code = "{start_replace}")]
581 pub start_span: Span,
582 pub start_replace: &'static str,
583 #[suggestion_part(code = "{end_replace}")]
585 pub end_replace: &'static str,
588 #[derive(LintDiagnostic)]
589 #[diag(lint_unused_import_braces)]
590 pub struct UnusedImportBracesDiag {
594 #[derive(LintDiagnostic)]
595 #[diag(lint_unused_allocation)]
596 pub struct UnusedAllocationDiag;
598 #[derive(LintDiagnostic)]
599 #[diag(lint_unused_allocation_mut)]
600 pub struct UnusedAllocationMutDiag;