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_non_camel_case_type)]
11 pub struct NonCamelCaseType<'a> {
15 pub sub: NonCamelCaseTypeSub,
18 #[derive(SessionSubdiagnostic)]
19 pub enum NonCamelCaseTypeSub {
25 #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
33 #[derive(LintDiagnostic)]
34 #[diag(lint_non_snake_case)]
35 pub struct NonSnakeCaseDiag<'a> {
40 pub sub: NonSnakeCaseDiagSub,
43 pub enum NonSnakeCaseDiagSub {
46 RenameOrConvertSuggestion { span: Span, suggestion: Ident },
47 ConvertSuggestion { span: Span, suggestion: String },
48 SuggestionAndNote { span: Span },
51 impl AddSubdiagnostic for NonSnakeCaseDiagSub {
52 fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
54 NonSnakeCaseDiagSub::Label { span } => {
55 diag.span_label(span, fluent::label);
57 NonSnakeCaseDiagSub::Help => {
58 diag.help(fluent::help);
60 NonSnakeCaseDiagSub::ConvertSuggestion { span, suggestion } => {
63 fluent::convert_suggestion,
65 Applicability::MaybeIncorrect,
68 NonSnakeCaseDiagSub::RenameOrConvertSuggestion { span, suggestion } => {
71 fluent::rename_or_convert_suggestion,
73 Applicability::MaybeIncorrect,
76 NonSnakeCaseDiagSub::SuggestionAndNote { span } => {
77 diag.note(fluent::cannot_convert_note);
80 fluent::rename_suggestion,
82 Applicability::MaybeIncorrect,
89 #[derive(LintDiagnostic)]
90 #[diag(lint_non_upper_case_global)]
91 pub struct NonUpperCaseGlobal<'a> {
95 pub sub: NonUpperCaseGlobalSub,
98 #[derive(SessionSubdiagnostic)]
99 pub enum NonUpperCaseGlobalSub {
105 #[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
113 #[derive(LintDiagnostic)]
114 #[diag(lint_noop_method_call)]
116 pub struct NoopMethodCallDiag<'a> {
118 pub receiver_ty: Ty<'a>,
123 #[derive(LintDiagnostic)]
124 #[diag(lint_pass_by_value)]
125 pub struct PassByValueDiag {
127 #[suggestion(code = "{ty}", applicability = "maybe-incorrect")]
128 pub suggestion: Span,
131 #[derive(LintDiagnostic)]
132 #[diag(lint_redundant_semicolons)]
133 pub struct RedundantSemicolonsDiag {
135 #[suggestion(code = "", applicability = "maybe-incorrect")]
136 pub suggestion: Span,
139 pub struct DropTraitConstraintsDiag<'a> {
140 pub predicate: Predicate<'a>,
145 impl<'a, G: EmissionGuarantee> DecorateLint<'_, G> for DropTraitConstraintsDiag<'a> {
146 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
147 let mut diag = diag.build(fluent::lint_drop_trait_constraints);
148 diag.set_arg("predicate", self.predicate);
149 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id));
154 pub struct DropGlue<'a> {
159 impl<'a, G: EmissionGuarantee> DecorateLint<'_, G> for DropGlue<'a> {
160 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
161 let mut diag = diag.build(fluent::lint_drop_glue);
162 diag.set_arg("needs_drop", self.tcx.def_path_str(self.def_id));
167 #[derive(LintDiagnostic)]
168 #[diag(lint_range_endpoint_out_of_range)]
169 pub struct RangeEndpointOutOfRange<'a> {
171 #[suggestion(code = "{start}..={literal}{suffix}", applicability = "machine-applicable")]
172 pub suggestion: Span,
178 #[derive(LintDiagnostic)]
179 #[diag(lint_overflowing_bin_hex)]
180 pub struct OverflowingBinHex<'a> {
184 pub actually: String,
186 pub sign: OverflowingBinHexSign,
188 pub sub: Option<OverflowingBinHexSub<'a>>,
191 pub enum OverflowingBinHexSign {
196 impl AddSubdiagnostic for OverflowingBinHexSign {
197 fn add_to_diagnostic(self, diag: &mut rustc_errors::Diagnostic) {
199 OverflowingBinHexSign::Positive => {
200 diag.note(fluent::positive_note);
202 OverflowingBinHexSign::Negative => {
203 diag.note(fluent::negative_note);
204 diag.note(fluent::negative_becomes_note);
210 #[derive(SessionSubdiagnostic)]
211 pub enum OverflowingBinHexSub<'a> {
214 code = "{sans_suffix}{suggestion_ty}",
215 applicability = "machine-applicable"
220 suggestion_ty: &'a str,
221 sans_suffix: &'a str,
224 Help { suggestion_ty: &'a str },
227 pub struct OverflowingInt<'a> {
232 pub suggestion_ty: Option<&'a str>,
235 // FIXME: refactor with `Option<&'a str>` in macro
236 impl<'a, G: EmissionGuarantee> DecorateLint<'_, G> for OverflowingInt<'a> {
237 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
238 let mut diag = diag.build(fluent::lint_overflowing_int);
239 diag.set_arg("ty", self.ty);
240 diag.set_arg("lit", self.lit);
241 diag.set_arg("min", self.min);
242 diag.set_arg("max", self.max);
243 diag.note(fluent::note);
244 if let Some(suggestion_ty) = self.suggestion_ty {
245 diag.set_arg("suggestion_ty", suggestion_ty);
246 diag.help(fluent::help);
252 #[derive(LintDiagnostic)]
253 #[diag(lint_only_cast_u8_to_char)]
254 pub struct OnlyCastu8ToChar {
255 #[suggestion(code = "'\\u{{{literal:X}}}'", applicability = "machine-applicable")]
260 #[derive(LintDiagnostic)]
261 #[diag(lint_overflowing_uint)]
263 pub struct OverflowingUInt<'a> {
270 #[derive(LintDiagnostic)]
271 #[diag(lint_overflowing_literal)]
273 pub struct OverflowingLiteral<'a> {
278 #[derive(LintDiagnostic)]
279 #[diag(lint_unused_comparisons)]
280 pub struct UnusedComparisons;
282 #[derive(LintDiagnostic)]
283 #[diag(lint_variant_size_differences)]
284 pub struct VariantSizeDifferencesDiag {
288 #[derive(LintDiagnostic)]
289 #[diag(lint_atomic_ordering_load)]
291 pub struct AtomicOrderingLoad;
293 #[derive(LintDiagnostic)]
294 #[diag(lint_atomic_ordering_store)]
296 pub struct AtomicOrderingStore;
298 #[derive(LintDiagnostic)]
299 #[diag(lint_atomic_ordering_fence)]
301 pub struct AtomicOrderingFence;
303 #[derive(LintDiagnostic)]
304 #[diag(lint_atomic_ordering_invalid)]
306 pub struct InvalidAtomicOrderingDiag {
309 pub fail_order_arg_span: Span,
312 #[derive(LintDiagnostic)]
313 #[diag(lint_unused_op)]
314 pub struct UnusedOp<'a> {
318 #[suggestion(style = "verbose", code = "let _ = ", applicability = "machine-applicable")]
319 pub suggestion: Span,
322 #[derive(LintDiagnostic)]
323 #[diag(lint_unused_result)]
324 pub struct UnusedResult<'a> {
328 // FIXME(davidtwco): this isn't properly translatable becauses of the
330 #[derive(LintDiagnostic)]
331 #[diag(lint_unused_closure)]
333 pub struct UnusedClosure<'a> {
339 // FIXME(davidtwco): this isn't properly translatable becauses of the
341 #[derive(LintDiagnostic)]
342 #[diag(lint_unused_generator)]
344 pub struct UnusedGenerator<'a> {
350 // FIXME(davidtwco): this isn't properly translatable becauses of the pre/post
352 pub struct UnusedDef<'a, 'b> {
355 pub cx: &'a LateContext<'b>,
357 pub note: Option<Symbol>,
360 // FIXME: refactor with `Option<String>` in macro
361 impl<'a, 'b, G: EmissionGuarantee> DecorateLint<'_, G> for UnusedDef<'a, 'b> {
362 fn decorate_lint(self, diag: rustc_errors::LintDiagnosticBuilder<'_, G>) {
363 let mut diag = diag.build(fluent::lint_unused_def);
364 diag.set_arg("pre", self.pre);
365 diag.set_arg("post", self.post);
366 diag.set_arg("def", self.cx.tcx.def_path_str(self.def_id));
367 // check for #[must_use = "..."]
368 if let Some(note) = self.note {
369 diag.note(note.as_str());
375 #[derive(LintDiagnostic)]
376 #[diag(lint_path_statement_drop)]
377 pub struct PathStatementDrop {
379 pub sub: PathStatementDropSub,
382 #[derive(SessionSubdiagnostic)]
383 pub enum PathStatementDropSub {
386 code = "drop({snippet});",
387 applicability = "machine-applicable"
401 #[derive(LintDiagnostic)]
402 #[diag(lint_path_statement_no_effect)]
403 pub struct PathStatementNoEffect;
405 #[derive(LintDiagnostic)]
406 #[diag(lint_unused_delim)]
407 pub struct UnusedDelim<'a> {
408 pub delim: &'static str,
411 pub suggestion: Option<UnusedDelimSuggestion>,
414 #[derive(Subdiagnostic)]
415 #[multipart_suggestion(suggestion, applicability = "machine-applicable")]
416 pub struct UnusedDelimSuggestion {
417 #[suggestion_part(code = "{start_replace}")]
418 pub start_span: Span,
419 pub start_replace: &'static str,
420 #[suggestion_part(code = "{end_replace}")]
422 pub end_replace: &'static str,
425 #[derive(LintDiagnostic)]
426 #[diag(lint_unused_import_braces)]
427 pub struct UnusedImportBracesDiag {
431 #[derive(LintDiagnostic)]
432 #[diag(lint_unused_allocation)]
433 pub struct UnusedAllocationDiag;
435 #[derive(LintDiagnostic)]
436 #[diag(lint_unused_allocation_mut)]
437 pub struct UnusedAllocationMutDiag;