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