1 use rustc_errors::{fluent, AddToDiagnostic, Applicability, DecorateLint, EmissionGuarantee};
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;
9 #[derive(LintDiagnostic)]
10 #[diag(lint_array_into_iter)]
11 pub struct ArrayIntoIterDiag<'a> {
13 #[suggestion(use_iter_suggestion, code = "iter", applicability = "machine-applicable")]
16 pub sub: Option<ArrayIntoIterDiagSub>,
19 #[derive(Subdiagnostic)]
20 pub enum ArrayIntoIterDiagSub {
21 #[suggestion(remove_into_iter_suggestion, code = "", applicability = "maybe-incorrect")]
26 #[multipart_suggestion(use_explicit_into_iter_suggestion, applicability = "maybe-incorrect")]
28 #[suggestion_part(code = "IntoIterator::into_iter(")]
30 #[suggestion_part(code = ")")]
35 #[derive(LintDiagnostic)]
36 #[diag(lint_enum_intrinsics_mem_discriminant)]
37 pub struct EnumIntrinsicsMemDiscriminate<'a> {
43 #[derive(LintDiagnostic)]
44 #[diag(lint_enum_intrinsics_mem_variant)]
46 pub struct EnumIntrinsicsMemVariant<'a> {
50 #[derive(LintDiagnostic)]
51 #[diag(lint_cstring_ptr)]
54 pub struct CStringPtr {
55 #[label(as_ptr_label)]
57 #[label(unwrap_label)]
60 #[derive(LintDiagnostic)]
61 #[diag(lint_identifier_non_ascii_char)]
62 pub struct IdentifierNonAsciiChar;
64 #[derive(LintDiagnostic)]
65 #[diag(lint_identifier_uncommon_codepoints)]
66 pub struct IdentifierUncommonCodepoints;
68 #[derive(LintDiagnostic)]
69 #[diag(lint_confusable_identifier_pair)]
70 pub struct ConfusableIdentifierPair {
71 pub existing_sym: Symbol,
77 #[derive(LintDiagnostic)]
78 #[diag(lint_mixed_script_confusables)]
79 #[note(includes_note)]
81 pub struct MixedScriptConfusables {
86 pub struct NonFmtPanicUnused {
88 pub suggestion: Option<Span>,
91 impl<G: EmissionGuarantee> DecorateLint<'_, G> for NonFmtPanicUnused {
92 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
93 let mut diag = diag.build(fluent::lint_non_fmt_panic_unused);
94 diag.set_arg("count", self.count);
95 diag.note(fluent::note);
96 if let Some(span) = self.suggestion {
99 fluent::add_args_suggestion,
101 Applicability::HasPlaceholders,
103 diag.span_suggestion(
105 fluent::add_fmt_suggestion,
107 Applicability::MachineApplicable,
114 #[derive(LintDiagnostic)]
115 #[diag(lint_non_fmt_panic_braces)]
117 pub struct NonFmtPanicBraces {
119 #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")]
120 pub suggestion: Option<Span>,
123 #[derive(LintDiagnostic)]
124 #[diag(lint_non_camel_case_type)]
125 pub struct NonCamelCaseType<'a> {
129 pub sub: NonCamelCaseTypeSub,
132 #[derive(Subdiagnostic)]
133 pub enum NonCamelCaseTypeSub {
139 #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
147 #[derive(LintDiagnostic)]
148 #[diag(lint_non_snake_case)]
149 pub struct NonSnakeCaseDiag<'a> {
154 pub sub: NonSnakeCaseDiagSub,
157 pub enum NonSnakeCaseDiagSub {
158 Label { span: Span },
160 RenameOrConvertSuggestion { span: Span, suggestion: Ident },
161 ConvertSuggestion { span: Span, suggestion: String },
162 SuggestionAndNote { span: Span },
165 impl AddToDiagnostic for NonSnakeCaseDiagSub {
166 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
169 &mut rustc_errors::Diagnostic,
170 rustc_errors::SubdiagnosticMessage,
171 ) -> rustc_errors::SubdiagnosticMessage,
174 NonSnakeCaseDiagSub::Label { span } => {
175 diag.span_label(span, fluent::label);
177 NonSnakeCaseDiagSub::Help => {
178 diag.help(fluent::help);
180 NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
181 diag.span_suggestion(
183 fluent::convert_suggestion,
185 Applicability::MaybeIncorrect,
188 NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => {
189 diag.span_suggestion(
191 fluent::rename_or_convert_suggestion,
193 Applicability::MaybeIncorrect,
196 NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
197 diag.note(fluent::cannot_convert_note);
198 diag.span_suggestion(
200 fluent::rename_suggestion,
202 Applicability::MaybeIncorrect,
209 #[derive(LintDiagnostic)]
210 #[diag(lint_non_upper_case_global)]
211 pub struct NonUpperCaseGlobal<'a> {
215 pub sub: NonUpperCaseGlobalSub,
218 #[derive(Subdiagnostic)]
219 pub enum NonUpperCaseGlobalSub {
225 #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
233 #[derive(LintDiagnostic)]
234 #[diag(lint_noop_method_call)]
236 pub struct NoopMethodCallDiag<'a> {
238 pub receiver_ty: Ty<'a>,
243 #[derive(LintDiagnostic)]
244 #[diag(lint_pass_by_value)]
245 pub struct PassByValueDiag {
247 #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
248 pub suggestion: Span,
251 #[derive(LintDiagnostic)]
252 #[diag(lint_redundant_semicolons)]
253 pub struct RedundantSemicolonsDiag {
255 #[suggestion(code = "", applicability = "maybe-incorrect")]
256 pub suggestion: Span,
259 pub struct DropTraitConstraintsDiag<'a> {
260 pub predicate: Predicate<'a>,
265 impl<'a, G: EmissionGuarantee> DecorateLint<'_, G> for DropTraitConstraintsDiag<'a> {
266 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
267 let mut diag = diag.build(fluent::lint_drop_trait_constraints);
268 diag.set_arg("predicate", self.predicate);
269 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id));
274 pub struct DropGlue<'a> {
279 impl<'a, G: EmissionGuarantee> DecorateLint<'_, G> for DropGlue<'a> {
280 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
281 let mut diag = diag.build(fluent::lint_drop_glue);
282 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id));
287 #[derive(LintDiagnostic)]
288 #[diag(lint_range_endpoint_out_of_range)]
289 pub struct RangeEndpointOutOfRange<'a> {
291 #[suggestion(code = "{start}..={literal}{suffix}", applicability = "machine-applicable")]
292 pub suggestion: Span,
298 #[derive(LintDiagnostic)]
299 #[diag(lint_overflowing_bin_hex)]
300 pub struct OverflowingBinHex<'a> {
304 pub actually: String,
306 pub sign: OverflowingBinHexSign,
308 pub sub: Option<OverflowingBinHexSub<'a>>,
311 pub enum OverflowingBinHexSign {
316 impl AddToDiagnostic for OverflowingBinHexSign {
317 fn add_to_diagnostic_with<F>(self, diag: &mut rustc_errors::Diagnostic, _: F)
320 &mut rustc_errors::Diagnostic,
321 rustc_errors::SubdiagnosticMessage,
322 ) -> rustc_errors::SubdiagnosticMessage,
325 OverflowingBinHexSign::Positive => {
326 diag.note(fluent::positive_note);
328 OverflowingBinHexSign::Negative => {
329 diag.note(fluent::negative_note);
330 diag.note(fluent::negative_becomes_note);
336 #[derive(Subdiagnostic)]
337 pub enum OverflowingBinHexSub<'a> {
340 code = "{sans_suffix}{suggestion_ty}",
341 applicability = "machine-applicable"
346 suggestion_ty: &'a str,
347 sans_suffix: &'a str,
350 Help { suggestion_ty: &'a str },
353 pub struct OverflowingInt<'a> {
358 pub suggestion_ty: Option<&'a str>,
361 // FIXME: refactor with `Option<&'a str>` in macro
362 impl<'a, G: EmissionGuarantee> DecorateLint<'_, G> for OverflowingInt<'a> {
363 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
364 let mut diag = diag.build(fluent::lint_overflowing_int);
365 diag.set_arg("ty", self.ty);
366 diag.set_arg("lit", self.lit);
367 diag.set_arg("min", self.min);
368 diag.set_arg("max", self.max);
369 diag.note(fluent::note);
370 if let Some(suggestion_ty) = self.suggestion_ty {
371 diag.set_arg("suggestion_ty", suggestion_ty);
372 diag.help(fluent::help);
378 #[derive(LintDiagnostic)]
379 #[diag(lint_only_cast_u8_to_char)]
380 pub struct OnlyCastu8ToChar {
381 #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")]
386 #[derive(LintDiagnostic)]
387 #[diag(lint_overflowing_uint)]
389 pub struct OverflowingUInt<'a> {
396 #[derive(LintDiagnostic)]
397 #[diag(lint_overflowing_literal)]
399 pub struct OverflowingLiteral<'a> {
404 #[derive(LintDiagnostic)]
405 #[diag(lint_unused_comparisons)]
406 pub struct UnusedComparisons;
408 #[derive(LintDiagnostic)]
409 #[diag(lint_variant_size_differences)]
410 pub struct VariantSizeDifferencesDiag {
414 #[derive(LintDiagnostic)]
415 #[diag(lint_atomic_ordering_load)]
417 pub struct AtomicOrderingLoad;
419 #[derive(LintDiagnostic)]
420 #[diag(lint_atomic_ordering_store)]
422 pub struct AtomicOrderingStore;
424 #[derive(LintDiagnostic)]
425 #[diag(lint_atomic_ordering_fence)]
427 pub struct AtomicOrderingFence;
429 #[derive(LintDiagnostic)]
430 #[diag(lint_atomic_ordering_invalid)]
432 pub struct InvalidAtomicOrderingDiag {
435 pub fail_order_arg_span: Span,
438 #[derive(LintDiagnostic)]
439 #[diag(lint_unused_op)]
440 pub struct UnusedOp<'a> {
444 #[suggestion(style = "verbose", code = "let _ = ", applicability = "machine-applicable")]
445 pub suggestion: Span,
448 #[derive(LintDiagnostic)]
449 #[diag(lint_unused_result)]
450 pub struct UnusedResult<'a> {
454 // FIXME(davidtwco): this isn't properly translatable becauses of the
456 #[derive(LintDiagnostic)]
457 #[diag(lint_unused_closure)]
459 pub struct UnusedClosure<'a> {
465 // FIXME(davidtwco): this isn't properly translatable becauses of the
467 #[derive(LintDiagnostic)]
468 #[diag(lint_unused_generator)]
470 pub struct UnusedGenerator<'a> {
476 // FIXME(davidtwco): this isn't properly translatable becauses of the pre/post
478 pub struct UnusedDef<'a, 'b> {
481 pub cx: &'a LateContext<'b>,
483 pub note: Option<Symbol>,
486 // FIXME: refactor with `Option<String>` in macro
487 impl<'a, 'b, G: EmissionGuarantee> DecorateLint<'_, G> for UnusedDef<'a, 'b> {
488 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
489 let mut diag = diag.build(fluent::lint_unused_def);
490 diag.set_arg("pre", self.pre);
491 diag.set_arg("post", self.post);
492 diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id));
493 // check for #[must_use = "..."]
494 if let Some(note) = self.note {
495 diag.note(note.as_str());
501 #[derive(LintDiagnostic)]
502 #[diag(lint_path_statement_drop)]
503 pub struct PathStatementDrop {
505 pub sub: PathStatementDropSub,
508 #[derive(Subdiagnostic)]
509 pub enum PathStatementDropSub {
510 #[suggestion(suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
523 #[derive(LintDiagnostic)]
524 #[diag(lint_path_statement_no_effect)]
525 pub struct PathStatementNoEffect;
527 #[derive(LintDiagnostic)]
528 #[diag(lint_unused_delim)]
529 pub struct UnusedDelim<'a> {
530 pub delim: &'static str,
533 pub suggestion: Option<UnusedDelimSuggestion>,
536 #[derive(Subdiagnostic)]
537 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
538 pub struct UnusedDelimSuggestion {
539 #[suggestion_part(code = "{start_replace}")]
540 pub start_span: Span,
541 pub start_replace: &'static str,
542 #[suggestion_part(code = "{end_replace}")]
544 pub end_replace: &'static str,
547 #[derive(LintDiagnostic)]
548 #[diag(lint_unused_import_braces)]
549 pub struct UnusedImportBracesDiag {
553 #[derive(LintDiagnostic)]
554 #[diag(lint_unused_allocation)]
555 pub struct UnusedAllocationDiag;
557 #[derive(LintDiagnostic)]
558 #[diag(lint_unused_allocation_mut)]
559 pub struct UnusedAllocationMutDiag;