Skip to content

Commit 3163c58

Browse files
committed
Auto merge of #58176 - Zoxc:lint-levels, r=oli-obk
Only insert nodes which changes lint levels in the LintLevelMap r? @eddyb
2 parents 2a8f6a7 + f07ce55 commit 3163c58

File tree

8 files changed

+80
-84
lines changed

8 files changed

+80
-84
lines changed

src/librustc/hir/map/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1019,6 +1019,7 @@ impl<'hir> Map<'hir> {
10191019
pub fn attrs(&self, id: NodeId) -> &'hir [ast::Attribute] {
10201020
self.read(id); // reveals attributes on the node
10211021
let attrs = match self.find(id) {
1022+
Some(Node::Local(l)) => Some(&l.attrs[..]),
10221023
Some(Node::Item(i)) => Some(&i.attrs[..]),
10231024
Some(Node::ForeignItem(fi)) => Some(&fi.attrs[..]),
10241025
Some(Node::TraitItem(ref ti)) => Some(&ti.attrs[..]),

src/librustc/lint/levels.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ pub struct LintLevelsBuilder<'a> {
157157

158158
pub struct BuilderPush {
159159
prev: u32,
160+
pub(super) changed: bool,
160161
}
161162

162163
impl<'a> LintLevelsBuilder<'a> {
@@ -454,6 +455,7 @@ impl<'a> LintLevelsBuilder<'a> {
454455

455456
BuilderPush {
456457
prev: prev,
458+
changed: prev != self.cur,
457459
}
458460
}
459461

@@ -512,11 +514,6 @@ impl LintLevelMap {
512514
self.sets.get_lint_level(lint, *idx, None, session)
513515
})
514516
}
515-
516-
/// Returns if this `id` has lint level information.
517-
pub fn lint_level_set(&self, id: HirId) -> Option<u32> {
518-
self.id_to_set.get(&id).cloned()
519-
}
520517
}
521518

522519
impl<'a> HashStable<StableHashingContext<'a>> for LintLevelMap {

src/librustc/lint/mod.rs

+17-4
Original file line numberDiff line numberDiff line change
@@ -721,6 +721,16 @@ pub fn struct_lint_level<'a>(sess: &'a Session,
721721
return err
722722
}
723723

724+
pub fn maybe_lint_level_root(tcx: TyCtxt<'_, '_, '_>, id: hir::HirId) -> bool {
725+
let attrs = tcx.hir().attrs_by_hir_id(id);
726+
for attr in attrs {
727+
if Level::from_str(&attr.name().as_str()).is_some() {
728+
return true;
729+
}
730+
}
731+
false
732+
}
733+
724734
fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
725735
-> Lrc<LintLevelMap>
726736
{
@@ -731,9 +741,10 @@ fn lint_levels<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, cnum: CrateNum)
731741
};
732742
let krate = tcx.hir().krate();
733743

734-
builder.with_lint_attrs(hir::CRATE_HIR_ID, &krate.attrs, |builder| {
735-
intravisit::walk_crate(builder, krate);
736-
});
744+
let push = builder.levels.push(&krate.attrs);
745+
builder.levels.register_id(hir::CRATE_HIR_ID);
746+
intravisit::walk_crate(&mut builder, krate);
747+
builder.levels.pop(push);
737748

738749
Lrc::new(builder.levels.build_map())
739750
}
@@ -751,7 +762,9 @@ impl<'a, 'tcx> LintLevelMapBuilder<'a, 'tcx> {
751762
where F: FnOnce(&mut Self)
752763
{
753764
let push = self.levels.push(attrs);
754-
self.levels.register_id(id);
765+
if push.changed {
766+
self.levels.register_id(id);
767+
}
755768
f(self);
756769
self.levels.pop(push);
757770
}

src/librustc/ty/context.rs

+37-23
Original file line numberDiff line numberDiff line change
@@ -2886,30 +2886,44 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
28862886
err.emit()
28872887
}
28882888

2889-
pub fn lint_level_at_node(self, lint: &'static Lint, mut id: hir::HirId)
2890-
-> (lint::Level, lint::LintSource)
2891-
{
2892-
// Right now we insert a `with_ignore` node in the dep graph here to
2893-
// ignore the fact that `lint_levels` below depends on the entire crate.
2894-
// For now this'll prevent false positives of recompiling too much when
2895-
// anything changes.
2896-
//
2897-
// Once red/green incremental compilation lands we should be able to
2898-
// remove this because while the crate changes often the lint level map
2899-
// will change rarely.
2900-
self.dep_graph.with_ignore(|| {
2901-
let sets = self.lint_levels(LOCAL_CRATE);
2902-
loop {
2903-
if let Some(pair) = sets.level_and_source(lint, id, self.sess) {
2904-
return pair
2905-
}
2906-
let next = self.hir().get_parent_node_by_hir_id(id);
2907-
if next == id {
2908-
bug!("lint traversal reached the root of the crate");
2909-
}
2910-
id = next;
2889+
/// Walks upwards from `id` to find a node which might change lint levels with attributes.
2890+
/// It stops at `bound` and just returns it if reached.
2891+
pub fn maybe_lint_level_root_bounded(
2892+
self,
2893+
mut id: hir::HirId,
2894+
bound: hir::HirId,
2895+
) -> hir::HirId {
2896+
loop {
2897+
if id == bound {
2898+
return bound;
29112899
}
2912-
})
2900+
if lint::maybe_lint_level_root(self, id) {
2901+
return id;
2902+
}
2903+
let next = self.hir().get_parent_node_by_hir_id(id);
2904+
if next == id {
2905+
bug!("lint traversal reached the root of the crate");
2906+
}
2907+
id = next;
2908+
}
2909+
}
2910+
2911+
pub fn lint_level_at_node(
2912+
self,
2913+
lint: &'static Lint,
2914+
mut id: hir::HirId
2915+
) -> (lint::Level, lint::LintSource) {
2916+
let sets = self.lint_levels(LOCAL_CRATE);
2917+
loop {
2918+
if let Some(pair) = sets.level_and_source(lint, id, self.sess) {
2919+
return pair
2920+
}
2921+
let next = self.hir().get_parent_node_by_hir_id(id);
2922+
if next == id {
2923+
bug!("lint traversal reached the root of the crate");
2924+
}
2925+
id = next;
2926+
}
29132927
}
29142928

29152929
pub fn struct_span_lint_hir<S: Into<MultiSpan>>(self,

src/librustc_mir/build/scope.rs

+19-11
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,6 @@ use crate::hair::LintLevel;
8282
use rustc::middle::region;
8383
use rustc::ty::Ty;
8484
use rustc::hir;
85-
use rustc::hir::def_id::LOCAL_CRATE;
8685
use rustc::mir::*;
8786
use syntax_pos::{Span};
8887
use rustc_data_structures::fx::FxHashMap;
@@ -309,16 +308,25 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
309308
let source_scope = self.source_scope;
310309
let tcx = self.hir.tcx();
311310
if let LintLevel::Explicit(current_hir_id) = lint_level {
312-
let same_lint_scopes = tcx.dep_graph.with_ignore(|| {
313-
let sets = tcx.lint_levels(LOCAL_CRATE);
314-
let parent_hir_id = self.source_scope_local_data[source_scope].lint_root;
315-
sets.lint_level_set(parent_hir_id) == sets.lint_level_set(current_hir_id)
316-
});
317-
318-
if !same_lint_scopes {
319-
self.source_scope =
320-
self.new_source_scope(region_scope.1.span, lint_level,
321-
None);
311+
// Use `maybe_lint_level_root_bounded` with `root_lint_level` as a bound
312+
// to avoid adding Hir dependences on our parents.
313+
// We estimate the true lint roots here to avoid creating a lot of source scopes.
314+
315+
let parent_root = tcx.maybe_lint_level_root_bounded(
316+
self.source_scope_local_data[source_scope].lint_root,
317+
self.hir.root_lint_level,
318+
);
319+
let current_root = tcx.maybe_lint_level_root_bounded(
320+
current_hir_id,
321+
self.hir.root_lint_level
322+
);
323+
324+
if parent_root != current_root {
325+
self.source_scope = self.new_source_scope(
326+
region_scope.1.span,
327+
LintLevel::Explicit(current_root),
328+
None
329+
);
322330
}
323331
}
324332
self.push_scope(region_scope);

src/librustc_mir/hair/cx/block.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ fn mirror_stmts<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>,
103103
},
104104
pattern,
105105
initializer: local.init.to_ref(),
106-
lint_level: cx.lint_level_of(local.hir_id),
106+
lint_level: LintLevel::Explicit(local.hir_id),
107107
},
108108
opt_destruction_scope: opt_dxn_ext,
109109
span: stmt_span,

src/librustc_mir/hair/cx/expr.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ impl<'tcx> Mirror<'tcx> for &'tcx hir::Expr {
4444
kind: ExprKind::Scope {
4545
region_scope: expr_scope,
4646
value: expr.to_ref(),
47-
lint_level: cx.lint_level_of(self.hir_id),
47+
lint_level: LintLevel::Explicit(self.hir_id),
4848
},
4949
};
5050

src/librustc_mir/hair/cx/mod.rs

+2-39
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use crate::hair::*;
66
use crate::hair::util::UserAnnotatedTyHelpers;
77

88
use rustc_data_structures::indexed_vec::Idx;
9-
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
9+
use rustc::hir::def_id::DefId;
1010
use rustc::hir::Node;
1111
use rustc::middle::region;
1212
use rustc::infer::InferCtxt;
@@ -76,11 +76,10 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
7676
// Constants always need overflow checks.
7777
check_overflow |= constness == hir::Constness::Const;
7878

79-
let lint_level = lint_level_for_hir_id(tcx, src_id);
8079
Cx {
8180
tcx,
8281
infcx,
83-
root_lint_level: lint_level,
82+
root_lint_level: src_id,
8483
param_env: tcx.param_env(src_def_id),
8584
identity_substs: InternalSubsts::identity_for_item(tcx.global_tcx(), src_def_id),
8685
region_scope_tree: tcx.region_scope_tree(src_def_id),
@@ -197,18 +196,6 @@ impl<'a, 'gcx, 'tcx> Cx<'a, 'gcx, 'tcx> {
197196
ty.needs_drop(self.tcx.global_tcx(), param_env)
198197
}
199198

200-
fn lint_level_of(&self, hir_id: hir::HirId) -> LintLevel {
201-
let has_lint_level = self.tcx.dep_graph.with_ignore(|| {
202-
self.tcx.lint_levels(LOCAL_CRATE).lint_level_set(hir_id).is_some()
203-
});
204-
205-
if has_lint_level {
206-
LintLevel::Explicit(hir_id)
207-
} else {
208-
LintLevel::Inherited
209-
}
210-
}
211-
212199
pub fn tcx(&self) -> TyCtxt<'a, 'gcx, 'tcx> {
213200
self.tcx
214201
}
@@ -236,30 +223,6 @@ impl UserAnnotatedTyHelpers<'gcx, 'tcx> for Cx<'_, 'gcx, 'tcx> {
236223
}
237224
}
238225

239-
fn lint_level_for_hir_id(tcx: TyCtxt<'_, '_, '_>, mut id: hir::HirId) -> hir::HirId {
240-
// Right now we insert a `with_ignore` node in the dep graph here to
241-
// ignore the fact that `lint_levels` below depends on the entire crate.
242-
// For now this'll prevent false positives of recompiling too much when
243-
// anything changes.
244-
//
245-
// Once red/green incremental compilation lands we should be able to
246-
// remove this because while the crate changes often the lint level map
247-
// will change rarely.
248-
tcx.dep_graph.with_ignore(|| {
249-
let sets = tcx.lint_levels(LOCAL_CRATE);
250-
loop {
251-
if sets.lint_level_set(id).is_some() {
252-
return id
253-
}
254-
let next = tcx.hir().get_parent_node_by_hir_id(id);
255-
if next == id {
256-
bug!("lint traversal reached the root of the crate");
257-
}
258-
id = next;
259-
}
260-
})
261-
}
262-
263226
mod block;
264227
mod expr;
265228
mod to_ref;

0 commit comments

Comments
 (0)