diff --git a/src/librustc/arena.rs b/src/librustc/arena.rs index e9751a23f1218..eb2eecd0515c9 100644 --- a/src/librustc/arena.rs +++ b/src/librustc/arena.rs @@ -16,6 +16,7 @@ macro_rules! arena_types { )>, [few] mir_keys: rustc::util::nodemap::DefIdSet, [decode] specialization_graph: rustc::traits::specialization_graph::Graph, + [few] crate_inherent_impls: rustc::ty::CrateInherentImpls, ], $tcx); ) } diff --git a/src/librustc/query/mod.rs b/src/librustc/query/mod.rs index c231354aed5af..07c957a3d1c33 100644 --- a/src/librustc/query/mod.rs +++ b/src/librustc/query/mod.rs @@ -274,7 +274,7 @@ rustc_queries! { /// 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. - query inherent_impls(_: DefId) -> Lrc> { + query inherent_impls(_: DefId) -> &'tcx [DefId] { eval_always } } @@ -380,7 +380,7 @@ rustc_queries! { /// Not meant to be used directly outside of coherence. /// (Defined only for `LOCAL_CRATE`.) query crate_inherent_impls(k: CrateNum) - -> Lrc { + -> &'tcx CrateInherentImpls { eval_always desc { "all inherent impls defined in crate `{:?}`", k } } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 856a22b295199..4e5114adb7cd7 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -3378,7 +3378,7 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) { /// (constructing this map requires touching the entire crate). #[derive(Clone, Debug, Default, HashStable)] pub struct CrateInherentImpls { - pub inherent_impls: DefIdMap>>, + pub inherent_impls: DefIdMap>, } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)] diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index c785d2820e412..f6aac74012014 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -134,7 +134,7 @@ provide! { <'tcx> tcx, def_id, other, cdata, (cdata.mir_const_qualif(def_id.index), Lrc::new(BitSet::new_empty(0))) } fn_sig => { cdata.fn_sig(def_id.index, tcx) } - inherent_impls => { Lrc::new(cdata.get_inherent_implementations_for_type(def_id.index)) } + inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) } is_foreign_item => { cdata.is_foreign_item(def_id.index) } describe_def => { cdata.get_def(def_id.index) } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index f456a5c1619c5..17d03db647e9b 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -998,12 +998,15 @@ impl<'a, 'tcx> CrateMetadata { None } - pub fn get_inherent_implementations_for_type(&self, id: DefIndex) -> Vec { - self.entry(id) - .inherent_impls - .decode(self) - .map(|index| self.local_def_id(index)) - .collect() + pub fn get_inherent_implementations_for_type( + &self, + tcx: TyCtxt<'_, 'tcx, '_>, + id: DefIndex + ) -> &'tcx [DefId] { + tcx.arena.alloc_from_iter(self.entry(id) + .inherent_impls + .decode(self) + .map(|index| self.local_def_id(index))) } pub fn get_implementations_for_trait(&self, diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index d167c7fcafbe4..644d95963e652 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -13,14 +13,13 @@ use rustc::hir; use rustc::hir::itemlikevisit::ItemLikeVisitor; use rustc::ty::{self, CrateInherentImpls, TyCtxt}; -use rustc_data_structures::sync::Lrc; use syntax::ast; use syntax_pos::Span; /// On-demand query: yields a map containing all types mapped to their inherent impls. pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) - -> Lrc { + -> &'tcx CrateInherentImpls { assert_eq!(crate_num, LOCAL_CRATE); let krate = tcx.hir().krate(); @@ -29,13 +28,13 @@ pub fn crate_inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, impls_map: Default::default(), }; krate.visit_all_item_likes(&mut collect); - Lrc::new(collect.impls_map) + tcx.arena.alloc(collect.impls_map) } /// On-demand query: yields a vector of the inherent impls for a specific type. pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty_def_id: DefId) - -> Lrc> { + -> &'tcx [DefId] { assert!(ty_def_id.is_local()); // NB. Until we adopt the red-green dep-tracking algorithm (see @@ -53,15 +52,11 @@ pub fn inherent_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // // [the plan]: https://github.com/rust-lang/rust-roadmap/issues/4 - thread_local! { - static EMPTY_DEF_ID_VEC: Lrc> = Lrc::new(vec![]) - } - let result = tcx.dep_graph.with_ignore(|| { let crate_map = tcx.crate_inherent_impls(ty_def_id.krate); match crate_map.inherent_impls.get(&ty_def_id) { - Some(v) => v.clone(), - None => EMPTY_DEF_ID_VEC.with(|v| v.clone()) + Some(v) => &v[..], + None => &[], } }); @@ -289,13 +284,8 @@ impl<'a, 'tcx> InherentCollect<'a, 'tcx> { // type def ID, if there is a base type for this implementation and // the implementation does not have any associated traits. let impl_def_id = self.tcx.hir().local_def_id_from_hir_id(item.hir_id); - let mut rc_vec = self.impls_map.inherent_impls - .entry(def_id) - .or_default(); - - // At this point, there should not be any clones of the - // `Lrc`, so we can still safely push into it in place: - Lrc::get_mut(&mut rc_vec).unwrap().push(impl_def_id); + let vec = self.impls_map.inherent_impls.entry(def_id).or_default(); + vec.push(impl_def_id); } else { struct_span_err!(self.tcx.sess, item.span,