diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index af425a95fb19c..25fc5b7a4f6d9 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -159,6 +159,14 @@ pub enum DepNode { DefSpan(D), Stability(D), Deprecation(D), + ItemBodyNestedBodies(D), + ConstIsRvaluePromotableToStatic(D), + ImplParent(D), + TraitOfItem(D), + IsExportedSymbol(D), + IsMirAvailable(D), + ItemAttrs(D), + FnArgNames(D), FileMap(D, Arc), } @@ -273,6 +281,14 @@ impl DepNode { DefSpan(ref d) => op(d).map(DefSpan), Stability(ref d) => op(d).map(Stability), Deprecation(ref d) => op(d).map(Deprecation), + ItemAttrs(ref d) => op(d).map(ItemAttrs), + FnArgNames(ref d) => op(d).map(FnArgNames), + ImplParent(ref d) => op(d).map(ImplParent), + TraitOfItem(ref d) => op(d).map(TraitOfItem), + IsExportedSymbol(ref d) => op(d).map(IsExportedSymbol), + ItemBodyNestedBodies(ref d) => op(d).map(ItemBodyNestedBodies), + ConstIsRvaluePromotableToStatic(ref d) => op(d).map(ConstIsRvaluePromotableToStatic), + IsMirAvailable(ref d) => op(d).map(IsMirAvailable), GlobalMetaData(ref d, kind) => op(d).map(|d| GlobalMetaData(d, kind)), FileMap(ref d, ref file_name) => op(d).map(|d| FileMap(d, file_name.clone())), } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 16b3fcd2f8c32..da899a9130c8b 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -210,27 +210,21 @@ pub trait CrateStore { fn visibility(&self, def: DefId) -> ty::Visibility; fn visible_parent_map<'a>(&'a self) -> ::std::cell::Ref<'a, DefIdMap>; fn item_generics_cloned(&self, def: DefId) -> ty::Generics; - fn item_attrs(&self, def_id: DefId) -> Rc<[ast::Attribute]>; - fn fn_arg_names(&self, did: DefId) -> Vec; // trait info fn implementations_of_trait(&self, filter: Option) -> Vec; // impl info fn impl_defaultness(&self, def: DefId) -> hir::Defaultness; - 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_cloned(&self, def: DefId) -> ty::AssociatedItem; // flags fn is_const_fn(&self, did: DefId) -> bool; fn is_default_impl(&self, impl_did: DefId) -> bool; - fn is_foreign_item(&self, did: DefId) -> bool; fn is_dllimport_foreign_item(&self, def: DefId) -> bool; fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool; - fn is_exported_symbol(&self, def_id: DefId) -> bool; // crate metadata fn dylib_dependency_formats(&self, cnum: CrateNum) @@ -337,28 +331,22 @@ impl CrateStore for DummyCrateStore { } fn item_generics_cloned(&self, def: DefId) -> ty::Generics { bug!("item_generics_cloned") } - fn item_attrs(&self, def_id: DefId) -> Rc<[ast::Attribute]> { bug!("item_attrs") } - fn fn_arg_names(&self, did: DefId) -> Vec { bug!("fn_arg_names") } // trait info fn implementations_of_trait(&self, filter: Option) -> Vec { vec![] } // impl info fn impl_defaultness(&self, def: DefId) -> hir::Defaultness { bug!("impl_defaultness") } - 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_cloned(&self, def: DefId) -> ty::AssociatedItem { bug!("associated_item_cloned") } // flags fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") } fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") } - fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") } fn is_dllimport_foreign_item(&self, id: DefId) -> bool { false } fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { false } - fn is_exported_symbol(&self, def_id: DefId) -> bool { false } // crate metadata fn dylib_dependency_formats(&self, cnum: CrateNum) diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index e03948db36831..5360a86560d39 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -205,7 +205,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EffectCheckVisitor<'a, 'tcx> { } else if match self.tcx.hir.get_if_local(def_id) { Some(hir::map::NodeForeignItem(..)) => true, Some(..) => false, - None => self.tcx.sess.cstore.is_foreign_item(def_id), + None => self.tcx.is_foreign_item(def_id), } { self.require_unsafe_ext(expr.id, expr.span, "use of extern static", true); } diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 82a4c1e1e626a..3b5dc2ae164b6 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -34,6 +34,7 @@ use std::ops::Deref; use std::rc::Rc; use syntax_pos::{Span, DUMMY_SP}; use syntax::attr; +use syntax::ast; use syntax::symbol::Symbol; pub trait Key: Clone + Hash + Eq + Debug { @@ -340,6 +341,36 @@ impl<'tcx> QueryDescription for queries::deprecation<'tcx> { } } +impl<'tcx> QueryDescription for queries::item_attrs<'tcx> { + fn describe(_: TyCtxt, _: DefId) -> String { + bug!("item_attrs") + } +} + +impl<'tcx> QueryDescription for queries::is_exported_symbol<'tcx> { + fn describe(_: TyCtxt, _: DefId) -> String { + bug!("is_exported_symbol") + } +} + +impl<'tcx> QueryDescription for queries::fn_arg_names<'tcx> { + fn describe(_: TyCtxt, _: DefId) -> String { + bug!("fn_arg_names") + } +} + +impl<'tcx> QueryDescription for queries::impl_parent<'tcx> { + fn describe(_: TyCtxt, _: DefId) -> String { + bug!("impl_parent") + } +} + +impl<'tcx> QueryDescription for queries::trait_of_item<'tcx> { + fn describe(_: TyCtxt, _: DefId) -> String { + bug!("trait_of_item") + } +} + impl<'tcx> QueryDescription for queries::item_body_nested_bodies<'tcx> { fn describe(tcx: TyCtxt, def_id: DefId) -> String { format!("nested item bodies of `{}`", tcx.item_path_str(def_id)) @@ -781,9 +812,14 @@ define_maps! { <'tcx> [] def_span: DefSpan(DefId) -> Span, [] stability: Stability(DefId) -> Option, [] deprecation: Deprecation(DefId) -> Option, - [] item_body_nested_bodies: metadata_dep_node(DefId) -> Rc>, - [] const_is_rvalue_promotable_to_static: metadata_dep_node(DefId) -> bool, - [] is_mir_available: metadata_dep_node(DefId) -> bool, + [] item_attrs: ItemAttrs(DefId) -> Rc<[ast::Attribute]>, + [] fn_arg_names: FnArgNames(DefId) -> Vec, + [] impl_parent: ImplParent(DefId) -> Option, + [] trait_of_item: TraitOfItem(DefId) -> Option, + [] is_exported_symbol: IsExportedSymbol(DefId) -> bool, + [] item_body_nested_bodies: ItemBodyNestedBodies(DefId) -> Rc>, + [] const_is_rvalue_promotable_to_static: ConstIsRvaluePromotableToStatic(DefId) -> bool, + [] is_mir_available: IsMirAvailable(DefId) -> bool, } fn coherent_trait_dep_node((_, def_id): (CrateNum, DefId)) -> DepNode { @@ -798,10 +834,6 @@ fn reachability_dep_node(_: CrateNum) -> DepNode { DepNode::Reachability } -fn metadata_dep_node(def_id: DefId) -> DepNode { - DepNode::MetaData(def_id) -} - fn mir_shim_dep_node(instance: ty::InstanceDef) -> DepNode { instance.dep_node() } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 99a5f6325ac75..51cdba56cf10a 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -2360,7 +2360,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if let Some(id) = self.hir.as_local_node_id(did) { Attributes::Borrowed(self.hir.attrs(id)) } else { - Attributes::Owned(self.sess.cstore.item_attrs(did)) + Attributes::Owned(self.item_attrs(did)) } } @@ -2396,7 +2396,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let trait_ref = self.impl_trait_ref(impl_def_id).unwrap(); // Record the trait->implementation mapping. - let parent = self.sess.cstore.impl_parent(impl_def_id).unwrap_or(trait_id); + let parent = self.impl_parent(impl_def_id).unwrap_or(trait_id); def.record_remote_impl(self, impl_def_id, trait_ref, parent); } @@ -2433,22 +2433,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } - /// If the given def ID describes an item belonging to a trait, - /// return the ID of the trait that the trait item belongs to. - /// Otherwise, return `None`. - pub fn trait_of_item(self, def_id: DefId) -> Option { - if def_id.krate != LOCAL_CRATE { - return self.sess.cstore.trait_of_item(def_id); - } - self.opt_associated_item(def_id) - .and_then(|associated_item| { - match associated_item.container { - TraitContainer(def_id) => Some(def_id), - ImplContainer(_) => None - } - }) - } - /// Construct a parameter environment suitable for static contexts or other contexts where there /// are no free type/lifetime parameters in scope. pub fn empty_parameter_environment(self) -> ParameterEnvironment<'tcx> { @@ -2688,6 +2672,20 @@ fn def_span<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Span { tcx.hir.span_if_local(def_id).unwrap() } +/// If the given def ID describes an item belonging to a trait, +/// return the ID of the trait that the trait item belongs to. +/// Otherwise, return `None`. +fn trait_of_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Option { + tcx.opt_associated_item(def_id) + .and_then(|associated_item| { + match associated_item.container { + TraitContainer(def_id) => Some(def_id), + ImplContainer(_) => None + } + }) +} + + pub fn provide(providers: &mut ty::maps::Providers) { *providers = ty::maps::Providers { associated_item, @@ -2695,6 +2693,7 @@ pub fn provide(providers: &mut ty::maps::Providers) { adt_sized_constraint, adt_dtorck_constraint, def_span, + trait_of_item, ..*providers }; } diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index 8b1aa0708807b..e79f23aee1145 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -74,7 +74,7 @@ pub fn lookup_const_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // constants, we only try to find the expression for a // trait-associated const if the caller gives us the // substitutions for the reference to it. - if tcx.sess.cstore.trait_of_item(def_id).is_some() { + if tcx.trait_of_item(def_id).is_some() { resolve_trait_associated_const(tcx, def_id, substs) } else { Some((def_id, substs)) diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index 6fa6a868605dc..f3fb427fed66f 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -41,8 +41,6 @@ use rustc::hir::svh::Svh; use rustc_back::target::Target; use rustc::hir; -use std::collections::BTreeMap; - macro_rules! provide { (<$lt:tt> $tcx:ident, $def_id:ident, $cdata:ident $($name:ident => $compute:block)*) => { pub fn provide<$lt>(providers: &mut Providers<$lt>) { @@ -113,21 +111,23 @@ provide! { <'tcx> tcx, def_id, cdata def_span => { cdata.get_span(def_id.index, &tcx.sess) } stability => { cdata.get_stability(def_id.index) } deprecation => { cdata.get_deprecation(def_id.index) } - item_body_nested_bodies => { - let map: BTreeMap<_, _> = cdata.entry(def_id.index).ast.into_iter().flat_map(|ast| { - ast.decode(cdata).nested_bodies.decode(cdata).map(|body| (body.id(), body)) - }).collect(); - - Rc::new(map) - } + item_attrs => { cdata.get_item_attrs(def_id.index, &tcx.dep_graph) } + // FIXME(#38501) We've skipped a `read` on the `HirBody` of + // a `fn` when encoding, so the dep-tracking wouldn't work. + // This is only used by rustdoc anyway, which shouldn't have + // incremental recompilation ever enabled. + fn_arg_names => { cdata.get_fn_arg_names(def_id.index) } + impl_parent => { cdata.get_parent_impl(def_id.index) } + trait_of_item => { cdata.get_trait_of_item(def_id.index) } + is_exported_symbol => { + let dep_node = cdata.metadata_dep_node(GlobalMetaDataKind::ExportedSymbols); + cdata.exported_symbols.get(&tcx.dep_graph, dep_node).contains(&def_id.index) + } + item_body_nested_bodies => { Rc::new(cdata.item_body_nested_bodies(def_id.index)) } const_is_rvalue_promotable_to_static => { - cdata.entry(def_id.index).ast.expect("const item missing `ast`") - .decode(cdata).rvalue_promotable_to_static - } - is_mir_available => { - !cdata.is_proc_macro(def_id.index) && - cdata.maybe_entry(def_id.index).and_then(|item| item.decode(cdata).mir).is_some() + cdata.const_is_rvalue_promotable_to_static(def_id.index) } + is_mir_available => { cdata.is_item_mir_available(def_id.index) } } impl CrateStore for cstore::CStore { @@ -145,22 +145,6 @@ impl CrateStore for cstore::CStore { self.get_crate_data(def.krate).get_generics(def.index) } - fn item_attrs(&self, def_id: DefId) -> Rc<[ast::Attribute]> - { - self.get_crate_data(def_id.krate) - .get_item_attrs(def_id.index, &self.dep_graph) - } - - fn fn_arg_names(&self, did: DefId) -> Vec - { - // FIXME(#38501) We've skipped a `read` on the `HirBody` of - // a `fn` when encoding, so the dep-tracking wouldn't work. - // This is only used by rustdoc anyway, which shouldn't have - // incremental recompilation ever enabled. - assert!(!self.dep_graph.is_fully_enabled()); - self.get_crate_data(did.krate).get_fn_arg_names(did.index) - } - fn implementations_of_trait(&self, filter: Option) -> Vec { if let Some(def_id) = filter { @@ -179,16 +163,6 @@ impl CrateStore for cstore::CStore { self.get_crate_data(def.krate).get_impl_defaultness(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) - } - - fn trait_of_item(&self, def_id: DefId) -> Option { - self.dep_graph.read(DepNode::MetaData(def_id)); - self.get_crate_data(def_id.krate).get_trait_of_item(def_id.index) - } - fn associated_item_cloned(&self, def: DefId) -> ty::AssociatedItem { self.dep_graph.read(DepNode::MetaData(def)); @@ -206,23 +180,11 @@ impl CrateStore for cstore::CStore { self.get_crate_data(impl_did.krate).is_default_impl(impl_did.index) } - fn is_foreign_item(&self, did: DefId) -> bool { - self.get_crate_data(did.krate).is_foreign_item(did.index) - } - fn is_statically_included_foreign_item(&self, def_id: DefId) -> bool { self.do_is_statically_included_foreign_item(def_id) } - fn is_exported_symbol(&self, def_id: DefId) -> bool { - let data = self.get_crate_data(def_id.krate); - let dep_node = data.metadata_dep_node(GlobalMetaDataKind::ExportedSymbols); - data.exported_symbols - .get(&self.dep_graph, dep_node) - .contains(&def_id.index) - } - fn is_dllimport_foreign_item(&self, def_id: DefId) -> bool { if def_id.krate == LOCAL_CRATE { self.dllimport_foreign_items.borrow().contains(&def_id.index) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 820b5a68bcc9b..ea845f722c345 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -30,6 +30,7 @@ use rustc::mir::Mir; use std::borrow::Cow; use std::cell::Ref; +use std::collections::BTreeMap; use std::io; use std::mem; use std::rc::Rc; @@ -453,16 +454,16 @@ impl<'tcx> EntryKind<'tcx> { } impl<'a, 'tcx> CrateMetadata { - pub fn is_proc_macro(&self, id: DefIndex) -> bool { + fn is_proc_macro(&self, id: DefIndex) -> bool { self.proc_macros.is_some() && id != CRATE_DEF_INDEX } - pub fn maybe_entry(&self, item_id: DefIndex) -> Option>> { + fn maybe_entry(&self, item_id: DefIndex) -> Option>> { assert!(!self.is_proc_macro(item_id)); self.root.index.lookup(self.blob.raw_bytes(), item_id) } - pub fn entry(&self, item_id: DefIndex) -> Entry<'tcx> { + fn entry(&self, item_id: DefIndex) -> Entry<'tcx> { match self.maybe_entry(item_id) { None => { bug!("entry: id not found: {:?} in crate {:?} with number {}", @@ -789,6 +790,22 @@ impl<'a, 'tcx> CrateMetadata { tcx.alloc_tables(ast.tables.decode((self, tcx))) } + pub fn item_body_nested_bodies(&self, id: DefIndex) -> BTreeMap { + self.entry(id).ast.into_iter().flat_map(|ast| { + ast.decode(self).nested_bodies.decode(self).map(|body| (body.id(), body)) + }).collect() + } + + pub fn const_is_rvalue_promotable_to_static(&self, id: DefIndex) -> bool { + self.entry(id).ast.expect("const item missing `ast`") + .decode(self).rvalue_promotable_to_static + } + + pub fn is_item_mir_available(&self, id: DefIndex) -> bool { + !self.is_proc_macro(id) && + self.maybe_entry(id).and_then(|item| item.decode(self).mir).is_some() + } + pub fn maybe_get_optimized_mir(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefIndex) diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index aef9140ba4556..1aed293294802 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -223,7 +223,7 @@ fn compute_symbol_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: Instance _ => false } } else { - tcx.sess.cstore.is_foreign_item(def_id) + tcx.is_foreign_item(def_id) }; if let Some(name) = weak_lang_items::link_name(&attrs) { diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 6d7d95f548721..5f8b79a994a55 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -652,8 +652,8 @@ fn should_trans_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance: &Instan } Some(_) => true, None => { - if tcx.sess.cstore.is_exported_symbol(def_id) || - tcx.sess.cstore.is_foreign_item(def_id) + if tcx.is_exported_symbol(def_id) || + tcx.is_foreign_item(def_id) { // We can link to the item in question, no instance needed // in this crate diff --git a/src/librustc_trans/consts.rs b/src/librustc_trans/consts.rs index 6afb340107d66..eac0a06256719 100644 --- a/src/librustc_trans/consts.rs +++ b/src/librustc_trans/consts.rs @@ -186,7 +186,7 @@ pub fn get_static(ccx: &CrateContext, def_id: DefId) -> ValueRef { llvm::set_thread_local(g, true); } } - if ccx.use_dll_storage_attrs() && !ccx.sess().cstore.is_foreign_item(def_id) { + if ccx.use_dll_storage_attrs() && !ccx.tcx().is_foreign_item(def_id) { // This item is external but not foreign, i.e. it originates from an external Rust // crate. Since we don't know whether this crate will be linked dynamically or // statically in the final application, we always mark such symbols as 'dllimport'. diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 24d056035ceec..2dde6d9d4ee55 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1180,7 +1180,7 @@ impl<'a, 'tcx> Clean for (DefId, ty::PolyFnSig<'tcx>) { let mut names = if cx.tcx.hir.as_local_node_id(did).is_some() { vec![].into_iter() } else { - cx.tcx.sess.cstore.fn_arg_names(did).into_iter() + cx.tcx.fn_arg_names(did).into_iter() }.peekable(); FnDecl { output: Return(sig.skip_binder().output().clean(cx)),