@@ -157,6 +157,43 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
157157 }
158158}
159159
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+
160197impl CStore {
161198 pub fn from_tcx ( tcx : TyCtxt < ' _ > ) -> FreezeReadGuard < ' _ , CStore > {
162199 FreezeReadGuard :: map ( tcx. untracked ( ) . cstore . read ( ) , |cstore| {
@@ -404,7 +441,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
404441 & self ,
405442 name : Symbol ,
406443 private_dep : Option < bool > ,
407- dep_root : Option < & CratePaths > ,
444+ origin : CrateOrigin < ' _ > ,
408445 ) -> bool {
409446 // Standard library crates are never private.
410447 if STDLIB_STABLE_CRATES . contains ( & name) {
@@ -414,10 +451,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
414451
415452 let extern_private = self . sess . opts . externs . get ( name. as_str ( ) ) . map ( |e| e. is_private_dep ) ;
416453
454+ if matches ! ( origin, CrateOrigin :: Injected ) {
455+ return true ;
456+ }
457+
417458 // Any descendants of `std` should be private. These crates are usually not marked
418459 // private in metadata, so we ignore that field.
419460 if extern_private. is_none ( )
420- && let Some ( dep) = dep_root
461+ && let Some ( dep) = origin . dep_root ( )
421462 && STDLIB_STABLE_CRATES . contains ( & dep. name )
422463 {
423464 return true ;
@@ -435,7 +476,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
435476 fn register_crate (
436477 & mut self ,
437478 host_lib : Option < Library > ,
438- dep_root : Option < & CratePaths > ,
479+ origin : CrateOrigin < ' _ > ,
439480 lib : Library ,
440481 dep_kind : CrateDepKind ,
441482 name : Symbol ,
@@ -447,7 +488,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
447488 let Library { source, metadata } = lib;
448489 let crate_root = metadata. get_root ( ) ;
449490 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 ) ;
451492
452493 // Claim this crate number and cache it
453494 let feed = self . cstore . intern_stable_crate_id ( & crate_root, self . tcx ) ?;
@@ -463,7 +504,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
463504 // Maintain a reference to the top most crate.
464505 // Stash paths for top-most crate locally if necessary.
465506 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 ( ) {
467508 dep_root
468509 } else {
469510 crate_paths = CratePaths :: new ( crate_root. name ( ) , source. clone ( ) ) ;
@@ -571,17 +612,23 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
571612 name : Symbol ,
572613 span : Span ,
573614 dep_kind : CrateDepKind ,
615+ origin : CrateOrigin < ' _ > ,
574616 ) -> Option < CrateNum > {
575617 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 ) {
577619 Ok ( cnum) => {
578620 self . cstore . set_used_recursively ( cnum) ;
579621 Some ( cnum)
580622 }
581623 Err ( err) => {
582624 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 ( ) ;
585632 err. report ( self . sess , span, missing_core) ;
586633 None
587634 }
@@ -592,15 +639,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
592639 & ' b mut self ,
593640 name : Symbol ,
594641 mut dep_kind : CrateDepKind ,
595- dep_of : Option < ( & ' b CratePaths , & ' b CrateDep ) > ,
642+ origin : CrateOrigin < ' b > ,
596643 ) -> Result < CrateNum , CrateError > {
597644 info ! ( "resolving crate `{}`" , name) ;
598645 if !name. as_str ( ) . is_ascii ( ) {
599646 return Err ( CrateError :: NonAsciiName ( name) ) ;
600647 }
601648
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 ( ) ;
604651 let hash = dep. map ( |d| d. hash ) ;
605652 let host_hash = dep. map ( |d| d. host_hash ) . flatten ( ) ;
606653 let extra_filename = dep. map ( |d| & d. extra_filename [ ..] ) ;
@@ -638,12 +685,12 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
638685
639686 match result {
640687 ( LoadResult :: Previous ( cnum) , None ) => {
641- info ! ( "library for `{}` was loaded previously" , name) ;
688+ info ! ( "library for `{}` was loaded previously, cnum {cnum} " , name) ;
642689 // When `private_dep` is none, it indicates the directly dependent crate. If it is
643690 // not specified by `--extern` on command line parameters, it may be
644691 // `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
645692 // `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 ) ;
647694 let data = self . cstore . get_crate_data_mut ( cnum) ;
648695 if data. is_proc_macro_crate ( ) {
649696 dep_kind = CrateDepKind :: MacrosOnly ;
@@ -654,7 +701,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
654701 }
655702 ( LoadResult :: Loaded ( library) , host_library) => {
656703 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)
658705 }
659706 _ => panic ! ( ) ,
660707 }
@@ -730,7 +777,10 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
730777 CrateDepKind :: MacrosOnly => CrateDepKind :: MacrosOnly ,
731778 _ => dep. kind ,
732779 } ;
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+ } ) ?;
734784 crate_num_map. push ( cnum) ;
735785 }
736786
@@ -824,7 +874,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
824874 } ;
825875 info ! ( "panic runtime not found -- loading {}" , name) ;
826876
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 {
828880 return ;
829881 } ;
830882 let data = self . cstore . get_crate_data ( cnum) ;
@@ -853,7 +905,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
853905 info ! ( "loading profiler" ) ;
854906
855907 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 {
857911 return ;
858912 } ;
859913 let data = self . cstore . get_crate_data ( cnum) ;
@@ -966,12 +1020,50 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
9661020 if entry. force {
9671021 let name_interned = Symbol :: intern ( name) ;
9681022 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+ ) ;
9701029 }
9711030 }
9721031 }
9731032 }
9741033
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+
9751067 fn inject_dependency_if (
9761068 & mut self ,
9771069 krate : CrateNum ,
@@ -1081,6 +1173,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
10811173 }
10821174
10831175 pub fn postprocess ( & mut self , krate : & ast:: Crate ) {
1176+ info ! ( "POSTPROCESS" ) ;
1177+ self . inject_compiler_builtins ( krate) ;
10841178 self . inject_forced_externs ( ) ;
10851179 self . inject_profiler_runtime ( ) ;
10861180 self . inject_allocator_crate ( krate) ;
@@ -1092,6 +1186,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
10921186 info ! ( "{:?}" , CrateDump ( self . cstore) ) ;
10931187 }
10941188
1189+ /// Process an `extern crate foo` AST node.
10951190 pub fn process_extern_crate (
10961191 & mut self ,
10971192 item : & ast:: Item ,
@@ -1111,13 +1206,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
11111206 }
11121207 None => item. ident . name ,
11131208 } ;
1209+
11141210 let dep_kind = if attr:: contains_name ( & item. attrs , sym:: no_link) {
11151211 CrateDepKind :: MacrosOnly
11161212 } else {
11171213 CrateDepKind :: Explicit
11181214 } ;
11191215
1120- let cnum = self . resolve_crate ( name, item. span , dep_kind) ?;
1216+ let cnum = self . resolve_crate ( name, item. span , dep_kind, CrateOrigin :: AstExtern ) ?;
11211217
11221218 let path_len = definitions. def_path ( def_id) . data . len ( ) ;
11231219 self . cstore . update_extern_crate ( cnum, ExternCrate {
@@ -1133,7 +1229,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
11331229 }
11341230
11351231 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 ) ?;
11371234
11381235 self . cstore . update_extern_crate ( cnum, ExternCrate {
11391236 src : ExternCrateSource :: Path ,
@@ -1147,7 +1244,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
11471244 }
11481245
11491246 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 ( )
11511248 }
11521249}
11531250
0 commit comments