Skip to content

Commit

Permalink
Update inherent_impls
Browse files Browse the repository at this point in the history
  • Loading branch information
Zoxc committed Apr 13, 2019
1 parent c168cc7 commit 9c3de34
Show file tree
Hide file tree
Showing 6 changed files with 21 additions and 27 deletions.
1 change: 1 addition & 0 deletions src/librustc/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
)
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vec<DefId>> {
query inherent_impls(_: DefId) -> &'tcx [DefId] {
eval_always
}
}
Expand Down Expand Up @@ -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<CrateInherentImpls> {
-> &'tcx CrateInherentImpls {
eval_always
desc { "all inherent impls defined in crate `{:?}`", k }
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Lrc<Vec<DefId>>>,
pub inherent_impls: DefIdMap<Vec<DefId>>,
}

#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_metadata/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) }
Expand Down
15 changes: 9 additions & 6 deletions src/librustc_metadata/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -998,12 +998,15 @@ impl<'a, 'tcx> CrateMetadata {
None
}

pub fn get_inherent_implementations_for_type(&self, id: DefIndex) -> Vec<DefId> {
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,
Expand Down
24 changes: 7 additions & 17 deletions src/librustc_typeck/coherence/inherent_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<CrateInherentImpls> {
-> &'tcx CrateInherentImpls {
assert_eq!(crate_num, LOCAL_CRATE);

let krate = tcx.hir().krate();
Expand All @@ -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<Vec<DefId>> {
-> &'tcx [DefId] {
assert!(ty_def_id.is_local());

// NB. Until we adopt the red-green dep-tracking algorithm (see
Expand All @@ -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<Vec<DefId>> = 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 => &[],
}
});

Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 9c3de34

Please sign in to comment.