@@ -212,7 +212,7 @@ use glue::{self, DropGlueKind};
212
212
use monomorphize:: { self , Instance } ;
213
213
use util:: nodemap:: { FxHashSet , FxHashMap , DefIdMap } ;
214
214
215
- use trans_item:: { TransItem , DefPathBasedNames } ;
215
+ use trans_item:: { TransItem , DefPathBasedNames , InstantiationMode } ;
216
216
217
217
use std:: iter;
218
218
@@ -337,6 +337,10 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
337
337
}
338
338
TransItem :: Static ( node_id) => {
339
339
let def_id = scx. tcx ( ) . map . local_def_id ( node_id) ;
340
+
341
+ // Sanity check whether this ended up being collected accidentally
342
+ debug_assert ! ( should_trans_locally( scx. tcx( ) , def_id) ) ;
343
+
340
344
let ty = scx. tcx ( ) . item_type ( def_id) ;
341
345
let ty = glue:: get_drop_glue_type ( scx, ty) ;
342
346
neighbors. push ( TransItem :: DropGlue ( DropGlueKind :: Ty ( ty) ) ) ;
@@ -346,6 +350,9 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
346
350
collect_neighbours ( scx, Instance :: mono ( scx, def_id) , & mut neighbors) ;
347
351
}
348
352
TransItem :: Fn ( instance) => {
353
+ // Sanity check whether this ended up being collected accidentally
354
+ debug_assert ! ( should_trans_locally( scx. tcx( ) , instance. def) ) ;
355
+
349
356
// Keep track of the monomorphization recursion depth
350
357
recursion_depth_reset = Some ( check_recursion_limit ( scx. tcx ( ) ,
351
358
instance,
@@ -374,7 +381,7 @@ fn record_inlining_canditates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
374
381
callees : & [ TransItem < ' tcx > ] ,
375
382
inlining_map : & mut InliningMap < ' tcx > ) {
376
383
let is_inlining_candidate = |trans_item : & TransItem < ' tcx > | {
377
- trans_item. needs_local_copy ( tcx)
384
+ trans_item. instantiation_mode ( tcx) == InstantiationMode :: LocalCopy
378
385
} ;
379
386
380
387
let inlining_candidates = callees. into_iter ( )
@@ -490,15 +497,16 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
490
497
. require ( ExchangeMallocFnLangItem )
491
498
. unwrap_or_else ( |e| self . scx . sess ( ) . fatal ( & e) ) ;
492
499
493
- assert ! ( can_have_local_instance ( self . scx. tcx( ) , exchange_malloc_fn_def_id) ) ;
494
- let empty_substs = self . scx . empty_substs_for_def_id ( exchange_malloc_fn_def_id) ;
495
- let exchange_malloc_fn_trans_item =
496
- create_fn_trans_item ( self . scx ,
497
- exchange_malloc_fn_def_id,
498
- empty_substs,
499
- self . param_substs ) ;
500
+ if should_trans_locally ( self . scx . tcx ( ) , exchange_malloc_fn_def_id) {
501
+ let empty_substs = self . scx . empty_substs_for_def_id ( exchange_malloc_fn_def_id) ;
502
+ let exchange_malloc_fn_trans_item =
503
+ create_fn_trans_item ( self . scx ,
504
+ exchange_malloc_fn_def_id,
505
+ empty_substs,
506
+ self . param_substs ) ;
500
507
501
- self . output . push ( exchange_malloc_fn_trans_item) ;
508
+ self . output . push ( exchange_malloc_fn_trans_item) ;
509
+ }
502
510
}
503
511
_ => { /* not interesting */ }
504
512
}
@@ -609,7 +617,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
609
617
match tcx. item_type ( def_id) . sty {
610
618
ty:: TyFnDef ( def_id, _, f) => {
611
619
// Some constructors also have type TyFnDef but they are
612
- // always instantiated inline and don't result in
620
+ // always instantiated inline and don't result in a
613
621
// translation item. Same for FFI functions.
614
622
if let Some ( hir_map:: NodeForeignItem ( _) ) = tcx. map . get_if_local ( def_id) {
615
623
return false ;
@@ -625,7 +633,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
625
633
_ => return false
626
634
}
627
635
628
- can_have_local_instance ( tcx, def_id)
636
+ should_trans_locally ( tcx, def_id)
629
637
}
630
638
}
631
639
@@ -675,10 +683,27 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
675
683
}
676
684
}
677
685
678
- fn can_have_local_instance < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
679
- def_id : DefId )
680
- -> bool {
681
- tcx. sess . cstore . can_have_local_instance ( tcx, def_id)
686
+ // Returns true if we should translate an instance in the local crate.
687
+ // Returns false if we can just link to the upstream crate and therefore don't
688
+ // need a translation item.
689
+ fn should_trans_locally < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
690
+ def_id : DefId )
691
+ -> bool {
692
+ if def_id. is_local ( ) {
693
+ true
694
+ } else {
695
+ if tcx. sess . cstore . is_exported_symbol ( def_id) ||
696
+ tcx. sess . cstore . is_foreign_item ( def_id) {
697
+ // We can link to the item in question, no instance needed in this
698
+ // crate
699
+ false
700
+ } else {
701
+ if !tcx. sess . cstore . is_item_mir_available ( def_id) {
702
+ bug ! ( "Cannot create local trans-item for {:?}" , def_id)
703
+ }
704
+ true
705
+ }
706
+ }
682
707
}
683
708
684
709
fn find_drop_glue_neighbors < ' a , ' tcx > ( scx : & SharedCrateContext < ' a , ' tcx > ,
@@ -698,14 +723,15 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
698
723
// Make sure the BoxFreeFn lang-item gets translated if there is a boxed value.
699
724
if let ty:: TyBox ( content_type) = ty. sty {
700
725
let def_id = scx. tcx ( ) . require_lang_item ( BoxFreeFnLangItem ) ;
701
- assert ! ( can_have_local_instance( scx. tcx( ) , def_id) ) ;
702
- let box_free_fn_trans_item =
703
- create_fn_trans_item ( scx,
704
- def_id,
705
- scx. tcx ( ) . mk_substs ( iter:: once ( Kind :: from ( content_type) ) ) ,
706
- scx. tcx ( ) . intern_substs ( & [ ] ) ) ;
707
-
708
- output. push ( box_free_fn_trans_item) ;
726
+
727
+ if should_trans_locally ( scx. tcx ( ) , def_id) {
728
+ let box_free_fn_trans_item =
729
+ create_fn_trans_item ( scx,
730
+ def_id,
731
+ scx. tcx ( ) . mk_substs ( iter:: once ( Kind :: from ( content_type) ) ) ,
732
+ scx. tcx ( ) . intern_substs ( & [ ] ) ) ;
733
+ output. push ( box_free_fn_trans_item) ;
734
+ }
709
735
}
710
736
711
737
// If the type implements Drop, also add a translation item for the
@@ -735,7 +761,7 @@ fn find_drop_glue_neighbors<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
735
761
_ => bug ! ( )
736
762
} ;
737
763
738
- if can_have_local_instance ( scx. tcx ( ) , destructor_did) {
764
+ if should_trans_locally ( scx. tcx ( ) , destructor_did) {
739
765
let trans_item = create_fn_trans_item ( scx,
740
766
destructor_did,
741
767
substs,
@@ -1080,7 +1106,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(scx: &SharedCrateContext<'a,
1080
1106
None
1081
1107
}
1082
1108
} )
1083
- . filter ( |& ( def_id, _) | can_have_local_instance ( scx. tcx ( ) , def_id) )
1109
+ . filter ( |& ( def_id, _) | should_trans_locally ( scx. tcx ( ) , def_id) )
1084
1110
. map ( |( def_id, substs) | create_fn_trans_item ( scx, def_id, substs, param_substs) ) ;
1085
1111
output. extend ( methods) ;
1086
1112
}
@@ -1255,7 +1281,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(scx: &SharedCrateContext<'a, '
1255
1281
continue ;
1256
1282
}
1257
1283
1258
- if can_have_local_instance ( tcx, method. def_id ) {
1284
+ if should_trans_locally ( tcx, method. def_id ) {
1259
1285
let item = create_fn_trans_item ( scx,
1260
1286
method. def_id ,
1261
1287
callee_substs,
0 commit comments