Add an ignore_deny_warnings field to lints

Previously this was just hard-coded for `FORBIDDEN_LINT_GROUPS`.
Allow it to be used for other lints.
This commit is contained in:
jyn
2026-04-26 16:07:28 +00:00
parent c7fe5e9d1e
commit ff8faebd96
3 changed files with 33 additions and 10 deletions
+5
View File
@@ -193,6 +193,11 @@
reason: fcw!(FutureReleaseError #81670),
report_in_deps: true,
};
// We exempt `FORBIDDEN_LINT_GROUPS` from `-Dwarnings` because it specifically
// triggers in cases (like #80988) where you have `forbid(warnings)`,
// and so if we turned that into an error, it'd defeat the purpose of the
// future compatibility warning.
ignore_deny_warnings
}
declare_lint! {
+4
View File
@@ -352,6 +352,9 @@ pub struct Lint {
/// `true` if this lint should not be filtered out under any circustamces
/// (e.g. the unknown_attributes lint)
pub eval_always: bool,
/// `true` if this lint is unaffected by `-D warnings`
pub ignore_deny_warnings: bool,
}
/// Extra information for a future incompatibility lint.
@@ -567,6 +570,7 @@ pub const fn default_fields_for_macro() -> Self {
feature_gate: None,
crate_level_only: false,
eval_always: false,
ignore_deny_warnings: false,
}
}
+24 -10
View File
@@ -7,8 +7,9 @@
use rustc_lint_defs::EditionFcw;
use rustc_macros::{Decodable, Encodable, HashStable};
use rustc_session::Session;
use rustc_session::lint::builtin::{self, FORBIDDEN_LINT_GROUPS};
use rustc_session::lint::{FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId};
use rustc_session::lint::{
FutureIncompatibilityReason, Level, Lint, LintExpectationId, LintId, builtin,
};
use rustc_span::{DUMMY_SP, ExpnKind, Span, Symbol, kw};
use tracing::instrument;
@@ -89,17 +90,30 @@ pub fn reveal_actual_level(
level.unwrap_or_else(|| (lint.lint.default_level(sess.edition()), None));
// If we're about to issue a warning, check at the last minute for any
// directives against the warnings "lint". If, for example, there's an
// directives against the `warnings` lint group. If, for example, there's an
// `allow(warnings)` in scope then we want to respect that instead.
//
// We exempt `FORBIDDEN_LINT_GROUPS` from this because it specifically
// triggers in cases (like #80988) where you have `forbid(warnings)`,
// and so if we turned that into an error, it'd defeat the purpose of the
// future compatibility warning.
if level == Level::Warn && lint != LintId::of(FORBIDDEN_LINT_GROUPS) {
if level == Level::Warn {
let (warnings_level, warnings_src) = probe_for_lint_level(LintId::of(builtin::WARNINGS));
if let Some((configured_warning_level, configured_lint_id)) = warnings_level {
if configured_warning_level != Level::Warn {
let respect_warnings_lint_group = match configured_warning_level {
// -Wwarnings is a no-op.
Level::Warn => false,
// Some warnings cannot be denied from the `warnings` lint group, only individually.
Level::Deny | Level::Forbid => !lint.lint.ignore_deny_warnings,
// All warnings respect -Awarnings.
Level::Allow => true,
// Not sure what the right behavior is here, but, sure, why not.
// See tests/ui/lint/rfc-2383-lint-reason/expect_warnings.rs.
Level::Expect => true,
Level::ForceWarn => {
sess.dcx().span_delayed_bug(
warnings_src.span(),
"cannot --force-warn the `warnings` lint group",
);
false
}
};
if respect_warnings_lint_group {
level = configured_warning_level;
lint_id = configured_lint_id;
*src = warnings_src;