Skip to content

Commit d01b9ec

Browse files
committed
make loop checking and attribute checking incremental
1 parent 0abf98e commit d01b9ec

File tree

11 files changed

+143
-16
lines changed

11 files changed

+143
-16
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,9 @@ define_dep_nodes!( <'tcx>
489489
[] UnsafetyCheckResult(DefId),
490490
[] UnsafeDeriveOnReprPacked(DefId),
491491

492+
[] CheckModAttrs(DefId),
493+
[] CheckModLoops(DefId),
494+
492495
[] Reachability,
493496
[] MirKeys,
494497
[eval_always] CrateVariances,

src/librustc/hir/check_attr.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,11 @@
1616
1717
use syntax_pos::Span;
1818
use ty::TyCtxt;
19+
use ty::maps::Providers;
20+
use ty::maps::queries;
1921

2022
use hir;
23+
use hir::def_id::DefId;
2124
use hir::intravisit::{self, Visitor, NestedVisitorMap};
2225

2326
#[derive(Copy, Clone, PartialEq)]
@@ -340,8 +343,9 @@ impl<'a, 'tcx> Visitor<'tcx> for CheckAttrVisitor<'a, 'tcx> {
340343
}
341344

342345
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
343-
let mut checker = CheckAttrVisitor { tcx };
344-
tcx.hir.krate().visit_all_item_likes(&mut checker.as_deep_visitor());
346+
for &module in &tcx.hir.krate().modules {
347+
queries::check_mod_attrs::ensure(tcx, tcx.hir.local_def_id(module));
348+
}
345349
}
346350

347351
fn is_c_like_enum(item: &hir::Item) -> bool {
@@ -357,3 +361,14 @@ fn is_c_like_enum(item: &hir::Item) -> bool {
357361
false
358362
}
359363
}
364+
365+
pub fn check_mod_attrs<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
366+
tcx.hir.visit_module_item_likes(module_def_id, CheckAttrVisitor { tcx }.as_deep_visitor());
367+
}
368+
369+
pub(crate) fn provide(providers: &mut Providers) {
370+
*providers = Providers {
371+
check_mod_attrs,
372+
..*providers
373+
};
374+
}

src/librustc/hir/lowering.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ pub struct LoweringContext<'a> {
9696
trait_impls: BTreeMap<DefId, Vec<NodeId>>,
9797
trait_auto_impl: BTreeMap<DefId, NodeId>,
9898

99+
modules: Vec<NodeId>,
100+
99101
is_generator: bool,
100102

101103
catch_scopes: Vec<NodeId>,
@@ -209,6 +211,7 @@ pub fn lower_crate(
209211
bodies: BTreeMap::new(),
210212
trait_impls: BTreeMap::new(),
211213
trait_auto_impl: BTreeMap::new(),
214+
modules: vec![CRATE_NODE_ID],
212215
exported_macros: Vec::new(),
213216
catch_scopes: Vec::new(),
214217
loop_scopes: Vec::new(),
@@ -361,6 +364,9 @@ impl<'a> LoweringContext<'a> {
361364
let mut item_lowered = true;
362365
self.lctx.with_hir_id_owner(item.id, |lctx| {
363366
if let Some(hir_item) = lctx.lower_item(item) {
367+
if let hir::Item_::ItemMod(..) = hir_item.node {
368+
lctx.modules.push(item.id);
369+
}
364370
lctx.items.insert(item.id, hir_item);
365371
} else {
366372
item_lowered = false;
@@ -436,6 +442,7 @@ impl<'a> LoweringContext<'a> {
436442
body_ids,
437443
trait_impls: self.trait_impls,
438444
trait_auto_impl: self.trait_auto_impl,
445+
modules: self.modules,
439446
}
440447
}
441448

src/librustc/hir/map/collector.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
7777
trait_impls: _,
7878
trait_auto_impl: _,
7979
body_ids: _,
80+
modules: _,
8081
} = *krate;
8182

8283
root_mod_sig_dep_index = dep_graph.input_task(

src/librustc/hir/map/mod.rs

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ use syntax::ext::base::MacroKind;
2828
use syntax_pos::Span;
2929

3030
use hir::*;
31+
use hir::itemlikevisit::ItemLikeVisitor;
3132
use hir::print::Nested;
3233
use hir::svh::Svh;
3334
use util::nodemap::FxHashMap;
@@ -608,6 +609,80 @@ impl<'hir> Map<'hir> {
608609
&self.forest.krate.attrs
609610
}
610611

612+
pub fn visit_module_item_likes<V>(&self, module: DefId, visitor: V)
613+
where V: itemlikevisit::ItemLikeVisitor<'hir>
614+
{
615+
let node_id = self.as_local_node_id(module).unwrap();
616+
617+
// Read the module so we'll be re-executed if new items appear in the module
618+
self.read(node_id);
619+
620+
struct Filter<'a, 'hir: 'a, V> {
621+
map: &'a Map<'hir>,
622+
module: NodeId,
623+
visitor: V,
624+
}
625+
626+
impl<'a, 'hir, V> Filter<'a, 'hir, V> {
627+
fn module_id(&self, mut id: NodeId) -> NodeId {
628+
loop {
629+
let entry = self.map.find_entry(id);
630+
631+
match entry {
632+
// We are in a module, return the id
633+
Some(EntryItem(_, _, Item { node: Item_::ItemMod(..), .. })) |
634+
Some(RootCrate(_)) => return id,
635+
636+
// Not a module, go to the parent
637+
_ => (),
638+
}
639+
640+
id = entry.and_then(|x| x.parent_node()).unwrap();
641+
}
642+
}
643+
644+
fn in_module(&self, id: NodeId) -> bool {
645+
if self.module_id(id) == self.module {
646+
self.map.read(id);
647+
true
648+
} else {
649+
false
650+
}
651+
}
652+
}
653+
654+
impl<'a, 'hir, V> ItemLikeVisitor<'hir> for Filter<'a, 'hir, V>
655+
where V: ItemLikeVisitor<'hir>
656+
{
657+
fn visit_item(&mut self, item: &'hir Item) {
658+
if self.in_module(item.id) {
659+
self.visitor.visit_item(item);
660+
}
661+
}
662+
663+
fn visit_trait_item(&mut self, trait_item: &'hir TraitItem) {
664+
if self.in_module(trait_item.id) {
665+
self.visitor.visit_trait_item(trait_item);
666+
}
667+
}
668+
669+
fn visit_impl_item(&mut self, impl_item: &'hir ImplItem) {
670+
if self.in_module(impl_item.id) {
671+
self.visitor.visit_impl_item(impl_item);
672+
}
673+
}
674+
}
675+
676+
let mut filter = Filter {
677+
map: self,
678+
module: node_id,
679+
visitor,
680+
};
681+
682+
// We can't krate() since that adds a dependency on the whole crate
683+
self.forest.krate.visit_all_item_likes(&mut filter);
684+
}
685+
611686
/// Retrieve the Node corresponding to `id`, panicking if it cannot
612687
/// be found.
613688
pub fn get(&self, id: NodeId) -> Node<'hir> {

src/librustc/hir/mod.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,10 @@ pub struct Crate {
694694
/// in the crate, you should iterate over this list rather than the keys
695695
/// of bodies.
696696
pub body_ids: Vec<BodyId>,
697+
698+
/// A list of modules written out in the order in which they
699+
/// appear in the crate. This includes the main crate module.
700+
pub modules: Vec<NodeId>,
697701
}
698702

699703
impl Crate {
@@ -2264,6 +2268,7 @@ pub type GlobMap = NodeMap<FxHashSet<Name>>;
22642268

22652269

22662270
pub fn provide(providers: &mut Providers) {
2271+
check_attr::provide(providers);
22672272
providers.describe_def = map::describe_def;
22682273
}
22692274

src/librustc/ty/maps/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,12 @@ define_maps! { <'tcx>
192192
/// HACK: when evaluated, this reports a "unsafe derive on repr(packed)" error
193193
[] fn unsafe_derive_on_repr_packed: UnsafeDeriveOnReprPacked(DefId) -> (),
194194

195+
/// Checks the attributes in the module
196+
[] fn check_mod_attrs: CheckModAttrs(DefId) -> (),
197+
198+
/// Checks the attributes in the module
199+
[] fn check_mod_loops: CheckModLoops(DefId) -> (),
200+
195201
/// The signature of functions and closures.
196202
[] fn fn_sig: FnSignature(DefId) -> ty::PolyFnSig<'tcx>,
197203

src/librustc/ty/maps/plumbing.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,8 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
10471047
DepKind::MirBorrowCheck => { force!(mir_borrowck, def_id!()); }
10481048
DepKind::UnsafetyCheckResult => { force!(unsafety_check_result, def_id!()); }
10491049
DepKind::UnsafeDeriveOnReprPacked => { force!(unsafe_derive_on_repr_packed, def_id!()); }
1050+
DepKind::CheckModAttrs => { force!(check_mod_attrs, def_id!()); }
1051+
DepKind::CheckModLoops => { force!(check_mod_loops, def_id!()); }
10501052
DepKind::Reachability => { force!(reachable_set, LOCAL_CRATE); }
10511053
DepKind::MirKeys => { force!(mir_keys, LOCAL_CRATE); }
10521054
DepKind::CrateVariances => { force!(crate_variances, LOCAL_CRATE); }

src/librustc_driver/driver.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1230,12 +1230,16 @@ where
12301230
// tcx available.
12311231
rustc_incremental::dep_graph_tcx_init(tcx);
12321232

1233-
time(sess, "loop checking", || loops::check_crate(sess, &hir_map));
1233+
time(sess, "loop checking", || loops::check_crate(tcx));
12341234

12351235
time(sess, "attribute checking", || {
12361236
hir::check_attr::check_crate(tcx)
12371237
});
12381238

1239+
time(sess, "stability index", || {
1240+
tcx.stability();
1241+
});
1242+
12391243
time(sess, "stability checking", || {
12401244
stability::check_unstable_api_usage(tcx)
12411245
});

src/librustc_passes/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,4 +46,5 @@ __build_diagnostic_array! { librustc_passes, DIAGNOSTICS }
4646

4747
pub fn provide(providers: &mut Providers) {
4848
rvalue_promotion::provide(providers);
49+
loops::provide(providers);
4950
}

src/librustc_passes/loops.rs

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ use self::Context::*;
1111

1212
use rustc::session::Session;
1313

14+
use rustc::ty::maps::Providers;
15+
use rustc::ty::maps::queries;
16+
use rustc::ty::TyCtxt;
17+
use rustc::hir::def_id::DefId;
1418
use rustc::hir::map::Map;
1519
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
1620
use rustc::hir::{self, Destination};
@@ -49,28 +53,32 @@ struct CheckLoopVisitor<'a, 'hir: 'a> {
4953
cx: Context,
5054
}
5155

52-
pub fn check_crate(sess: &Session, map: &Map) {
53-
let krate = map.krate();
54-
krate.visit_all_item_likes(&mut CheckLoopVisitor {
55-
sess,
56-
hir_map: map,
56+
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
57+
for &module in &tcx.hir.krate().modules {
58+
queries::check_mod_loops::ensure(tcx, tcx.hir.local_def_id(module));
59+
}
60+
}
61+
62+
pub fn check_mod_loops<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, module_def_id: DefId) {
63+
tcx.hir.visit_module_item_likes(module_def_id, CheckLoopVisitor {
64+
sess: &tcx.sess,
65+
hir_map: &tcx.hir,
5766
cx: Normal,
5867
}.as_deep_visitor());
5968
}
6069

70+
pub(crate) fn provide(providers: &mut Providers) {
71+
*providers = Providers {
72+
check_mod_loops,
73+
..*providers
74+
};
75+
}
76+
6177
impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
6278
fn nested_visit_map<'this>(&'this mut self) -> NestedVisitorMap<'this, 'hir> {
6379
NestedVisitorMap::OnlyBodies(&self.hir_map)
6480
}
6581

66-
fn visit_item(&mut self, i: &'hir hir::Item) {
67-
self.with_context(Normal, |v| intravisit::walk_item(v, i));
68-
}
69-
70-
fn visit_impl_item(&mut self, i: &'hir hir::ImplItem) {
71-
self.with_context(Normal, |v| intravisit::walk_impl_item(v, i));
72-
}
73-
7482
fn visit_expr(&mut self, e: &'hir hir::Expr) {
7583
match e.node {
7684
hir::ExprWhile(ref e, ref b, _) => {

0 commit comments

Comments
 (0)