Skip to content

Commit 78f7ac5

Browse files
committed
rejigger how we handle used trait imports
The previous way was not friendly to incremental compilation. The new plan is to compute, for each body, a set of trait imports used in that body (slightly subtle: for a closure, we assign the trait imports to the enclosing fn). Then we walk all bodies and union these sets. The reason we do this is that we can save the individual sets in the incremental state, and then recompute only those sets that are needed. Before we were planning to save only the final union, but in that case if some components are invalidated we have to recompute *all* of them since we don't have enough information to "partly" invalidate a result. In truth, this set probably ought to be part of the `TypeckTables`; however, I opted not to do that because I don't want to have to save/restore the entire tables in the incremental state yet (since it contains a lot of `NodeId` references, and removing those is a significant refactoring).
1 parent fdd7e3c commit 78f7ac5

File tree

8 files changed

+48
-11
lines changed

8 files changed

+48
-11
lines changed

src/librustc/dep_graph/dep_node.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ pub enum DepNode<D: Clone + Debug> {
113113
AssociatedItemDefIds(D),
114114
InherentImpls(D),
115115
TypeckTables(D),
116+
UsedTraitImports(D),
116117

117118
// The set of impls for a given trait. Ultimately, it would be
118119
// nice to get more fine-grained here (e.g., to include a
@@ -162,6 +163,7 @@ impl<D: Clone + Debug> DepNode<D> {
162163
AssociatedItemDefIds,
163164
InherentImpls,
164165
TypeckTables,
166+
UsedTraitImports,
165167
TraitImpls,
166168
ReprHints,
167169
}
@@ -230,6 +232,7 @@ impl<D: Clone + Debug> DepNode<D> {
230232
AssociatedItemDefIds(ref d) => op(d).map(AssociatedItemDefIds),
231233
InherentImpls(ref d) => op(d).map(InherentImpls),
232234
TypeckTables(ref d) => op(d).map(TypeckTables),
235+
UsedTraitImports(ref d) => op(d).map(UsedTraitImports),
233236
TraitImpls(ref d) => op(d).map(TraitImpls),
234237
TraitItems(ref d) => op(d).map(TraitItems),
235238
ReprHints(ref d) => op(d).map(ReprHints),

src/librustc/ty/context.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ pub struct GlobalCtxt<'tcx> {
499499

500500
/// Set of trait imports actually used in the method resolution.
501501
/// This is used for warning unused imports.
502-
pub used_trait_imports: RefCell<DefIdSet>,
502+
pub used_trait_imports: RefCell<DepTrackingMap<maps::UsedTraitImports<'tcx>>>,
503503

504504
/// The set of external nominal types whose implementations have been read.
505505
/// This is used for lazy resolution of methods.
@@ -788,7 +788,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
788788
inherent_impls: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
789789
used_unsafe: RefCell::new(NodeSet()),
790790
used_mut_nodes: RefCell::new(NodeSet()),
791-
used_trait_imports: RefCell::new(DefIdSet()),
791+
used_trait_imports: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
792792
populated_external_types: RefCell::new(DefIdSet()),
793793
populated_external_primitive_impls: RefCell::new(DefIdSet()),
794794
stability: RefCell::new(stability),

src/librustc/ty/maps.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use dep_graph::{DepNode, DepTrackingMapConfig};
1212
use hir::def_id::DefId;
1313
use mir;
1414
use ty::{self, Ty};
15+
use util::nodemap::DefIdSet;
1516

1617
use std::cell::RefCell;
1718
use std::marker::PhantomData;
@@ -49,3 +50,4 @@ dep_map_ty! { Mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>> }
4950
dep_map_ty! { ClosureKinds: ItemSignature(DefId) -> ty::ClosureKind }
5051
dep_map_ty! { ClosureTypes: ItemSignature(DefId) -> ty::ClosureTy<'tcx> }
5152
dep_map_ty! { TypeckTables: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx> }
53+
dep_map_ty! { UsedTraitImports: UsedTraitImports(DefId) -> DefIdSet }

src/librustc_typeck/check/method/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
138138

139139
if let Some(import_id) = pick.import_id {
140140
let import_def_id = self.tcx.hir.local_def_id(import_id);
141-
self.tcx.used_trait_imports.borrow_mut().insert(import_def_id);
141+
debug!("used_trait_import: {:?}", import_def_id);
142+
self.used_trait_imports.borrow_mut().insert(import_def_id);
142143
}
143144

144145
self.tcx.check_stability(pick.item.def_id, call_expr.id, span);
@@ -338,7 +339,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
338339

339340
if let Some(import_id) = pick.import_id {
340341
let import_def_id = self.tcx.hir.local_def_id(import_id);
341-
self.tcx.used_trait_imports.borrow_mut().insert(import_def_id);
342+
debug!("used_trait_import: {:?}", import_def_id);
343+
self.used_trait_imports.borrow_mut().insert(import_def_id);
342344
}
343345

344346
let def = pick.item.def();

src/librustc_typeck/check/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ use CrateCtxt;
102102
use TypeAndSubsts;
103103
use lint;
104104
use util::common::{ErrorReported, indenter};
105-
use util::nodemap::{DefIdMap, FxHashMap, FxHashSet, NodeMap};
105+
use util::nodemap::{DefIdMap, DefIdSet, FxHashMap, FxHashSet, NodeMap};
106106

107107
use std::cell::{Cell, RefCell};
108108
use std::cmp;
@@ -179,6 +179,11 @@ pub struct Inherited<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
179179
// Obligations which will have to be checked at the end of
180180
// type-checking, after all functions have been inferred.
181181
deferred_obligations: RefCell<Vec<traits::DeferredObligation<'tcx>>>,
182+
183+
// a set of trait import def-ids that we use during method
184+
// resolution; during writeback, this is written into
185+
// `tcx.used_trait_imports` for this item def-id
186+
used_trait_imports: RefCell<FxHashSet<DefId>>,
182187
}
183188

184189
impl<'a, 'gcx, 'tcx> Deref for Inherited<'a, 'gcx, 'tcx> {
@@ -513,6 +518,7 @@ impl<'a, 'gcx, 'tcx> Inherited<'a, 'gcx, 'tcx> {
513518
deferred_cast_checks: RefCell::new(Vec::new()),
514519
anon_types: RefCell::new(DefIdMap()),
515520
deferred_obligations: RefCell::new(Vec::new()),
521+
used_trait_imports: RefCell::new(DefIdSet()),
516522
}
517523
}
518524

src/librustc_typeck/check/writeback.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ use rustc::ty::{self, Ty, TyCtxt, MethodCall, MethodCallee};
1919
use rustc::ty::adjustment;
2020
use rustc::ty::fold::{TypeFolder,TypeFoldable};
2121
use rustc::infer::{InferCtxt, FixupError};
22-
use rustc::util::nodemap::DefIdMap;
22+
use rustc::util::nodemap::{DefIdMap, DefIdSet};
2323

2424
use std::cell::Cell;
25+
use std::mem;
2526

2627
use syntax::ast;
2728
use syntax_pos::Span;
@@ -56,6 +57,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
5657

5758
let tables = self.tcx.alloc_tables(wbcx.tables);
5859
self.tcx.tables.borrow_mut().insert(item_def_id, tables);
60+
61+
let used_trait_imports = mem::replace(&mut *self.used_trait_imports.borrow_mut(),
62+
DefIdSet());
63+
debug!("used_trait_imports({:?}) = {:?}", item_def_id, used_trait_imports);
64+
self.tcx.used_trait_imports.borrow_mut().insert(item_def_id, used_trait_imports);
5965
}
6066
}
6167

src/librustc_typeck/check_unused.rs

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,21 @@ use syntax_pos::{Span, DUMMY_SP};
1717

1818
use rustc::hir;
1919
use rustc::hir::itemlikevisit::ItemLikeVisitor;
20+
use rustc::util::nodemap::DefIdSet;
2021

21-
struct UnusedTraitImportVisitor<'a, 'tcx: 'a> {
22+
struct CheckVisitor<'a, 'tcx: 'a> {
2223
tcx: TyCtxt<'a, 'tcx, 'tcx>,
24+
used_trait_imports: DefIdSet,
2325
}
2426

25-
impl<'a, 'tcx> UnusedTraitImportVisitor<'a, 'tcx> {
27+
impl<'a, 'tcx> CheckVisitor<'a, 'tcx> {
2628
fn check_import(&self, id: ast::NodeId, span: Span) {
2729
if !self.tcx.maybe_unused_trait_imports.contains(&id) {
2830
return;
2931
}
3032

3133
let import_def_id = self.tcx.hir.local_def_id(id);
32-
if self.tcx.used_trait_imports.borrow().contains(&import_def_id) {
34+
if self.used_trait_imports.contains(&import_def_id) {
3335
return;
3436
}
3537

@@ -42,7 +44,7 @@ impl<'a, 'tcx> UnusedTraitImportVisitor<'a, 'tcx> {
4244
}
4345
}
4446

45-
impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for UnusedTraitImportVisitor<'a, 'tcx> {
47+
impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CheckVisitor<'a, 'tcx> {
4648
fn visit_item(&mut self, item: &hir::Item) {
4749
if item.vis == hir::Public || item.span == DUMMY_SP {
4850
return;
@@ -61,6 +63,21 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for UnusedTraitImportVisitor<'a, 'tcx> {
6163

6264
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
6365
let _task = tcx.dep_graph.in_task(DepNode::UnusedTraitCheck);
64-
let mut visitor = UnusedTraitImportVisitor { tcx: tcx };
66+
67+
let mut used_trait_imports = DefIdSet();
68+
for &body_id in tcx.hir.krate().bodies.keys() {
69+
let item_id = tcx.hir.body_owner(body_id);
70+
let item_def_id = tcx.hir.local_def_id(item_id);
71+
72+
// this will have been written by the main typeck pass
73+
if let Some(imports) = tcx.used_trait_imports.borrow().get(&item_def_id) {
74+
debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
75+
used_trait_imports.extend(imports);
76+
} else {
77+
debug!("GatherVisitor: item_def_id={:?} with no imports", item_def_id);
78+
}
79+
}
80+
81+
let mut visitor = CheckVisitor { tcx, used_trait_imports };
6582
tcx.hir.krate().visit_all_item_likes(&mut visitor);
6683
}

src/librustc_typeck/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ This API is completely unstable and subject to change.
7777
#![feature(box_patterns)]
7878
#![feature(box_syntax)]
7979
#![feature(conservative_impl_trait)]
80+
#![feature(field_init_shorthand)]
8081
#![feature(loop_break_value)]
8182
#![feature(quote)]
8283
#![feature(rustc_diagnostic_macros)]

0 commit comments

Comments
 (0)