@@ -15,7 +15,7 @@ use locator::{self, CratePaths};
1515use native_libs:: relevant_lib;
1616use schema:: CrateRoot ;
1717
18- use rustc:: hir:: def_id:: { CrateNum , DefIndex } ;
18+ use rustc:: hir:: def_id:: { CrateNum , DefIndex , CRATE_DEF_INDEX } ;
1919use rustc:: hir:: svh:: Svh ;
2020use rustc:: middle:: allocator:: AllocatorKind ;
2121use rustc:: middle:: cstore:: DepKind ;
@@ -944,53 +944,80 @@ impl<'a> CrateLoader<'a> {
944944 // (need_lib_alloc and prefer_dynamic) then we select `None`, and if the
945945 // exe allocation crate doesn't exist for this target then we also
946946 // select `None`.
947- let exe_allocation_crate =
947+ let exe_allocation_crate_data =
948948 if need_lib_alloc && !self . sess . opts . cg . prefer_dynamic {
949949 None
950950 } else {
951- self . sess . target . target . options . exe_allocation_crate . as_ref ( )
951+ self . sess
952+ . target
953+ . target
954+ . options
955+ . exe_allocation_crate
956+ . as_ref ( )
957+ . map ( |name| {
958+ // We've determined that we're injecting an "exe allocator" which means
959+ // that we're going to load up a whole new crate. An example of this is
960+ // that we're producing a normal binary on Linux which means we need to
961+ // load the `alloc_jemalloc` crate to link as an allocator.
962+ let name = Symbol :: intern ( name) ;
963+ let ( cnum, data) = self . resolve_crate ( & None ,
964+ name,
965+ name,
966+ None ,
967+ DUMMY_SP ,
968+ PathKind :: Crate ,
969+ DepKind :: Implicit ) ;
970+ self . sess . injected_allocator . set ( Some ( cnum) ) ;
971+ data
972+ } )
952973 } ;
953974
954- match exe_allocation_crate {
955- // We've determined that we're injecting an "exe allocator" which
956- // means that we're going to load up a whole new crate. An example
957- // of this is that we're producing a normal binary on Linux which
958- // means we need to load the `alloc_jemalloc` crate to link as an
959- // allocator.
960- Some ( krate) => {
961- self . sess . allocator_kind . set ( Some ( AllocatorKind :: DefaultExe ) ) ;
962- let name = Symbol :: intern ( krate) ;
963- let dep_kind = DepKind :: Implicit ;
964- let ( cnum, _data) =
965- self . resolve_crate ( & None ,
966- name,
967- name,
968- None ,
969- DUMMY_SP ,
970- PathKind :: Crate , dep_kind) ;
971- self . sess . injected_allocator . set ( Some ( cnum) ) ;
975+ let allocation_crate_data = exe_allocation_crate_data. or_else ( || {
976+ if attr:: contains_name ( & krate. attrs , "default_lib_allocator" ) {
977+ // Prefer self as the allocator if there's a collision
978+ return None ;
972979 }
973-
974980 // We're not actually going to inject an allocator, we're going to
975981 // require that something in our crate graph is the default lib
976982 // allocator. This is typically libstd, so this'll rarely be an
977983 // error.
978- None => {
979- self . sess . allocator_kind . set ( Some ( AllocatorKind :: DefaultLib ) ) ;
980- let mut found_lib_allocator =
981- attr:: contains_name ( & krate. attrs , "default_lib_allocator" ) ;
982- self . cstore . iter_crate_data ( |_, data| {
983- if !found_lib_allocator {
984- if data. has_default_lib_allocator ( ) {
985- found_lib_allocator = true ;
986- }
984+ let mut allocator = None ;
985+ self . cstore . iter_crate_data ( |_, data| {
986+ if allocator. is_none ( ) && data. has_default_lib_allocator ( ) {
987+ allocator = Some ( data. clone ( ) ) ;
988+ }
989+ } ) ;
990+ allocator
991+ } ) ;
992+
993+ match allocation_crate_data {
994+ Some ( data) => {
995+ // We have an allocator. We detect separately what kind it is, to allow for some
996+ // flexibility in misconfiguration.
997+ let attrs = data. get_item_attrs ( CRATE_DEF_INDEX ) ;
998+ let kind_interned = attr:: first_attr_value_str_by_name ( & attrs, "rustc_alloc_kind" )
999+ . map ( Symbol :: as_str) ;
1000+ let kind_str = kind_interned
1001+ . as_ref ( )
1002+ . map ( |s| s as & str ) ;
1003+ let alloc_kind = match kind_str {
1004+ None |
1005+ Some ( "lib" ) => AllocatorKind :: DefaultLib ,
1006+ Some ( "exe" ) => AllocatorKind :: DefaultExe ,
1007+ Some ( other) => {
1008+ self . sess . err ( & format ! ( "Allocator kind {} not known" , other) ) ;
1009+ return ;
9871010 }
988- } ) ;
989- if found_lib_allocator {
990- return
1011+ } ;
1012+ self . sess . allocator_kind . set ( Some ( alloc_kind) ) ;
1013+ } ,
1014+ None => {
1015+ if !attr:: contains_name ( & krate. attrs , "default_lib_allocator" ) {
1016+ self . sess . err ( "no #[default_lib_allocator] found but one is \
1017+ required; is libstd not linked?") ;
1018+ return ;
9911019 }
992- self . sess . err ( "no #[default_lib_allocator] found but one is \
993- required; is libstd not linked?") ;
1020+ self . sess . allocator_kind . set ( Some ( AllocatorKind :: DefaultLib ) ) ;
9941021 }
9951022 }
9961023
0 commit comments