@@ -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 ,
@@ -268,12 +271,39 @@ fn upstream_monomorphizations_provider<'a, 'tcx>(
268
271
269
272
let mut instances = DefIdMap ( ) ;
270
273
274
+ let cnum_stable_ids: IndexVec < CrateNum , Fingerprint > = {
275
+ let mut cnum_stable_ids = IndexVec :: from_elem_n ( Fingerprint :: ZERO ,
276
+ cnums. len ( ) + 1 ) ;
277
+
278
+ for & cnum in cnums. iter ( ) {
279
+ cnum_stable_ids[ cnum] = tcx. def_path_hash ( DefId {
280
+ krate : cnum,
281
+ index : CRATE_DEF_INDEX ,
282
+ } ) . 0 ;
283
+ }
284
+
285
+ cnum_stable_ids
286
+ } ;
287
+
271
288
for & cnum in cnums. iter ( ) {
272
289
for & ( ref exported_symbol, _) in tcx. exported_symbols ( cnum) . iter ( ) {
273
290
if let & ExportedSymbol :: Generic ( def_id, substs) = exported_symbol {
274
- instances. entry ( def_id)
275
- . or_insert_with ( || FxHashMap ( ) )
276
- . insert ( substs, cnum) ;
291
+ let substs_map = instances. entry ( def_id)
292
+ . or_insert_with ( || FxHashMap ( ) ) ;
293
+
294
+ match substs_map. entry ( substs) {
295
+ Occupied ( mut e) => {
296
+ // If there are multiple monomorphizations available,
297
+ // we select one deterministically.
298
+ let other_cnum = * e. get ( ) ;
299
+ if cnum_stable_ids[ other_cnum] > cnum_stable_ids[ cnum] {
300
+ e. insert ( cnum) ;
301
+ }
302
+ }
303
+ Vacant ( e) => {
304
+ e. insert ( cnum) ;
305
+ }
306
+ }
277
307
}
278
308
}
279
309
}
0 commit comments