pub n_glues_created: Cell<usize>,
pub n_null_glues: Cell<usize>,
pub n_real_glues: Cell<usize>,
- pub n_fallback_instantiations: Cell<usize>,
pub n_fns: Cell<usize>,
- pub n_monos: Cell<usize>,
pub n_inlines: Cell<usize>,
pub n_closures: Cell<usize>,
pub n_llvm_insns: Cell<usize>,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
stats: Stats,
check_overflow: bool,
- check_drop_flag_for_sanity: bool,
mir_map: &'a MirMap<'tcx>,
mir_cache: RefCell<DepTrackingMap<MirCache<'tcx>>>,
translation_items: RefCell<FnvHashSet<TransItem<'tcx>>>,
trait_cache: RefCell<DepTrackingMap<TraitSelectionCache<'tcx>>>,
+ project_cache: RefCell<DepTrackingMap<ProjectionCache<'tcx>>>,
}
/// The local portion of a `CrateContext`. There is one `LocalCrateContext`
drop_glues: RefCell<FnvHashMap<DropGlueKind<'tcx>, (ValueRef, FnType)>>,
/// Cache instances of monomorphic and polymorphic items
instances: RefCell<FnvHashMap<Instance<'tcx>, ValueRef>>,
- monomorphizing: RefCell<DefIdMap<usize>>,
/// Cache generated vtables
vtables: RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>>,
/// Cache of constant strings,
}
}
+// # Global Cache
+
+pub struct ProjectionCache<'gcx> {
+ data: PhantomData<&'gcx ()>
+}
+
+impl<'gcx> DepTrackingMapConfig for ProjectionCache<'gcx> {
+ type Key = Ty<'gcx>;
+ type Value = Ty<'gcx>;
+ fn to_dep_node(key: &Self::Key) -> DepNode<DefId> {
+ // Ideally, we'd just put `key` into the dep-node, but we
+ // can't put full types in there. So just collect up all the
+ // def-ids of structs/enums as well as any traits that we
+ // project out of. It doesn't matter so much what we do here,
+ // except that if we are too coarse, we'll create overly
+ // coarse edges between impls and the trans. For example, if
+ // we just used the def-id of things we are projecting out of,
+ // then the key for `<Foo as SomeTrait>::T` and `<Bar as
+ // SomeTrait>::T` would both share a dep-node
+ // (`TraitSelect(SomeTrait)`), and hence the impls for both
+ // `Foo` and `Bar` would be considered inputs. So a change to
+ // `Bar` would affect things that just normalized `Foo`.
+ // Anyway, this heuristic is not ideal, but better than
+ // nothing.
+ let def_ids: Vec<DefId> =
+ key.walk()
+ .filter_map(|t| match t.sty {
+ ty::TyStruct(adt_def, _) |
+ ty::TyEnum(adt_def, _) =>
+ Some(adt_def.did),
+ ty::TyProjection(ref proj) =>
+ Some(proj.trait_ref.def_id),
+ _ =>
+ None
+ })
+ .collect();
+ DepNode::TraitSelect(def_ids)
+ }
+}
+
/// This list owns a number of LocalCrateContexts and binds them to their common
/// SharedCrateContext. This type just exists as a convenience, something to
/// pass around all LocalCrateContexts with and get an iterator over them.
symbol_hasher: Sha256,
link_meta: LinkMeta,
reachable: NodeSet,
- check_overflow: bool,
- check_drop_flag_for_sanity: bool)
+ check_overflow: bool)
-> SharedCrateContext<'b, 'tcx> {
let (metadata_llcx, metadata_llmod) = unsafe {
create_context_and_module(&tcx.sess, "metadata")
n_glues_created: Cell::new(0),
n_null_glues: Cell::new(0),
n_real_glues: Cell::new(0),
- n_fallback_instantiations: Cell::new(0),
n_fns: Cell::new(0),
- n_monos: Cell::new(0),
n_inlines: Cell::new(0),
n_closures: Cell::new(0),
n_llvm_insns: Cell::new(0),
fn_stats: RefCell::new(Vec::new()),
},
check_overflow: check_overflow,
- check_drop_flag_for_sanity: check_drop_flag_for_sanity,
use_dll_storage_attrs: use_dll_storage_attrs,
translation_items: RefCell::new(FnvHashSet()),
trait_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
+ project_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
}
}
&self.trait_cache
}
+ pub fn project_cache(&self) -> &RefCell<DepTrackingMap<ProjectionCache<'tcx>>> {
+ &self.project_cache
+ }
+
pub fn link_meta<'a>(&'a self) -> &'a LinkMeta {
&self.link_meta
}
/// Given the def-id of some item that has no type parameters, make
/// a suitable "empty substs" for it.
pub fn empty_substs_for_def_id(&self, item_def_id: DefId) -> &'tcx Substs<'tcx> {
- Substs::for_item(self.tcx(), item_def_id, |_, _| ty::ReErased, |_, _| {
+ Substs::for_item(self.tcx(), item_def_id,
+ |_, _| self.tcx().mk_region(ty::ReErased),
+ |_, _| {
bug!("empty_substs_for_def_id: {:?} has type parameters", item_def_id)
})
}
fn_pointer_shims: RefCell::new(FnvHashMap()),
drop_glues: RefCell::new(FnvHashMap()),
instances: RefCell::new(FnvHashMap()),
- monomorphizing: RefCell::new(DefIdMap()),
vtables: RefCell::new(FnvHashMap()),
const_cstr_cache: RefCell::new(FnvHashMap()),
const_unsized: RefCell::new(FnvHashMap()),
&self.local().instances
}
- pub fn monomorphizing<'a>(&'a self) -> &'a RefCell<DefIdMap<usize>> {
- &self.local().monomorphizing
- }
-
pub fn vtables<'a>(&'a self) -> &'a RefCell<FnvHashMap<ty::PolyTraitRef<'tcx>, ValueRef>> {
&self.local().vtables
}
TypeOfDepthLock(self.local())
}
- pub fn check_overflow(&self) -> bool {
- self.shared.check_overflow
+ pub fn layout_of(&self, ty: Ty<'tcx>) -> &'tcx ty::layout::Layout {
+ self.tcx().infer_ctxt(None, None, traits::Reveal::All).enter(|infcx| {
+ ty.layout(&infcx).unwrap_or_else(|e| {
+ bug!("failed to get layout for `{}`: {}", ty, e);
+ })
+ })
}
- pub fn check_drop_flag_for_sanity(&self) -> bool {
- // This controls whether we emit a conditional llvm.debugtrap
- // guarded on whether the dropflag is one of its (two) valid
- // values.
- self.shared.check_drop_flag_for_sanity
+ pub fn check_overflow(&self) -> bool {
+ self.shared.check_overflow
}
pub fn use_dll_storage_attrs(&self) -> bool {