refactor: refactor to derive for some lints.

This commit is contained in:
Rejyr 2022-11-10 19:32:30 -05:00
parent ca7df9a2a9
commit 78fce795d8
6 changed files with 100 additions and 141 deletions

View File

@ -15,6 +15,7 @@ lint_enum_intrinsics_mem_variant =
lint_expectation = this lint expectation is unfulfilled lint_expectation = this lint expectation is unfulfilled
.note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message .note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message
.rationale = {$rationale}
lint_for_loops_over_fallibles = lint_for_loops_over_fallibles =
for loop over {$article} `{$ty}`. This is more readably written as an `if let` statement for loop over {$article} `{$ty}`. This is more readably written as an `if let` statement
@ -39,7 +40,8 @@ lint_deprecated_lint_name =
lint name `{$name}` is deprecated and may not have an effect in the future. lint name `{$name}` is deprecated and may not have an effect in the future.
.suggestion = change it to .suggestion = change it to
lint_renamed_or_removed_lint_suggestion = use the new name lint_renamed_or_removed_lint = {$msg}
.suggestion = use the new name
lint_unknown_lint = lint_unknown_lint =
unknown lint: `{$name}` unknown lint: `{$name}`

View File

@ -26,7 +26,8 @@ use crate::{
BuiltinAnonymousParams, BuiltinBoxPointers, BuiltinConstNoMangle, BuiltinAnonymousParams, BuiltinBoxPointers, BuiltinConstNoMangle,
BuiltinDeprecatedAttrUsed, BuiltinDerefNullptr, BuiltinEllipsisInclusiveRangePatternsLint, BuiltinDeprecatedAttrUsed, BuiltinDerefNullptr, BuiltinEllipsisInclusiveRangePatternsLint,
BuiltinExplicitOutlives, BuiltinExplicitOutlivesSuggestion, BuiltinIncompleteFeatures, BuiltinExplicitOutlives, BuiltinExplicitOutlivesSuggestion, BuiltinIncompleteFeatures,
BuiltinKeywordIdents, BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc, BuiltinIncompleteFeaturesHelp, BuiltinIncompleteFeaturesNote, BuiltinKeywordIdents,
BuiltinMissingCopyImpl, BuiltinMissingDebugImpl, BuiltinMissingDoc,
BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns, BuiltinMutablesTransmutes, BuiltinNoMangleGeneric, BuiltinNonShorthandFieldPatterns,
BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinUnexpectedCliConfigName, BuiltinSpecialModuleNameUsed, BuiltinTrivialBounds, BuiltinUnexpectedCliConfigName,
BuiltinUnexpectedCliConfigValue, BuiltinUnnameableTestItems, BuiltinUnreachablePub, BuiltinUnexpectedCliConfigValue, BuiltinUnnameableTestItems, BuiltinUnreachablePub,
@ -2379,14 +2380,17 @@ impl EarlyLintPass for IncompleteFeatures {
.chain(features.declared_lib_features.iter().map(|(name, span)| (name, span))) .chain(features.declared_lib_features.iter().map(|(name, span)| (name, span)))
.filter(|(&name, _)| features.incomplete(name)) .filter(|(&name, _)| features.incomplete(name))
.for_each(|(&name, &span)| { .for_each(|(&name, &span)| {
let note = rustc_feature::find_feature_issue(name, GateIssue::Language)
.map(|n| BuiltinIncompleteFeaturesNote { n });
let help = if HAS_MIN_FEATURES.contains(&name) {
Some(BuiltinIncompleteFeaturesHelp)
} else {
None
};
cx.emit_spanned_lint( cx.emit_spanned_lint(
INCOMPLETE_FEATURES, INCOMPLETE_FEATURES,
span, span,
BuiltinIncompleteFeatures { BuiltinIncompleteFeatures { name, note, help },
name,
note: rustc_feature::find_feature_issue(name, GateIssue::Language),
help: HAS_MIN_FEATURES.contains(&name).then_some(()),
},
); );
}); });
} }

View File

@ -1,6 +1,6 @@
#![deny(rustc::untranslatable_diagnostic)] #![deny(rustc::untranslatable_diagnostic)]
#![deny(rustc::diagnostic_outside_of_impl)] #![deny(rustc::diagnostic_outside_of_impl)]
use crate::lints::Expectation; use crate::lints::{Expectation, ExpectationNote};
use rustc_middle::ty::query::Providers; use rustc_middle::ty::query::Providers;
use rustc_middle::ty::TyCtxt; use rustc_middle::ty::TyCtxt;
use rustc_session::lint::builtin::UNFULFILLED_LINT_EXPECTATIONS; use rustc_session::lint::builtin::UNFULFILLED_LINT_EXPECTATIONS;
@ -29,11 +29,13 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
if !fulfilled_expectations.contains(&id) if !fulfilled_expectations.contains(&id)
&& tool_filter.map_or(true, |filter| expectation.lint_tool == Some(filter)) && tool_filter.map_or(true, |filter| expectation.lint_tool == Some(filter))
{ {
let rationale = expectation.reason.map(|rationale| ExpectationNote { rationale });
let note = expectation.is_unfulfilled_lint_expectations.then_some(());
tcx.emit_spanned_lint( tcx.emit_spanned_lint(
UNFULFILLED_LINT_EXPECTATIONS, UNFULFILLED_LINT_EXPECTATIONS,
*hir_id, *hir_id,
expectation.emission_span, expectation.emission_span,
Expectation { expectation }, Expectation { rationale, note },
); );
} }
} else { } else {

View File

@ -4,7 +4,7 @@ use crate::context::{CheckLintNameResult, LintStore};
use crate::late::unerased_lint_store; use crate::late::unerased_lint_store;
use crate::lints::{ use crate::lints::{
DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAtributeLint, RenamedOrRemovedLint, DeprecatedLintName, IgnoredUnlessCrateSpecified, OverruledAtributeLint, RenamedOrRemovedLint,
UnknownLint, RenamedOrRemovedLintSuggestion, UnknownLint, UnknownLintSuggestion,
}; };
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
@ -887,10 +887,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
_ if !self.warn_about_weird_lints => {} _ if !self.warn_about_weird_lints => {}
CheckLintNameResult::Warning(msg, renamed) => { CheckLintNameResult::Warning(msg, renamed) => {
let suggestion =
renamed.as_ref().map(|replace| RenamedOrRemovedLintSuggestion {
suggestion: sp,
replace: replace.as_str(),
});
self.emit_spanned_lint( self.emit_spanned_lint(
RENAMED_AND_REMOVED_LINTS, RENAMED_AND_REMOVED_LINTS,
sp.into(), sp.into(),
RenamedOrRemovedLint { msg, suggestion: sp, renamed }, RenamedOrRemovedLint { msg, suggestion },
); );
} }
CheckLintNameResult::NoLint(suggestion) => { CheckLintNameResult::NoLint(suggestion) => {
@ -899,10 +904,12 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
} else { } else {
name.to_string() name.to_string()
}; };
let suggestion = suggestion
.map(|replace| UnknownLintSuggestion { suggestion: sp, replace });
self.emit_spanned_lint( self.emit_spanned_lint(
UNKNOWN_LINTS, UNKNOWN_LINTS,
sp.into(), sp.into(),
UnknownLint { name, suggestion: sp, replace: suggestion }, UnknownLint { name, suggestion },
); );
} }
} }

View File

@ -3,10 +3,7 @@ use std::num::NonZeroU32;
use rustc_errors::{fluent, AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage}; use rustc_errors::{fluent, AddToDiagnostic, Applicability, DecorateLint, DiagnosticMessage};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_macros::{LintDiagnostic, Subdiagnostic};
use rustc_middle::{ use rustc_middle::ty::{Predicate, Ty, TyCtxt};
lint::LintExpectation,
ty::{Predicate, Ty, TyCtxt},
};
use rustc_span::{edition::Edition, symbol::Ident, Span, Symbol}; use rustc_span::{edition::Edition, symbol::Ident, Span, Symbol};
use crate::{errors::OverruledAttributeSub, LateContext}; use crate::{errors::OverruledAttributeSub, LateContext};
@ -80,6 +77,7 @@ pub struct BuiltinMissingDebugImpl<'a> {
pub def_id: DefId, pub def_id: DefId,
} }
// Needed for def_path_str
impl<'a> DecorateLint<'a, ()> for BuiltinMissingDebugImpl<'_> { impl<'a> DecorateLint<'a, ()> for BuiltinMissingDebugImpl<'_> {
fn decorate_lint<'b>( fn decorate_lint<'b>(
self, self,
@ -225,31 +223,24 @@ pub struct BuiltinExplicitOutlivesSuggestion {
pub applicability: Applicability, pub applicability: Applicability,
} }
#[derive(LintDiagnostic)]
#[diag(lint_builtin_incomplete_features)]
pub struct BuiltinIncompleteFeatures { pub struct BuiltinIncompleteFeatures {
pub name: Symbol, pub name: Symbol,
pub note: Option<NonZeroU32>, #[subdiagnostic]
pub help: Option<()>, pub note: Option<BuiltinIncompleteFeaturesNote>,
#[subdiagnostic]
pub help: Option<BuiltinIncompleteFeaturesHelp>,
} }
impl<'a> DecorateLint<'a, ()> for BuiltinIncompleteFeatures { #[derive(Subdiagnostic)]
fn decorate_lint<'b>( #[help(help)]
self, pub struct BuiltinIncompleteFeaturesHelp;
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
diag.set_arg("name", self.name);
if let Some(n) = self.note {
diag.set_arg("n", n);
diag.note(fluent::note);
}
if let Some(_) = self.help {
diag.help(fluent::help);
}
diag
}
fn msg(&self) -> DiagnosticMessage { #[derive(Subdiagnostic)]
fluent::lint_builtin_incomplete_features #[note(note)]
} pub struct BuiltinIncompleteFeaturesNote {
pub n: NonZeroU32,
} }
// FIXME: migrate "the type `{}` does not permit {}" // FIXME: migrate "the type `{}` does not permit {}"
@ -308,29 +299,19 @@ pub struct EnumIntrinsicsMemVariant<'a> {
} }
// expect.rs // expect.rs
pub struct Expectation<'a> { #[derive(LintDiagnostic)]
pub expectation: &'a LintExpectation, #[diag(lint_expectation)]
pub struct Expectation {
#[subdiagnostic]
pub rationale: Option<ExpectationNote>,
#[note]
pub note: Option<()>,
} }
impl<'a> DecorateLint<'a, ()> for Expectation<'_> { #[derive(Subdiagnostic)]
fn decorate_lint<'b>( #[note(rationale)]
self, pub struct ExpectationNote {
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>, pub rationale: Symbol,
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
if let Some(rationale) = self.expectation.reason {
diag.note(rationale.as_str());
}
if self.expectation.is_unfulfilled_lint_expectations {
diag.note(fluent::note);
}
diag
}
fn msg(&self) -> DiagnosticMessage {
fluent::lint_expectation
}
} }
// for_loops_over_fallibles.rs // for_loops_over_fallibles.rs
@ -511,59 +492,37 @@ pub struct DeprecatedLintName<'a> {
pub replace: &'a str, pub replace: &'a str,
} }
// FIXME: Non-translatable msg
#[derive(LintDiagnostic)]
#[diag(lint_renamed_or_removed_lint)]
pub struct RenamedOrRemovedLint<'a> { pub struct RenamedOrRemovedLint<'a> {
pub msg: &'a str, pub msg: &'a str,
#[subdiagnostic]
pub suggestion: Option<RenamedOrRemovedLintSuggestion<'a>>,
}
#[derive(Subdiagnostic)]
#[suggestion(suggestion, code = "{replace}", applicability = "machine-applicable")]
pub struct RenamedOrRemovedLintSuggestion<'a> {
#[primary_span]
pub suggestion: Span, pub suggestion: Span,
pub renamed: &'a Option<String>, pub replace: &'a str,
} }
impl<'a> DecorateLint<'a, ()> for RenamedOrRemovedLint<'_> { #[derive(LintDiagnostic)]
fn decorate_lint<'b>( #[diag(lint_unknown_lint)]
self, pub struct UnknownLint {
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
if let Some(new_name) = self.renamed {
diag.span_suggestion(
self.suggestion,
fluent::lint_renamed_or_removed_lint_suggestion,
new_name,
Applicability::MachineApplicable,
);
};
diag
}
fn msg(&self) -> rustc_errors::DiagnosticMessage {
rustc_errors::DiagnosticMessage::Str(self.msg.to_string())
}
}
pub struct UnknownLint<'a> {
pub name: String, pub name: String,
#[subdiagnostic]
pub suggestion: Option<UnknownLintSuggestion>,
}
#[derive(Subdiagnostic)]
#[suggestion(suggestion, code = "{replace}", applicability = "maybe-incorrect")]
pub struct UnknownLintSuggestion {
#[primary_span]
pub suggestion: Span, pub suggestion: Span,
pub replace: &'a Option<Symbol>, pub replace: Symbol,
}
impl<'a> DecorateLint<'a, ()> for UnknownLint<'_> {
fn decorate_lint<'b>(
self,
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
diag.set_arg("name", self.name);
if let Some(replace) = self.replace {
diag.span_suggestion(
self.suggestion,
fluent::suggestion,
replace,
Applicability::MaybeIncorrect,
);
};
diag
}
fn msg(&self) -> rustc_errors::DiagnosticMessage {
fluent::lint_unknown_lint
}
} }
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
@ -618,6 +577,7 @@ pub struct NonFmtPanicUnused {
pub suggestion: Option<Span>, pub suggestion: Option<Span>,
} }
// Used because of two suggestions based on one Option<Span>
impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused { impl<'a> DecorateLint<'a, ()> for NonFmtPanicUnused {
fn decorate_lint<'b>( fn decorate_lint<'b>(
self, self,
@ -803,6 +763,7 @@ pub struct DropTraitConstraintsDiag<'a> {
pub def_id: DefId, pub def_id: DefId,
} }
// Needed for def_path_str
impl<'a> DecorateLint<'a, ()> for DropTraitConstraintsDiag<'_> { impl<'a> DecorateLint<'a, ()> for DropTraitConstraintsDiag<'_> {
fn decorate_lint<'b>( fn decorate_lint<'b>(
self, self,
@ -822,6 +783,7 @@ pub struct DropGlue<'a> {
pub def_id: DefId, pub def_id: DefId,
} }
// Needed for def_path_str
impl<'a> DecorateLint<'a, ()> for DropGlue<'_> { impl<'a> DecorateLint<'a, ()> for DropGlue<'_> {
fn decorate_lint<'b>( fn decorate_lint<'b>(
self, self,
@ -902,35 +864,22 @@ pub enum OverflowingBinHexSub<'a> {
Help { suggestion_ty: &'a str }, Help { suggestion_ty: &'a str },
} }
#[derive(LintDiagnostic)]
#[diag(lint_overflowing_int)]
#[note]
pub struct OverflowingInt<'a> { pub struct OverflowingInt<'a> {
pub ty: &'a str, pub ty: &'a str,
pub lit: String, pub lit: String,
pub min: i128, pub min: i128,
pub max: u128, pub max: u128,
pub suggestion_ty: Option<&'a str>, #[subdiagnostic]
pub help: Option<OverflowingIntHelp<'a>>,
} }
// FIXME: refactor with `Option<&'a str>` in macro #[derive(Subdiagnostic)]
impl<'a> DecorateLint<'a, ()> for OverflowingInt<'_> { #[help(help)]
fn decorate_lint<'b>( pub struct OverflowingIntHelp<'a> {
self, pub suggestion_ty: &'a str,
diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
diag.set_arg("ty", self.ty);
diag.set_arg("lit", self.lit);
diag.set_arg("min", self.min);
diag.set_arg("max", self.max);
diag.note(fluent::note);
if let Some(suggestion_ty) = self.suggestion_ty {
diag.set_arg("suggestion_ty", suggestion_ty);
diag.help(fluent::help);
}
diag
}
fn msg(&self) -> rustc_errors::DiagnosticMessage {
fluent::lint_overflowing_int
}
} }
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
@ -972,6 +921,7 @@ pub struct ImproperCTypes<'a> {
pub span_note: Option<Span>, pub span_note: Option<Span>,
} }
// Used because of the complexity of Option<DiagnosticMessage>, DiagnosticMessage, and Option<Span>
impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> { impl<'a> DecorateLint<'a, ()> for ImproperCTypes<'_> {
fn decorate_lint<'b>( fn decorate_lint<'b>(
self, self,
@ -1074,7 +1024,7 @@ pub struct UnusedDef<'a, 'b> {
pub note: Option<Symbol>, pub note: Option<Symbol>,
} }
// FIXME: refactor with `Option<String>` in macro // Needed because of def_path_str
impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> { impl<'a> DecorateLint<'a, ()> for UnusedDef<'_, '_> {
fn decorate_lint<'b>( fn decorate_lint<'b>(
self, self,

View File

@ -3,7 +3,7 @@
use crate::lints::{ use crate::lints::{
AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes, AtomicOrderingFence, AtomicOrderingLoad, AtomicOrderingStore, ImproperCTypes,
InvalidAtomicOrderingDiag, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign, InvalidAtomicOrderingDiag, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign,
OverflowingBinHexSub, OverflowingInt, OverflowingLiteral, OverflowingUInt, OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral, OverflowingUInt,
RangeEndpointOutOfRange, UnusedComparisons, VariantSizeDifferencesDiag, RangeEndpointOutOfRange, UnusedComparisons, VariantSizeDifferencesDiag,
}; };
use crate::{LateContext, LateLintPass, LintContext}; use crate::{LateContext, LateLintPass, LintContext};
@ -339,24 +339,18 @@ fn lint_int_literal<'tcx>(
return; return;
} }
cx.emit_spanned_lint( let lit = cx
OVERFLOWING_LITERALS,
e.span,
OverflowingInt {
ty: t.name_str(),
lit: cx
.sess() .sess()
.source_map() .source_map()
.span_to_snippet(lit.span) .span_to_snippet(lit.span)
.expect("must get snippet from literal"), .expect("must get snippet from literal");
min, let help = get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative)
max, .map(|suggestion_ty| OverflowingIntHelp { suggestion_ty });
suggestion_ty: get_type_suggestion(
cx.typeck_results().node_type(e.hir_id), cx.emit_spanned_lint(
v, OVERFLOWING_LITERALS,
negative, e.span,
), OverflowingInt { ty: t.name_str(), lit, min, max, help },
},
); );
} }
} }