@@ -142,6 +142,7 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
142
142
writeln ! ( fmt, " cnum: {cnum}" ) ?;
143
143
writeln ! ( fmt, " hash: {}" , data. hash( ) ) ?;
144
144
writeln ! ( fmt, " reqd: {:?}" , data. dep_kind( ) ) ?;
145
+ writeln ! ( fmt, " priv: {:?}" , data. is_private_dep( ) ) ?;
145
146
let CrateSource { dylib, rlib, rmeta } = data. source ( ) ;
146
147
if let Some ( dylib) = dylib {
147
148
writeln ! ( fmt, " dylib: {}" , dylib. 0 . display( ) ) ?;
@@ -157,6 +158,43 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
157
158
}
158
159
}
159
160
161
+ /// Reason that a crate is being sourced as a dependency.
162
+ #[ derive( Clone , Copy ) ]
163
+ enum CrateOrigin < ' a > {
164
+ /// This crate was a dependency of another crate.
165
+ Dependency {
166
+ dep_root : & ' a CratePaths ,
167
+ /// Dependency info about this crate.
168
+ dep : & ' a CrateDep ,
169
+ } ,
170
+ /// Injected by `rustc`.
171
+ Injected ,
172
+ /// An extern that has been provided with the `force` option.
173
+ ForcedExtern ,
174
+ /// Part of the extern prelude.
175
+ ExternPrelude ,
176
+ /// Provided by `extern crate foo`.
177
+ AstExtern ,
178
+ }
179
+
180
+ impl < ' a > CrateOrigin < ' a > {
181
+ /// Return the dependency root, if any.
182
+ fn dep_root ( & self ) -> Option < & ' a CratePaths > {
183
+ match self {
184
+ CrateOrigin :: Dependency { dep_root, .. } => Some ( dep_root) ,
185
+ _ => None ,
186
+ }
187
+ }
188
+
189
+ /// Return dependency information, if any.
190
+ fn dep ( & self ) -> Option < & ' a CrateDep > {
191
+ match self {
192
+ CrateOrigin :: Dependency { dep, .. } => Some ( dep) ,
193
+ _ => None ,
194
+ }
195
+ }
196
+ }
197
+
160
198
impl CStore {
161
199
pub fn from_tcx ( tcx : TyCtxt < ' _ > ) -> FreezeReadGuard < ' _ , CStore > {
162
200
FreezeReadGuard :: map ( tcx. untracked ( ) . cstore . read ( ) , |cstore| {
@@ -404,7 +442,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
404
442
& self ,
405
443
name : Symbol ,
406
444
private_dep : Option < bool > ,
407
- dep_root : Option < & CratePaths > ,
445
+ origin : CrateOrigin < ' _ > ,
408
446
) -> bool {
409
447
// Standard library crates are never private.
410
448
if STDLIB_STABLE_CRATES . contains ( & name) {
@@ -414,10 +452,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
414
452
415
453
let extern_private = self . sess . opts . externs . get ( name. as_str ( ) ) . map ( |e| e. is_private_dep ) ;
416
454
455
+ if matches ! ( origin, CrateOrigin :: Injected ) {
456
+ return true ;
457
+ }
458
+
417
459
// Any descendants of `std` should be private. These crates are usually not marked
418
460
// private in metadata, so we ignore that field.
419
461
if extern_private. is_none ( )
420
- && let Some ( dep) = dep_root
462
+ && let Some ( dep) = origin . dep_root ( )
421
463
&& STDLIB_STABLE_CRATES . contains ( & dep. name )
422
464
{
423
465
return true ;
@@ -435,7 +477,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
435
477
fn register_crate (
436
478
& mut self ,
437
479
host_lib : Option < Library > ,
438
- dep_root : Option < & CratePaths > ,
480
+ origin : CrateOrigin < ' _ > ,
439
481
lib : Library ,
440
482
dep_kind : CrateDepKind ,
441
483
name : Symbol ,
@@ -447,7 +489,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
447
489
let Library { source, metadata } = lib;
448
490
let crate_root = metadata. get_root ( ) ;
449
491
let host_hash = host_lib. as_ref ( ) . map ( |lib| lib. metadata . get_root ( ) . hash ( ) ) ;
450
- let private_dep = self . is_private_dep ( name, private_dep, dep_root ) ;
492
+ let private_dep = self . is_private_dep ( name, private_dep, origin ) ;
451
493
452
494
// Claim this crate number and cache it
453
495
let feed = self . cstore . intern_stable_crate_id ( & crate_root, self . tcx ) ?;
@@ -463,7 +505,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
463
505
// Maintain a reference to the top most crate.
464
506
// Stash paths for top-most crate locally if necessary.
465
507
let crate_paths;
466
- let dep_root = if let Some ( dep_root) = dep_root {
508
+ let dep_root = if let Some ( dep_root) = origin . dep_root ( ) {
467
509
dep_root
468
510
} else {
469
511
crate_paths = CratePaths :: new ( crate_root. name ( ) , source. clone ( ) ) ;
@@ -571,17 +613,23 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
571
613
name : Symbol ,
572
614
span : Span ,
573
615
dep_kind : CrateDepKind ,
616
+ origin : CrateOrigin < ' _ > ,
574
617
) -> Option < CrateNum > {
575
618
self . used_extern_options . insert ( name) ;
576
- match self . maybe_resolve_crate ( name, dep_kind, None ) {
619
+ match self . maybe_resolve_crate ( name, dep_kind, origin ) {
577
620
Ok ( cnum) => {
578
621
self . cstore . set_used_recursively ( cnum) ;
579
622
Some ( cnum)
580
623
}
581
624
Err ( err) => {
582
625
debug ! ( "failed to resolve crate {} {:?}" , name, dep_kind) ;
583
- let missing_core =
584
- self . maybe_resolve_crate ( sym:: core, CrateDepKind :: Explicit , None ) . is_err ( ) ;
626
+ let missing_core = self
627
+ . maybe_resolve_crate (
628
+ sym:: core,
629
+ CrateDepKind :: Explicit ,
630
+ CrateOrigin :: ExternPrelude ,
631
+ )
632
+ . is_err ( ) ;
585
633
err. report ( self . sess , span, missing_core) ;
586
634
None
587
635
}
@@ -592,15 +640,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
592
640
& ' b mut self ,
593
641
name : Symbol ,
594
642
mut dep_kind : CrateDepKind ,
595
- dep_of : Option < ( & ' b CratePaths , & ' b CrateDep ) > ,
643
+ origin : CrateOrigin < ' b > ,
596
644
) -> Result < CrateNum , CrateError > {
597
645
info ! ( "resolving crate `{}`" , name) ;
598
646
if !name. as_str ( ) . is_ascii ( ) {
599
647
return Err ( CrateError :: NonAsciiName ( name) ) ;
600
648
}
601
649
602
- let dep_root = dep_of . map ( |d| d . 0 ) ;
603
- let dep = dep_of . map ( |d| d . 1 ) ;
650
+ let dep_root = origin . dep_root ( ) ;
651
+ let dep = origin . dep ( ) ;
604
652
let hash = dep. map ( |d| d. hash ) ;
605
653
let host_hash = dep. map ( |d| d. host_hash ) . flatten ( ) ;
606
654
let extra_filename = dep. map ( |d| & d. extra_filename [ ..] ) ;
@@ -638,12 +686,12 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
638
686
639
687
match result {
640
688
( LoadResult :: Previous ( cnum) , None ) => {
641
- info ! ( "library for `{}` was loaded previously" , name) ;
689
+ info ! ( "library for `{}` was loaded previously, cnum {cnum} " , name) ;
642
690
// When `private_dep` is none, it indicates the directly dependent crate. If it is
643
691
// not specified by `--extern` on command line parameters, it may be
644
692
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
645
693
// `public-dependency` here.
646
- let private_dep = self . is_private_dep ( name, private_dep, dep_root ) ;
694
+ let private_dep = self . is_private_dep ( name, private_dep, origin ) ;
647
695
let data = self . cstore . get_crate_data_mut ( cnum) ;
648
696
if data. is_proc_macro_crate ( ) {
649
697
dep_kind = CrateDepKind :: MacrosOnly ;
@@ -654,7 +702,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
654
702
}
655
703
( LoadResult :: Loaded ( library) , host_library) => {
656
704
info ! ( "register newly loaded library for `{}`" , name) ;
657
- self . register_crate ( host_library, dep_root , library, dep_kind, name, private_dep)
705
+ self . register_crate ( host_library, origin , library, dep_kind, name, private_dep)
658
706
}
659
707
_ => panic ! ( ) ,
660
708
}
@@ -730,7 +778,10 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
730
778
CrateDepKind :: MacrosOnly => CrateDepKind :: MacrosOnly ,
731
779
_ => dep. kind ,
732
780
} ;
733
- let cnum = self . maybe_resolve_crate ( dep. name , dep_kind, Some ( ( dep_root, & dep) ) ) ?;
781
+ let cnum = self . maybe_resolve_crate ( dep. name , dep_kind, CrateOrigin :: Dependency {
782
+ dep_root,
783
+ dep : & dep,
784
+ } ) ?;
734
785
crate_num_map. push ( cnum) ;
735
786
}
736
787
@@ -824,7 +875,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
824
875
} ;
825
876
info ! ( "panic runtime not found -- loading {}" , name) ;
826
877
827
- let Some ( cnum) = self . resolve_crate ( name, DUMMY_SP , CrateDepKind :: Implicit ) else {
878
+ let Some ( cnum) =
879
+ self . resolve_crate ( name, DUMMY_SP , CrateDepKind :: Implicit , CrateOrigin :: Injected )
880
+ else {
828
881
return ;
829
882
} ;
830
883
let data = self . cstore . get_crate_data ( cnum) ;
@@ -853,7 +906,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
853
906
info ! ( "loading profiler" ) ;
854
907
855
908
let name = Symbol :: intern ( & self . sess . opts . unstable_opts . profiler_runtime ) ;
856
- let Some ( cnum) = self . resolve_crate ( name, DUMMY_SP , CrateDepKind :: Implicit ) else {
909
+ let Some ( cnum) =
910
+ self . resolve_crate ( name, DUMMY_SP , CrateDepKind :: Implicit , CrateOrigin :: Injected )
911
+ else {
857
912
return ;
858
913
} ;
859
914
let data = self . cstore . get_crate_data ( cnum) ;
@@ -966,12 +1021,54 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
966
1021
if entry. force {
967
1022
let name_interned = Symbol :: intern ( name) ;
968
1023
if !self . used_extern_options . contains ( & name_interned) {
969
- self . resolve_crate ( name_interned, DUMMY_SP , CrateDepKind :: Explicit ) ;
1024
+ self . resolve_crate (
1025
+ name_interned,
1026
+ DUMMY_SP ,
1027
+ CrateDepKind :: Explicit ,
1028
+ CrateOrigin :: ForcedExtern ,
1029
+ ) ;
970
1030
}
971
1031
}
972
1032
}
973
1033
}
974
1034
1035
+ /// Inject the `compiler_builtins` crate if it is not already in the graph.
1036
+ fn inject_compiler_builtins ( & mut self , krate : & ast:: Crate ) {
1037
+ // `compiler_builtins` does not get extern builtins, nor do `#![no_core]` crates
1038
+ if attr:: contains_name ( & krate. attrs , sym:: compiler_builtins)
1039
+ || attr:: contains_name ( & krate. attrs , sym:: no_core)
1040
+ {
1041
+ info ! ( "`compiler_builtins` unneeded" ) ;
1042
+ return ;
1043
+ }
1044
+
1045
+ // If a `#![compiler_builtins]` crate already exists, avoid injecting it twice. This is
1046
+ // the common case since usually it appears as a dependency of `std` or `core`.
1047
+ for ( cnum, cmeta) in self . cstore . iter_crate_data ( ) {
1048
+ if cmeta. is_compiler_builtins ( ) {
1049
+ info ! ( "`compiler_builtins` already exists (cnum = {cnum}); skipping injection" ) ;
1050
+ return ;
1051
+ }
1052
+ }
1053
+
1054
+ // Allow builtins to remain unresolved, which will just mean linker errors if the
1055
+ // relevant symbols aren't otherwise provided.
1056
+ let Ok ( cnum) = self . maybe_resolve_crate (
1057
+ sym:: compiler_builtins,
1058
+ CrateDepKind :: Explicit ,
1059
+ CrateOrigin :: Injected ,
1060
+ ) else {
1061
+ info ! ( "`compiler_builtins` not resolved" ) ;
1062
+ return ;
1063
+ } ;
1064
+
1065
+ // Sanity check that the loaded crate is `#![compiler_builtins]`
1066
+ let cmeta = self . cstore . get_crate_data ( cnum) ;
1067
+ if !cmeta. is_compiler_builtins ( ) {
1068
+ self . dcx ( ) . emit_err ( errors:: CrateNotCompilerBuiltins { crate_name : cmeta. name ( ) } ) ;
1069
+ }
1070
+ }
1071
+
975
1072
fn inject_dependency_if (
976
1073
& mut self ,
977
1074
krate : CrateNum ,
@@ -1081,6 +1178,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
1081
1178
}
1082
1179
1083
1180
pub fn postprocess ( & mut self , krate : & ast:: Crate ) {
1181
+ self . inject_compiler_builtins ( krate) ;
1084
1182
self . inject_forced_externs ( ) ;
1085
1183
self . inject_profiler_runtime ( ) ;
1086
1184
self . inject_allocator_crate ( krate) ;
@@ -1092,6 +1190,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
1092
1190
info ! ( "{:?}" , CrateDump ( self . cstore) ) ;
1093
1191
}
1094
1192
1193
+ /// Process an `extern crate foo` AST node.
1095
1194
pub fn process_extern_crate (
1096
1195
& mut self ,
1097
1196
item : & ast:: Item ,
@@ -1117,7 +1216,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
1117
1216
CrateDepKind :: Explicit
1118
1217
} ;
1119
1218
1120
- let cnum = self . resolve_crate ( name, item. span , dep_kind) ?;
1219
+ let cnum = self . resolve_crate ( name, item. span , dep_kind, CrateOrigin :: AstExtern ) ?;
1121
1220
1122
1221
let path_len = definitions. def_path ( def_id) . data . len ( ) ;
1123
1222
self . cstore . update_extern_crate ( cnum, ExternCrate {
@@ -1133,7 +1232,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
1133
1232
}
1134
1233
1135
1234
pub fn process_path_extern ( & mut self , name : Symbol , span : Span ) -> Option < CrateNum > {
1136
- let cnum = self . resolve_crate ( name, span, CrateDepKind :: Explicit ) ?;
1235
+ let cnum =
1236
+ self . resolve_crate ( name, span, CrateDepKind :: Explicit , CrateOrigin :: ExternPrelude ) ?;
1137
1237
1138
1238
self . cstore . update_extern_crate ( cnum, ExternCrate {
1139
1239
src : ExternCrateSource :: Path ,
@@ -1147,7 +1247,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
1147
1247
}
1148
1248
1149
1249
pub fn maybe_process_path_extern ( & mut self , name : Symbol ) -> Option < CrateNum > {
1150
- self . maybe_resolve_crate ( name, CrateDepKind :: Explicit , None ) . ok ( )
1250
+ self . maybe_resolve_crate ( name, CrateDepKind :: Explicit , CrateOrigin :: ExternPrelude ) . ok ( )
1151
1251
}
1152
1252
}
1153
1253
0 commit comments