about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo.net>2017-05-11 15:47:15 +0200
committerMichael Woerister <michaelwoerister@posteo.net>2017-05-15 15:27:49 +0200
commit77b7df33077aedfe8df903f95165872243f4acd4 (patch)
tree30a746bbd922f9a361a73f085d0cd5d91a4ea5bc /src
parent513cc6d538885959f504b2fba4f613d2b9690a4c (diff)
downloadrust-77b7df33077aedfe8df903f95165872243f4acd4.tar.gz
rust-77b7df33077aedfe8df903f95165872243f4acd4.zip
Fix instability in GlobalMetadata::Impls ICH.
Diffstat (limited to 'src')
-rw-r--r--src/librustc_metadata/encoder.rs28
1 files changed, 21 insertions, 7 deletions
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index fa4ebed1618..93fcdc455e5 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -943,7 +943,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
                 let trait_ref = tcx.impl_trait_ref(def_id);
                 let parent = if let Some(trait_ref) = trait_ref {
                     let trait_def = tcx.trait_def(trait_ref.def_id);
-                    trait_def.ancestors(def_id).skip(1).next().and_then(|node| {
+                    trait_def.ancestors(tcx, def_id).skip(1).next().and_then(|node| {
                         match node {
                             specialization_graph::Node::Impl(parent) => Some(parent),
                             _ => None,
@@ -1295,23 +1295,37 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, 'tcx> {
 
     /// Encodes an index, mapping each trait to its (local) implementations.
     fn encode_impls(&mut self, _: ()) -> LazySeq<TraitImpls> {
+        debug!("IsolatedEncoder::encode_impls()");
+        let tcx = self.tcx;
         let mut visitor = ImplVisitor {
-            tcx: self.tcx,
+            tcx: tcx,
             impls: FxHashMap(),
         };
-        self.tcx.hir.krate().visit_all_item_likes(&mut visitor);
+        tcx.hir.krate().visit_all_item_likes(&mut visitor);
+
+        let mut all_impls: Vec<_> = visitor.impls.into_iter().collect();
 
-        let all_impls: Vec<_> = visitor.impls
+        // Bring everything into deterministic order for hashing
+        all_impls.sort_unstable_by_key(|&(trait_def_id, _)| {
+            tcx.def_path_hash(trait_def_id)
+        });
+
+        let all_impls: Vec<_> = all_impls
             .into_iter()
-            .map(|(trait_def_id, impls)| {
+            .map(|(trait_def_id, mut impls)| {
+                // Bring everything into deterministic order for hashing
+                impls.sort_unstable_by_key(|&def_index| {
+                    tcx.hir.definitions().def_path_hash(def_index)
+                });
+
                 TraitImpls {
                     trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index),
-                    impls: self.lazy_seq(impls),
+                    impls: self.lazy_seq_from_slice(&impls[..]),
                 }
             })
             .collect();
 
-        self.lazy_seq(all_impls)
+        self.lazy_seq_from_slice(&all_impls[..])
     }
 
     // Encodes all symbols exported from this crate into the metadata.