@@ -14,15 +14,18 @@ use std::sync::Arc;
14
14
use monomorphize:: Instance ;
15
15
use rustc:: hir;
16
16
use rustc:: hir:: TransFnAttrFlags ;
17
- use rustc:: hir:: def_id:: CrateNum ;
18
- use rustc:: hir :: def_id :: { DefId , LOCAL_CRATE } ;
17
+ use rustc:: hir:: def_id:: { CrateNum , DefId , LOCAL_CRATE , CRATE_DEF_INDEX } ;
18
+ use rustc:: ich :: Fingerprint ;
19
19
use rustc:: middle:: exported_symbols:: { SymbolExportLevel , ExportedSymbol , metadata_symbol_name} ;
20
20
use rustc:: session:: config;
21
21
use rustc:: ty:: { TyCtxt , SymbolName } ;
22
22
use rustc:: ty:: maps:: Providers ;
23
23
use rustc:: ty:: subst:: Substs ;
24
24
use rustc:: util:: nodemap:: { FxHashMap , DefIdMap } ;
25
25
use rustc_allocator:: ALLOCATOR_METHODS ;
26
+ use rustc_data_structures:: indexed_vec:: IndexVec ;
27
+ use syntax:: attr;
28
+ use std:: collections:: hash_map:: Entry :: * ;
26
29
27
30
pub type ExportedSymbols = FxHashMap <
28
31
CrateNum ,
@@ -282,12 +285,39 @@ fn upstream_monomorphizations_provider<'a, 'tcx>(
282
285
283
286
let mut instances = DefIdMap ( ) ;
284
287
288
+ let cnum_stable_ids: IndexVec < CrateNum , Fingerprint > = {
289
+ let mut cnum_stable_ids = IndexVec :: from_elem_n ( Fingerprint :: ZERO ,
290
+ cnums. len ( ) + 1 ) ;
291
+
292
+ for & cnum in cnums. iter ( ) {
293
+ cnum_stable_ids[ cnum] = tcx. def_path_hash ( DefId {
294
+ krate : cnum,
295
+ index : CRATE_DEF_INDEX ,
296
+ } ) . 0 ;
297
+ }
298
+
299
+ cnum_stable_ids
300
+ } ;
301
+
285
302
for & cnum in cnums. iter ( ) {
286
303
for & ( ref exported_symbol, _) in tcx. exported_symbols ( cnum) . iter ( ) {
287
304
if let & ExportedSymbol :: Generic ( def_id, substs) = exported_symbol {
288
- instances. entry ( def_id)
289
- . or_insert_with ( || FxHashMap ( ) )
290
- . insert ( substs, cnum) ;
305
+ let substs_map = instances. entry ( def_id)
306
+ . or_insert_with ( || FxHashMap ( ) ) ;
307
+
308
+ match substs_map. entry ( substs) {
309
+ Occupied ( mut e) => {
310
+ // If there are multiple monomorphizations available,
311
+ // we select one deterministically.
312
+ let other_cnum = * e. get ( ) ;
313
+ if cnum_stable_ids[ other_cnum] > cnum_stable_ids[ cnum] {
314
+ e. insert ( cnum) ;
315
+ }
316
+ }
317
+ Vacant ( e) => {
318
+ e. insert ( cnum) ;
319
+ }
320
+ }
291
321
}
292
322
}
293
323
}
0 commit comments