Emit unfullfilled_lint_expectation
using a HirId
for performance (RFC-2383)
This commit is contained in:
parent
a14456f91f
commit
3414ad9551
@ -1,10 +1,9 @@
|
||||
use crate::builtin;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_middle::lint::struct_lint_level;
|
||||
use rustc_hir::HirId;
|
||||
use rustc_middle::{lint::LintExpectation, ty::TyCtxt};
|
||||
use rustc_session::lint::LintExpectationId;
|
||||
use rustc_span::symbol::sym;
|
||||
use rustc_span::MultiSpan;
|
||||
|
||||
pub fn check_expectations(tcx: TyCtxt<'_>) {
|
||||
if !tcx.sess.features_untracked().enabled(sym::lint_reasons) {
|
||||
@ -17,24 +16,28 @@ pub fn check_expectations(tcx: TyCtxt<'_>) {
|
||||
|
||||
for (id, expectation) in lint_expectations {
|
||||
if !fulfilled_expectations.contains(id) {
|
||||
emit_unfulfilled_expectation_lint(tcx, expectation);
|
||||
// This check will always be true, since `lint_expectations` only
|
||||
// holds stable ids
|
||||
if let LintExpectationId::Stable { hir_id, .. } = id {
|
||||
emit_unfulfilled_expectation_lint(tcx, *hir_id, expectation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn emit_unfulfilled_expectation_lint(tcx: TyCtxt<'_>, expectation: &LintExpectation) {
|
||||
fn emit_unfulfilled_expectation_lint(
|
||||
tcx: TyCtxt<'_>,
|
||||
hir_id: HirId,
|
||||
expectation: &LintExpectation,
|
||||
) {
|
||||
// FIXME: The current implementation doesn't cover cases where the
|
||||
// `unfulfilled_lint_expectations` is actually expected by another lint
|
||||
// expectation. This can be added here as we have the lint level of this
|
||||
// expectation, and we can also mark the lint expectation it would fulfill
|
||||
// as such. This is currently not implemented to get some early feedback
|
||||
// before diving deeper into this.
|
||||
struct_lint_level(
|
||||
tcx.sess,
|
||||
// expectation. This can be added here by checking the lint level and
|
||||
// retrieving the `LintExpectationId` if it was expected.
|
||||
tcx.struct_span_lint_hir(
|
||||
builtin::UNFULFILLED_LINT_EXPECTATIONS,
|
||||
expectation.emission_level,
|
||||
expectation.emission_level_source,
|
||||
Some(MultiSpan::from_span(expectation.emission_span)),
|
||||
hir_id,
|
||||
expectation.emission_span,
|
||||
|diag| {
|
||||
let mut diag = diag.build("this lint expectation is unfulfilled");
|
||||
if let Some(rationale) = expectation.reason {
|
||||
|
@ -245,9 +245,9 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
for (attr_index, attr) in attrs.iter().enumerate() {
|
||||
let level = match Level::from_attr(attr) {
|
||||
None => continue,
|
||||
Some(Level::Expect(unstable_id)) if source_hir_id.is_some() => {
|
||||
let stable_id =
|
||||
self.create_stable_id(unstable_id, source_hir_id.unwrap(), attr_index);
|
||||
Some(Level::Expect(unstable_id)) if let Some(hir_id) = source_hir_id => {
|
||||
let stable_id = self.create_stable_id(unstable_id, hir_id, attr_index);
|
||||
|
||||
Level::Expect(stable_id)
|
||||
}
|
||||
Some(lvl) => lvl,
|
||||
@ -303,12 +303,6 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
}
|
||||
}
|
||||
|
||||
let (unfulfilled_lint_lvl, unfulfilled_lint_src) = self.sets.get_lint_level(
|
||||
builtin::UNFULFILLED_LINT_EXPECTATIONS,
|
||||
self.cur,
|
||||
Some(&specs),
|
||||
&sess,
|
||||
);
|
||||
for (lint_index, li) in metas.iter_mut().enumerate() {
|
||||
let level = match level {
|
||||
Level::Expect(mut id) => {
|
||||
@ -360,15 +354,8 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
self.insert_spec(&mut specs, id, (level, src));
|
||||
}
|
||||
if let Level::Expect(expect_id) = level {
|
||||
self.lint_expectations.insert(
|
||||
expect_id,
|
||||
LintExpectation::new(
|
||||
reason,
|
||||
sp,
|
||||
unfulfilled_lint_lvl,
|
||||
unfulfilled_lint_src,
|
||||
),
|
||||
);
|
||||
self.lint_expectations
|
||||
.insert(expect_id, LintExpectation::new(reason, sp));
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,15 +373,8 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
self.insert_spec(&mut specs, *id, (level, src));
|
||||
}
|
||||
if let Level::Expect(expect_id) = level {
|
||||
self.lint_expectations.insert(
|
||||
expect_id,
|
||||
LintExpectation::new(
|
||||
reason,
|
||||
sp,
|
||||
unfulfilled_lint_lvl,
|
||||
unfulfilled_lint_src,
|
||||
),
|
||||
);
|
||||
self.lint_expectations
|
||||
.insert(expect_id, LintExpectation::new(reason, sp));
|
||||
}
|
||||
}
|
||||
Err((Some(ids), ref new_lint_name)) => {
|
||||
@ -433,15 +413,8 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
self.insert_spec(&mut specs, *id, (level, src));
|
||||
}
|
||||
if let Level::Expect(expect_id) = level {
|
||||
self.lint_expectations.insert(
|
||||
expect_id,
|
||||
LintExpectation::new(
|
||||
reason,
|
||||
sp,
|
||||
unfulfilled_lint_lvl,
|
||||
unfulfilled_lint_src,
|
||||
),
|
||||
);
|
||||
self.lint_expectations
|
||||
.insert(expect_id, LintExpectation::new(reason, sp));
|
||||
}
|
||||
}
|
||||
Err((None, _)) => {
|
||||
@ -537,15 +510,8 @@ impl<'s> LintLevelsBuilder<'s> {
|
||||
self.insert_spec(&mut specs, id, (level, src));
|
||||
}
|
||||
if let Level::Expect(expect_id) = level {
|
||||
self.lint_expectations.insert(
|
||||
expect_id,
|
||||
LintExpectation::new(
|
||||
reason,
|
||||
sp,
|
||||
unfulfilled_lint_lvl,
|
||||
unfulfilled_lint_src,
|
||||
),
|
||||
);
|
||||
self.lint_expectations
|
||||
.insert(expect_id, LintExpectation::new(reason, sp));
|
||||
}
|
||||
} else {
|
||||
panic!("renamed lint does not exist: {}", new_name);
|
||||
|
@ -204,20 +204,11 @@ pub struct LintExpectation {
|
||||
pub reason: Option<Symbol>,
|
||||
/// The [`Span`] of the attribute that this expectation originated from.
|
||||
pub emission_span: Span,
|
||||
/// The [`Level`] that this lint diagnostic should be emitted if unfulfilled.
|
||||
pub emission_level: Level,
|
||||
/// The [`LintLevelSource`] information needed for [`struct_lint_level`].
|
||||
pub emission_level_source: LintLevelSource,
|
||||
}
|
||||
|
||||
impl LintExpectation {
|
||||
pub fn new(
|
||||
reason: Option<Symbol>,
|
||||
attr_span: Span,
|
||||
emission_level: Level,
|
||||
emission_level_source: LintLevelSource,
|
||||
) -> Self {
|
||||
Self { reason, emission_span: attr_span, emission_level, emission_level_source }
|
||||
pub fn new(reason: Option<Symbol>, attr_span: Span) -> Self {
|
||||
Self { reason, emission_span: attr_span }
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user