Skip to content

Commit 44cb8fa

Browse files
committed
Check lint expectations and emit lint if unfulfilled (RFC-2383)
1 parent 2ca9037 commit 44cb8fa

File tree

3 files changed

+52
-0
lines changed

3 files changed

+52
-0
lines changed

compiler/rustc_lint/src/expect.rs

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use crate::builtin;
2+
use rustc_data_structures::fx::FxHashMap;
3+
use rustc_middle::lint::struct_lint_level;
4+
use rustc_middle::{lint::LintExpectation, ty::TyCtxt};
5+
use rustc_session::lint::LintExpectationId;
6+
use rustc_span::symbol::sym;
7+
use rustc_span::MultiSpan;
8+
9+
pub fn check_expectations(tcx: TyCtxt<'_>) {
10+
if !tcx.sess.features_untracked().enabled(sym::lint_reasons) {
11+
return;
12+
}
13+
14+
let fulfilled_expectations = tcx.sess.diagnostic().steal_fulfilled_expectation_ids();
15+
let lint_expectations: &FxHashMap<LintExpectationId, LintExpectation> =
16+
&tcx.lint_levels(()).lint_expectations;
17+
18+
for (id, expectation) in lint_expectations {
19+
if fulfilled_expectations.contains(id) {
20+
continue;
21+
}
22+
23+
emit_unfulfilled_expectation_lint(tcx, expectation);
24+
}
25+
}
26+
27+
fn emit_unfulfilled_expectation_lint(tcx: TyCtxt<'_>, expectation: &LintExpectation) {
28+
// FIXME The current implementation doesn't cover cases where the
29+
// `unfulfilled_lint_expectations` is actually expected by another lint
30+
// expectation. This can be added here as we have the lint level of this
31+
// expectation, and we can also mark the lint expectation it would fulfill
32+
// as such. This is currently not implemented to get some early feedback
33+
// before diving deeper into this.
34+
struct_lint_level(
35+
tcx.sess,
36+
builtin::UNFULFILLED_LINT_EXPECTATIONS,
37+
expectation.emission_level,
38+
expectation.emission_level_source,
39+
Some(MultiSpan::from_span(expectation.emission_span)),
40+
|diag| {
41+
let mut diag = diag.build("this lint expectation is unfulfilled");
42+
if let Some(rationale) = expectation.reason {
43+
diag.note(&rationale.as_str());
44+
}
45+
diag.emit();
46+
},
47+
);
48+
}

compiler/rustc_lint/src/late.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,4 +503,7 @@ pub fn check_crate<'tcx, T: LateLintPass<'tcx>>(
503503
});
504504
},
505505
);
506+
507+
// This check has to be run after all lints are done processing for this crate
508+
tcx.sess.time("check_lint_expectations", || crate::expect::check_expectations(tcx));
506509
}

compiler/rustc_lint/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ mod context;
5252
mod early;
5353
mod enum_intrinsics_non_enums;
5454
pub mod hidden_unicode_codepoints;
55+
mod expect;
5556
mod internal;
5657
mod late;
5758
mod levels;

0 commit comments

Comments
 (0)