@@ -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.
@@ -170,8 +170,10 @@ enum CrateOrigin<'a> {
170170 IndirectDependency {
171171 /// Where this dependency was included from.
172172 dep_root : & ' a CratePaths ,
173- /// True if the parent is private, meaning the dependent should also be private.
174- parent_private : bool ,
173+ /// Crate number of parent dependency.
174+ parent_crate : CrateNum ,
175+ /// Privacy of the parent dependency.
176+ parent_privacy : DepPrivacy ,
175177 /// Dependency info about this crate.
176178 dep : & ' a CrateDep ,
177179 } ,
@@ -197,17 +199,6 @@ impl<'a> CrateOrigin<'a> {
197199 _ => None ,
198200 }
199201 }
200-
201- /// `Some(true)` if the dependency is private or its parent is private, `Some(false)` if the
202- /// dependency is not private, `None` if it could not be determined.
203- fn private_dep ( & self ) -> Option < bool > {
204- match self {
205- CrateOrigin :: IndirectDependency { parent_private, dep, .. } => {
206- Some ( dep. is_private || * parent_private)
207- }
208- _ => None ,
209- }
210- }
211202}
212203
213204impl CStore {
@@ -541,24 +532,30 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
541532 /// Sometimes the directly dependent crate is not specified by `--extern`, in this case,
542533 /// `private-dep` is none during loading. This is equivalent to the scenario where the
543534 /// command parameter is set to `public-dependency`
544- fn is_private_dep (
545- & self ,
546- name : Symbol ,
547- private_dep : Option < bool > ,
548- origin : CrateOrigin < ' _ > ,
549- ) -> bool {
535+ fn privacy_of_dep ( & self , name : Symbol , origin : CrateOrigin < ' _ > ) -> DepPrivacy {
550536 if matches ! ( origin, CrateOrigin :: Injected ) {
551- return true ;
537+ return DepPrivacy :: Direct ( true ) ;
552538 }
553539
554540 let extern_private = self . sess . opts . externs . get ( name. as_str ( ) ) . map ( |e| e. is_private_dep ) ;
555- match ( extern_private, private_dep) {
556- // Explicit non-private via `--extern`, explicit non-private from metadata, or
557- // unspecified with default to public.
558- ( Some ( false ) , _) | ( _, Some ( false ) ) | ( None , None ) => false ,
559- // Marked private via `--extern priv:mycrate` or in metadata.
560- ( Some ( true ) | None , Some ( true ) | None ) => true ,
561- }
541+
542+ let dep_privacy = match origin {
543+ CrateOrigin :: IndirectDependency { dep_root : _, parent_crate, parent_privacy, dep } => {
544+ let is_private = dep. is_private ;
545+ match parent_privacy {
546+ _ if parent_crate == LOCAL_CRATE => DepPrivacy :: Direct ( is_private) ,
547+ DepPrivacy :: Direct ( false ) if !is_private => DepPrivacy :: TransitivePublic ,
548+ DepPrivacy :: TransitivePublic if !is_private => DepPrivacy :: TransitivePublic ,
549+ DepPrivacy :: ExternCrate if !is_private => DepPrivacy :: TransitivePublic ,
550+ _ => DepPrivacy :: TransitivePrivate ,
551+ }
552+ }
553+ // Short-circuited from the very beginning of this function.
554+ CrateOrigin :: Injected => unreachable ! ( ) ,
555+ CrateOrigin :: Extern => DepPrivacy :: ExternCrate ,
556+ } ;
557+
558+ extern_private. map_or ( dep_privacy, |private| dep_privacy. merge ( DepPrivacy :: Direct ( private) ) )
562559 }
563560
564561 fn register_crate (
@@ -568,25 +565,24 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
568565 lib : Library ,
569566 dep_kind : CrateDepKind ,
570567 name : Symbol ,
571- private_dep : Option < bool > ,
568+ dep_privacy : DepPrivacy ,
572569 ) -> Result < CrateNum , CrateError > {
573570 let _prof_timer =
574571 self . sess . prof . generic_activity_with_arg ( "metadata_register_crate" , name. as_str ( ) ) ;
575572
576573 let Library { source, metadata } = lib;
577574 let crate_root = metadata. get_root ( ) ;
578575 let host_hash = host_lib. as_ref ( ) . map ( |lib| lib. metadata . get_root ( ) . hash ( ) ) ;
579- let private_dep = self . is_private_dep ( name, private_dep, origin) ;
580576
581577 // Claim this crate number and cache it
582578 let feed = self . cstore . intern_stable_crate_id ( & crate_root, self . tcx ) ?;
583579 let cnum = feed. key ( ) ;
584580
585581 info ! (
586- "register crate `{}` (cnum = {}. private_dep = {})" ,
582+ "register crate `{}` (cnum = {}. dep_privacy = {:? })" ,
587583 crate_root. name( ) ,
588584 cnum,
589- private_dep
585+ dep_privacy
590586 ) ;
591587
592588 // Maintain a reference to the top most crate.
@@ -600,7 +596,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
600596 } ;
601597
602598 let cnum_map =
603- self . resolve_crate_deps ( dep_root, & crate_root, & metadata, cnum, dep_kind, private_dep ) ?;
599+ self . resolve_crate_deps ( dep_root, & crate_root, & metadata, cnum, dep_kind, dep_privacy ) ?;
604600
605601 let raw_proc_macros = if crate_root. is_proc_macro_crate ( ) {
606602 let temp_root;
@@ -627,7 +623,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
627623 cnum_map,
628624 dep_kind,
629625 source,
630- private_dep ,
626+ dep_privacy ,
631627 host_hash,
632628 ) ;
633629
@@ -720,11 +716,11 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
720716 }
721717 }
722718
723- fn maybe_resolve_crate < ' b > (
724- & ' b mut self ,
719+ fn maybe_resolve_crate (
720+ & mut self ,
725721 name : Symbol ,
726722 mut dep_kind : CrateDepKind ,
727- origin : CrateOrigin < ' b > ,
723+ origin : CrateOrigin < ' _ > ,
728724 ) -> Result < CrateNum , CrateError > {
729725 info ! ( "resolving crate `{}`" , name) ;
730726 if !name. as_str ( ) . is_ascii ( ) {
@@ -737,7 +733,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
737733 let host_hash = dep. map ( |d| d. host_hash ) . flatten ( ) ;
738734 let extra_filename = dep. map ( |d| & d. extra_filename [ ..] ) ;
739735 let path_kind = if dep. is_some ( ) { PathKind :: Dependency } else { PathKind :: Crate } ;
740- let private_dep = origin . private_dep ( ) ;
736+ let dep_privacy = self . privacy_of_dep ( name , origin ) ;
741737
742738 let result = if let Some ( cnum) = self . existing_match ( name, hash, path_kind) {
743739 ( LoadResult :: Previous ( cnum) , None )
@@ -775,18 +771,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
775771 // not specified by `--extern` on command line parameters, it may be
776772 // `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
777773 // `public-dependency` here.
778- let private_dep = self . is_private_dep ( name, private_dep, origin) ;
779774 let data = self . cstore . get_crate_data_mut ( cnum) ;
780775 if data. is_proc_macro_crate ( ) {
781776 dep_kind = CrateDepKind :: MacrosOnly ;
782777 }
783778 data. set_dep_kind ( cmp:: max ( data. dep_kind ( ) , dep_kind) ) ;
784- data. update_and_private_dep ( private_dep ) ;
779+ data. update_merge_dep_privacy ( dep_privacy ) ;
785780 Ok ( cnum)
786781 }
787782 ( LoadResult :: Loaded ( library) , host_library) => {
788783 info ! ( "register newly loaded library for `{}`" , name) ;
789- self . register_crate ( host_library, origin, library, dep_kind, name, private_dep )
784+ self . register_crate ( host_library, origin, library, dep_kind, name, dep_privacy )
790785 }
791786 _ => panic ! ( ) ,
792787 }
@@ -822,7 +817,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
822817 metadata : & MetadataBlob ,
823818 krate : CrateNum ,
824819 dep_kind : CrateDepKind ,
825- parent_is_private : bool ,
820+ crate_root_privacy : DepPrivacy ,
826821 ) -> Result < CrateNumMap , CrateError > {
827822 debug ! (
828823 "resolving deps of external crate `{}` with dep root `{}`" ,
@@ -857,7 +852,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
857852 dep_kind,
858853 CrateOrigin :: IndirectDependency {
859854 dep_root,
860- parent_private : parent_is_private,
855+ parent_crate : krate,
856+ parent_privacy : crate_root_privacy,
861857 dep : & dep,
862858 } ,
863859 ) ?;
0 commit comments