@@ -39,7 +39,7 @@ use tracing::{debug, info, trace};
3939use  crate :: errors; 
4040use  crate :: locator:: { CrateError ,  CrateLocator ,  CratePaths } ; 
4141use  crate :: rmeta:: { 
42-     CrateDep ,  CrateMetadata ,  CrateNumMap ,  CrateRoot ,  MetadataBlob ,  TargetModifiers , 
42+     CrateDep ,  CrateMetadata ,  CrateNumMap ,  CrateRoot ,  DepPrivacy ,   MetadataBlob ,  TargetModifiers , 
4343} ; 
4444
4545/// The backend's way to give the crate store access to the metadata in a library. 
@@ -162,6 +162,14 @@ impl<'a> std::fmt::Debug for CrateDump<'a> {
162162    } 
163163} 
164164
165+ #[ derive( Clone ,  Copy ) ]  
166+ struct  DepOf < ' b >  { 
167+     dep_root :  & ' b  CratePaths , 
168+     parent :  CrateNum , 
169+     privacy_of_parent :  DepPrivacy , 
170+     dep :  & ' b  CrateDep , 
171+ } 
172+ 
165173impl  CStore  { 
166174    pub  fn  from_tcx ( tcx :  TyCtxt < ' _ > )  -> FreezeReadGuard < ' _ ,  CStore >  { 
167175        FreezeReadGuard :: map ( tcx. untracked ( ) . cstore . read ( ) ,  |cstore| { 
@@ -493,36 +501,41 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
493501     /// Sometimes the directly dependent crate is not specified by `--extern`, in this case, 
494502     /// `private-dep` is none during loading. This is equivalent to the scenario where the 
495503     /// command parameter is set to `public-dependency` 
496-      fn  is_private_dep ( 
497-         & self , 
498-         name :  Symbol , 
499-         private_dep :  Option < bool > , 
500-         dep_root :  Option < & CratePaths > , 
501-     )  -> bool  { 
504+      fn  privacy_of_dep ( & self ,  name :  Symbol ,  dep_of :  Option < DepOf < ' _ > > )  -> DepPrivacy  { 
502505        // Standard library crates are never private. 
503506        if  STDLIB_STABLE_CRATES . contains ( & name)  { 
504507            tracing:: info!( "returning false for {name} is private" ) ; 
505-             return  false ; 
508+             return  DepPrivacy :: Direct ( false ) ; 
506509        } 
507510
508511        let  extern_private = self . sess . opts . externs . get ( name. as_str ( ) ) . map ( |e| e. is_private_dep ) ; 
509512
510513        // Any descendants of `std` should be private. These crates are usually not marked 
511514        // private in metadata, so we ignore that field. 
512515        if  extern_private. is_none ( ) 
513-             && let  Some ( dep)  = dep_root
516+             && let  Some ( dep)  = dep_of . map ( |d| d . dep_root ) 
514517            && STDLIB_STABLE_CRATES . contains ( & dep. name ) 
515518        { 
516-             return  true ; 
519+             return  DepPrivacy :: Direct ( true ) ; 
517520        } 
518521
519-         match  ( extern_private,  private_dep)  { 
520-             // Explicit non-private via `--extern`, explicit non-private from metadata, or 
521-             // unspecified with default to public. 
522-             ( Some ( false ) ,  _)  | ( _,  Some ( false ) )  | ( None ,  None )  => false , 
523-             // Marked private via `--extern priv:mycrate` or in metadata. 
524-             ( Some ( true )  | None ,  Some ( true )  | None )  => true , 
525-         } 
522+         let  dep_privacy = if  let  Some ( dep_of)  = dep_of { 
523+             let  is_private = dep_of. dep . is_private ; 
524+             if  dep_of. parent  == LOCAL_CRATE  { 
525+                 DepPrivacy :: Direct ( is_private) 
526+             }  else  { 
527+                 match  dep_of. privacy_of_parent  { 
528+                     DepPrivacy :: Direct ( false )  if  !is_private => DepPrivacy :: TransitivePublic , 
529+                     DepPrivacy :: TransitivePublic  if  !is_private => DepPrivacy :: TransitivePublic , 
530+                     DepPrivacy :: ExternCrate  if  !is_private => DepPrivacy :: TransitivePublic , 
531+                     _ => DepPrivacy :: TransitivePrivate , 
532+                 } 
533+             } 
534+         }  else  { 
535+             DepPrivacy :: ExternCrate 
536+         } ; 
537+ 
538+         extern_private. map_or ( dep_privacy,  |private| dep_privacy. merge ( DepPrivacy :: Direct ( private) ) ) 
526539    } 
527540
528541    fn  register_crate ( 
@@ -532,25 +545,24 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
532545        lib :  Library , 
533546        dep_kind :  CrateDepKind , 
534547        name :  Symbol , 
535-         private_dep :   Option < bool > , 
548+         dep_privacy :   DepPrivacy , 
536549    )  -> Result < CrateNum ,  CrateError >  { 
537550        let  _prof_timer =
538551            self . sess . prof . generic_activity_with_arg ( "metadata_register_crate" ,  name. as_str ( ) ) ; 
539552
540553        let  Library  {  source,  metadata }  = lib; 
541554        let  crate_root = metadata. get_root ( ) ; 
542555        let  host_hash = host_lib. as_ref ( ) . map ( |lib| lib. metadata . get_root ( ) . hash ( ) ) ; 
543-         let  private_dep = self . is_private_dep ( name,  private_dep,  dep_root) ; 
544556
545557        // Claim this crate number and cache it 
546558        let  feed = self . cstore . intern_stable_crate_id ( & crate_root,  self . tcx ) ?; 
547559        let  cnum = feed. key ( ) ; 
548560
549561        info ! ( 
550-             "register crate `{}` (cnum = {}. private_dep  = {})" , 
562+             "register crate `{}` (cnum = {}. dep_privacy  = {:? })" , 
551563            crate_root. name( ) , 
552564            cnum, 
553-             private_dep 
565+             dep_privacy 
554566        ) ; 
555567
556568        // Maintain a reference to the top most crate. 
@@ -563,7 +575,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
563575            & crate_paths
564576        } ; 
565577
566-         let  cnum_map = self . resolve_crate_deps ( dep_root,  & crate_root,  & metadata,  cnum,  dep_kind) ?; 
578+         let  cnum_map =
579+             self . resolve_crate_deps ( dep_root,  & crate_root,  & metadata,  cnum,  dep_kind,  dep_privacy) ?; 
567580
568581        let  raw_proc_macros = if  crate_root. is_proc_macro_crate ( )  { 
569582            let  temp_root; 
@@ -590,7 +603,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
590603            cnum_map, 
591604            dep_kind, 
592605            source, 
593-             private_dep , 
606+             dep_privacy , 
594607            host_hash, 
595608        ) ; 
596609
@@ -681,24 +694,24 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
681694        } 
682695    } 
683696
684-     fn  maybe_resolve_crate < ' b > ( 
685-         & ' b   mut  self , 
697+     fn  maybe_resolve_crate ( 
698+         & mut  self , 
686699        name :  Symbol , 
687700        mut  dep_kind :  CrateDepKind , 
688-         dep_of :  Option < ( & ' b   CratePaths ,   & ' b   CrateDep ) > , 
701+         dep_of :  Option < DepOf < ' _ > > , 
689702    )  -> Result < CrateNum ,  CrateError >  { 
690703        info ! ( "resolving crate `{}`" ,  name) ; 
691704        if  !name. as_str ( ) . is_ascii ( )  { 
692705            return  Err ( CrateError :: NonAsciiName ( name) ) ; 
693706        } 
694707
695-         let  dep_root = dep_of. map ( |d| d. 0 ) ; 
696-         let  dep = dep_of. map ( |d| d. 1 ) ; 
708+         let  dep_root = dep_of. map ( |d| d. dep_root ) ; 
709+         let  dep = dep_of. map ( |d| d. dep ) ; 
697710        let  hash = dep. map ( |d| d. hash ) ; 
698711        let  host_hash = dep. map ( |d| d. host_hash ) . flatten ( ) ; 
699712        let  extra_filename = dep. map ( |d| & d. extra_filename [ ..] ) ; 
700713        let  path_kind = if  dep. is_some ( )  {  PathKind :: Dependency  }  else  {  PathKind :: Crate  } ; 
701-         let  private_dep  = dep . map ( |d| d . is_private ) ; 
714+         let  dep_privacy  = self . privacy_of_dep ( name ,  dep_of ) ; 
702715
703716        let  result = if  let  Some ( cnum)  = self . existing_match ( name,  hash,  path_kind)  { 
704717            ( LoadResult :: Previous ( cnum) ,  None ) 
@@ -732,22 +745,22 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
732745        match  result { 
733746            ( LoadResult :: Previous ( cnum) ,  None )  => { 
734747                info ! ( "library for `{}` was loaded previously" ,  name) ; 
735-                 // When `private_dep ` is none, it indicates the directly dependent crate. If it is 
748+                 // When `dep_of ` is none, it indicates the directly dependent crate. If it is 
736749                // not specified by `--extern` on command line parameters, it may be 
737750                // `private-dependency` when `register_crate` is called for the first time. Then it must be updated to 
738751                // `public-dependency` here. 
739-                 let  private_dep = self . is_private_dep ( name,  private_dep,  dep_root) ; 
740752                let  data = self . cstore . get_crate_data_mut ( cnum) ; 
741753                if  data. is_proc_macro_crate ( )  { 
742754                    dep_kind = CrateDepKind :: MacrosOnly ; 
743755                } 
744756                data. set_dep_kind ( cmp:: max ( data. dep_kind ( ) ,  dep_kind) ) ; 
745-                 data. update_and_private_dep ( private_dep ) ; 
757+                 data. update_merge_dep_privacy ( dep_privacy ) ; 
746758                Ok ( cnum) 
747759            } 
748760            ( LoadResult :: Loaded ( library) ,  host_library)  => { 
749761                info ! ( "register newly loaded library for `{}`" ,  name) ; 
750-                 self . register_crate ( host_library,  dep_root,  library,  dep_kind,  name,  private_dep) 
762+ 
763+                 self . register_crate ( host_library,  dep_root,  library,  dep_kind,  name,  dep_privacy) 
751764            } 
752765            _ => panic ! ( ) , 
753766        } 
@@ -795,6 +808,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
795808        metadata :  & MetadataBlob , 
796809        krate :  CrateNum , 
797810        dep_kind :  CrateDepKind , 
811+         crate_root_privacy :  DepPrivacy , 
798812    )  -> Result < CrateNumMap ,  CrateError >  { 
799813        debug ! ( 
800814            "resolving deps of external crate `{}` with dep root `{}`" , 
@@ -823,7 +837,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
823837                CrateDepKind :: MacrosOnly  => CrateDepKind :: MacrosOnly , 
824838                _ => dep. kind , 
825839            } ; 
826-             let  cnum = self . maybe_resolve_crate ( dep. name ,  dep_kind,  Some ( ( dep_root,  & dep) ) ) ?; 
840+             let  dep_of =
841+                 DepOf  {  dep_root,  parent :  krate,  privacy_of_parent :  crate_root_privacy,  dep :  & dep } ; 
842+             let  cnum = self . maybe_resolve_crate ( dep. name ,  dep_kind,  Some ( dep_of) ) ?; 
827843            crate_num_map. push ( cnum) ; 
828844        } 
829845
0 commit comments