Skip to content

Commit

Permalink
Auto merge of #101620 - cjgillot:compute_lint_levels_by_def, r=oli-obk
Browse files Browse the repository at this point in the history
Compute lint levels by definition

Lint levels are currently computed once for the whole crate. Any code that wants to emit a lint depends on this single `lint_levels(())` query. This query contains the `Span` for each attribute that participates in the lint level tree, so any code that wants to emit a lint basically depends on the spans in all files in the crate.

Contrary to hard errors, we do not clear the incremental session on lints, so this implicit world dependency pessimizes incremental reuse. (And is furthermore invisible for allowed lints.)

This PR completes #99634 (thanks for the initial work `@fee1-dead)` and includes it in the dependency graph.

The design is based on 2 queries:
1. `lint_levels_on(HirId) -> FxHashMap<LintId, LevelAndSource>` which accesses the attributes at the given `HirId` and processes them into lint levels.  The `TyCtxt` is responsible for probing the HIR tree to find the user-visible level.
2. `lint_expectations(())` which lists all the `#[expect]` attributes in the crate.

This PR also introduces the ability to reconstruct a `HirId` from a `DepNode` by encoding the local part of the `DefPathHash` and the `ItemLocalId` in the two `u64` of the fingerprint.  This allows for the dep-graph to directly recompute `lint_levels_on` directly, without having to force the calling query.

Closes #95094.
Supersedes #99634.
  • Loading branch information
bors committed Sep 15, 2022
2 parents 750bd1a + 42a92eb commit 2cb9a65
Show file tree
Hide file tree
Showing 18 changed files with 670 additions and 488 deletions.
5 changes: 3 additions & 2 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -338,9 +338,10 @@ impl Diagnostic {
// The lint index inside the attribute is manually transferred here.
let lint_index = expectation_id.get_lint_index();
expectation_id.set_lint_index(None);
let mut stable_id = *unstable_to_stable
let mut stable_id = unstable_to_stable
.get(&expectation_id)
.expect("each unstable `LintExpectationId` must have a matching stable id");
.expect("each unstable `LintExpectationId` must have a matching stable id")
.normalize();

stable_id.set_lint_index(lint_index);
*expectation_id = stable_id;
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_errors/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1167,7 +1167,7 @@ impl HandlerInner {

if let Some(expectation_id) = diagnostic.level.get_expectation_id() {
self.suppressed_expected_diag = true;
self.fulfilled_expectations.insert(expectation_id);
self.fulfilled_expectations.insert(expectation_id.normalize());
}

if matches!(diagnostic.level, Warning(_))
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_lint/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ pub struct LateContext<'tcx> {

/// Context for lint checking of the AST, after expansion, before lowering to HIR.
pub struct EarlyContext<'a> {
pub builder: LintLevelsBuilder<'a>,
pub builder: LintLevelsBuilder<'a, crate::levels::TopDown>,
pub buffered: LintBuffer,
}

Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_lint/src/early.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> {
F: FnOnce(&mut Self),
{
let is_crate_node = id == ast::CRATE_NODE_ID;
debug!(?id);
let push = self.context.builder.push(attrs, is_crate_node, None);

self.check_id(id);
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_lint/src/expect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@ fn check_expectations(tcx: TyCtxt<'_>, tool_filter: Option<Symbol>) {
return;
}

let lint_expectations = tcx.lint_expectations(());
let fulfilled_expectations = tcx.sess.diagnostic().steal_fulfilled_expectation_ids();
let lint_expectations = &tcx.lint_levels(()).lint_expectations;

tracing::debug!(?lint_expectations, ?fulfilled_expectations);

for (id, expectation) in lint_expectations {
// This check will always be true, since `lint_expectations` only
Expand Down
Loading

0 comments on commit 2cb9a65

Please sign in to comment.