diff options
| author | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2020-08-01 16:14:22 +0300 |
|---|---|---|
| committer | Eduard-Mihai Burtescu <edy.burt@gmail.com> | 2020-08-01 16:14:22 +0300 |
| commit | 6bf3a4bcd836e4b29108bfb6d8d7b00d405fd03e (patch) | |
| tree | 3bf6856215108452899fe769389996d9d3c713f9 /src | |
| parent | dfe1e3b641abbede6230e3931d14f0d43e5b8e54 (diff) | |
| download | rust-6bf3a4bcd836e4b29108bfb6d8d7b00d405fd03e.tar.gz rust-6bf3a4bcd836e4b29108bfb6d8d7b00d405fd03e.zip | |
rustc_metadata: track the simplified Self type for every trait impl.
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_metadata/rmeta/decoder.rs | 21 | ||||
| -rw-r--r-- | src/librustc_metadata/rmeta/encoder.rs | 12 | ||||
| -rw-r--r-- | src/librustc_metadata/rmeta/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc_middle/query/mod.rs | 4 | ||||
| -rw-r--r-- | src/librustc_middle/ty/trait_def.rs | 50 | ||||
| -rw-r--r-- | src/librustdoc/passes/collect_trait_impls.rs | 2 |
6 files changed, 54 insertions, 37 deletions
diff --git a/src/librustc_metadata/rmeta/decoder.rs b/src/librustc_metadata/rmeta/decoder.rs index 414c3ad633e..c176b8c4359 100644 --- a/src/librustc_metadata/rmeta/decoder.rs +++ b/src/librustc_metadata/rmeta/decoder.rs @@ -78,7 +78,8 @@ crate struct CrateMetadata { /// Trait impl data. /// FIXME: Used only from queries and can use query cache, /// so pre-decoding can probably be avoided. - trait_impls: FxHashMap<(u32, DefIndex), Lazy<[DefIndex]>>, + trait_impls: + FxHashMap<(u32, DefIndex), Lazy<[(DefIndex, Option<ty::fast_reject::SimplifiedType>)]>>, /// Proc macro descriptions for this crate, if it's a proc macro crate. raw_proc_macros: Option<&'static [ProcMacro]>, /// Source maps for code from the crate. @@ -1289,7 +1290,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { &self, tcx: TyCtxt<'tcx>, filter: Option<DefId>, - ) -> &'tcx [DefId] { + ) -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] { if self.root.is_proc_macro_crate() { // proc-macro crates export no trait impls. return &[]; @@ -1305,16 +1306,20 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { if let Some(filter) = filter { if let Some(impls) = self.trait_impls.get(&filter) { - tcx.arena.alloc_from_iter(impls.decode(self).map(|idx| self.local_def_id(idx))) + tcx.arena.alloc_from_iter( + impls.decode(self).map(|(idx, simplified_self_ty)| { + (self.local_def_id(idx), simplified_self_ty) + }), + ) } else { &[] } } else { - tcx.arena.alloc_from_iter( - self.trait_impls - .values() - .flat_map(|impls| impls.decode(self).map(|idx| self.local_def_id(idx))), - ) + tcx.arena.alloc_from_iter(self.trait_impls.values().flat_map(|impls| { + impls + .decode(self) + .map(|(idx, simplified_self_ty)| (self.local_def_id(idx), simplified_self_ty)) + })) } } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 49aaa845bc2..d0ee90e70ba 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1607,7 +1607,7 @@ impl EncodeContext<'a, 'tcx> { .into_iter() .map(|(trait_def_id, mut impls)| { // Bring everything into deterministic order for hashing - impls.sort_by_cached_key(|&index| { + impls.sort_by_cached_key(|&(index, _)| { tcx.hir().definitions().def_path_hash(LocalDefId { local_def_index: index }) }); @@ -1849,7 +1849,7 @@ impl EncodeContext<'a, 'tcx> { struct ImplVisitor<'tcx> { tcx: TyCtxt<'tcx>, - impls: FxHashMap<DefId, Vec<DefIndex>>, + impls: FxHashMap<DefId, Vec<(DefIndex, Option<ty::fast_reject::SimplifiedType>)>>, } impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { @@ -1857,7 +1857,13 @@ impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { if let hir::ItemKind::Impl { .. } = item.kind { let impl_id = self.tcx.hir().local_def_id(item.hir_id); if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id.to_def_id()) { - self.impls.entry(trait_ref.def_id).or_default().push(impl_id.local_def_index); + let simplified_self_ty = + ty::fast_reject::simplify_type(self.tcx, trait_ref.self_ty(), false); + + self.impls + .entry(trait_ref.def_id) + .or_default() + .push((impl_id.local_def_index, simplified_self_ty)); } } } diff --git a/src/librustc_metadata/rmeta/mod.rs b/src/librustc_metadata/rmeta/mod.rs index 1837b86f4b5..391803634ca 100644 --- a/src/librustc_metadata/rmeta/mod.rs +++ b/src/librustc_metadata/rmeta/mod.rs @@ -233,7 +233,7 @@ crate struct CrateDep { #[derive(RustcEncodable, RustcDecodable)] crate struct TraitImpls { trait_id: (u32, DefIndex), - impls: Lazy<[DefIndex]>, + impls: Lazy<[(DefIndex, Option<ty::fast_reject::SimplifiedType>)]>, } /// Define `LazyTables` and `TableBuilders` at the same time. diff --git a/src/librustc_middle/query/mod.rs b/src/librustc_middle/query/mod.rs index 69f1366abf8..1efb2b7b2fe 100644 --- a/src/librustc_middle/query/mod.rs +++ b/src/librustc_middle/query/mod.rs @@ -1125,11 +1125,11 @@ rustc_queries! { TypeChecking { query implementations_of_trait(_: (CrateNum, DefId)) - -> &'tcx [DefId] { + -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] { desc { "looking up implementations of a trait in a crate" } } query all_trait_implementations(_: CrateNum) - -> &'tcx [DefId] { + -> &'tcx [(DefId, Option<ty::fast_reject::SimplifiedType>)] { desc { "looking up all (?) trait implementations" } } } diff --git a/src/librustc_middle/ty/trait_def.rs b/src/librustc_middle/ty/trait_def.rs index 8f125098ee6..f93cce3f4da 100644 --- a/src/librustc_middle/ty/trait_def.rs +++ b/src/librustc_middle/ty/trait_def.rs @@ -187,32 +187,38 @@ pub(super) fn all_local_trait_impls<'tcx>( pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> TraitImpls { let mut impls = TraitImpls::default(); - { - let mut add_impl = |impl_def_id: DefId| { - let impl_self_ty = tcx.type_of(impl_def_id); - if impl_def_id.is_local() && impl_self_ty.references_error() { - return; - } - - if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, false) { - impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id); - } else { - impls.blanket_impls.push(impl_def_id); - } - }; - - // Traits defined in the current crate can't have impls in upstream - // crates, so we don't bother querying the cstore. - if !trait_id.is_local() { - for &cnum in tcx.crates().iter() { - for &def_id in tcx.implementations_of_trait((cnum, trait_id)).iter() { - add_impl(def_id); + // Traits defined in the current crate can't have impls in upstream + // crates, so we don't bother querying the cstore. + if !trait_id.is_local() { + for &cnum in tcx.crates().iter() { + for &(impl_def_id, simplified_self_ty) in + tcx.implementations_of_trait((cnum, trait_id)).iter() + { + if let Some(simplified_self_ty) = simplified_self_ty { + impls + .non_blanket_impls + .entry(simplified_self_ty) + .or_default() + .push(impl_def_id); + } else { + impls.blanket_impls.push(impl_def_id); } } } + } + + for &hir_id in tcx.hir().trait_impls(trait_id) { + let impl_def_id = tcx.hir().local_def_id(hir_id).to_def_id(); + + let impl_self_ty = tcx.type_of(impl_def_id); + if impl_self_ty.references_error() { + continue; + } - for &hir_id in tcx.hir().trait_impls(trait_id) { - add_impl(tcx.hir().local_def_id(hir_id).to_def_id()); + if let Some(simplified_self_ty) = fast_reject::simplify_type(tcx, impl_self_ty, false) { + impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id); + } else { + impls.blanket_impls.push(impl_def_id); } } diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 0fdeefd79e9..3000afde0c2 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -28,7 +28,7 @@ pub fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate { let mut new_items = Vec::new(); for &cnum in cx.tcx.crates().iter() { - for &did in cx.tcx.all_trait_implementations(cnum).iter() { + for &(did, _) in cx.tcx.all_trait_implementations(cnum).iter() { inline::build_impl(cx, did, None, &mut new_items); } } |
