Skip to content

Commit 78fce79

Browse files
committed
refactor: refactor to derive for some lints.
1 parent ca7df9a commit 78fce79

File tree

6 files changed

+99
-140
lines changed

6 files changed

+99
-140
lines changed

compiler/rustc_error_messages/locales/en-US/lint.ftl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ lint_enum_intrinsics_mem_variant =
1515
1616
lint_expectation = this lint expectation is unfulfilled
1717
.note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
18+
.rationale = {$rationale}
1819
1920
lint_for_loops_over_fallibles =
2021
for loop over {$article} `{$ty}`. This is more readably written as an `if let` statement
@@ -39,7 +40,8 @@ lint_deprecated_lint_name =
3940
lint name `{$name}` is deprecated and may not have an effect in the future.
4041
.suggestion = change it to
4142
42-
lint_renamed_or_removed_lint_suggestion = use the new name
43+
lint_renamed_or_removed_lint = {$msg}
44+
.suggestion = use the new name
4345
4446
lint_unknown_lint =
4547
unknown lint: `{$name}`

compiler/rustc_lint/src/builtin.rs

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@ use crate::{
2626
BuiltinAnonymousParams, BuiltinBoxPointers, BuiltinConstNoMangle,
2727
BuiltinDeprecatedAttrUsed, BuiltinDerefNullptr, BuiltinEllipsisInclusiveRangePatternsLint,
2828
BuiltinExplicitOutlives, BuiltinExplicitOutlivesSuggestion, BuiltinIncompleteFeatures,
29-
BuiltinKeywordIdents, BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,
29+
BuiltinIncompleteFeaturesHelp, BuiltinIncompleteFeaturesNote, BuiltinKeywordIdents,
30+
BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,
3031
BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns,
3132
BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinUnexpectedCliConfigName,
3233
BuiltinUnexpectedCliConfigValue, BuiltinUnnameableTestItems, BuiltinUnreachablePub,
@@ -2379,14 +2380,17 @@ impl EarlyLintPass for IncompleteFeatures {
23792380
.chain(features.declared_lib_features.iter().map(|(name, span)| (name, span)))
23802381
.filter(|(&name, _)| features.incomplete(name))
23812382
.for_each(|(&name, &span)| {
2383+
let note = rustc_feature::find_feature_issue(name, GateIssue::Language)
2384+
.map(|n| BuiltinIncompleteFeaturesNote { n });
2385+
let help = if HAS_MIN_FEATURES.contains(&name) {
2386+
Some(BuiltinIncompleteFeaturesHelp)
2387+
} else {
2388+
None
2389+
};
23822390
cx.emit_spanned_lint(
23832391
INCOMPLETE_FEATURES,
23842392
span,
2385-
BuiltinIncompleteFeatures {
2386-
name,
2387-
note: rustc_feature::find_feature_issue(name, GateIssue::Language),
2388-
help: HAS_MIN_FEATURES.contains(&name).then_some(()),
2389-
},
2393+
BuiltinIncompleteFeatures { name, note, help },
23902394
);
23912395
});
23922396
}

compiler/rustc_lint/src/expect.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![deny(rustc::untranslatable_diagnostic)]
22
#![deny(rustc::diagnostic_outside_of_impl)]
3-
use crate::lints::Expectation;
3+
use crate::lints::{Expectation, ExpectationNote};
44
use rustc_middle::ty::query::Providers;
55
use rustc_middle::ty::TyCtxt;
66
use rustc_session::lint::builtin::UNFULFILLED_LINT_EXPECTATIONS;
@@ -29,11 +29,13 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
2929
if !fulfilled_expectations.contains(&id)
3030
&& tool_filter.map_or(true, |filter| expectation.lint_tool == Some(filter))
3131
{
32+
let rationale = expectation.reason.map(|rationale| ExpectationNote { rationale });
33+
let note = expectation.is_unfulfilled_lint_expectations.then_some(());
3234
tcx.emit_spanned_lint(
3335
UNFULFILLED_LINT_EXPECTATIONS,
3436
*hir_id,
3537
expectation.emission_span,
36-
Expectation { expectation },
38+
Expectation { rationale, note },
3739
);
3840
}
3941
} else {

compiler/rustc_lint/src/levels.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::context::{CheckLintNameResult, LintStore};
44
use crate::late::unerased_lint_store;
55
use crate::lints::{
66
DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAtributeLint, RenamedOrRemovedLint,
7-
UnknownLint,
7+
RenamedOrRemovedLintSuggestion, UnknownLint, UnknownLintSuggestion,
88
};
99
use rustc_ast as ast;
1010
use rustc_ast_pretty::pprust;
@@ -887,10 +887,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
887887
_ if !self.warn_about_weird_lints => {}
888888

889889
CheckLintNameResult::Warning(msg, renamed) => {
890+
let suggestion =
891+
renamed.as_ref().map(|replace| RenamedOrRemovedLintSuggestion {
892+
suggestion: sp,
893+
replace: replace.as_str(),
894+
});
890895
self.emit_spanned_lint(
891896
RENAMED_AND_REMOVED_LINTS,
892897
sp.into(),
893-
RenamedOrRemovedLint { msg, suggestion: sp, renamed },
898+
RenamedOrRemovedLint { msg, suggestion },
894899
);
895900
}
896901
CheckLintNameResult::NoLint(suggestion) => {
@@ -899,10 +904,12 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
899904
} else {
900905
name.to_string()
901906
};
907+
let suggestion = suggestion
908+
.map(|replace| UnknownLintSuggestion { suggestion: sp, replace });
902909
self.emit_spanned_lint(
903910
UNKNOWN_LINTS,
904911
sp.into(),
905-
UnknownLint { name, suggestion: sp, replace: suggestion },
912+
UnknownLint { name, suggestion },
906913
);
907914
}
908915
}

compiler/rustc_lint/src/lints.rs

Lines changed: 62 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ use std::num::NonZeroU32;
33
use rustc_errors::{fluent, AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage};
44
use rustc_hir::def_id::DefId;
55
use rustc_macros::{LintDiagnostic, Subdiagnostic};
6-
use rustc_middle::{
7-
lint::LintExpectation,
8-
ty::{Predicate, Ty, TyCtxt},
9-
};
6+
use rustc_middle::ty::{Predicate, Ty, TyCtxt};
107
use rustc_span::{edition::Edition, symbol::Ident, Span, Symbol};
118

129
use crate::{errors::OverruledAttributeSub, LateContext};
@@ -80,6 +77,7 @@ pub struct BuiltinMissingDebugImpl<'a> {
8077
pub def_id: DefId,
8178
}
8279

80+
// Needed for def_path_str
8381
impl<'a> DecorateLint<'a, ()> for BuiltinMissingDebugImpl<'_> {
8482
fn decorate_lint<'b>(
8583
self,
@@ -225,31 +223,24 @@ pub struct BuiltinExplicitOutlivesSuggestion {
225223
pub applicability: Applicability,
226224
}
227225

226+
#[derive(LintDiagnostic)]
227+
#[diag(lint_builtin_incomplete_features)]
228228
pub struct BuiltinIncompleteFeatures {
229229
pub name: Symbol,
230-
pub note: Option<NonZeroU32>,
231-
pub help: Option<()>,
230+
#[subdiagnostic]
231+
pub note: Option<BuiltinIncompleteFeaturesNote>,
232+
#[subdiagnostic]
233+
pub help: Option<BuiltinIncompleteFeaturesHelp>,
232234
}
233235

234-
impl<'a> DecorateLint<'a, ()> for BuiltinIncompleteFeatures {
235-
fn decorate_lint<'b>(
236-
self,
237-
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
238-
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
239-
diag.set_arg("name", self.name);
240-
if let Some(n) = self.note {
241-
diag.set_arg("n", n);
242-
diag.note(fluent::note);
243-
}
244-
if let Some(_) = self.help {
245-
diag.help(fluent::help);
246-
}
247-
diag
248-
}
236+
#[derive(Subdiagnostic)]
237+
#[help(help)]
238+
pub struct BuiltinIncompleteFeaturesHelp;
249239

250-
fn msg(&self) -> DiagnosticMessage {
251-
fluent::lint_builtin_incomplete_features
252-
}
240+
#[derive(Subdiagnostic)]
241+
#[note(note)]
242+
pub struct BuiltinIncompleteFeaturesNote {
243+
pub n: NonZeroU32,
253244
}
254245

255246
// FIXME: migrate "the type `{}` does not permit {}"
@@ -308,29 +299,19 @@ pub struct EnumIntrinsicsMemVariant<'a> {
308299
}
309300

310301
// expect.rs
311-
pub struct Expectation<'a> {
312-
pub expectation: &'a LintExpectation,
302+
#[derive(LintDiagnostic)]
303+
#[diag(lint_expectation)]
304+
pub struct Expectation {
305+
#[subdiagnostic]
306+
pub rationale: Option<ExpectationNote>,
307+
#[note]
308+
pub note: Option<()>,
313309
}
314310

315-
impl<'a> DecorateLint<'a, ()> for Expectation<'_> {
316-
fn decorate_lint<'b>(
317-
self,
318-
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
319-
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
320-
if let Some(rationale) = self.expectation.reason {
321-
diag.note(rationale.as_str());
322-
}
323-
324-
if self.expectation.is_unfulfilled_lint_expectations {
325-
diag.note(fluent::note);
326-
}
327-
328-
diag
329-
}
330-
331-
fn msg(&self) -> DiagnosticMessage {
332-
fluent::lint_expectation
333-
}
311+
#[derive(Subdiagnostic)]
312+
#[note(rationale)]
313+
pub struct ExpectationNote {
314+
pub rationale: Symbol,
334315
}
335316

336317
// for_loops_over_fallibles.rs
@@ -511,59 +492,37 @@ pub struct DeprecatedLintName<'a> {
511492
pub replace: &'a str,
512493
}
513494

495+
// FIXME: Non-translatable msg
496+
#[derive(LintDiagnostic)]
497+
#[diag(lint_renamed_or_removed_lint)]
514498
pub struct RenamedOrRemovedLint<'a> {
515499
pub msg: &'a str,
516-
pub suggestion: Span,
517-
pub renamed: &'a Option<String>,
500+
#[subdiagnostic]
501+
pub suggestion: Option<RenamedOrRemovedLintSuggestion<'a>>,
518502
}
519503

520-
impl<'a> DecorateLint<'a, ()> for RenamedOrRemovedLint<'_> {
521-
fn decorate_lint<'b>(
522-
self,
523-
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
524-
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
525-
if let Some(new_name) = self.renamed {
526-
diag.span_suggestion(
527-
self.suggestion,
528-
fluent::lint_renamed_or_removed_lint_suggestion,
529-
new_name,
530-
Applicability::MachineApplicable,
531-
);
532-
};
533-
diag
534-
}
535-
536-
fn msg(&self) -> rustc_errors::DiagnosticMessage {
537-
rustc_errors::DiagnosticMessage::Str(self.msg.to_string())
538-
}
504+
#[derive(Subdiagnostic)]
505+
#[suggestion(suggestion, code = "{replace}", applicability = "machine-applicable")]
506+
pub struct RenamedOrRemovedLintSuggestion<'a> {
507+
#[primary_span]
508+
pub suggestion: Span,
509+
pub replace: &'a str,
539510
}
540511

541-
pub struct UnknownLint<'a> {
512+
#[derive(LintDiagnostic)]
513+
#[diag(lint_unknown_lint)]
514+
pub struct UnknownLint {
542515
pub name: String,
543-
pub suggestion: Span,
544-
pub replace: &'a Option<Symbol>,
516+
#[subdiagnostic]
517+
pub suggestion: Option<UnknownLintSuggestion>,
545518
}
546519

547-
impl<'a> DecorateLint<'a, ()> for UnknownLint<'_> {
548-
fn decorate_lint<'b>(
549-
self,
550-
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
551-
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
552-
diag.set_arg("name", self.name);
553-
if let Some(replace) = self.replace {
554-
diag.span_suggestion(
555-
self.suggestion,
556-
fluent::suggestion,
557-
replace,
558-
Applicability::MaybeIncorrect,
559-
);
560-
};
561-
diag
562-
}
563-
564-
fn msg(&self) -> rustc_errors::DiagnosticMessage {
565-
fluent::lint_unknown_lint
566-
}
520+
#[derive(Subdiagnostic)]
521+
#[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
522+
pub struct UnknownLintSuggestion {
523+
#[primary_span]
524+
pub suggestion: Span,
525+
pub replace: Symbol,
567526
}
568527

569528
#[derive(LintDiagnostic)]
@@ -618,6 +577,7 @@ pub struct NonFmtPanicUnused {
618577
pub suggestion: Option<Span>,
619578
}
620579

580+
// Used because of two suggestions based on one Option<Span>
621581
impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
622582
fn decorate_lint<'b>(
623583
self,
@@ -803,6 +763,7 @@ pub struct DropTraitConstraintsDiag<'a> {
803763
pub def_id: DefId,
804764
}
805765

766+
// Needed for def_path_str
806767
impl<'a> DecorateLint<'a, ()> for DropTraitConstraintsDiag<'_> {
807768
fn decorate_lint<'b>(
808769
self,
@@ -822,6 +783,7 @@ pub struct DropGlue<'a> {
822783
pub def_id: DefId,
823784
}
824785

786+
// Needed for def_path_str
825787
impl<'a> DecorateLint<'a, ()> for DropGlue<'_> {
826788
fn decorate_lint<'b>(
827789
self,
@@ -902,35 +864,22 @@ pub enum OverflowingBinHexSub<'a> {
902864
Help { suggestion_ty: &'a str },
903865
}
904866

867+
#[derive(LintDiagnostic)]
868+
#[diag(lint_overflowing_int)]
869+
#[note]
905870
pub struct OverflowingInt<'a> {
906871
pub ty: &'a str,
907872
pub lit: String,
908873
pub min: i128,
909874
pub max: u128,
910-
pub suggestion_ty: Option<&'a str>,
875+
#[subdiagnostic]
876+
pub help: Option<OverflowingIntHelp<'a>>,
911877
}
912878

913-
// FIXME: refactor with `Option<&'a str>` in macro
914-
impl<'a> DecorateLint<'a, ()> for OverflowingInt<'_> {
915-
fn decorate_lint<'b>(
916-
self,
917-
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
918-
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
919-
diag.set_arg("ty", self.ty);
920-
diag.set_arg("lit", self.lit);
921-
diag.set_arg("min", self.min);
922-
diag.set_arg("max", self.max);
923-
diag.note(fluent::note);
924-
if let Some(suggestion_ty) = self.suggestion_ty {
925-
diag.set_arg("suggestion_ty", suggestion_ty);
926-
diag.help(fluent::help);
927-
}
928-
diag
929-
}
930-
931-
fn msg(&self) -> rustc_errors::DiagnosticMessage {
932-
fluent::lint_overflowing_int
933-
}
879+
#[derive(Subdiagnostic)]
880+
#[help(help)]
881+
pub struct OverflowingIntHelp<'a> {
882+
pub suggestion_ty: &'a str,
934883
}
935884

936885
#[derive(LintDiagnostic)]
@@ -972,6 +921,7 @@ pub struct ImproperCTypes<'a> {
972921
pub span_note: Option<Span>,
973922
}
974923

924+
// Used because of the complexity of Option<DiagnosticMessage>, DiagnosticMessage, and Option<Span>
975925
impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> {
976926
fn decorate_lint<'b>(
977927
self,
@@ -1074,7 +1024,7 @@ pub struct UnusedDef<'a, 'b> {
10741024
pub note: Option<Symbol>,
10751025
}
10761026

1077-
// FIXME: refactor with `Option<String>` in macro
1027+
// Needed because of def_path_str
10781028
impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> {
10791029
fn decorate_lint<'b>(
10801030
self,

0 commit comments

Comments
 (0)