@@ -15,7 +15,7 @@ use locator::{self, CratePaths};
15
15
use native_libs:: relevant_lib;
16
16
use schema:: CrateRoot ;
17
17
18
- use rustc:: hir:: def_id:: { CrateNum , DefIndex } ;
18
+ use rustc:: hir:: def_id:: { CrateNum , DefIndex , CRATE_DEF_INDEX } ;
19
19
use rustc:: hir:: svh:: Svh ;
20
20
use rustc:: middle:: allocator:: AllocatorKind ;
21
21
use rustc:: middle:: cstore:: DepKind ;
@@ -944,53 +944,80 @@ impl<'a> CrateLoader<'a> {
944
944
// (need_lib_alloc and prefer_dynamic) then we select `None`, and if the
945
945
// exe allocation crate doesn't exist for this target then we also
946
946
// select `None`.
947
- let exe_allocation_crate =
947
+ let exe_allocation_crate_data =
948
948
if need_lib_alloc && !self . sess . opts . cg . prefer_dynamic {
949
949
None
950
950
} 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
+ } )
952
973
} ;
953
974
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 ;
972
979
}
973
-
974
980
// We're not actually going to inject an allocator, we're going to
975
981
// require that something in our crate graph is the default lib
976
982
// allocator. This is typically libstd, so this'll rarely be an
977
983
// 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 ;
987
1010
}
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 ;
991
1019
}
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 ) ) ;
994
1021
}
995
1022
}
996
1023
0 commit comments