From ff8faebd96a1607bff9e5947c7e2f23daaa9d791 Mon Sep 17 00:00:00 2001 From: jyn Date: Sun, 26 Apr 2026 16:07:28 +0000 Subject: [PATCH] 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. --- compiler/rustc_lint_defs/src/builtin.rs | 5 ++++ compiler/rustc_lint_defs/src/lib.rs | 4 +++ compiler/rustc_middle/src/lint.rs | 34 +++++++++++++++++-------- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index b027872dd99c..0d15a24b1242 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -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! { diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 8cbd2456fccd..f249f5310e62 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -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, } } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index c42783fc77e3..7ea059c5d29d 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -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;