@@ -29,7 +29,7 @@ use rustc_session::lint::{self, BuiltinLintDiag};
2929use rustc_session:: output:: validate_crate_name;
3030use rustc_session:: search_paths:: PathKind ;
3131use rustc_span:: edition:: Edition ;
32- use rustc_span:: { DUMMY_SP , Ident , Span , Symbol , sym} ;
32+ use rustc_span:: { DUMMY_SP , Ident , STDLIB_STABLE_CRATES , Span , Symbol , sym} ;
3333use rustc_target:: spec:: { PanicStrategy , Target , TargetTuple } ;
3434use tracing:: { debug, info, trace} ;
3535
@@ -390,19 +390,51 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
390390 None
391391 }
392392
393- // The `dependency` type is determined by the command line arguments(`--extern`) and
394- // `private_dep`. However, sometimes the directly dependent crate is not specified by
395- // `--extern`, in this case, `private-dep` is none during loading. This is equivalent to the
396- // scenario where the command parameter is set to `public-dependency`
397- fn is_private_dep ( & self , name : & str , private_dep : Option < bool > ) -> bool {
398- self . sess . opts . externs . get ( name) . map_or ( private_dep. unwrap_or ( false ) , |e| e. is_private_dep )
399- && private_dep. unwrap_or ( true )
393+ /// Determine whether a dependency should be considered private.
394+ ///
395+ /// Dependencies are private if they get extern option specified, e.g. `--extern priv:mycrate`.
396+ /// This is stored in metadata, so `private_dep` can be correctly set during load. A `Some`
397+ /// value for `private_dep` indicates that the crate is known to be private or public (note
398+ /// that any `None` or `Some(false)` use of the same crate will make it public).
399+ ///
400+ /// Sometimes the directly dependent crate is not specified by `--extern`, in this case,
401+ /// `private-dep` is none during loading. This is equivalent to the scenario where the
402+ /// command parameter is set to `public-dependency`
403+ fn is_private_dep (
404+ & self ,
405+ name : Symbol ,
406+ private_dep : Option < bool > ,
407+ dep_root : Option < & CratePaths > ,
408+ ) -> bool {
409+ // Standard library crates are never private.
410+ if STDLIB_STABLE_CRATES . contains ( & name) {
411+ tracing:: info!( "returning false for {name} is private" ) ;
412+ return false ;
413+ }
414+
415+ let extern_private = self . sess . opts . externs . get ( name. as_str ( ) ) . map ( |e| e. is_private_dep ) ;
416+
417+ // Any descendants of `std` should be private. These crates are usually not marked
418+ // private in metadata, so we ignore that field.
419+ if extern_private. is_none ( )
420+ && dep_root. map_or ( false , |d| STDLIB_STABLE_CRATES . contains ( & d. name ) )
421+ {
422+ return true ;
423+ }
424+
425+ match ( extern_private, private_dep) {
426+ // Explicit non-private via `--extern`, explicit non-private from metadata, or
427+ // unspecified with default to public.
428+ ( Some ( false ) , _) | ( _, Some ( false ) ) | ( None , None ) => false ,
429+ // Marked private via `--extern priv:mycrate` or in metadata.
430+ ( Some ( true ) | None , Some ( true ) | None ) => true ,
431+ }
400432 }
401433
402434 fn register_crate (
403435 & mut self ,
404436 host_lib : Option < Library > ,
405- root : Option < & CratePaths > ,
437+ dep_root : Option < & CratePaths > ,
406438 lib : Library ,
407439 dep_kind : CrateDepKind ,
408440 name : Symbol ,
@@ -414,7 +446,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
414446 let Library { source, metadata } = lib;
415447 let crate_root = metadata. get_root ( ) ;
416448 let host_hash = host_lib. as_ref ( ) . map ( |lib| lib. metadata . get_root ( ) . hash ( ) ) ;
417- let private_dep = self . is_private_dep ( name. as_str ( ) , private_dep) ;
449+ let private_dep = self . is_private_dep ( name, private_dep, dep_root ) ;
418450
419451 // Claim this crate number and cache it
420452 let feed = self . cstore . intern_stable_crate_id ( & crate_root, self . tcx ) ?;
@@ -430,14 +462,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
430462 // Maintain a reference to the top most crate.
431463 // Stash paths for top-most crate locally if necessary.
432464 let crate_paths;
433- let root = if let Some ( root ) = root {
434- root
465+ let dep_root = if let Some ( dep_root ) = dep_root {
466+ dep_root
435467 } else {
436468 crate_paths = CratePaths :: new ( crate_root. name ( ) , source. clone ( ) ) ;
437469 & crate_paths
438470 } ;
439471
440- let cnum_map = self . resolve_crate_deps ( root , & crate_root, & metadata, cnum, dep_kind) ?;
472+ let cnum_map = self . resolve_crate_deps ( dep_root , & crate_root, & metadata, cnum, dep_kind) ?;
441473
442474 let raw_proc_macros = if crate_root. is_proc_macro_crate ( ) {
443475 let temp_root;
@@ -559,23 +591,21 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
559591 & ' b mut self ,
560592 name : Symbol ,
561593 mut dep_kind : CrateDepKind ,
562- dep : Option < ( & ' b CratePaths , & ' b CrateDep ) > ,
594+ dep_of : Option < ( & ' b CratePaths , & ' b CrateDep ) > ,
563595 ) -> Result < CrateNum , CrateError > {
564596 info ! ( "resolving crate `{}`" , name) ;
565597 if !name. as_str ( ) . is_ascii ( ) {
566598 return Err ( CrateError :: NonAsciiName ( name) ) ;
567599 }
568- let ( root, hash, host_hash, extra_filename, path_kind, private_dep) = match dep {
569- Some ( ( root, dep) ) => (
570- Some ( root) ,
571- Some ( dep. hash ) ,
572- dep. host_hash ,
573- Some ( & dep. extra_filename [ ..] ) ,
574- PathKind :: Dependency ,
575- Some ( dep. is_private ) ,
576- ) ,
577- None => ( None , None , None , None , PathKind :: Crate , None ) ,
578- } ;
600+
601+ let dep_root = dep_of. map ( |d| d. 0 ) ;
602+ let dep = dep_of. map ( |d| d. 1 ) ;
603+ let hash = dep. map ( |d| d. hash ) ;
604+ let host_hash = dep. map ( |d| d. host_hash ) . flatten ( ) ;
605+ let extra_filename = dep. map ( |d| & d. extra_filename [ ..] ) ;
606+ let path_kind = if dep. is_some ( ) { PathKind :: Dependency } else { PathKind :: Crate } ;
607+ let private_dep = dep. map ( |d| d. is_private ) ;
608+
579609 let result = if let Some ( cnum) = self . existing_match ( name, hash, path_kind) {
580610 ( LoadResult :: Previous ( cnum) , None )
581611 } else {
@@ -599,7 +629,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
599629 dep_kind = CrateDepKind :: MacrosOnly ;
600630 match self . load_proc_macro ( & mut locator, path_kind, host_hash) ? {
601631 Some ( res) => res,
602- None => return Err ( locator. into_error ( root . cloned ( ) ) ) ,
632+ None => return Err ( locator. into_error ( dep_root . cloned ( ) ) ) ,
603633 }
604634 }
605635 }
@@ -612,7 +642,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
612642 // not specified by `--extern` on command line parameters, it may be
613643 // `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
614644 // `public-dependency` here.
615- let private_dep = self . is_private_dep ( name. as_str ( ) , private_dep) ;
645+ let private_dep = self . is_private_dep ( name, private_dep, dep_root ) ;
616646 let data = self . cstore . get_crate_data_mut ( cnum) ;
617647 if data. is_proc_macro_crate ( ) {
618648 dep_kind = CrateDepKind :: MacrosOnly ;
@@ -623,7 +653,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
623653 }
624654 ( LoadResult :: Loaded ( library) , host_library) => {
625655 info ! ( "register newly loaded library for `{}`" , name) ;
626- self . register_crate ( host_library, root , library, dep_kind, name, private_dep)
656+ self . register_crate ( host_library, dep_root , library, dep_kind, name, private_dep)
627657 }
628658 _ => panic ! ( ) ,
629659 }
@@ -663,16 +693,20 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
663693 } ) )
664694 }
665695
666- // Go through the crate metadata and load any crates that it references
696+ /// Go through the crate metadata and load any crates that it references.
667697 fn resolve_crate_deps (
668698 & mut self ,
669- root : & CratePaths ,
699+ dep_root : & CratePaths ,
670700 crate_root : & CrateRoot ,
671701 metadata : & MetadataBlob ,
672702 krate : CrateNum ,
673703 dep_kind : CrateDepKind ,
674704 ) -> Result < CrateNumMap , CrateError > {
675- debug ! ( "resolving deps of external crate" ) ;
705+ debug ! (
706+ "resolving deps of external crate `{}` with dep root `{}`" ,
707+ crate_root. name( ) ,
708+ dep_root. name
709+ ) ;
676710 if crate_root. is_proc_macro_crate ( ) {
677711 return Ok ( CrateNumMap :: new ( ) ) ;
678712 }
@@ -685,14 +719,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
685719 crate_num_map. push ( krate) ;
686720 for dep in deps {
687721 info ! (
688- "resolving dep crate {} hash: `{}` extra filename: `{}`" ,
689- dep. name, dep. hash, dep. extra_filename
722+ "resolving dep `{}`->`{}` hash: `{}` extra filename: `{}`" ,
723+ crate_root. name( ) ,
724+ dep. name,
725+ dep. hash,
726+ dep. extra_filename
690727 ) ;
691728 let dep_kind = match dep_kind {
692729 CrateDepKind :: MacrosOnly => CrateDepKind :: MacrosOnly ,
693730 _ => dep. kind ,
694731 } ;
695- let cnum = self . maybe_resolve_crate ( dep. name , dep_kind, Some ( ( root , & dep) ) ) ?;
732+ let cnum = self . maybe_resolve_crate ( dep. name , dep_kind, Some ( ( dep_root , & dep) ) ) ?;
696733 crate_num_map. push ( cnum) ;
697734 }
698735
0 commit comments