From 213ef111cfdb4bca63b5c37f440b2c028c6ca676 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Mon, 12 Mar 2018 18:28:53 +0100 Subject: [PATCH] Select upstream monomorphizations in a stable way. --- src/librustc_trans/back/symbol_export.rs | 40 +++++++++++++++++++++--- 1 file changed, 35 insertions(+), 5 deletions(-) diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs index e6bdcd5d7655..0f88e9cd7b79 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 = { + 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); + } + } } } }