about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2020-08-01 16:14:22 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2020-08-01 16:14:22 +0300
commit6bf3a4bcd836e4b29108bfb6d8d7b00d405fd03e (patch)
tree3bf6856215108452899fe769389996d9d3c713f9 /src
parentdfe1e3b641abbede6230e3931d14f0d43e5b8e54 (diff)
downloadrust-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.rs21
-rw-r--r--src/librustc_metadata/rmeta/encoder.rs12
-rw-r--r--src/librustc_metadata/rmeta/mod.rs2
-rw-r--r--src/librustc_middle/query/mod.rs4
-rw-r--r--src/librustc_middle/ty/trait_def.rs50
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs2
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);
         }
     }