1
Fork 0

Remove LintExpectationId from Level variants

This commit is contained in:
Oli Scherer 2025-03-19 08:59:19 +00:00
parent c51816ee59
commit 805f389da5
15 changed files with 124 additions and 123 deletions

View file

@ -17,13 +17,12 @@ use rustc_hir::def_id::{CrateNum, DefId};
use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
use rustc_hir::{Pat, PatKind};
use rustc_middle::bug;
use rustc_middle::lint::LevelAndSource;
use rustc_middle::middle::privacy::EffectiveVisibilities;
use rustc_middle::ty::layout::{LayoutError, LayoutOfHelpers, TyAndLayout};
use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, Printer, with_no_trimmed_paths};
use rustc_middle::ty::{self, GenericArg, RegisteredTools, Ty, TyCtxt, TypingEnv, TypingMode};
use rustc_session::lint::{
FutureIncompatibleInfo, Level, Lint, LintBuffer, LintExpectationId, LintId,
};
use rustc_session::lint::{FutureIncompatibleInfo, Lint, LintBuffer, LintExpectationId, LintId};
use rustc_session::{LintStoreMarker, Session};
use rustc_span::edit_distance::find_best_match_for_names;
use rustc_span::{Ident, Span, Symbol, sym};
@ -573,7 +572,7 @@ pub trait LintContext {
}
/// This returns the lint level for the given lint at the current location.
fn get_lint_level(&self, lint: &'static Lint) -> Level;
fn get_lint_level(&self, lint: &'static Lint) -> LevelAndSource;
/// This function can be used to manually fulfill an expectation. This can
/// be used for lints which contain several spans, and should be suppressed,
@ -642,8 +641,8 @@ impl<'tcx> LintContext for LateContext<'tcx> {
}
}
fn get_lint_level(&self, lint: &'static Lint) -> Level {
self.tcx.lint_level_at_node(lint, self.last_node_with_lint_attrs).level
fn get_lint_level(&self, lint: &'static Lint) -> LevelAndSource {
self.tcx.lint_level_at_node(lint, self.last_node_with_lint_attrs)
}
}
@ -663,8 +662,8 @@ impl LintContext for EarlyContext<'_> {
self.builder.opt_span_lint(lint, span.map(|s| s.into()), decorate)
}
fn get_lint_level(&self, lint: &'static Lint) -> Level {
self.builder.lint_level(lint).level
fn get_lint_level(&self, lint: &'static Lint) -> LevelAndSource {
self.builder.lint_level(lint)
}
}

View file

@ -84,10 +84,10 @@ impl LintLevelSets {
) -> LevelAndSource {
let lint = LintId::of(lint);
let (level, mut src) = self.raw_lint_id_level(lint, idx, aux);
let level = reveal_actual_level(level, &mut src, sess, lint, |id| {
let (level, lint_id) = reveal_actual_level(level, &mut src, sess, lint, |id| {
self.raw_lint_id_level(id, idx, aux)
});
LevelAndSource { level, src }
LevelAndSource { level, lint_id, src }
}
fn raw_lint_id_level(
@ -95,17 +95,17 @@ impl LintLevelSets {
id: LintId,
mut idx: LintStackIndex,
aux: Option<&FxIndexMap<LintId, LevelAndSource>>,
) -> (Option<Level>, LintLevelSource) {
) -> (Option<(Level, Option<LintExpectationId>)>, LintLevelSource) {
if let Some(specs) = aux
&& let Some(&LevelAndSource { level, src }) = specs.get(&id)
&& let Some(&LevelAndSource { level, lint_id, src }) = specs.get(&id)
{
return (Some(level), src);
return (Some((level, lint_id)), src);
}
loop {
let LintSet { ref specs, parent } = self.list[idx];
if let Some(&LevelAndSource { level, src }) = specs.get(&id) {
return (Some(level), src);
if let Some(&LevelAndSource { level, lint_id, src }) = specs.get(&id) {
return (Some((level, lint_id)), src);
}
if idx == COMMAND_LINE {
return (None, LintLevelSource::Default);
@ -379,13 +379,7 @@ impl<'tcx> Visitor<'tcx> for LintLevelMaximum<'tcx> {
fn visit_attribute(&mut self, attribute: &'tcx hir::Attribute) {
if matches!(
Level::from_attr(attribute),
Some(
Level::Warn
| Level::Deny
| Level::Forbid
| Level::Expect(..)
| Level::ForceWarn(..),
)
Some((Level::Warn | Level::Deny | Level::Forbid | Level::Expect | Level::ForceWarn, _))
) {
let store = unerased_lint_store(self.tcx.sess);
// Lint attributes are always a metalist inside a
@ -541,9 +535,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
for &(ref lint_name, level) in &self.sess.opts.lint_opts {
// Checks the validity of lint names derived from the command line.
let (tool_name, lint_name_only) = parse_lint_and_tool_name(lint_name);
if lint_name_only == crate::WARNINGS.name_lower()
&& matches!(level, Level::ForceWarn(_))
{
if lint_name_only == crate::WARNINGS.name_lower() && matches!(level, Level::ForceWarn) {
self.sess
.dcx()
.emit_err(UnsupportedGroup { lint_group: crate::WARNINGS.name_lower() });
@ -586,7 +578,6 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
_ => {}
};
let orig_level = level;
let lint_flag_val = Symbol::intern(lint_name);
let Ok(ids) = self.store.find_lints(lint_name) else {
@ -595,15 +586,15 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
};
for id in ids {
// ForceWarn and Forbid cannot be overridden
if let Some(LevelAndSource { level: Level::ForceWarn(_) | Level::Forbid, .. }) =
if let Some(LevelAndSource { level: Level::ForceWarn | Level::Forbid, .. }) =
self.current_specs().get(&id)
{
continue;
}
if self.check_gated_lint(id, DUMMY_SP, true) {
let src = LintLevelSource::CommandLine(lint_flag_val, orig_level);
self.insert(id, LevelAndSource { level, src });
let src = LintLevelSource::CommandLine(lint_flag_val, level);
self.insert(id, LevelAndSource { level, lint_id: None, src });
}
}
}
@ -612,8 +603,8 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
/// Attempts to insert the `id` to `level_src` map entry. If unsuccessful
/// (e.g. if a forbid was already inserted on the same scope), then emits a
/// diagnostic with no change to `specs`.
fn insert_spec(&mut self, id: LintId, LevelAndSource { level, src }: LevelAndSource) {
let LevelAndSource { level: old_level, src: old_src } =
fn insert_spec(&mut self, id: LintId, LevelAndSource { level, lint_id, src }: LevelAndSource) {
let LevelAndSource { level: old_level, src: old_src, .. } =
self.provider.get_lint_level(id.lint, self.sess);
// Setting to a non-forbid level is an error if the lint previously had
@ -686,7 +677,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
// The lint `unfulfilled_lint_expectations` can't be expected, as it would suppress itself.
// Handling expectations of this lint would add additional complexity with little to no
// benefit. The expect level for this lint will therefore be ignored.
if let Level::Expect(_) = level
if let Level::Expect = level
&& id == LintId::of(UNFULFILLED_LINT_EXPECTATIONS)
{
return;
@ -694,16 +685,16 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
match (old_level, level) {
// If the new level is an expectation store it in `ForceWarn`
(Level::ForceWarn(_), Level::Expect(expectation_id)) => self.insert(
id,
LevelAndSource { level: Level::ForceWarn(Some(expectation_id)), src: old_src },
),
// Keep `ForceWarn` level but drop the expectation
(Level::ForceWarn(_), _) => {
self.insert(id, LevelAndSource { level: Level::ForceWarn(None), src: old_src })
(Level::ForceWarn, Level::Expect) => {
self.insert(id, LevelAndSource { level: Level::ForceWarn, lint_id, src: old_src })
}
// Keep `ForceWarn` level but drop the expectation
(Level::ForceWarn, _) => self.insert(
id,
LevelAndSource { level: Level::ForceWarn, lint_id: None, src: old_src },
),
// Set the lint level as normal
_ => self.insert(id, LevelAndSource { level, src }),
_ => self.insert(id, LevelAndSource { level, lint_id, src }),
};
}
@ -718,7 +709,11 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
if attr.has_name(sym::automatically_derived) {
self.insert(
LintId::of(SINGLE_USE_LIFETIMES),
LevelAndSource { level: Level::Allow, src: LintLevelSource::Default },
LevelAndSource {
level: Level::Allow,
lint_id: None,
src: LintLevelSource::Default,
},
);
continue;
}
@ -731,16 +726,20 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
{
self.insert(
LintId::of(MISSING_DOCS),
LevelAndSource { level: Level::Allow, src: LintLevelSource::Default },
LevelAndSource {
level: Level::Allow,
lint_id: None,
src: LintLevelSource::Default,
},
);
continue;
}
let level = match Level::from_attr(attr) {
let (level, lint_id) = match Level::from_attr(attr) {
None => continue,
// This is the only lint level with a `LintExpectationId` that can be created from
// an attribute.
Some(Level::Expect(unstable_id)) if let Some(hir_id) = source_hir_id => {
Some((Level::Expect, Some(unstable_id))) if let Some(hir_id) = source_hir_id => {
let LintExpectationId::Unstable { lint_index: None, attr_id: _ } = unstable_id
else {
bug!("stable id Level::from_attr")
@ -752,9 +751,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
lint_index: None,
};
Level::Expect(stable_id)
(Level::Expect, Some(stable_id))
}
Some(lvl) => lvl,
Some((lvl, id)) => (lvl, id),
};
let Some(mut metas) = attr.meta_item_list() else { continue };
@ -802,13 +801,10 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
}
for (lint_index, li) in metas.iter_mut().enumerate() {
let level = match level {
Level::Expect(mut id) => {
id.set_lint_index(Some(lint_index as u16));
Level::Expect(id)
}
level => level,
};
let mut lint_id = lint_id;
if let Some(id) = &mut lint_id {
id.set_lint_index(Some(lint_index as u16));
}
let sp = li.span();
let meta_item = match li {
@ -940,7 +936,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
let src = LintLevelSource::Node { name, span: sp, reason };
for &id in ids {
if self.check_gated_lint(id, sp, false) {
self.insert_spec(id, LevelAndSource { level, src });
self.insert_spec(id, LevelAndSource { level, lint_id, src });
}
}
@ -949,7 +945,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
// overriding the lint level but instead add an expectation that can't be
// fulfilled. The lint message will include an explanation, that the
// `unfulfilled_lint_expectations` lint can't be expected.
if let Level::Expect(expect_id) = level {
if let (Level::Expect, Some(expect_id)) = (level, lint_id) {
// The `unfulfilled_lint_expectations` lint is not part of any lint
// groups. Therefore. we only need to check the slice if it contains a
// single lint.
@ -971,7 +967,7 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
}
if self.lint_added_lints && !is_crate_node {
for (id, &LevelAndSource { level, ref src }) in self.current_specs().iter() {
for (id, &LevelAndSource { level, ref src, .. }) in self.current_specs().iter() {
if !id.lint.crate_level_only {
continue;
}