use rustc_hir as hir;
use rustc_hir::{intravisit, HirId};
use rustc_middle::hir::nested_filter;
-use rustc_middle::lint::LevelAndSource;
-use rustc_middle::lint::LintDiagnosticBuilder;
use rustc_middle::lint::{
- struct_lint_level, LintLevelMap, LintLevelSets, LintLevelSource, LintSet, LintStackIndex,
- COMMAND_LINE,
+ struct_lint_level, LevelAndSource, LintDiagnosticBuilder, LintExpectation, LintLevelMap,
+ LintLevelSets, LintLevelSource, LintSet, LintStackIndex, COMMAND_LINE,
};
use rustc_middle::ty::query::Providers;
use rustc_middle::ty::{RegisteredTools, TyCtxt};
use rustc_session::lint::{
builtin::{self, FORBIDDEN_LINT_GROUPS},
- Level, Lint, LintId,
+ Level, Lint, LintExpectationId, LintId,
};
use rustc_session::parse::feature_err;
use rustc_session::Session;
pub struct LintLevelsBuilder<'s> {
sess: &'s Session,
+ lint_expectations: FxHashMap<LintExpectationId, LintExpectation>,
sets: LintLevelSets,
id_to_set: FxHashMap<HirId, LintStackIndex>,
cur: LintStackIndex,
) -> Self {
let mut builder = LintLevelsBuilder {
sess,
+ lint_expectations: Default::default(),
sets: LintLevelSets::new(),
cur: COMMAND_LINE,
id_to_set: Default::default(),
let sess = self.sess;
let bad_attr = |span| struct_span_err!(sess, span, E0452, "malformed lint attribute input");
for attr in attrs {
- let Some(level) = Level::from_symbol(attr.name_or_empty()) else {
+ let Some(level) = Level::from_symbol(attr.name_or_empty(), attr.id.as_u32()) else {
continue
};
}
}
}
+
+ if !specs.is_empty() {
+ // Only lints that are currently registered in the lint store
+ // have been found and added to `specs`. Creating the expectation
+ // here ensures that it can be fulfilled during this compilation
+ // session.
+ if let Level::Expect(expect_id) = level {
+ let has_lints = specs
+ .values()
+ .any(|(lvl, _src)| matches!(lvl, Level::Expect(check_id) if check_id.eq(&expect_id)));
+
+ if has_lints {
+ let lint = builtin::UNFULFILLED_LINT_EXPECTATIONS;
+ let (lvl, src) =
+ self.sets.get_lint_level(lint, self.cur, Some(&specs), &sess);
+ let expectation = LintExpectation::new(reason, attr.span, lvl, src);
+ self.lint_expectations.insert(expect_id, expectation);
+ }
+ }
+ }
}
if !is_crate_node {
}
pub fn build_map(self) -> LintLevelMap {
- LintLevelMap { sets: self.sets, id_to_set: self.id_to_set }
+ LintLevelMap {
+ sets: self.sets,
+ id_to_set: self.id_to_set,
+ lint_expectations: self.lint_expectations,
+ }
}
}