1 use rustc_errors::{fluent, AddSubdiagnostic, Applicability, DecorateLint, EmissionGuarantee};
2 use rustc_hir::def_id::DefId;
3 use rustc_macros::{LintDiagnostic, SessionSubdiagnostic};
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(SessionSubdiagnostic)]
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_cstring_ptr)]
39 pub struct CStringPtr {
40 #[label(as_ptr_label)]
42 #[label(unwrap_label)]
45 #[derive(LintDiagnostic)]
46 #[diag(lint_identifier_non_ascii_char)]
47 pub struct IdentifierNonAsciiChar;
49 #[derive(LintDiagnostic)]
50 #[diag(lint_identifier_uncommon_codepoints)]
51 pub struct IdentifierUncommonCodepoints;
53 #[derive(LintDiagnostic)]
54 #[diag(lint_confusable_identifier_pair)]
55 pub struct ConfusableIdentifierPair {
56 pub existing_sym: Symbol,
62 #[derive(LintDiagnostic)]
63 #[diag(lint_mixed_script_confusables)]
64 #[note(includes_note)]
66 pub struct MixedScriptConfusables {
71 pub struct NonFmtPanicUnused {
73 pub suggestion: Option<Span>,
76 impl<G: EmissionGuarantee> DecorateLint<'_, G> for NonFmtPanicUnused {
77 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
78 let mut diag = diag.build(fluent::lint_non_fmt_panic_unused);
79 diag.set_arg("count", self.count);
80 diag.note(fluent::note);
81 if let Some(span) = self.suggestion {
84 fluent::add_args_suggestion,
86 Applicability::HasPlaceholders,
90 fluent::add_fmt_suggestion,
92 Applicability::MachineApplicable,
99 #[derive(LintDiagnostic)]
100 #[diag(lint_non_fmt_panic_braces)]
102 pub struct NonFmtPanicBraces {
104 #[suggestion(code = "\"{{}}\", ", applicability = "machine-applicable")]
105 pub suggestion: Option<Span>,
108 #[derive(LintDiagnostic)]
109 #[diag(lint_non_camel_case_type)]
110 pub struct NonCamelCaseType<'a> {
114 pub sub: NonCamelCaseTypeSub,
117 #[derive(SessionSubdiagnostic)]
118 pub enum NonCamelCaseTypeSub {
124 #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
132 #[derive(LintDiagnostic)]
133 #[diag(lint_non_snake_case)]
134 pub struct NonSnakeCaseDiag<'a> {
139 pub sub: NonSnakeCaseDiagSub,
142 pub enum NonSnakeCaseDiagSub {
143 Label { span: Span },
145 RenameOrConvertSuggestion { span: Span, suggestion: Ident },
146 ConvertSuggestion { span: Span, suggestion: String },
147 SuggestionAndNote { span: Span },
150 impl AddSubdiagnostic for NonSnakeCaseDiagSub {
151 fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
153 NonSnakeCaseDiagSub::Label { span } => {
154 diag.span_label(span, fluent::label);
156 NonSnakeCaseDiagSub::Help => {
157 diag.help(fluent::help);
159 NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
160 diag.span_suggestion(
162 fluent::convert_suggestion,
164 Applicability::MaybeIncorrect,
167 NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => {
168 diag.span_suggestion(
170 fluent::rename_or_convert_suggestion,
172 Applicability::MaybeIncorrect,
175 NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
176 diag.note(fluent::cannot_convert_note);
177 diag.span_suggestion(
179 fluent::rename_suggestion,
181 Applicability::MaybeIncorrect,
188 #[derive(LintDiagnostic)]
189 #[diag(lint_non_upper_case_global)]
190 pub struct NonUpperCaseGlobal<'a> {
194 pub sub: NonUpperCaseGlobalSub,
197 #[derive(SessionSubdiagnostic)]
198 pub enum NonUpperCaseGlobalSub {
204 #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
212 #[derive(LintDiagnostic)]
213 #[diag(lint_noop_method_call)]
215 pub struct NoopMethodCallDiag<'a> {
217 pub receiver_ty: Ty<'a>,
222 #[derive(LintDiagnostic)]
223 #[diag(lint_pass_by_value)]
224 pub struct PassByValueDiag {
226 #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
227 pub suggestion: Span,
230 #[derive(LintDiagnostic)]
231 #[diag(lint_redundant_semicolons)]
232 pub struct RedundantSemicolonsDiag {
234 #[suggestion(code = "", applicability = "maybe-incorrect")]
235 pub suggestion: Span,
238 pub struct DropTraitConstraintsDiag<'a> {
239 pub predicate: Predicate<'a>,
244 impl<'a, G: EmissionGuarantee> DecorateLint<'_, G> for DropTraitConstraintsDiag<'a> {
245 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
246 let mut diag = diag.build(fluent::lint_drop_trait_constraints);
247 diag.set_arg("predicate", self.predicate);
248 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id));
253 pub struct DropGlue<'a> {
258 impl<'a, G: EmissionGuarantee> DecorateLint<'_, G> for DropGlue<'a> {
259 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
260 let mut diag = diag.build(fluent::lint_drop_glue);
261 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id));
266 #[derive(LintDiagnostic)]
267 #[diag(lint_range_endpoint_out_of_range)]
268 pub struct RangeEndpointOutOfRange<'a> {
270 #[suggestion(code = "{start}..={literal}{suffix}", applicability = "machine-applicable")]
271 pub suggestion: Span,
277 #[derive(LintDiagnostic)]
278 #[diag(lint_overflowing_bin_hex)]
279 pub struct OverflowingBinHex<'a> {
283 pub actually: String,
285 pub sign: OverflowingBinHexSign,
287 pub sub: Option<OverflowingBinHexSub<'a>>,
290 pub enum OverflowingBinHexSign {
295 impl AddSubdiagnostic for OverflowingBinHexSign {
296 fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
298 OverflowingBinHexSign::Positive => {
299 diag.note(fluent::positive_note);
301 OverflowingBinHexSign::Negative => {
302 diag.note(fluent::negative_note);
303 diag.note(fluent::negative_becomes_note);
309 #[derive(SessionSubdiagnostic)]
310 pub enum OverflowingBinHexSub<'a> {
313 code = "{sans_suffix}{suggestion_ty}",
314 applicability = "machine-applicable"
319 suggestion_ty: &'a str,
320 sans_suffix: &'a str,
323 Help { suggestion_ty: &'a str },
326 pub struct OverflowingInt<'a> {
331 pub suggestion_ty: Option<&'a str>,
334 // FIXME: refactor with `Option<&'a str>` in macro
335 impl<'a, G: EmissionGuarantee> DecorateLint<'_, G> for OverflowingInt<'a> {
336 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
337 let mut diag = diag.build(fluent::lint_overflowing_int);
338 diag.set_arg("ty", self.ty);
339 diag.set_arg("lit", self.lit);
340 diag.set_arg("min", self.min);
341 diag.set_arg("max", self.max);
342 diag.note(fluent::note);
343 if let Some(suggestion_ty) = self.suggestion_ty {
344 diag.set_arg("suggestion_ty", suggestion_ty);
345 diag.help(fluent::help);
351 #[derive(LintDiagnostic)]
352 #[diag(lint_only_cast_u8_to_char)]
353 pub struct OnlyCastu8ToChar {
354 #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")]
359 #[derive(LintDiagnostic)]
360 #[diag(lint_overflowing_uint)]
362 pub struct OverflowingUInt<'a> {
369 #[derive(LintDiagnostic)]
370 #[diag(lint_overflowing_literal)]
372 pub struct OverflowingLiteral<'a> {
377 #[derive(LintDiagnostic)]
378 #[diag(lint_unused_comparisons)]
379 pub struct UnusedComparisons;
381 #[derive(LintDiagnostic)]
382 #[diag(lint_variant_size_differences)]
383 pub struct VariantSizeDifferencesDiag {
387 #[derive(LintDiagnostic)]
388 #[diag(lint_atomic_ordering_load)]
390 pub struct AtomicOrderingLoad;
392 #[derive(LintDiagnostic)]
393 #[diag(lint_atomic_ordering_store)]
395 pub struct AtomicOrderingStore;
397 #[derive(LintDiagnostic)]
398 #[diag(lint_atomic_ordering_fence)]
400 pub struct AtomicOrderingFence;
402 #[derive(LintDiagnostic)]
403 #[diag(lint_atomic_ordering_invalid)]
405 pub struct InvalidAtomicOrderingDiag {
408 pub fail_order_arg_span: Span,
411 #[derive(LintDiagnostic)]
412 #[diag(lint_unused_op)]
413 pub struct UnusedOp<'a> {
417 #[suggestion(style = "verbose", code = "let _ = ", applicability = "machine-applicable")]
418 pub suggestion: Span,
421 #[derive(LintDiagnostic)]
422 #[diag(lint_unused_result)]
423 pub struct UnusedResult<'a> {
427 // FIXME(davidtwco): this isn't properly translatable becauses of the
429 #[derive(LintDiagnostic)]
430 #[diag(lint_unused_closure)]
432 pub struct UnusedClosure<'a> {
438 // FIXME(davidtwco): this isn't properly translatable becauses of the
440 #[derive(LintDiagnostic)]
441 #[diag(lint_unused_generator)]
443 pub struct UnusedGenerator<'a> {
449 // FIXME(davidtwco): this isn't properly translatable becauses of the pre/post
451 pub struct UnusedDef<'a, 'b> {
454 pub cx: &'a LateContext<'b>,
456 pub note: Option<Symbol>,
459 // FIXME: refactor with `Option<String>` in macro
460 impl<'a, 'b, G: EmissionGuarantee> DecorateLint<'_, G> for UnusedDef<'a, 'b> {
461 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
462 let mut diag = diag.build(fluent::lint_unused_def);
463 diag.set_arg("pre", self.pre);
464 diag.set_arg("post", self.post);
465 diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id));
466 // check for #[must_use = "..."]
467 if let Some(note) = self.note {
468 diag.note(note.as_str());
474 #[derive(LintDiagnostic)]
475 #[diag(lint_path_statement_drop)]
476 pub struct PathStatementDrop {
478 pub sub: PathStatementDropSub,
481 #[derive(SessionSubdiagnostic)]
482 pub enum PathStatementDropSub {
483 #[suggestion(suggestion, code = "drop({snippet});", applicability = "machine-applicable")]
496 #[derive(LintDiagnostic)]
497 #[diag(lint_path_statement_no_effect)]
498 pub struct PathStatementNoEffect;
500 #[derive(LintDiagnostic)]
501 #[diag(lint_unused_delim)]
502 pub struct UnusedDelim<'a> {
503 pub delim: &'static str,
506 pub suggestion: Option<UnusedDelimSuggestion>,
509 #[derive(Subdiagnostic)]
510 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
511 pub struct UnusedDelimSuggestion {
512 #[suggestion_part(code = "{start_replace}")]
513 pub start_span: Span,
514 pub start_replace: &'static str,
515 #[suggestion_part(code = "{end_replace}")]
517 pub end_replace: &'static str,
520 #[derive(LintDiagnostic)]
521 #[diag(lint_unused_import_braces)]
522 pub struct UnusedImportBracesDiag {
526 #[derive(LintDiagnostic)]
527 #[diag(lint_unused_allocation)]
528 pub struct UnusedAllocationDiag;
530 #[derive(LintDiagnostic)]
531 #[diag(lint_unused_allocation_mut)]
532 pub struct UnusedAllocationMutDiag;