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

@ -715,7 +715,7 @@ fn print_crate_info(
// lint is unstable and feature gate isn't active, don't print
continue;
}
let level = lint_levels.lint_level(lint).0;
let level = lint_levels.lint_level(lint).level;
println_info!("{}={}", lint.name_lower(), level.as_str());
}
}

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) => {
let mut lint_id = lint_id;
if let Some(id) = &mut lint_id {
id.set_lint_index(Some(lint_index as u16));
Level::Expect(id)
}
level => level,
};
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;
}

View file

@ -199,9 +199,9 @@ pub enum Level {
///
/// See RFC 2383.
///
/// The [`LintExpectationId`] is used to later link a lint emission to the actual
/// Requires a [`LintExpectationId`] to later link a lint emission to the actual
/// expectation. It can be ignored in most cases.
Expect(LintExpectationId),
Expect,
/// The `warn` level will produce a warning if the lint was violated, however the
/// compiler will continue with its execution.
Warn,
@ -209,9 +209,9 @@ pub enum Level {
/// to ensure that a lint can't be suppressed. This lint level can currently only be set
/// via the console and is therefore session specific.
///
/// The [`LintExpectationId`] is intended to fulfill expectations marked via the
/// Requires a [`LintExpectationId`] to fulfill expectations marked via the
/// `#[expect]` attribute, that will still be suppressed due to the level.
ForceWarn(Option<LintExpectationId>),
ForceWarn,
/// The `deny` level will produce an error and stop further execution after the lint
/// pass is complete.
Deny,
@ -225,9 +225,9 @@ impl Level {
pub fn as_str(self) -> &'static str {
match self {
Level::Allow => "allow",
Level::Expect(_) => "expect",
Level::Expect => "expect",
Level::Warn => "warn",
Level::ForceWarn(_) => "force-warn",
Level::ForceWarn => "force-warn",
Level::Deny => "deny",
Level::Forbid => "forbid",
}
@ -246,24 +246,30 @@ impl Level {
}
/// Converts an `Attribute` to a level.
pub fn from_attr(attr: &impl AttributeExt) -> Option<Self> {
pub fn from_attr(attr: &impl AttributeExt) -> Option<(Self, Option<LintExpectationId>)> {
Self::from_symbol(attr.name_or_empty(), || Some(attr.id()))
}
/// Converts a `Symbol` to a level.
pub fn from_symbol(s: Symbol, id: impl FnOnce() -> Option<AttrId>) -> Option<Self> {
pub fn from_symbol(
s: Symbol,
id: impl FnOnce() -> Option<AttrId>,
) -> Option<(Self, Option<LintExpectationId>)> {
match s {
sym::allow => Some(Level::Allow),
sym::allow => Some((Level::Allow, None)),
sym::expect => {
if let Some(attr_id) = id() {
Some(Level::Expect(LintExpectationId::Unstable { attr_id, lint_index: None }))
Some((
Level::Expect,
Some(LintExpectationId::Unstable { attr_id, lint_index: None }),
))
} else {
None
}
}
sym::warn => Some(Level::Warn),
sym::deny => Some(Level::Deny),
sym::forbid => Some(Level::Forbid),
sym::warn => Some((Level::Warn, None)),
sym::deny => Some((Level::Deny, None)),
sym::forbid => Some((Level::Forbid, None)),
_ => None,
}
}
@ -274,8 +280,8 @@ impl Level {
Level::Deny => "-D",
Level::Forbid => "-F",
Level::Allow => "-A",
Level::ForceWarn(_) => "--force-warn",
Level::Expect(_) => {
Level::ForceWarn => "--force-warn",
Level::Expect => {
unreachable!("the expect level does not have a commandline flag")
}
}
@ -283,17 +289,10 @@ impl Level {
pub fn is_error(self) -> bool {
match self {
Level::Allow | Level::Expect(_) | Level::Warn | Level::ForceWarn(_) => false,
Level::Allow | Level::Expect | Level::Warn | Level::ForceWarn => false,
Level::Deny | Level::Forbid => true,
}
}
pub fn get_expectation_id(&self) -> Option<LintExpectationId> {
match self {
Level::Expect(id) | Level::ForceWarn(Some(id)) => Some(*id),
_ => None,
}
}
}
/// Specification of a single lint.

View file

@ -55,6 +55,7 @@ impl LintLevelSource {
#[derive(Copy, Clone, Debug, HashStable, Encodable, Decodable)]
pub struct LevelAndSource {
pub level: Level,
pub lint_id: Option<LintExpectationId>,
pub src: LintLevelSource,
}
@ -73,14 +74,18 @@ pub struct ShallowLintLevelMap {
///
/// The return of this function is suitable for diagnostics.
pub fn reveal_actual_level(
level: Option<Level>,
level: Option<(Level, Option<LintExpectationId>)>,
src: &mut LintLevelSource,
sess: &Session,
lint: LintId,
probe_for_lint_level: impl FnOnce(LintId) -> (Option<Level>, LintLevelSource),
) -> Level {
probe_for_lint_level: impl FnOnce(
LintId,
)
-> (Option<(Level, Option<LintExpectationId>)>, LintLevelSource),
) -> (Level, Option<LintExpectationId>) {
// If `level` is none then we actually assume the default level for this lint.
let mut level = level.unwrap_or_else(|| lint.lint.default_level(sess.edition()));
let (mut level, mut lint_id) =
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
@ -92,16 +97,17 @@ pub fn reveal_actual_level(
// future compatibility warning.
if level == Level::Warn && lint != LintId::of(FORBIDDEN_LINT_GROUPS) {
let (warnings_level, warnings_src) = probe_for_lint_level(LintId::of(builtin::WARNINGS));
if let Some(configured_warning_level) = warnings_level {
if let Some((configured_warning_level, configured_lint_id)) = warnings_level {
if configured_warning_level != Level::Warn {
level = configured_warning_level;
lint_id = configured_lint_id;
*src = warnings_src;
}
}
}
// 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 = if let LintLevelSource::CommandLine(_, Level::ForceWarn) = src {
level
} else {
cmp::min(level, sess.opts.lint_cap.unwrap_or(Level::Forbid))
@ -112,7 +118,7 @@ pub fn reveal_actual_level(
level = cmp::min(*driver_level, level);
}
level
(level, lint_id)
}
impl ShallowLintLevelMap {
@ -125,11 +131,11 @@ impl ShallowLintLevelMap {
tcx: TyCtxt<'_>,
id: LintId,
start: HirId,
) -> (Option<Level>, LintLevelSource) {
) -> (Option<(Level, Option<LintExpectationId>)>, LintLevelSource) {
if let Some(map) = self.specs.get(&start.local_id)
&& let Some(&LevelAndSource { level, src }) = map.get(&id)
&& let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id)
{
return (Some(level), src);
return (Some((level, lint_id)), src);
}
let mut owner = start.owner;
@ -141,9 +147,9 @@ impl ShallowLintLevelMap {
specs = &tcx.shallow_lint_levels_on(owner).specs;
}
if let Some(map) = specs.get(&parent.local_id)
&& let Some(&LevelAndSource { level, src }) = map.get(&id)
&& let Some(&LevelAndSource { level, lint_id, src }) = map.get(&id)
{
return (Some(level), src);
return (Some((level, lint_id)), src);
}
}
@ -159,10 +165,10 @@ impl ShallowLintLevelMap {
cur: HirId,
) -> LevelAndSource {
let (level, mut src) = self.probe_for_lint_level(tcx, lint, cur);
let level = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| {
let (level, lint_id) = reveal_actual_level(level, &mut src, tcx.sess, lint, |lint| {
self.probe_for_lint_level(tcx, lint, cur)
});
LevelAndSource { level, src }
LevelAndSource { level, lint_id, src }
}
}
@ -285,7 +291,7 @@ pub fn lint_level(
span: Option<MultiSpan>,
decorate: Box<dyn '_ + for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>)>,
) {
let LevelAndSource { level, src } = level;
let LevelAndSource { level, lint_id, src } = level;
// Check for future incompatibility lints and issue a stronger warning.
let future_incompatible = lint.future_incompatible;
@ -297,15 +303,15 @@ pub fn lint_level(
);
// Convert lint level to error level.
let (err_level, lint_id) = match level {
let err_level = match level {
Level::Allow => {
if has_future_breakage {
(rustc_errors::Level::Allow, None)
rustc_errors::Level::Allow
} else {
return;
}
}
Level::Expect(expect_id) => {
Level::Expect => {
// This case is special as we actually allow the lint itself in this context, but
// we can't return early like in the case for `Level::Allow` because we still
// need the lint diagnostic to be emitted to `rustc_error::DiagCtxtInner`.
@ -313,11 +319,11 @@ pub fn lint_level(
// We can also not mark the lint expectation as fulfilled here right away, as it
// can still be cancelled in the decorate function. All of this means that we simply
// create a `Diag` and continue as we would for warnings.
(rustc_errors::Level::Expect, Some(expect_id))
rustc_errors::Level::Expect
}
Level::ForceWarn(expect_id) => (rustc_errors::Level::ForceWarning, expect_id),
Level::Warn => (rustc_errors::Level::Warning, None),
Level::Deny | Level::Forbid => (rustc_errors::Level::Error, None),
Level::ForceWarn => rustc_errors::Level::ForceWarning,
Level::Warn => rustc_errors::Level::Warning,
Level::Deny | Level::Forbid => rustc_errors::Level::Error,
};
let mut err = Diag::new(sess.dcx(), err_level, "");
if let Some(span) = span {
@ -356,7 +362,7 @@ pub fn lint_level(
// the compiler. It is therefore not necessary to add any information for the user.
// This will therefore directly call the decorate function which will in turn emit
// the diagnostic.
if let Level::Expect(_) = level {
if let Level::Expect = level {
decorate(&mut err);
err.emit();
return;

View file

@ -19,8 +19,8 @@ use rustc_middle::middle::privacy::Level;
use rustc_middle::query::Providers;
use rustc_middle::ty::{self, TyCtxt};
use rustc_middle::{bug, span_bug};
use rustc_session::lint;
use rustc_session::lint::builtin::DEAD_CODE;
use rustc_session::lint::{self, LintExpectationId};
use rustc_span::{Symbol, sym};
use crate::errors::{
@ -697,7 +697,7 @@ fn has_allow_dead_code_or_lang_attr(
fn has_allow_expect_dead_code(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
let hir_id = tcx.local_def_id_to_hir_id(def_id);
let lint_level = tcx.lint_level_at_node(lint::builtin::DEAD_CODE, hir_id).level;
matches!(lint_level, lint::Allow | lint::Expect(_))
matches!(lint_level, lint::Allow | lint::Expect)
}
fn has_used_like_attr(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
@ -915,7 +915,7 @@ fn live_symbols_and_ignored_derived_traits(
struct DeadItem {
def_id: LocalDefId,
name: Symbol,
level: lint::Level,
level: (lint::Level, Option<LintExpectationId>),
}
struct DeadVisitor<'tcx> {
@ -959,9 +959,10 @@ impl<'tcx> DeadVisitor<'tcx> {
ShouldWarnAboutField::Yes
}
fn def_lint_level(&self, id: LocalDefId) -> lint::Level {
fn def_lint_level(&self, id: LocalDefId) -> (lint::Level, Option<LintExpectationId>) {
let hir_id = self.tcx.local_def_id_to_hir_id(id);
self.tcx.lint_level_at_node(DEAD_CODE, hir_id).level
let level = self.tcx.lint_level_at_node(DEAD_CODE, hir_id);
(level.level, level.lint_id)
}
// # Panics

View file

@ -89,7 +89,7 @@ pub(crate) fn lint_nonexhaustive_missing_variants<'p, 'tcx>(
// arm. This no longer makes sense so we warn users, to avoid silently breaking their
// usage of the lint.
for arm in arms {
let LevelAndSource { level, src } =
let LevelAndSource { level, src, .. } =
rcx.tcx.lint_level_at_node(NON_EXHAUSTIVE_OMITTED_PATTERNS, arm.arm_data);
if !matches!(level, rustc_session::lint::Level::Allow) {
let decorator = NonExhaustiveOmittedPatternLintOnArm {

View file

@ -1700,7 +1700,7 @@ pub fn get_cmd_lint_options(
let mut lint_opts_with_position = vec![];
let mut describe_lints = false;
for level in [lint::Allow, lint::Warn, lint::ForceWarn(None), lint::Deny, lint::Forbid] {
for level in [lint::Allow, lint::Warn, lint::ForceWarn, lint::Deny, lint::Forbid] {
for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
if lint_name == "help" {
describe_lints = true;

View file

@ -216,7 +216,7 @@ impl DocVisitor<'_> for CoverageCalculator<'_, '_> {
let has_doc_example = tests.found_tests != 0;
let hir_id = DocContext::as_local_hir_id(self.ctx.tcx, i.item_id).unwrap();
let LevelAndSource { level, src } =
let LevelAndSource { level, src, .. } =
self.ctx.tcx.lint_level_at_node(MISSING_DOCS, hir_id);
// In case we have:

View file

@ -107,7 +107,7 @@ pub(crate) fn should_have_doc_example(cx: &DocContext<'_>, item: &clean::Item) -
{
return false;
}
let LevelAndSource { level, src } = cx.tcx.lint_level_at_node(
let LevelAndSource { level, src, .. } = cx.tcx.lint_level_at_node(
crate::lint::MISSING_DOC_CODE_EXAMPLES,
cx.tcx.local_def_id_to_hir_id(def_id),
);

View file

@ -2,6 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_help;
use rustc_ast::ast::{Crate, Inline, Item, ItemKind, ModKind};
use rustc_errors::MultiSpan;
use rustc_lint::{EarlyContext, EarlyLintPass, Level, LintContext};
use rustc_middle::lint::LevelAndSource;
use rustc_session::impl_lint_pass;
use rustc_span::{FileName, Span};
use std::collections::BTreeMap;
@ -45,11 +46,10 @@ declare_clippy_lint! {
"file loaded as module multiple times"
}
#[derive(PartialOrd, Ord, PartialEq, Eq)]
struct Modules {
local_path: PathBuf,
spans: Vec<Span>,
lint_levels: Vec<Level>,
lint_levels: Vec<LevelAndSource>,
}
#[derive(Default)]
@ -95,11 +95,11 @@ impl EarlyLintPass for DuplicateMod {
.iter()
.zip(lint_levels)
.filter_map(|(span, lvl)| {
if let Some(id) = lvl.get_expectation_id() {
if let Some(id) = lvl.lint_id {
cx.fulfill_expectation(id);
}
(!matches!(lvl, Level::Allow | Level::Expect(_))).then_some(*span)
(!matches!(lvl.level, Level::Allow | Level::Expect)).then_some(*span)
})
.collect();

View file

@ -408,9 +408,9 @@ mod zombie_processes;
use clippy_config::{Conf, get_configuration_metadata, sanitize_explanation};
use clippy_utils::macros::FormatArgsStorage;
use utils::attr_collector::{AttrCollector, AttrStorage};
use rustc_data_structures::fx::FxHashSet;
use rustc_lint::{Lint, LintId};
use utils::attr_collector::{AttrCollector, AttrStorage};
/// Register all pre expansion lints
///

View file

@ -138,7 +138,7 @@ impl RawStrings {
);
},
);
if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS), rustc_lint::Allow) {
if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS).level, rustc_lint::Allow) {
return;
}
}

View file

@ -404,7 +404,7 @@ fn check_final_expr<'tcx>(
match cx.tcx.hir_attrs(expr.hir_id) {
[] => {},
[attr] => {
if matches!(Level::from_attr(attr), Some(Level::Expect(_)))
if matches!(Level::from_attr(attr), Some((Level::Expect, _)))
&& let metas = attr.meta_item_list()
&& let Some(lst) = metas
&& let [MetaItemInner::MetaItem(meta_item), ..] = lst.as_slice()

View file

@ -1977,14 +1977,14 @@ pub fn fulfill_or_allowed(cx: &LateContext<'_>, lint: &'static Lint, ids: impl I
let mut suppress_lint = false;
for id in ids {
let LevelAndSource { level, .. } = cx.tcx.lint_level_at_node(lint, id);
if let Some(expectation) = level.get_expectation_id() {
let LevelAndSource { level, lint_id, .. } = cx.tcx.lint_level_at_node(lint, id);
if let Some(expectation) = lint_id {
cx.fulfill_expectation(expectation);
}
match level {
Level::Allow | Level::Expect(_) => suppress_lint = true,
Level::Warn | Level::ForceWarn(_) | Level::Deny | Level::Forbid => {},
Level::Allow | Level::Expect => suppress_lint = true,
Level::Warn | Level::ForceWarn | Level::Deny | Level::Forbid => {},
}
}