about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Woerister <michaelwoerister@posteo>2018-03-12 18:28:53 +0100
committerMichael Woerister <michaelwoerister@posteo>2018-04-06 12:14:08 +0200
commit213ef111cfdb4bca63b5c37f440b2c028c6ca676 (patch)
treedebb32baf9a2bf8b5db46ee641eff4065100dc0e
parent5316a458b2ebf12aab1922ce905d38df6496ac8a (diff)
downloadrust-213ef111cfdb4bca63b5c37f440b2c028c6ca676.tar.gz
rust-213ef111cfdb4bca63b5c37f440b2c028c6ca676.zip
Select upstream monomorphizations in a stable way.
-rw-r--r--src/librustc_trans/back/symbol_export.rs40
1 files changed, 35 insertions, 5 deletions
diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs
index e6bdcd5d765..0f88e9cd7b7 100644
--- a/src/librustc_trans/back/symbol_export.rs
+++ b/src/librustc_trans/back/symbol_export.rs
@@ -14,8 +14,8 @@ use std::sync::Arc;
 use monomorphize::Instance;
 use rustc::hir;
 use rustc::hir::TransFnAttrFlags;
-use rustc::hir::def_id::CrateNum;
-use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
+use rustc::ich::Fingerprint;
 use rustc::middle::exported_symbols::{SymbolExportLevel, ExportedSymbol, metadata_symbol_name};
 use rustc::session::config;
 use rustc::ty::{TyCtxt, SymbolName};
@@ -23,6 +23,9 @@ use rustc::ty::maps::Providers;
 use rustc::ty::subst::Substs;
 use rustc::util::nodemap::{FxHashMap, DefIdMap};
 use rustc_allocator::ALLOCATOR_METHODS;
+use rustc_data_structures::indexed_vec::IndexVec;
+use syntax::attr;
+use std::collections::hash_map::Entry::*;
 
 pub type ExportedSymbols = FxHashMap<
     CrateNum,
@@ -282,12 +285,39 @@ fn upstream_monomorphizations_provider<'a, 'tcx>(
 
     let mut instances = DefIdMap();
 
+    let cnum_stable_ids: IndexVec<CrateNum, Fingerprint> = {
+        let mut cnum_stable_ids = IndexVec::from_elem_n(Fingerprint::ZERO,
+                                                        cnums.len() + 1);
+
+        for &cnum in cnums.iter() {
+            cnum_stable_ids[cnum] = tcx.def_path_hash(DefId {
+                krate: cnum,
+                index: CRATE_DEF_INDEX,
+            }).0;
+        }
+
+        cnum_stable_ids
+    };
+
     for &cnum in cnums.iter() {
         for &(ref exported_symbol, _) in tcx.exported_symbols(cnum).iter() {
             if let &ExportedSymbol::Generic(def_id, substs) = exported_symbol {
-                instances.entry(def_id)
-                         .or_insert_with(|| FxHashMap())
-                         .insert(substs, cnum);
+                let substs_map = instances.entry(def_id)
+                                          .or_insert_with(|| FxHashMap());
+
+                match substs_map.entry(substs) {
+                    Occupied(mut e) => {
+                        // If there are multiple monomorphizations available,
+                        // we select one deterministically.
+                        let other_cnum = *e.get();
+                        if cnum_stable_ids[other_cnum] > cnum_stable_ids[cnum] {
+                            e.insert(cnum);
+                        }
+                    }
+                    Vacant(e) => {
+                        e.insert(cnum);
+                    }
+                }
             }
         }
     }