@@ -212,7 +212,7 @@ use glue::{self, DropGlueKind};
212212use monomorphize:: { self , Instance } ;
213213use util:: nodemap:: { FxHashSet , FxHashMap , DefIdMap } ;
214214
215- use trans_item:: { TransItem , DefPathBasedNames } ;
215+ use trans_item:: { TransItem , DefPathBasedNames , InstantiationMode } ;
216216
217217use std:: iter;
218218
@@ -337,6 +337,10 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
337337 }
338338 TransItem :: Static ( node_id) => {
339339 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+
340344 let ty = scx. tcx ( ) . item_type ( def_id) ;
341345 let ty = glue:: get_drop_glue_type ( scx, ty) ;
342346 neighbors. push ( TransItem :: DropGlue ( DropGlueKind :: Ty ( ty) ) ) ;
@@ -346,6 +350,9 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
346350 collect_neighbours ( scx, Instance :: mono ( scx, def_id) , & mut neighbors) ;
347351 }
348352 TransItem :: Fn ( instance) => {
353+ // Sanity check whether this ended up being collected accidentally
354+ debug_assert ! ( should_trans_locally( scx. tcx( ) , instance. def) ) ;
355+
349356 // Keep track of the monomorphization recursion depth
350357 recursion_depth_reset = Some ( check_recursion_limit ( scx. tcx ( ) ,
351358 instance,
@@ -374,7 +381,7 @@ fn record_inlining_canditates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
374381 callees : & [ TransItem < ' tcx > ] ,
375382 inlining_map : & mut InliningMap < ' tcx > ) {
376383 let is_inlining_candidate = |trans_item : & TransItem < ' tcx > | {
377- trans_item. needs_local_copy ( tcx)
384+ trans_item. instantiation_mode ( tcx) == InstantiationMode :: LocalCopy
378385 } ;
379386
380387 let inlining_candidates = callees. into_iter ( )
@@ -490,15 +497,16 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
490497 . require ( ExchangeMallocFnLangItem )
491498 . unwrap_or_else ( |e| self . scx . sess ( ) . fatal ( & e) ) ;
492499
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 ) ;
500507
501- self . output . push ( exchange_malloc_fn_trans_item) ;
508+ self . output . push ( exchange_malloc_fn_trans_item) ;
509+ }
502510 }
503511 _ => { /* not interesting */ }
504512 }
@@ -609,7 +617,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
609617 match tcx. item_type ( def_id) . sty {
610618 ty:: TyFnDef ( def_id, _, f) => {
611619 // 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
613621 // translation item. Same for FFI functions.
614622 if let Some ( hir_map:: NodeForeignItem ( _) ) = tcx. map . get_if_local ( def_id) {
615623 return false ;
@@ -625,7 +633,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
625633 _ => return false
626634 }
627635
628- can_have_local_instance ( tcx, def_id)
636+ should_trans_locally ( tcx, def_id)
629637 }
630638 }
631639
@@ -675,10 +683,27 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
675683 }
676684}
677685
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+ }
682707}
683708
684709fn 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>,
698723 // Make sure the BoxFreeFn lang-item gets translated if there is a boxed value.
699724 if let ty:: TyBox ( content_type) = ty. sty {
700725 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+ }
709735 }
710736
711737 // 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>,
735761 _ => bug ! ( )
736762 } ;
737763
738- if can_have_local_instance ( scx. tcx ( ) , destructor_did) {
764+ if should_trans_locally ( scx. tcx ( ) , destructor_did) {
739765 let trans_item = create_fn_trans_item ( scx,
740766 destructor_did,
741767 substs,
@@ -1080,7 +1106,7 @@ fn create_trans_items_for_vtable_methods<'a, 'tcx>(scx: &SharedCrateContext<'a,
10801106 None
10811107 }
10821108 } )
1083- . filter ( |& ( def_id, _) | can_have_local_instance ( scx. tcx ( ) , def_id) )
1109+ . filter ( |& ( def_id, _) | should_trans_locally ( scx. tcx ( ) , def_id) )
10841110 . map ( |( def_id, substs) | create_fn_trans_item ( scx, def_id, substs, param_substs) ) ;
10851111 output. extend ( methods) ;
10861112 }
@@ -1255,7 +1281,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(scx: &SharedCrateContext<'a, '
12551281 continue ;
12561282 }
12571283
1258- if can_have_local_instance ( tcx, method. def_id ) {
1284+ if should_trans_locally ( tcx, method. def_id ) {
12591285 let item = create_fn_trans_item ( scx,
12601286 method. def_id ,
12611287 callee_substs,
0 commit comments