From b5c4244c6c46df22bb55531b629f4c314fe2ab22 Mon Sep 17 00:00:00 2001 From: Eduard Burtescu Date: Thu, 29 Sep 2016 02:30:53 +0300 Subject: [PATCH] rustc: introduce a query system for type information in ty::maps. --- src/librustc/hir/lowering.rs | 2 +- src/librustc/middle/cstore.rs | 82 +++------ src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc/middle/stability.rs | 34 ++-- src/librustc/session/mod.rs | 8 +- src/librustc/traits/fulfill.rs | 2 +- src/librustc/ty/context.rs | 16 +- src/librustc/ty/item_path.rs | 2 +- src/librustc/ty/maps.rs | 119 +++++++++---- src/librustc/ty/mod.rs | 147 ++++------------ src/librustc/util/ppaux.rs | 2 +- src/librustc_const_eval/eval.rs | 2 +- src/librustc_driver/driver.rs | 9 +- src/librustc_driver/test.rs | 2 + src/librustc_lint/bad_style.rs | 2 +- src/librustc_metadata/cstore.rs | 2 + src/librustc_metadata/cstore_impl.rs | 177 ++++++++++---------- src/librustc_metadata/decoder.rs | 61 +++---- src/librustc_metadata/encoder.rs | 4 +- src/librustc_metadata/lib.rs | 1 + src/librustc_resolve/build_reduced_graph.rs | 4 +- src/librustc_typeck/check/upvar.rs | 2 +- src/librustc_typeck/check/writeback.rs | 6 +- src/librustc_typeck/coherence/builtin.rs | 2 +- src/librustc_typeck/coherence/mod.rs | 2 +- src/librustc_typeck/collect.rs | 32 ++-- src/librustdoc/visit_lib.rs | 2 +- 27 files changed, 333 insertions(+), 393 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 82e644d710d..bfcaf1e00f0 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -525,7 +525,7 @@ impl<'a> LoweringContext<'a> { return n; } assert!(!def_id.is_local()); - let n = self.sess.cstore.item_generics(def_id).regions.len(); + let n = self.sess.cstore.item_generics_cloned(def_id).regions.len(); self.type_def_lifetime_params.insert(def_id, n); n }); diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 671da0d1197..cb5ced57bd8 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -28,12 +28,12 @@ use hir::map as hir_map; use hir::map::definitions::{Definitions, DefKey, DisambiguatedDefPathData}; use hir::svh::Svh; use middle::lang_items; -use ty::{self, Ty, TyCtxt}; -use mir::Mir; +use ty::{self, TyCtxt}; use session::Session; use session::search_paths::PathKind; use util::nodemap::{NodeSet, DefIdMap}; +use std::any::Any; use std::collections::BTreeMap; use std::path::PathBuf; use std::rc::Rc; @@ -163,28 +163,18 @@ pub struct ExternCrate { /// A store of Rust crates, through with their metadata /// can be accessed. -pub trait CrateStore<'tcx> { +pub trait CrateStore { + fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc; + // item info fn describe_def(&self, def: DefId) -> Option; fn def_span(&self, sess: &Session, def: DefId) -> Span; fn stability(&self, def: DefId) -> Option; fn deprecation(&self, def: DefId) -> Option; fn visibility(&self, def: DefId) -> ty::Visibility; - fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind; - fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> ty::ClosureTy<'tcx>; - fn item_variances(&self, def: DefId) -> Vec; - fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Ty<'tcx>; fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap>; - fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> ty::GenericPredicates<'tcx>; - fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> ty::GenericPredicates<'tcx>; - fn item_generics(&self, def: DefId) -> ty::Generics; + fn item_generics_cloned(&self, def: DefId) -> ty::Generics; fn item_attrs(&self, def_id: DefId) -> Vec; - fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef; - fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> &'tcx ty::AdtDef; fn fn_arg_names(&self, did: DefId) -> Vec; fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec; @@ -192,17 +182,12 @@ pub trait CrateStore<'tcx> { fn implementations_of_trait(&self, filter: Option) -> Vec; // impl info - fn associated_item_def_ids(&self, def_id: DefId) -> Vec; - fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option>; fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity; - fn custom_coerce_unsized_kind(&self, def: DefId) - -> Option; fn impl_parent(&self, impl_def_id: DefId) -> Option; // trait/impl-item info fn trait_of_item(&self, def_id: DefId) -> Option; - fn associated_item(&self, def: DefId) -> Option; + fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem; // flags fn is_const_fn(&self, did: DefId) -> bool; @@ -252,12 +237,11 @@ pub trait CrateStore<'tcx> { fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro; // misc. metadata - fn maybe_get_item_body<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option<&'tcx hir::Body>; + fn maybe_get_item_body<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) + -> Option<&'tcx hir::Body>; fn item_body_nested_bodies(&self, def: DefId) -> BTreeMap; fn const_is_rvalue_promotable_to_static(&self, def: DefId) -> bool; - fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx>; fn is_item_mir_available(&self, def: DefId) -> bool; // This is basically a 1-based range of ints, which is a little @@ -272,10 +256,10 @@ pub trait CrateStore<'tcx> { fn used_crates(&self, prefer: LinkagePreference) -> Vec<(CrateNum, LibSource)>; fn used_crate_source(&self, cnum: CrateNum) -> CrateSource; fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option; - fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - reexports: &def::ExportMap, - link_meta: &LinkMeta, - reachable: &NodeSet) -> Vec; + fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, + reexports: &def::ExportMap, + link_meta: &LinkMeta, + reachable: &NodeSet) -> Vec; fn metadata_encoding_version(&self) -> &[u8]; } @@ -309,33 +293,23 @@ pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option) { /// A dummy crate store that does not support any non-local crates, /// for test purposes. pub struct DummyCrateStore; + #[allow(unused_variables)] -impl<'tcx> CrateStore<'tcx> for DummyCrateStore { +impl CrateStore for DummyCrateStore { + fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc + { bug!("crate_data_as_rc_any") } // item info fn describe_def(&self, def: DefId) -> Option { bug!("describe_def") } fn def_span(&self, sess: &Session, def: DefId) -> Span { bug!("def_span") } fn stability(&self, def: DefId) -> Option { bug!("stability") } fn deprecation(&self, def: DefId) -> Option { bug!("deprecation") } fn visibility(&self, def: DefId) -> ty::Visibility { bug!("visibility") } - fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind { bug!("closure_kind") } - fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) - -> ty::ClosureTy<'tcx> { bug!("closure_ty") } - fn item_variances(&self, def: DefId) -> Vec { bug!("item_variances") } - fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Ty<'tcx> { bug!("item_type") } fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap> { bug!("visible_parent_map") } - fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> ty::GenericPredicates<'tcx> { bug!("item_predicates") } - fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> ty::GenericPredicates<'tcx> { bug!("item_super_predicates") } - fn item_generics(&self, def: DefId) -> ty::Generics { bug!("item_generics") } + fn item_generics_cloned(&self, def: DefId) -> ty::Generics + { bug!("item_generics_cloned") } fn item_attrs(&self, def_id: DefId) -> Vec { bug!("item_attrs") } - fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef - { bug!("trait_def") } - fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> &'tcx ty::AdtDef - { bug!("adt_def") } fn fn_arg_names(&self, did: DefId) -> Vec { bug!("fn_arg_names") } fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec { vec![] } @@ -343,19 +317,13 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn implementations_of_trait(&self, filter: Option) -> Vec { vec![] } // impl info - fn associated_item_def_ids(&self, def_id: DefId) -> Vec - { bug!("associated_items") } - fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option> { bug!("impl_trait_ref") } fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity { bug!("impl_polarity") } - fn custom_coerce_unsized_kind(&self, def: DefId) - -> Option - { bug!("custom_coerce_unsized_kind") } fn impl_parent(&self, def: DefId) -> Option { bug!("impl_parent") } // trait/impl-item info fn trait_of_item(&self, def_id: DefId) -> Option { bug!("trait_of_item") } - fn associated_item(&self, def: DefId) -> Option { bug!("associated_item") } + fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem + { bug!("associated_item_cloned") } // flags fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") } @@ -418,8 +386,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn load_macro(&self, did: DefId, sess: &Session) -> LoadedMacro { bug!("load_macro") } // misc. metadata - fn maybe_get_item_body<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option<&'tcx hir::Body> { + fn maybe_get_item_body<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) + -> Option<&'tcx hir::Body> { bug!("maybe_get_item_body") } fn item_body_nested_bodies(&self, def: DefId) -> BTreeMap { @@ -429,8 +397,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { bug!("const_is_rvalue_promotable_to_static") } - fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Mir<'tcx> { bug!("get_item_mir") } fn is_item_mir_available(&self, def: DefId) -> bool { bug!("is_item_mir_available") } @@ -448,7 +414,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { { vec![] } fn used_crate_source(&self, cnum: CrateNum) -> CrateSource { bug!("used_crate_source") } fn extern_mod_stmt_cnum(&self, emod_id: ast::NodeId) -> Option { None } - fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, + fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, reexports: &def::ExportMap, link_meta: &LinkMeta, reachable: &NodeSet) -> Vec { vec![] } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 95cbd738651..37749816eb1 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -995,7 +995,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } else { let cstore = &self.sess.cstore; self.xcrate_object_lifetime_defaults.entry(def_id).or_insert_with(|| { - cstore.item_generics(def_id).types.into_iter().map(|def| { + cstore.item_generics_cloned(def_id).types.into_iter().map(|def| { def.object_lifetime_default }).collect() }) diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 487e13b47fe..baa22d70614 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -433,23 +433,27 @@ struct Checker<'a, 'tcx: 'a> { impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // (See issue #38412) - fn skip_stability_check_due_to_privacy(self, def_id: DefId) -> bool { - let visibility = { - // Check if `def_id` is a trait method. - match self.sess.cstore.associated_item(def_id) { - Some(ty::AssociatedItem { container: ty::TraitContainer(trait_def_id), .. }) => { - // Trait methods do not declare visibility (even - // for visibility info in cstore). Use containing - // trait instead, so methods of pub traits are - // themselves considered pub. - self.sess.cstore.visibility(trait_def_id) - } - _ => { - // Otherwise, cstore info works directly. - self.sess.cstore.visibility(def_id) + fn skip_stability_check_due_to_privacy(self, mut def_id: DefId) -> bool { + // Check if `def_id` is a trait method. + match self.sess.cstore.describe_def(def_id) { + Some(Def::Method(_)) | + Some(Def::AssociatedTy(_)) | + Some(Def::AssociatedConst(_)) => { + match self.associated_item(def_id).container { + ty::TraitContainer(trait_def_id) => { + // Trait methods do not declare visibility (even + // for visibility info in cstore). Use containing + // trait instead, so methods of pub traits are + // themselves considered pub. + def_id = trait_def_id; + } + _ => {} } } - }; + _ => {} + } + + let visibility = self.sess.cstore.visibility(def_id); match visibility { // must check stability for pub items. diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs index 68edcc60779..3ba82f34c32 100644 --- a/src/librustc/session/mod.rs +++ b/src/librustc/session/mod.rs @@ -64,7 +64,7 @@ pub struct Session { pub target: config::Config, pub host: Target, pub opts: config::Options, - pub cstore: Rc CrateStore<'a>>, + pub cstore: Rc, pub parse_sess: ParseSess, // For a library crate, this is always none pub entry_fn: RefCell>, @@ -510,7 +510,7 @@ pub fn build_session(sopts: config::Options, dep_graph: &DepGraph, local_crate_source_file: Option, registry: errors::registry::Registry, - cstore: Rc CrateStore<'a>>) + cstore: Rc) -> Session { build_session_with_codemap(sopts, dep_graph, @@ -525,7 +525,7 @@ pub fn build_session_with_codemap(sopts: config::Options, dep_graph: &DepGraph, local_crate_source_file: Option, registry: errors::registry::Registry, - cstore: Rc CrateStore<'a>>, + cstore: Rc, codemap: Rc, emitter_dest: Option>) -> Session { @@ -575,7 +575,7 @@ pub fn build_session_(sopts: config::Options, local_crate_source_file: Option, span_diagnostic: errors::Handler, codemap: Rc, - cstore: Rc CrateStore<'a>>) + cstore: Rc) -> Session { let host = match Target::search(config::host_triple()) { Ok(t) => t, diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index e28a8392e58..c31ab2372b6 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -155,7 +155,7 @@ impl<'a, 'gcx, 'tcx> DeferredObligation<'tcx> { -> Option>> { if let ty::TyAnon(def_id, substs) = self.predicate.skip_binder().self_ty().sty { let ty = if def_id.is_local() { - tcx.maps.types.borrow().get(&def_id).cloned() + tcx.maps.ty.borrow().get(&def_id).cloned() } else { Some(tcx.item_type(def_id)) }; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 665d60281d1..62aa6522a7b 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -44,6 +44,7 @@ use util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::accumulate_vec::AccumulateVec; use arena::{TypedArena, DroplessArena}; +use rustc_data_structures::indexed_vec::IndexVec; use std::borrow::Borrow; use std::cell::{Cell, RefCell}; use std::hash::{Hash, Hasher}; @@ -220,7 +221,7 @@ pub struct TypeckTables<'tcx> { /// Records the type of each closure. pub closure_tys: NodeMap>, - /// Records the type of each closure. + /// Records the kind of each closure. pub closure_kinds: NodeMap, /// For each fn, records the "liberated" types of its arguments @@ -389,6 +390,8 @@ pub struct GlobalCtxt<'tcx> { global_arenas: &'tcx GlobalArenas<'tcx>, global_interners: CtxtInterners<'tcx>, + pub sess: &'tcx Session, + pub specializes_cache: RefCell, pub dep_graph: DepGraph, @@ -396,8 +399,6 @@ pub struct GlobalCtxt<'tcx> { /// Common types, pre-interned for your convenience. pub types: CommonTypes<'tcx>, - pub sess: &'tcx Session, - /// Map indicating what traits are in scope for places where this /// is relevant; generated by resolve. pub trait_map: TraitMap, @@ -659,6 +660,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// value (types, substs, etc.) can only be used while `ty::tls` has a valid /// reference to the context, to allow formatting values that need it. pub fn create_and_enter(s: &'tcx Session, + local_providers: ty::maps::Providers<'tcx>, + extern_providers: ty::maps::Providers<'tcx>, arenas: &'tcx GlobalArenas<'tcx>, arena: &'tcx DroplessArena, resolutions: ty::Resolutions, @@ -676,7 +679,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let common_types = CommonTypes::new(&interners); let dep_graph = hir.dep_graph.clone(); let fulfilled_predicates = traits::GlobalFulfilledPredicates::new(dep_graph.clone()); + let max_cnum = s.cstore.crates().iter().map(|c| c.as_usize()).max().unwrap_or(0); + let mut providers = IndexVec::from_elem_n(extern_providers, max_cnum + 1); + providers[LOCAL_CRATE] = local_providers; tls::enter_global(GlobalCtxt { + sess: s, specializes_cache: RefCell::new(traits::SpecializesCache::new()), global_arenas: arenas, global_interners: interners, @@ -686,11 +693,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { region_maps: region_maps, free_region_maps: RefCell::new(FxHashMap()), variance_computed: Cell::new(false), - sess: s, trait_map: resolutions.trait_map, fulfilled_predicates: RefCell::new(fulfilled_predicates), hir: hir, - maps: maps::Maps::new(dep_graph), + maps: maps::Maps::new(dep_graph, providers), freevars: RefCell::new(resolutions.freevars), maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports, rcache: RefCell::new(FxHashMap()), diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index c31895b3e9d..7bf1ba155b5 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -201,7 +201,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } else { // for local crates, check whether type info is // available; typeck might not have completed yet - self.maps.impl_trait_refs.borrow().contains_key(&impl_def_id) + self.maps.impl_trait_ref.borrow().contains_key(&impl_def_id) }; if !use_types { diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 3e37bd50f94..4a91cdd24fc 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -9,49 +9,102 @@ // except according to those terms. use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig}; -use hir::def_id::DefId; +use hir::def_id::{CrateNum, DefId}; use middle::const_val::ConstVal; -use ty::{self, Ty}; +use mir; +use ty::{self, Ty, TyCtxt}; +use util::common::MemoizationMap; use util::nodemap::DefIdSet; +use rustc_data_structures::indexed_vec::IndexVec; use std::cell::RefCell; -use std::marker::PhantomData; use std::rc::Rc; use syntax::attr; +trait Key { + fn map_crate(&self) -> CrateNum; +} + +impl Key for DefId { + fn map_crate(&self) -> CrateNum { + self.krate + } +} + macro_rules! define_maps { - ($($(#[$attr:meta])* pub $field:ident: $node_name:ident($key:ty) -> $value:ty),*) => { - pub struct Maps<'tcx> { - $($(#[$attr])* pub $field: RefCell>>),* + (<$tcx:tt> + $($(#[$attr:meta])* + pub $name:ident: $node:ident($K:ty) -> $V:ty),*) => { + pub struct Maps<$tcx> { + providers: IndexVec>, + $($(#[$attr])* pub $name: RefCell>>),* } - impl<'tcx> Maps<'tcx> { - pub fn new(dep_graph: DepGraph) -> Self { + impl<$tcx> Maps<$tcx> { + pub fn new(dep_graph: DepGraph, + providers: IndexVec>) + -> Self { Maps { - $($field: RefCell::new(DepTrackingMap::new(dep_graph.clone()))),* + providers, + $($name: RefCell::new(DepTrackingMap::new(dep_graph.clone()))),* } } } - $(#[allow(bad_style)] - pub struct $field<'tcx> { - data: PhantomData<&'tcx ()> + pub mod queries { + use std::marker::PhantomData; + + $(#[allow(bad_style)] + pub struct $name<$tcx> { + data: PhantomData<&$tcx ()> + })* } - impl<'tcx> DepTrackingMapConfig for $field<'tcx> { - type Key = $key; - type Value = $value; - fn to_dep_node(key: &$key) -> DepNode { DepNode::$node_name(*key) } + $(impl<$tcx> DepTrackingMapConfig for queries::$name<$tcx> { + type Key = $K; + type Value = $V; + fn to_dep_node(key: &$K) -> DepNode { DepNode::$node(*key) } })* + + pub struct Providers<$tcx> { + $(pub $name: for<'a> fn(TyCtxt<'a, $tcx, $tcx>, $K) -> $V),* + } + + impl<$tcx> Copy for Providers<$tcx> {} + impl<$tcx> Clone for Providers<$tcx> { + fn clone(&self) -> Self { *self } + } + + impl<$tcx> Default for Providers<$tcx> { + fn default() -> Self { + $(fn $name<'a, $tcx>(_: TyCtxt<'a, $tcx, $tcx>, key: $K) -> $V { + bug!("tcx.maps.{}({:?}) unsupported by its crate", + stringify!($name), key); + })* + Providers { $($name),* } + } + } + + impl<$tcx> Maps<$tcx> { + $($(#[$attr])* + pub fn $name<'a, 'lcx>(&self, tcx: TyCtxt<'a, $tcx, 'lcx>, key: $K) -> $V { + self.$name.memoize(key, || { + (self.providers[key.map_crate()].$name)(tcx.global_tcx(), key) + }) + })* + } } } -define_maps! { - /// Maps from a trait item to the trait item "descriptor" - pub associated_items: AssociatedItems(DefId) -> ty::AssociatedItem, - +// Each of these maps also corresponds to a method on a +// `Provider` trait for requesting a value of that type, +// and a method on `Maps` itself for doing that in a +// a way that memoizes and does dep-graph tracking, +// wrapping around the actual chain of providers that +// the driver creates (using several `rustc_*` crates). +define_maps! { <'tcx> /// Records the type of every item. - pub types: ItemSignature(DefId) -> Ty<'tcx>, + pub ty: ItemSignature(DefId) -> Ty<'tcx>, /// Maps from the def-id of an item (trait/struct/enum/fn) to its /// associated generics and predicates. @@ -66,18 +119,22 @@ define_maps! { /// additional acyclicity requirements). pub super_predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx>, - /// Maps from an impl/trait def-id to a list of the def-ids of its items - pub associated_item_def_ids: AssociatedItemDefIds(DefId) -> Rc>, - - pub impl_trait_refs: ItemSignature(DefId) -> Option>, - pub trait_defs: ItemSignature(DefId) -> &'tcx ty::TraitDef, - pub adt_defs: ItemSignature(DefId) -> &'tcx ty::AdtDef, + pub trait_def: ItemSignature(DefId) -> &'tcx ty::TraitDef, + pub adt_def: ItemSignature(DefId) -> &'tcx ty::AdtDef, pub adt_sized_constraint: SizedConstraint(DefId) -> Ty<'tcx>, /// Maps from def-id of a type or region parameter to its /// (inferred) variance. pub variances: ItemSignature(DefId) -> Rc>, + /// Maps from an impl/trait def-id to a list of the def-ids of its items + pub associated_item_def_ids: AssociatedItemDefIds(DefId) -> Rc>, + + /// Maps from a trait item to the trait item "descriptor" + pub associated_item: AssociatedItems(DefId) -> ty::AssociatedItem, + + pub impl_trait_ref: ItemSignature(DefId) -> Option>, + /// Maps a DefId of a type to a list of its inherent impls. /// Contains implementations of methods that are inherent to a type. /// Methods in these implementations don't need to be exported. @@ -93,18 +150,18 @@ define_maps! { /// /// Note that cross-crate MIR appears to be always borrowed /// (in the `RefCell` sense) to prevent accidental mutation. - pub mir: Mir(DefId) -> &'tcx RefCell<::mir::Mir<'tcx>>, + pub mir: Mir(DefId) -> &'tcx RefCell>, /// Records the type of each closure. The def ID is the ID of the /// expression defining the closure. - pub closure_kinds: ItemSignature(DefId) -> ty::ClosureKind, + pub closure_kind: ItemSignature(DefId) -> ty::ClosureKind, /// Records the type of each closure. The def ID is the ID of the /// expression defining the closure. - pub closure_types: ItemSignature(DefId) -> ty::ClosureTy<'tcx>, + pub closure_type: ItemSignature(DefId) -> ty::ClosureTy<'tcx>, /// Caches CoerceUnsized kinds for impls on custom types. - pub custom_coerce_unsized_kinds: ItemSignature(DefId) + pub custom_coerce_unsized_kind: ItemSignature(DefId) -> ty::adjustment::CustomCoerceUnsized, pub typeck_tables: TypeckTables(DefId) -> &'tcx ty::TypeckTables<'tcx>, diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 7e0a35916d0..dd3ed2d9c2c 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1908,28 +1908,6 @@ impl LvaluePreference { } } -/// Helper for looking things up in the various maps that are populated during -/// typeck::collect (e.g., `tcx.associated_items`, `tcx.types`, etc). All of -/// these share the pattern that if the id is local, it should have been loaded -/// into the map by the `typeck::collect` phase. If the def-id is external, -/// then we have to go consult the crate loading code (and cache the result for -/// the future). -fn lookup_locally_or_in_crate_store(descr: &str, - def_id: DefId, - map: &M, - load_external: F) - -> M::Value where - M: MemoizationMap, - F: FnOnce() -> M::Value, -{ - map.memoize(def_id, || { - if def_id.is_local() { - bug!("No def'n found for {:?} in tcx.{}", def_id, descr); - } - load_external() - }) -} - impl BorrowKind { pub fn from_mutbl(m: hir::Mutability) -> BorrowKind { match m { @@ -2095,31 +2073,15 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn custom_coerce_unsized_kind(self, did: DefId) -> adjustment::CustomCoerceUnsized { - self.maps.custom_coerce_unsized_kinds.memoize(did, || { - let (kind, src) = if did.krate != LOCAL_CRATE { - (self.sess.cstore.custom_coerce_unsized_kind(did), "external") - } else { - (None, "local") - }; - - match kind { - Some(kind) => kind, - None => { - bug!("custom_coerce_unsized_kind: \ - {} impl `{}` is missing its kind", - src, self.item_path_str(did)); - } - } - }) + self.maps.custom_coerce_unsized_kind(self, did) } pub fn associated_item(self, def_id: DefId) -> AssociatedItem { - self.maps.associated_items.memoize(def_id, || { - if !def_id.is_local() { - return self.sess.cstore.associated_item(def_id) - .expect("missing AssociatedItem in metadata"); - } + if !def_id.is_local() { + return self.maps.associated_item(self, def_id); + } + self.maps.associated_item.memoize(def_id, || { // When the user asks for a given associated item, we // always go ahead and convert all the associated items in // the container. Note that we are also careful only to @@ -2141,7 +2103,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.associated_item_from_impl_item_ref(parent_def_id, impl_trait_ref.is_some(), impl_item_ref); - self.maps.associated_items.borrow_mut() + self.maps.associated_item.borrow_mut() .insert(assoc_item.def_id, assoc_item); } } @@ -2150,7 +2112,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { for trait_item_ref in trait_item_refs { let assoc_item = self.associated_item_from_trait_item_ref(parent_def_id, trait_item_ref); - self.maps.associated_items.borrow_mut() + self.maps.associated_item.borrow_mut() .insert(assoc_item.def_id, assoc_item); } } @@ -2162,7 +2124,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // memoize wants us to return something, so return // the one we generated for this def-id - *self.maps.associated_items.borrow().get(&def_id).unwrap() + *self.maps.associated_item.borrow().get(&def_id).unwrap() }) } @@ -2220,11 +2182,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn associated_item_def_ids(self, def_id: DefId) -> Rc> { - self.maps.associated_item_def_ids.memoize(def_id, || { - if !def_id.is_local() { - return Rc::new(self.sess.cstore.associated_item_def_ids(def_id)); - } + if !def_id.is_local() { + return self.maps.associated_item_def_ids(self, def_id); + } + self.maps.associated_item_def_ids.memoize(def_id, || { let id = self.hir.as_local_node_id(def_id).unwrap(); let item = self.hir.expect_item(id); let vec: Vec<_> = match item.node { @@ -2256,9 +2218,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns the trait-ref corresponding to a given impl, or None if it is /// an inherent impl. pub fn impl_trait_ref(self, id: DefId) -> Option> { - lookup_locally_or_in_crate_store( - "impl_trait_refs", id, &self.maps.impl_trait_refs, - || self.sess.cstore.impl_trait_ref(self.global_tcx(), id)) + self.maps.impl_trait_ref(self, id) } // Returns `ty::VariantDef` if `def` refers to a struct, @@ -2337,58 +2297,37 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // If the given item is in an external crate, looks up its type and adds it to // the type cache. Returns the type parameters and type. pub fn item_type(self, did: DefId) -> Ty<'gcx> { - lookup_locally_or_in_crate_store( - "item_types", did, &self.maps.types, - || self.sess.cstore.item_type(self.global_tcx(), did)) + self.maps.ty(self, did) } /// Given the did of a trait, returns its canonical trait ref. pub fn lookup_trait_def(self, did: DefId) -> &'gcx TraitDef { - lookup_locally_or_in_crate_store( - "trait_defs", did, &self.maps.trait_defs, - || self.alloc_trait_def(self.sess.cstore.trait_def(self.global_tcx(), did)) - ) + self.maps.trait_def(self, did) } /// Given the did of an ADT, return a reference to its definition. pub fn lookup_adt_def(self, did: DefId) -> &'gcx AdtDef { - lookup_locally_or_in_crate_store( - "adt_defs", did, &self.maps.adt_defs, - || self.sess.cstore.adt_def(self.global_tcx(), did)) + self.maps.adt_def(self, did) } /// Given the did of an item, returns its generics. pub fn item_generics(self, did: DefId) -> &'gcx Generics { - lookup_locally_or_in_crate_store( - "generics", did, &self.maps.generics, - || self.alloc_generics(self.sess.cstore.item_generics(did))) + self.maps.generics(self, did) } /// Given the did of an item, returns its full set of predicates. pub fn item_predicates(self, did: DefId) -> GenericPredicates<'gcx> { - lookup_locally_or_in_crate_store( - "predicates", did, &self.maps.predicates, - || self.sess.cstore.item_predicates(self.global_tcx(), did)) + self.maps.predicates(self, did) } /// Given the did of a trait, returns its superpredicates. pub fn item_super_predicates(self, did: DefId) -> GenericPredicates<'gcx> { - lookup_locally_or_in_crate_store( - "super_predicates", did, &self.maps.super_predicates, - || self.sess.cstore.item_super_predicates(self.global_tcx(), did)) + self.maps.super_predicates(self, did) } /// Given the did of an item, returns its MIR, borrowed immutably. pub fn item_mir(self, did: DefId) -> Ref<'gcx, Mir<'gcx>> { - lookup_locally_or_in_crate_store("mir_map", did, &self.maps.mir, || { - let mir = self.sess.cstore.get_item_mir(self.global_tcx(), did); - let mir = self.alloc_mir(mir); - - // Perma-borrow MIR from extern crates to prevent mutation. - mem::forget(mir.borrow()); - - mir - }).borrow() + self.maps.mir(self, did).borrow() } /// If `type_needs_drop` returns true, then `ty` is definitely @@ -2451,9 +2390,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn item_variances(self, item_id: DefId) -> Rc> { - lookup_locally_or_in_crate_store( - "item_variance_map", item_id, &self.maps.variances, - || Rc::new(self.sess.cstore.item_variances(item_id))) + self.maps.variances(self, item_id) } pub fn trait_has_default_impl(self, trait_def_id: DefId) -> bool { @@ -2528,16 +2465,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn closure_kind(self, def_id: DefId) -> ty::ClosureKind { - // If this is a local def-id, it should be inserted into the - // tables by typeck; else, it will be retreived from - // the external crate metadata. - if let Some(&kind) = self.maps.closure_kinds.borrow().get(&def_id) { - return kind; - } - - let kind = self.sess.cstore.closure_kind(def_id); - self.maps.closure_kinds.borrow_mut().insert(def_id, kind); - kind + self.maps.closure_kind(self, def_id) } pub fn closure_type(self, @@ -2545,16 +2473,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { substs: ClosureSubsts<'tcx>) -> ty::ClosureTy<'tcx> { - // If this is a local def-id, it should be inserted into the - // tables by typeck; else, it will be retreived from - // the external crate metadata. - if let Some(ty) = self.maps.closure_types.borrow().get(&def_id) { + if let Some(ty) = self.maps.closure_type.borrow().get(&def_id) { return ty.subst(self, substs.substs); } - let ty = self.sess.cstore.closure_ty(self.global_tcx(), def_id); - self.maps.closure_types.borrow_mut().insert(def_id, ty.clone()); - ty.subst(self, substs.substs) + self.maps.closure_type(self, def_id).subst(self, substs.substs) } /// Given the def_id of an impl, return the def_id of the trait it implements. @@ -2566,15 +2489,17 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// If the given def ID describes a method belonging to an impl, return the /// ID of the impl that the method belongs to. Otherwise, return `None`. pub fn impl_of_method(self, def_id: DefId) -> Option { - if def_id.krate != LOCAL_CRATE { - return self.sess.cstore.associated_item(def_id).and_then(|item| { - match item.container { - TraitContainer(_) => None, - ImplContainer(def_id) => Some(def_id), - } - }); - } - match self.maps.associated_items.borrow().get(&def_id).cloned() { + let item = if def_id.krate != LOCAL_CRATE { + if let Some(Def::Method(_)) = self.sess.cstore.describe_def(def_id) { + Some(self.associated_item(def_id)) + } else { + None + } + } else { + self.maps.associated_item.borrow().get(&def_id).cloned() + }; + + match item { Some(trait_item) => { match trait_item.container { TraitContainer(_) => None, @@ -2592,7 +2517,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if def_id.krate != LOCAL_CRATE { return self.sess.cstore.trait_of_item(def_id); } - match self.maps.associated_items.borrow().get(&def_id) { + match self.maps.associated_item.borrow().get(&def_id) { Some(associated_item) => { match associated_item.container { TraitContainer(def_id) => Some(def_id), diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index fa53760eca4..3981c8a7c4f 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -770,7 +770,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> { TyAdt(def, substs) => { ty::tls::with(|tcx| { if def.did.is_local() && - !tcx.maps.types.borrow().contains_key(&def.did) { + !tcx.maps.ty.borrow().contains_key(&def.did) { write!(f, "{}<..>", tcx.item_path_str(def.did)) } else { parameterized(f, substs, def.did, &[]) diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 13ece31f4ce..967705c7481 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -123,7 +123,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } else { let expr_tables_ty = tcx.sess.cstore.maybe_get_item_body(tcx, def_id).map(|body| { (&body.value, Some(tcx.item_tables(def_id)), - Some(tcx.sess.cstore.item_type(tcx, def_id))) + Some(tcx.item_type(def_id))) }); match tcx.sess.cstore.describe_def(def_id) { Some(Def::AssociatedConst(_)) => { diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index de789d5686f..6dbdf55f1ca 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -28,7 +28,7 @@ use rustc_incremental::{self, IncrementalHashesMap}; use rustc_incremental::ich::Fingerprint; use rustc_resolve::{MakeGlobMap, Resolver}; use rustc_metadata::creader::CrateLoader; -use rustc_metadata::cstore::CStore; +use rustc_metadata::cstore::{self, CStore}; use rustc_trans::back::{link, write}; use rustc_trans as trans; use rustc_typeck as typeck; @@ -872,7 +872,14 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, let index = stability::Index::new(&hir_map); + let local_providers = ty::maps::Providers::default(); + let mut extern_providers = ty::maps::Providers::default(); + + cstore::provide(&mut extern_providers); + TyCtxt::create_and_enter(sess, + local_providers, + extern_providers, arenas, arena, resolutions, diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index 5481de1811d..2aa1b9981b3 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -139,6 +139,8 @@ fn test_env(source_string: &str, let region_map = region::resolve_crate(&sess, &hir_map); let index = stability::Index::new(&hir_map); TyCtxt::create_and_enter(&sess, + ty::maps::Providers::default(), + ty::maps::Providers::default(), &arenas, &arena, resolutions, diff --git a/src/librustc_lint/bad_style.rs b/src/librustc_lint/bad_style.rs index 5fcefe0d539..353b86820c4 100644 --- a/src/librustc_lint/bad_style.rs +++ b/src/librustc_lint/bad_style.rs @@ -29,7 +29,7 @@ pub enum MethodLateContext { pub fn method_context(cx: &LateContext, id: ast::NodeId, span: Span) -> MethodLateContext { let def_id = cx.tcx.hir.local_def_id(id); - match cx.tcx.maps.associated_items.borrow().get(&def_id) { + match cx.tcx.maps.associated_item.borrow().get(&def_id) { None => span_bug!(span, "missing method descriptor?!"), Some(item) => { match item.container { diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 4709ca6101c..bb30245df5f 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -35,6 +35,8 @@ pub use rustc::middle::cstore::{NativeLibrary, NativeLibraryKind, LinkagePrefere pub use rustc::middle::cstore::NativeLibraryKind::*; pub use rustc::middle::cstore::{CrateSource, LinkMeta, LibSource}; +pub use cstore_impl::provide; + // A map from external crate numbers (as decoded from some crate file) to // local crate numbers (as generated during this session). Each external // crate may refer to types in other external crates, and each has their diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index bd184c5c5e6..770591bc17a 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -13,20 +13,25 @@ use encoder; use locator; use schema; +use rustc::dep_graph::DepTrackingMapConfig; use rustc::middle::cstore::{CrateStore, CrateSource, LibSource, DepKind, ExternCrate}; use rustc::middle::cstore::{NativeLibrary, LinkMeta, LinkagePreference, LoadedMacro}; use rustc::hir::def::{self, Def}; use rustc::middle::lang_items; use rustc::session::Session; -use rustc::ty::{self, Ty, TyCtxt}; +use rustc::ty::{self, TyCtxt}; +use rustc::ty::maps::Providers; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc::dep_graph::DepNode; use rustc::hir::map::{DefKey, DefPath, DisambiguatedDefPathData}; -use rustc::mir::Mir; use rustc::util::nodemap::{NodeSet, DefIdMap}; use rustc_back::PanicStrategy; +use std::any::Any; +use std::mem; +use std::rc::Rc; + use syntax::ast; use syntax::attr; use syntax::parse::filemap_to_tts; @@ -38,7 +43,73 @@ use rustc::hir; use std::collections::BTreeMap; -impl<'tcx> CrateStore<'tcx> for cstore::CStore { +macro_rules! provide { + (<$lt:tt> $tcx:ident, $def_id:ident, $cdata:ident $($name:ident => $compute:block)*) => { + pub fn provide<$lt>(providers: &mut Providers<$lt>) { + $(fn $name<'a, $lt:$lt>($tcx: TyCtxt<'a, $lt, $lt>, $def_id: DefId) + -> as + DepTrackingMapConfig>::Value { + assert!(!$def_id.is_local()); + + $tcx.dep_graph.read(DepNode::MetaData($def_id)); + + let $cdata = $tcx.sess.cstore.crate_data_as_rc_any($def_id.krate); + let $cdata = $cdata.downcast_ref::() + .expect("CrateStore crated ata is not a CrateMetadata"); + $compute + })* + + *providers = Providers { + $($name,)* + ..*providers + }; + } + } +} + +provide! { <'tcx> tcx, def_id, cdata + ty => { cdata.get_type(def_id.index, tcx) } + generics => { tcx.alloc_generics(cdata.get_generics(def_id.index)) } + predicates => { cdata.get_predicates(def_id.index, tcx) } + super_predicates => { cdata.get_super_predicates(def_id.index, tcx) } + trait_def => { + tcx.alloc_trait_def(cdata.get_trait_def(def_id.index, tcx)) + } + adt_def => { cdata.get_adt_def(def_id.index, tcx) } + variances => { Rc::new(cdata.get_item_variances(def_id.index)) } + associated_item_def_ids => { + let mut result = vec![]; + cdata.each_child_of_item(def_id.index, |child| result.push(child.def.def_id())); + Rc::new(result) + } + associated_item => { cdata.get_associated_item(def_id.index) } + impl_trait_ref => { cdata.get_impl_trait(def_id.index, tcx) } + custom_coerce_unsized_kind => { + cdata.get_custom_coerce_unsized_kind(def_id.index).unwrap_or_else(|| { + bug!("custom_coerce_unsized_kind: `{:?}` is missing its kind", def_id); + }) + } + mir => { + let mir = cdata.maybe_get_item_mir(tcx, def_id.index).unwrap_or_else(|| { + bug!("get_item_mir: missing MIR for `{:?}`", def_id) + }); + + let mir = tcx.alloc_mir(mir); + + // Perma-borrow MIR from extern crates to prevent mutation. + mem::forget(mir.borrow()); + + mir + } + closure_kind => { cdata.closure_kind(def_id.index) } + closure_type => { cdata.closure_ty(def_id.index, tcx) } +} + +impl CrateStore for cstore::CStore { + fn crate_data_as_rc_any(&self, krate: CrateNum) -> Rc { + self.get_crate_data(krate) + } + fn describe_def(&self, def: DefId) -> Option { self.dep_graph.read(DepNode::MetaData(def)); self.get_crate_data(def.krate).get_def(def.index) @@ -64,46 +135,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(def.krate).get_visibility(def.index) } - fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind - { - assert!(!def_id.is_local()); - self.dep_graph.read(DepNode::MetaData(def_id)); - self.get_crate_data(def_id.krate).closure_kind(def_id.index) - } - - fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx> { - assert!(!def_id.is_local()); - self.dep_graph.read(DepNode::MetaData(def_id)); - self.get_crate_data(def_id.krate).closure_ty(def_id.index, tcx) - } - - fn item_variances(&self, def: DefId) -> Vec { - self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).get_item_variances(def.index) - } - - fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Ty<'tcx> - { - self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).get_type(def.index, tcx) - } - - fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> ty::GenericPredicates<'tcx> - { - self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).get_predicates(def.index, tcx) - } - - fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> ty::GenericPredicates<'tcx> - { - self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).get_super_predicates(def.index, tcx) - } - - fn item_generics(&self, def: DefId) -> ty::Generics { + fn item_generics_cloned(&self, def: DefId) -> ty::Generics { self.dep_graph.read(DepNode::MetaData(def)); self.get_crate_data(def.krate).get_generics(def.index) } @@ -114,18 +146,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(def_id.krate).get_item_attrs(def_id.index) } - fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::TraitDef - { - self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).get_trait_def(def.index, tcx) - } - - fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> &'tcx ty::AdtDef - { - self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).get_adt_def(def.index, tcx) - } - fn fn_arg_names(&self, did: DefId) -> Vec { // FIXME(#38501) We've skipped a `read` on the `HirBody` of @@ -154,34 +174,12 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { result } - fn associated_item_def_ids(&self, def_id: DefId) -> Vec { - self.dep_graph.read(DepNode::MetaData(def_id)); - let mut result = vec![]; - self.get_crate_data(def_id.krate) - .each_child_of_item(def_id.index, |child| result.push(child.def.def_id())); - result - } - fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity { self.dep_graph.read(DepNode::MetaData(def)); self.get_crate_data(def.krate).get_impl_polarity(def.index) } - fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Option> - { - self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).get_impl_trait(def.index, tcx) - } - - fn custom_coerce_unsized_kind(&self, def: DefId) - -> Option - { - self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).get_custom_coerce_unsized_kind(def.index) - } - fn impl_parent(&self, impl_def: DefId) -> Option { self.dep_graph.read(DepNode::MetaData(impl_def)); self.get_crate_data(impl_def.krate).get_parent_impl(impl_def.index) @@ -192,7 +190,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(def_id.krate).get_trait_of_item(def_id.index) } - fn associated_item(&self, def: DefId) -> Option + fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem { self.dep_graph.read(DepNode::MetaData(def)); self.get_crate_data(def.krate).get_associated_item(def.index) @@ -425,10 +423,10 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { }) } - fn maybe_get_item_body<'a>(&'tcx self, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - def_id: DefId) - -> Option<&'tcx hir::Body> + fn maybe_get_item_body<'a, 'tcx>(&self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + def_id: DefId) + -> Option<&'tcx hir::Body> { if let Some(cached) = tcx.hir.get_inlined_body(def_id) { return Some(cached); @@ -450,13 +448,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.get_crate_data(def.krate).const_is_rvalue_promotable_to_static(def.index) } - fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx> { - self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index).unwrap_or_else(|| { - bug!("get_item_mir: missing MIR for {}", tcx.item_path_str(def)) - }) - } - fn is_item_mir_available(&self, def: DefId) -> bool { self.dep_graph.read(DepNode::MetaData(def)); self.get_crate_data(def.krate).is_item_mir_available(def.index) @@ -504,10 +495,10 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.do_extern_mod_stmt_cnum(emod_id) } - fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, - reexports: &def::ExportMap, - link_meta: &LinkMeta, - reachable: &NodeSet) -> Vec + fn encode_metadata<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, + reexports: &def::ExportMap, + link_meta: &LinkMeta, + reachable: &NodeSet) -> Vec { encoder::encode_metadata(tcx, self, reexports, link_meta, reachable) } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index aa18fbe2ba8..3f8873ddc27 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -584,7 +584,7 @@ impl<'a, 'tcx> CrateMetadata { let adt = tcx.alloc_adt_def(did, kind, variants, repr); if let Some(ctor_index) = ctor_index { // Make adt definition available through constructor id as well. - tcx.maps.adt_defs.borrow_mut().insert(self.local_def_id(ctor_index), adt); + tcx.maps.adt_def.borrow_mut().insert(self.local_def_id(ctor_index), adt); } adt @@ -822,54 +822,35 @@ impl<'a, 'tcx> CrateMetadata { } } - pub fn get_associated_item(&self, id: DefIndex) -> Option { + pub fn get_associated_item(&self, id: DefIndex) -> ty::AssociatedItem { let item = self.entry(id); - let parent_and_name = || { - let def_key = self.def_key(id); - (self.local_def_id(def_key.parent.unwrap()), - def_key.disambiguated_data.data.get_opt_name().unwrap()) - }; + let def_key = self.def_key(id); + let parent = self.local_def_id(def_key.parent.unwrap()); + let name = def_key.disambiguated_data.data.get_opt_name().unwrap(); - Some(match item.kind { + let (kind, container, has_self) = match item.kind { EntryKind::AssociatedConst(container) => { - let (parent, name) = parent_and_name(); - ty::AssociatedItem { - name: name, - kind: ty::AssociatedKind::Const, - vis: item.visibility.decode(self), - defaultness: container.defaultness(), - def_id: self.local_def_id(id), - container: container.with_def_id(parent), - method_has_self_argument: false - } + (ty::AssociatedKind::Const, container, false) } EntryKind::Method(data) => { - let (parent, name) = parent_and_name(); let data = data.decode(self); - ty::AssociatedItem { - name: name, - kind: ty::AssociatedKind::Method, - vis: item.visibility.decode(self), - defaultness: data.container.defaultness(), - def_id: self.local_def_id(id), - container: data.container.with_def_id(parent), - method_has_self_argument: data.has_self - } + (ty::AssociatedKind::Method, data.container, data.has_self) } EntryKind::AssociatedType(container) => { - let (parent, name) = parent_and_name(); - ty::AssociatedItem { - name: name, - kind: ty::AssociatedKind::Type, - vis: item.visibility.decode(self), - defaultness: container.defaultness(), - def_id: self.local_def_id(id), - container: container.with_def_id(parent), - method_has_self_argument: false - } + (ty::AssociatedKind::Type, container, false) } - _ => return None, - }) + _ => bug!() + }; + + ty::AssociatedItem { + name: name, + kind: kind, + vis: item.visibility.decode(self), + defaultness: container.defaultness(), + def_id: self.local_def_id(id), + container: container.with_def_id(parent), + method_has_self_argument: has_self + } } pub fn get_item_variances(&self, id: DefIndex) -> Vec { diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index e6110172fc4..e101dc8cb58 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -711,7 +711,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let data = ImplData { polarity: polarity, parent_impl: parent, - coerce_unsized_kind: tcx.maps.custom_coerce_unsized_kinds + coerce_unsized_kind: tcx.maps.custom_coerce_unsized_kind .borrow() .get(&def_id) .cloned(), @@ -1096,7 +1096,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let data = ClosureData { kind: tcx.closure_kind(def_id), - ty: self.lazy(&tcx.maps.closure_types.borrow()[&def_id]), + ty: self.lazy(&tcx.maps.closure_type.borrow()[&def_id]), }; Entry { diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 2fbdb8c0de6..0ce886ce9e9 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -20,6 +20,7 @@ #![feature(box_patterns)] #![feature(conservative_impl_trait)] #![feature(core_intrinsics)] +#![cfg_attr(stage0, feature(field_init_shorthand))] #![feature(i128_type)] #![feature(proc_macro_internals)] #![feature(quote)] diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index ec02e9235be..89cff39c59e 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -462,8 +462,8 @@ impl<'a> Resolver<'a> { self.define(module, ident, ns, (child.def, ty::Visibility::Public, DUMMY_SP, Mark::root())); - let has_self = self.session.cstore.associated_item(child.def.def_id()) - .map_or(false, |item| item.method_has_self_argument); + let has_self = self.session.cstore.associated_item_cloned(child.def.def_id()) + .method_has_self_argument; self.trait_item_map.insert((def_id, child.name, ns), (child.def, has_self)); } module.populated.set(true); diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs index c2f64b1bd79..7b146842671 100644 --- a/src/librustc_typeck/check/upvar.rs +++ b/src/librustc_typeck/check/upvar.rs @@ -208,9 +208,9 @@ impl<'a, 'gcx, 'tcx> AdjustBorrowKind<'a, 'gcx, 'tcx> { // If we are also inferred the closure kind here, update the // main table and process any deferred resolutions. - let closure_def_id = self.fcx.tcx.hir.local_def_id(id); if let Some(&kind) = self.temp_closure_kinds.get(&id) { self.fcx.tables.borrow_mut().closure_kinds.insert(id, kind); + let closure_def_id = self.fcx.tcx.hir.local_def_id(id); debug!("closure_kind({:?}) = {:?}", closure_def_id, kind); let mut deferred_call_resolutions = diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index b3a4b83b683..650f32eb6b2 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -290,12 +290,12 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { for (&id, closure_ty) in self.fcx.tables.borrow().closure_tys.iter() { let closure_ty = self.resolve(closure_ty, ResolvingClosure(id)); let def_id = self.tcx().hir.local_def_id(id); - self.tcx().maps.closure_types.borrow_mut().insert(def_id, closure_ty); + self.tcx().maps.closure_type.borrow_mut().insert(def_id, closure_ty); } for (&id, &closure_kind) in self.fcx.tables.borrow().closure_kinds.iter() { let def_id = self.tcx().hir.local_def_id(id); - self.tcx().maps.closure_kinds.borrow_mut().insert(def_id, closure_kind); + self.tcx().maps.closure_kind.borrow_mut().insert(def_id, closure_kind); } } @@ -361,7 +361,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { } }); - gcx.maps.types.borrow_mut().insert(def_id, outside_ty); + gcx.maps.ty.borrow_mut().insert(def_id, outside_ty); } } diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index e15386b87ad..bfe8abb201c 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -341,7 +341,7 @@ fn visit_implementation_of_coerce_unsized<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, infcx.resolve_regions_and_report_errors(&free_regions, impl_node_id); if let Some(kind) = kind { - tcx.maps.custom_coerce_unsized_kinds.borrow_mut().insert(impl_did, kind); + tcx.maps.custom_coerce_unsized_kind.borrow_mut().insert(impl_did, kind); } }); } diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 1301f33d30b..4aa0650e57f 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -39,7 +39,7 @@ mod unsafety; struct CoherenceCollect<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - inherent_impls: RefMut<'a, DepTrackingMap>>, + inherent_impls: RefMut<'a, DepTrackingMap>>, } impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CoherenceCollect<'a, 'tcx> { diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 3851cd2bb44..90d12b26c6a 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -606,7 +606,7 @@ fn convert_field<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, { generics_of_def_id(ccx, ty_f.did); let tt = ccx.icx(ty_f.did).to_ty(&field.ty); - ccx.tcx.maps.types.borrow_mut().insert(ty_f.did, tt); + ccx.tcx.maps.ty.borrow_mut().insert(ty_f.did, tt); ccx.tcx.maps.predicates.borrow_mut().insert(ty_f.did, ty::GenericPredicates { parent: Some(ccx.tcx.hir.get_parent_did(field.id)), predicates: vec![] @@ -619,7 +619,7 @@ fn convert_method(ccx: &CrateCtxt, id: ast::NodeId, sig: &hir::MethodSig) { let fty = AstConv::ty_of_fn(&ccx.icx(def_id), sig.unsafety, sig.abi, &sig.decl); let substs = mk_item_substs(ccx, def_id); let fty = ccx.tcx.mk_fn_def(def_id, substs, fty); - ccx.tcx.maps.types.borrow_mut().insert(def_id, fty); + ccx.tcx.maps.ty.borrow_mut().insert(def_id, fty); ty_generic_predicates(ccx, def_id, &sig.generics); } @@ -635,7 +635,7 @@ fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, }; let def_id = ccx.tcx.hir.local_def_id(id); ccx.tcx.maps.predicates.borrow_mut().insert(def_id, predicates); - ccx.tcx.maps.types.borrow_mut().insert(def_id, ty); + ccx.tcx.maps.ty.borrow_mut().insert(def_id, ty); } fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, @@ -651,7 +651,7 @@ fn convert_associated_type<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ccx.tcx.maps.predicates.borrow_mut().insert(def_id, predicates); if let Some(ty) = ty { - ccx.tcx.maps.types.borrow_mut().insert(def_id, ty); + ccx.tcx.maps.ty.borrow_mut().insert(def_id, ty); } } @@ -725,7 +725,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { tcx.record_trait_has_default_impl(trait_ref.def_id); - tcx.maps.impl_trait_refs.borrow_mut().insert(ccx.tcx.hir.local_def_id(it.id), + tcx.maps.impl_trait_ref.borrow_mut().insert(ccx.tcx.hir.local_def_id(it.id), Some(trait_ref)); } hir::ItemImpl(.., ref opt_trait_ref, _, _) => { @@ -735,7 +735,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { let trait_ref = opt_trait_ref.as_ref().map(|ast_trait_ref| { AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty) }); - tcx.maps.impl_trait_refs.borrow_mut().insert(def_id, trait_ref); + tcx.maps.impl_trait_ref.borrow_mut().insert(def_id, trait_ref); predicates_of_item(ccx, it); }, @@ -864,7 +864,7 @@ fn convert_variant_ctor<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, })) } }; - tcx.maps.types.borrow_mut().insert(def_id, ctor_ty); + tcx.maps.ty.borrow_mut().insert(def_id, ctor_ty); tcx.maps.predicates.borrow_mut().insert(def_id, ty::GenericPredicates { parent: Some(ccx.tcx.hir.get_parent_did(ctor_id)), predicates: vec![] @@ -966,10 +966,10 @@ fn convert_struct_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ReprOptions::new(&ccx.tcx, did)); if let Some(ctor_id) = ctor_id { // Make adt definition available through constructor id as well. - ccx.tcx.maps.adt_defs.borrow_mut().insert(ctor_id, adt); + ccx.tcx.maps.adt_def.borrow_mut().insert(ctor_id, adt); } - ccx.tcx.maps.adt_defs.borrow_mut().insert(did, adt); + ccx.tcx.maps.adt_def.borrow_mut().insert(did, adt); adt } @@ -983,7 +983,7 @@ fn convert_union_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, ty::VariantDiscr::Relative(0), def)]; let adt = ccx.tcx.alloc_adt_def(did, AdtKind::Union, variants, ReprOptions::new(&ccx.tcx, did)); - ccx.tcx.maps.adt_defs.borrow_mut().insert(did, adt); + ccx.tcx.maps.adt_def.borrow_mut().insert(did, adt); adt } @@ -1061,7 +1061,7 @@ fn convert_enum_def<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let did = tcx.hir.local_def_id(it.id); let adt = tcx.alloc_adt_def(did, AdtKind::Enum, variants, ReprOptions::new(&ccx.tcx, did)); - tcx.maps.adt_defs.borrow_mut().insert(did, adt); + tcx.maps.adt_def.borrow_mut().insert(did, adt); adt } @@ -1150,7 +1150,7 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) -> &'t let tcx = ccx.tcx; let def_id = tcx.hir.local_def_id(it.id); - tcx.maps.trait_defs.memoize(def_id, || { + tcx.maps.trait_def.memoize(def_id, || { let unsafety = match it.node { hir::ItemTrait(unsafety, ..) => unsafety, _ => span_bug!(it.span, "trait_def_of_item invoked on non-trait"), @@ -1380,7 +1380,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, } else { return ccx.tcx.item_type(def_id); }; - ccx.tcx.maps.types.memoize(def_id, || { + ccx.tcx.maps.ty.memoize(def_id, || { use rustc::hir::map::*; use rustc::hir::*; @@ -1389,7 +1389,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let icx = ccx.icx(def_id); - let ty = match ccx.tcx.hir.get(node_id) { + match ccx.tcx.hir.get(node_id) { NodeItem(item) => { match item.node { ItemStatic(ref t, ..) | ItemConst(ref t, _) | @@ -1455,9 +1455,7 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, x => { bug!("unexpected sort of node in type_of_def_id(): {:?}", x); } - }; - - ty + } }) } diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index cee292f9915..852c98eb2fd 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -24,7 +24,7 @@ use clean::{AttributesExt, NestedAttributesExt}; /// specific rustdoc annotations into account (i.e. `doc(hidden)`) pub struct LibEmbargoVisitor<'a, 'b: 'a, 'tcx: 'b> { cx: &'a ::core::DocContext<'b, 'tcx>, - cstore: &'a CrateStore<'tcx>, + cstore: &'a CrateStore, // Accessibility levels for reachable nodes access_levels: RefMut<'a, AccessLevels>, // Previous accessibility level, None means unreachable