From 9de0b2dd659a885789a142fc31043db6ba127d15 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 13 May 2026 16:57:02 +1000 Subject: [PATCH 1/4] Improve `reveal_actual_level` `reveal_actual_level` has two call sites, which look like this: ``` let (level, mut src) = self.raw_lint_id_level(lint, idx, aux); let (level, lint_id) = reveal_actual_level(level, &mut src, sess, lint, |id| { self.raw_lint_id_level(id, idx, aux) }); ``` and: ``` let (level, mut src) = self.probe_for_lint_level(tcx, lint, cur); let (level, lint_id) = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| { self.probe_for_lint_level(tcx, lint, cur) }); ``` They both have the same pattern: there's a prior call expression that is then repeated within a closure passed to `reveal_actual_level`. This commit moves that prior call inside `reveal_actual_level`, making things simpler. --- compiler/rustc_lint/src/levels.rs | 6 ++---- compiler/rustc_middle/src/lint.rs | 24 ++++++++++-------------- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 8f68f6b8abf40..c0526b9ff6696 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -84,10 +84,8 @@ impl LintLevelSets { sess: &Session, ) -> LevelAndSource { let lint = LintId::of(lint); - let (level, mut src) = self.raw_lint_id_level(lint, idx, aux); - let (level, lint_id) = reveal_actual_level(level, &mut src, sess, lint, |id| { - self.raw_lint_id_level(id, idx, aux) - }); + let (level, lint_id, src) = + reveal_actual_level(sess, lint, |id| self.raw_lint_id_level(id, idx, aux)); LevelAndSource { level, lint_id, src } } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index bb293f0268996..0130b1b913e79 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -71,20 +71,18 @@ pub struct ShallowLintLevelMap { pub specs: SortedMap>, } -/// From an initial level and source, verify the effect of special annotations: -/// `warnings` lint level and lint caps. +/// Verify the effect of special annotations: `warnings` lint level and lint caps. /// /// The return of this function is suitable for diagnostics. pub fn reveal_actual_level( - level: Option<(Level, Option)>, - src: &mut LintLevelSource, sess: &Session, lint: LintId, - probe_for_lint_level: impl FnOnce( + probe_for_lint_level: impl Fn( LintId, - ) - -> (Option<(Level, Option)>, LintLevelSource), -) -> (Level, Option) { + ) -> (Option<(Level, Option)>, LintLevelSource), +) -> (Level, Option, LintLevelSource) { + let (level, mut src) = probe_for_lint_level(lint); + // If `level` is none then we actually assume the default level for this lint. let (mut level, mut lint_id) = level.unwrap_or_else(|| (lint.lint.default_level(sess.edition()), None)); @@ -116,7 +114,7 @@ pub fn reveal_actual_level( if respect_warnings_lint_group { level = configured_warning_level; lint_id = configured_lint_id; - *src = warnings_src; + src = warnings_src; } } } @@ -133,7 +131,7 @@ pub fn reveal_actual_level( level = cmp::min(*driver_level, level); } - (level, lint_id) + (level, lint_id, src) } impl ShallowLintLevelMap { @@ -179,10 +177,8 @@ impl ShallowLintLevelMap { lint: LintId, cur: HirId, ) -> LevelAndSource { - let (level, mut src) = self.probe_for_lint_level(tcx, lint, cur); - let (level, lint_id) = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| { - self.probe_for_lint_level(tcx, lint, cur) - }); + let (level, lint_id, src) = + reveal_actual_level(tcx.sess, lint, |lint| self.probe_for_lint_level(tcx, lint, cur)); LevelAndSource { level, lint_id, src } } } From 202e86102cbe1683323959cabd9abf7fbbc1a386 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 13 May 2026 18:01:27 +1000 Subject: [PATCH 2/4] Change `reveal_actual_level` return type It currently returns a triple: `(Level, Option, LintLevelSource)`. That's structurally identical to `LevelAndSource`, so this commit changes it accordingly. --- compiler/rustc_lint/src/levels.rs | 5 +---- compiler/rustc_middle/src/lint.rs | 8 +++----- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index c0526b9ff6696..cdb8e94a1ed8f 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -83,10 +83,7 @@ impl LintLevelSets { aux: Option<&FxIndexMap>, sess: &Session, ) -> LevelAndSource { - let lint = LintId::of(lint); - let (level, lint_id, src) = - reveal_actual_level(sess, lint, |id| self.raw_lint_id_level(id, idx, aux)); - LevelAndSource { level, lint_id, src } + reveal_actual_level(sess, LintId::of(lint), |id| self.raw_lint_id_level(id, idx, aux)) } fn raw_lint_id_level( diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 0130b1b913e79..46d83775ce548 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -80,7 +80,7 @@ pub fn reveal_actual_level( probe_for_lint_level: impl Fn( LintId, ) -> (Option<(Level, Option)>, LintLevelSource), -) -> (Level, Option, LintLevelSource) { +) -> LevelAndSource { let (level, mut src) = probe_for_lint_level(lint); // If `level` is none then we actually assume the default level for this lint. @@ -131,7 +131,7 @@ pub fn reveal_actual_level( level = cmp::min(*driver_level, level); } - (level, lint_id, src) + LevelAndSource { level, lint_id, src } } impl ShallowLintLevelMap { @@ -177,9 +177,7 @@ impl ShallowLintLevelMap { lint: LintId, cur: HirId, ) -> LevelAndSource { - let (level, lint_id, src) = - reveal_actual_level(tcx.sess, lint, |lint| self.probe_for_lint_level(tcx, lint, cur)); - LevelAndSource { level, lint_id, src } + reveal_actual_level(tcx.sess, lint, |lint| self.probe_for_lint_level(tcx, lint, cur)) } } From 7cd42a77fb8eca581d9755596d8a9e05bca4e47c Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 13 May 2026 18:08:43 +1000 Subject: [PATCH 3/4] Change `reveal_actual_level`'s closure's return type It's currrently `(Option<(Level, Option)>, LintLevelSource)`. But when the first element of the pair is `None` the second element is always `LintLevelSource::Default`. So this commit moves the `LintLevelSource` within the `Option`, which simplifies things a bit. --- compiler/rustc_lint/src/levels.rs | 8 ++++---- compiler/rustc_middle/src/lint.rs | 28 ++++++++++++++-------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index cdb8e94a1ed8f..10d5e1ff53a30 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -91,20 +91,20 @@ impl LintLevelSets { id: LintId, mut idx: LintStackIndex, aux: Option<&FxIndexMap>, - ) -> (Option<(Level, Option)>, LintLevelSource) { + ) -> Option<(Level, Option, LintLevelSource)> { if let Some(specs) = aux && let Some(&LevelAndSource { level, lint_id, src }) = specs.get(&id) { - return (Some((level, lint_id)), src); + return Some((level, lint_id, src)); } loop { let LintSet { ref specs, parent } = self.list[idx]; if let Some(&LevelAndSource { level, lint_id, src }) = specs.get(&id) { - return (Some((level, lint_id)), src); + return Some((level, lint_id, src)); } if idx == COMMAND_LINE { - return (None, LintLevelSource::Default); + return None; } idx = parent; } diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 46d83775ce548..82f56b090345e 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -77,22 +77,22 @@ pub struct ShallowLintLevelMap { pub fn reveal_actual_level( sess: &Session, lint: LintId, - probe_for_lint_level: impl Fn( - LintId, - ) -> (Option<(Level, Option)>, LintLevelSource), + probe_for_lint_level: impl Fn(LintId) -> Option<(Level, Option, LintLevelSource)>, ) -> LevelAndSource { - let (level, mut src) = probe_for_lint_level(lint); + let level = probe_for_lint_level(lint); // If `level` is none then we actually assume the default level for this lint. - let (mut level, mut lint_id) = - level.unwrap_or_else(|| (lint.lint.default_level(sess.edition()), None)); + let (mut level, mut lint_id, mut src) = level.unwrap_or_else(|| { + (lint.lint.default_level(sess.edition()), None, LintLevelSource::Default) + }); // If we're about to issue a warning, check at the last minute for any // directives against the `warnings` lint group. If, for example, there's an // `allow(warnings)` in scope then we want to respect that instead. 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 { + let warnings_level = probe_for_lint_level(LintId::of(builtin::WARNINGS)); + if let Some((configured_warning_level, configured_lint_id, configured_src)) = warnings_level + { let respect_warnings_lint_group = match configured_warning_level { // -Wwarnings is a no-op. Level::Warn => false, @@ -105,7 +105,7 @@ pub fn reveal_actual_level( Level::Expect => true, Level::ForceWarn => { sess.dcx().span_delayed_bug( - warnings_src.span(), + configured_src.span(), "cannot --force-warn the `warnings` lint group", ); false @@ -114,7 +114,7 @@ pub fn reveal_actual_level( if respect_warnings_lint_group { level = configured_warning_level; lint_id = configured_lint_id; - src = warnings_src; + src = configured_src; } } } @@ -144,11 +144,11 @@ impl ShallowLintLevelMap { tcx: TyCtxt<'_>, id: LintId, start: HirId, - ) -> (Option<(Level, Option)>, LintLevelSource) { + ) -> Option<(Level, Option, LintLevelSource)> { if let Some(map) = self.specs.get(&start.local_id) && let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id) { - return (Some((level, lint_id)), src); + return Some((level, lint_id, src)); } let mut owner = start.owner; @@ -162,11 +162,11 @@ impl ShallowLintLevelMap { if let Some(map) = specs.get(&parent.local_id) && let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id) { - return (Some((level, lint_id)), src); + return Some((level, lint_id, src)); } } - (None, LintLevelSource::Default) + None } /// Fetch and return the user-visible lint level for the given lint at the given HirId. From b86ef8908276271181602e293ac0b9bec8368ba7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Wed, 13 May 2026 18:14:21 +1000 Subject: [PATCH 4/4] Change `reveal_actual_level`'s closure's return type, again Again, the returned triple is equivalent to `LevelAndSource`. --- compiler/rustc_lint/src/levels.rs | 10 ++++---- compiler/rustc_middle/src/lint.rs | 42 +++++++++++++++---------------- 2 files changed, 25 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_lint/src/levels.rs b/compiler/rustc_lint/src/levels.rs index 10d5e1ff53a30..a5fe6bdfe6c5d 100644 --- a/compiler/rustc_lint/src/levels.rs +++ b/compiler/rustc_lint/src/levels.rs @@ -91,17 +91,17 @@ impl LintLevelSets { id: LintId, mut idx: LintStackIndex, aux: Option<&FxIndexMap>, - ) -> Option<(Level, Option, LintLevelSource)> { + ) -> Option { if let Some(specs) = aux - && let Some(&LevelAndSource { level, lint_id, src }) = specs.get(&id) + && let Some(level) = specs.get(&id) { - return Some((level, lint_id, src)); + return Some(*level); } loop { let LintSet { ref specs, parent } = self.list[idx]; - if let Some(&LevelAndSource { level, lint_id, src }) = specs.get(&id) { - return Some((level, lint_id, src)); + if let Some(level) = specs.get(&id) { + return Some(*level); } if idx == COMMAND_LINE { return None; diff --git a/compiler/rustc_middle/src/lint.rs b/compiler/rustc_middle/src/lint.rs index 82f56b090345e..a05d24cdabadb 100644 --- a/compiler/rustc_middle/src/lint.rs +++ b/compiler/rustc_middle/src/lint.rs @@ -77,23 +77,23 @@ pub struct ShallowLintLevelMap { pub fn reveal_actual_level( sess: &Session, lint: LintId, - probe_for_lint_level: impl Fn(LintId) -> Option<(Level, Option, LintLevelSource)>, + probe_for_lint_level: impl Fn(LintId) -> Option, ) -> LevelAndSource { let level = probe_for_lint_level(lint); // If `level` is none then we actually assume the default level for this lint. - let (mut level, mut lint_id, mut src) = level.unwrap_or_else(|| { - (lint.lint.default_level(sess.edition()), None, LintLevelSource::Default) + let mut level = level.unwrap_or_else(|| LevelAndSource { + level: lint.lint.default_level(sess.edition()), + lint_id: None, + src: LintLevelSource::Default, }); // If we're about to issue a warning, check at the last minute for any // directives against the `warnings` lint group. If, for example, there's an // `allow(warnings)` in scope then we want to respect that instead. - if level == Level::Warn { - let warnings_level = probe_for_lint_level(LintId::of(builtin::WARNINGS)); - if let Some((configured_warning_level, configured_lint_id, configured_src)) = warnings_level - { - let respect_warnings_lint_group = match configured_warning_level { + if level.level == Level::Warn { + if let Some(configured_level) = probe_for_lint_level(LintId::of(builtin::WARNINGS)) { + let respect_warnings_lint_group = match configured_level.level { // -Wwarnings is a no-op. Level::Warn => false, // Some warnings cannot be denied from the `warnings` lint group, only individually. @@ -105,33 +105,31 @@ pub fn reveal_actual_level( Level::Expect => true, Level::ForceWarn => { sess.dcx().span_delayed_bug( - configured_src.span(), + configured_level.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 = configured_src; + level = configured_level; } } } // Ensure that we never exceed the `--cap-lints` argument unless the source is a --force-warn - level = if let LintLevelSource::CommandLine(_, Level::ForceWarn) = src { - level + level.level = if let LintLevelSource::CommandLine(_, Level::ForceWarn) = level.src { + level.level } else { - cmp::min(level, sess.opts.lint_cap.unwrap_or(Level::Forbid)) + cmp::min(level.level, sess.opts.lint_cap.unwrap_or(Level::Forbid)) }; if let Some(driver_level) = sess.driver_lint_caps.get(&lint) { // Ensure that we never exceed driver level. - level = cmp::min(*driver_level, level); + level.level = cmp::min(level.level, *driver_level); } - LevelAndSource { level, lint_id, src } + level } impl ShallowLintLevelMap { @@ -144,11 +142,11 @@ impl ShallowLintLevelMap { tcx: TyCtxt<'_>, id: LintId, start: HirId, - ) -> Option<(Level, Option, LintLevelSource)> { + ) -> Option { if let Some(map) = self.specs.get(&start.local_id) - && let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id) + && let Some(level) = map.get(&id) { - return Some((level, lint_id, src)); + return Some(*level); } let mut owner = start.owner; @@ -160,9 +158,9 @@ impl ShallowLintLevelMap { specs = &tcx.shallow_lint_levels_on(owner).specs; } if let Some(map) = specs.get(&parent.local_id) - && let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id) + && let Some(level) = map.get(&id) { - return Some((level, lint_id, src)); + return Some(*level); } }