Remove LintExpectationId
from Level
variants
This commit is contained in:
parent
c51816ee59
commit
805f389da5
15 changed files with 124 additions and 123 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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),
|
||||
);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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
|
||||
///
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue