Skip to content

Commit f4c183b

Browse files
committed
move the trans trait caches into tcx
Arguably these could become custom queries, but I chose not to do that because the relationship of queries and trait system is not yet fleshed out enough. For now it seems fine to have them be `DepTrackingMap` using the memoize pattern.
1 parent e48a759 commit f4c183b

File tree

5 files changed

+89
-78
lines changed

5 files changed

+89
-78
lines changed

src/librustc/traits/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ mod object_safety;
5555
mod select;
5656
mod specialize;
5757
mod structural_impls;
58+
pub mod trans;
5859
mod util;
5960

6061
/// An `Obligation` represents some trait reference (e.g. `int:Eq`) for

src/librustc/traits/trans/mod.rs

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
2+
use hir::def_id::DefId;
3+
use std::cell::RefCell;
4+
use std::marker::PhantomData;
5+
use traits::Vtable;
6+
use ty::{self, Ty};
7+
8+
/// Specializes caches used in trans -- in particular, they assume all
9+
/// types are fully monomorphized and that free regions can be erased.
10+
pub struct TransTraitCaches<'tcx> {
11+
pub trait_cache: RefCell<DepTrackingMap<TraitSelectionCache<'tcx>>>,
12+
pub project_cache: RefCell<DepTrackingMap<ProjectionCache<'tcx>>>,
13+
}
14+
15+
impl<'tcx> TransTraitCaches<'tcx> {
16+
pub fn new(graph: DepGraph) -> Self {
17+
TransTraitCaches {
18+
trait_cache: RefCell::new(DepTrackingMap::new(graph.clone())),
19+
project_cache: RefCell::new(DepTrackingMap::new(graph)),
20+
}
21+
}
22+
}
23+
24+
// Implement DepTrackingMapConfig for `trait_cache`
25+
pub struct TraitSelectionCache<'tcx> {
26+
data: PhantomData<&'tcx ()>
27+
}
28+
29+
impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> {
30+
type Key = ty::PolyTraitRef<'tcx>;
31+
type Value = Vtable<'tcx, ()>;
32+
fn to_dep_node(key: &ty::PolyTraitRef<'tcx>) -> DepNode<DefId> {
33+
key.to_poly_trait_predicate().dep_node()
34+
}
35+
}
36+
37+
// # Global Cache
38+
39+
pub struct ProjectionCache<'gcx> {
40+
data: PhantomData<&'gcx ()>
41+
}
42+
43+
impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
44+
type Key = Ty<'gcx>;
45+
type Value = Ty<'gcx>;
46+
fn to_dep_node(key: &Self::Key) -> DepNode<DefId> {
47+
// Ideally, we'd just put `key` into the dep-node, but we
48+
// can't put full types in there. So just collect up all the
49+
// def-ids of structs/enums as well as any traits that we
50+
// project out of. It doesn't matter so much what we do here,
51+
// except that if we are too coarse, we'll create overly
52+
// coarse edges between impls and the trans. For example, if
53+
// we just used the def-id of things we are projecting out of,
54+
// then the key for `<Foo as SomeTrait>::T` and `<Bar as
55+
// SomeTrait>::T` would both share a dep-node
56+
// (`TraitSelect(SomeTrait)`), and hence the impls for both
57+
// `Foo` and `Bar` would be considered inputs. So a change to
58+
// `Bar` would affect things that just normalized `Foo`.
59+
// Anyway, this heuristic is not ideal, but better than
60+
// nothing.
61+
let def_ids: Vec<DefId> =
62+
key.walk()
63+
.filter_map(|t| match t.sty {
64+
ty::TyAdt(adt_def, _) => Some(adt_def.did),
65+
ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
66+
_ => None,
67+
})
68+
.collect();
69+
70+
DepNode::ProjectionCache { def_ids: def_ids }
71+
}
72+
}
73+

src/librustc/ty/context.rs

+3
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,8 @@ pub struct GlobalCtxt<'tcx> {
407407

408408
pub specializes_cache: RefCell<traits::SpecializesCache>,
409409

410+
pub trans_trait_caches: traits::trans::TransTraitCaches<'tcx>,
411+
410412
pub dep_graph: DepGraph,
411413

412414
/// Common types, pre-interned for your convenience.
@@ -689,6 +691,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
689691
providers[LOCAL_CRATE] = local_providers;
690692
tls::enter_global(GlobalCtxt {
691693
sess: s,
694+
trans_trait_caches: traits::trans::TransTraitCaches::new(dep_graph.clone()),
692695
specializes_cache: RefCell::new(traits::SpecializesCache::new()),
693696
global_arenas: arenas,
694697
global_interners: interners,

src/librustc_trans/context.rs

+1-65
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
use llvm;
1212
use llvm::{ContextRef, ModuleRef, ValueRef};
13-
use rustc::dep_graph::{DepGraph, DepGraphSafe, DepNode, DepTrackingMap, DepTrackingMapConfig};
13+
use rustc::dep_graph::{DepGraph, DepGraphSafe};
1414
use rustc::hir;
1515
use rustc::hir::def_id::DefId;
1616
use rustc::traits;
@@ -34,7 +34,6 @@ use util::nodemap::{NodeSet, DefIdMap, FxHashMap};
3434

3535
use std::ffi::{CStr, CString};
3636
use std::cell::{Cell, RefCell};
37-
use std::marker::PhantomData;
3837
use std::ptr;
3938
use std::iter;
4039
use std::str;
@@ -84,9 +83,6 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
8483
check_overflow: bool,
8584

8685
use_dll_storage_attrs: bool,
87-
88-
trait_cache: RefCell<DepTrackingMap<TraitSelectionCache<'tcx>>>,
89-
project_cache: RefCell<DepTrackingMap<ProjectionCache<'tcx>>>,
9086
}
9187

9288
/// The local portion of a `CrateContext`. There is one `LocalCrateContext`
@@ -171,56 +167,6 @@ pub struct LocalCrateContext<'a, 'tcx: 'a> {
171167
symbol_cache: &'a SymbolCache<'a, 'tcx>,
172168
}
173169

174-
// Implement DepTrackingMapConfig for `trait_cache`
175-
pub struct TraitSelectionCache<'tcx> {
176-
data: PhantomData<&'tcx ()>
177-
}
178-
179-
impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> {
180-
type Key = ty::PolyTraitRef<'tcx>;
181-
type Value = traits::Vtable<'tcx, ()>;
182-
fn to_dep_node(key: &ty::PolyTraitRef<'tcx>) -> DepNode<DefId> {
183-
key.to_poly_trait_predicate().dep_node()
184-
}
185-
}
186-
187-
// # Global Cache
188-
189-
pub struct ProjectionCache<'gcx> {
190-
data: PhantomData<&'gcx ()>
191-
}
192-
193-
impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
194-
type Key = Ty<'gcx>;
195-
type Value = Ty<'gcx>;
196-
fn to_dep_node(key: &Self::Key) -> DepNode<DefId> {
197-
// Ideally, we'd just put `key` into the dep-node, but we
198-
// can't put full types in there. So just collect up all the
199-
// def-ids of structs/enums as well as any traits that we
200-
// project out of. It doesn't matter so much what we do here,
201-
// except that if we are too coarse, we'll create overly
202-
// coarse edges between impls and the trans. For example, if
203-
// we just used the def-id of things we are projecting out of,
204-
// then the key for `<Foo as SomeTrait>::T` and `<Bar as
205-
// SomeTrait>::T` would both share a dep-node
206-
// (`TraitSelect(SomeTrait)`), and hence the impls for both
207-
// `Foo` and `Bar` would be considered inputs. So a change to
208-
// `Bar` would affect things that just normalized `Foo`.
209-
// Anyway, this heuristic is not ideal, but better than
210-
// nothing.
211-
let def_ids: Vec<DefId> =
212-
key.walk()
213-
.filter_map(|t| match t.sty {
214-
ty::TyAdt(adt_def, _) => Some(adt_def.did),
215-
ty::TyProjection(ref proj) => Some(proj.trait_ref.def_id),
216-
_ => None,
217-
})
218-
.collect();
219-
220-
DepNode::ProjectionCache { def_ids: def_ids }
221-
}
222-
}
223-
224170
/// A CrateContext value binds together one LocalCrateContext with the
225171
/// SharedCrateContext. It exists as a convenience wrapper, so we don't have to
226172
/// pass around (SharedCrateContext, LocalCrateContext) tuples all over trans.
@@ -382,8 +328,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
382328
tcx: tcx,
383329
check_overflow: check_overflow,
384330
use_dll_storage_attrs: use_dll_storage_attrs,
385-
trait_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
386-
project_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
387331
}
388332
}
389333

@@ -403,14 +347,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
403347
&self.exported_symbols
404348
}
405349

406-
pub fn trait_cache(&self) -> &RefCell<DepTrackingMap<TraitSelectionCache<'tcx>>> {
407-
&self.trait_cache
408-
}
409-
410-
pub fn project_cache(&self) -> &RefCell<DepTrackingMap<ProjectionCache<'tcx>>> {
411-
&self.project_cache
412-
}
413-
414350
pub fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
415351
self.tcx
416352
}

src/librustc_trans/monomorphize.rs

+11-13
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ fn fulfill_obligation<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
117117
// Remove any references to regions; this helps improve caching.
118118
let trait_ref = tcx.erase_regions(&trait_ref);
119119

120-
scx.trait_cache().memoize(trait_ref, || {
120+
tcx.trans_trait_caches.trait_cache.memoize(trait_ref, || {
121121
debug!("trans::fulfill_obligation(trait_ref={:?}, def_id={:?})",
122122
trait_ref, trait_ref.def_id());
123123

@@ -307,7 +307,7 @@ pub fn apply_param_substs<'a, 'tcx, T>(scx: &SharedCrateContext<'a, 'tcx>,
307307
debug!("apply_param_substs(param_substs={:?}, value={:?})", param_substs, value);
308308
let substituted = value.subst(tcx, param_substs);
309309
let substituted = scx.tcx().erase_regions(&substituted);
310-
AssociatedTypeNormalizer::new(scx).fold(&substituted)
310+
AssociatedTypeNormalizer::new(tcx).fold(&substituted)
311311
}
312312

313313
/// Returns the normalized type of a struct field
@@ -319,15 +319,13 @@ pub fn field_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
319319
tcx.normalize_associated_type(&f.ty(tcx, param_substs))
320320
}
321321

322-
struct AssociatedTypeNormalizer<'a, 'b: 'a, 'gcx: 'b> {
323-
shared: &'a SharedCrateContext<'b, 'gcx>,
322+
struct AssociatedTypeNormalizer<'a, 'gcx: 'a> {
323+
tcx: TyCtxt<'a, 'gcx, 'gcx>,
324324
}
325325

326-
impl<'a, 'b, 'gcx> AssociatedTypeNormalizer<'a, 'b, 'gcx> {
327-
fn new(shared: &'a SharedCrateContext<'b, 'gcx>) -> Self {
328-
AssociatedTypeNormalizer {
329-
shared: shared,
330-
}
326+
impl<'a, 'gcx> AssociatedTypeNormalizer<'a, 'gcx> {
327+
fn new(tcx: TyCtxt<'a, 'gcx, 'gcx>) -> Self {
328+
AssociatedTypeNormalizer { tcx }
331329
}
332330

333331
fn fold<T:TypeFoldable<'gcx>>(&mut self, value: &T) -> T {
@@ -339,18 +337,18 @@ impl<'a, 'b, 'gcx> AssociatedTypeNormalizer<'a, 'b, 'gcx> {
339337
}
340338
}
341339

342-
impl<'a, 'b, 'gcx> TypeFolder<'gcx, 'gcx> for AssociatedTypeNormalizer<'a, 'b, 'gcx> {
340+
impl<'a, 'gcx> TypeFolder<'gcx, 'gcx> for AssociatedTypeNormalizer<'a, 'gcx> {
343341
fn tcx<'c>(&'c self) -> TyCtxt<'c, 'gcx, 'gcx> {
344-
self.shared.tcx()
342+
self.tcx
345343
}
346344

347345
fn fold_ty(&mut self, ty: Ty<'gcx>) -> Ty<'gcx> {
348346
if !ty.has_projection_types() {
349347
ty
350348
} else {
351-
self.shared.project_cache().memoize(ty, || {
349+
self.tcx.trans_trait_caches.project_cache.memoize(ty, || {
352350
debug!("AssociatedTypeNormalizer: ty={:?}", ty);
353-
self.shared.tcx().normalize_associated_type(&ty)
351+
self.tcx.normalize_associated_type(&ty)
354352
})
355353
}
356354
}

0 commit comments

Comments
 (0)