@@ -39,7 +39,7 @@ use tracing::{debug, info, trace};
39
39
use crate :: errors;
40
40
use crate :: locator:: { CrateError , CrateLocator , CratePaths } ;
41
41
use crate :: rmeta:: {
42
- CrateDep , CrateMetadata , CrateNumMap , CrateRoot , MetadataBlob , TargetModifiers ,
42
+ CrateDep , CrateMetadata , CrateNumMap , CrateRoot , DepPrivacy , MetadataBlob , TargetModifiers ,
43
43
} ;
44
44
45
45
/// 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> {
162
162
}
163
163
}
164
164
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
+
165
173
impl CStore {
166
174
pub fn from_tcx ( tcx : TyCtxt < ' _ > ) -> FreezeReadGuard < ' _ , CStore > {
167
175
FreezeReadGuard :: map ( tcx. untracked ( ) . cstore . read ( ) , |cstore| {
@@ -493,36 +501,41 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
493
501
/// Sometimes the directly dependent crate is not specified by `--extern`, in this case,
494
502
/// `private-dep` is none during loading. This is equivalent to the scenario where the
495
503
/// 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 {
502
505
// Standard library crates are never private.
503
506
if STDLIB_STABLE_CRATES . contains ( & name) {
504
507
tracing:: info!( "returning false for {name} is private" ) ;
505
- return false ;
508
+ return DepPrivacy :: Direct ( false ) ;
506
509
}
507
510
508
511
let extern_private = self . sess . opts . externs . get ( name. as_str ( ) ) . map ( |e| e. is_private_dep ) ;
509
512
510
513
// Any descendants of `std` should be private. These crates are usually not marked
511
514
// private in metadata, so we ignore that field.
512
515
if extern_private. is_none ( )
513
- && let Some ( dep) = dep_root
516
+ && let Some ( dep) = dep_of . map ( |d| d . dep_root )
514
517
&& STDLIB_STABLE_CRATES . contains ( & dep. name )
515
518
{
516
- return true ;
519
+ return DepPrivacy :: Direct ( true ) ;
517
520
}
518
521
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) ) )
526
539
}
527
540
528
541
fn register_crate (
@@ -532,25 +545,24 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
532
545
lib : Library ,
533
546
dep_kind : CrateDepKind ,
534
547
name : Symbol ,
535
- private_dep : Option < bool > ,
548
+ dep_privacy : DepPrivacy ,
536
549
) -> Result < CrateNum , CrateError > {
537
550
let _prof_timer =
538
551
self . sess . prof . generic_activity_with_arg ( "metadata_register_crate" , name. as_str ( ) ) ;
539
552
540
553
let Library { source, metadata } = lib;
541
554
let crate_root = metadata. get_root ( ) ;
542
555
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) ;
544
556
545
557
// Claim this crate number and cache it
546
558
let feed = self . cstore . intern_stable_crate_id ( & crate_root, self . tcx ) ?;
547
559
let cnum = feed. key ( ) ;
548
560
549
561
info ! (
550
- "register crate `{}` (cnum = {}. private_dep = {})" ,
562
+ "register crate `{}` (cnum = {}. dep_privacy = {:? })" ,
551
563
crate_root. name( ) ,
552
564
cnum,
553
- private_dep
565
+ dep_privacy
554
566
) ;
555
567
556
568
// Maintain a reference to the top most crate.
@@ -563,7 +575,8 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
563
575
& crate_paths
564
576
} ;
565
577
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) ?;
567
580
568
581
let raw_proc_macros = if crate_root. is_proc_macro_crate ( ) {
569
582
let temp_root;
@@ -590,7 +603,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
590
603
cnum_map,
591
604
dep_kind,
592
605
source,
593
- private_dep ,
606
+ dep_privacy ,
594
607
host_hash,
595
608
) ;
596
609
@@ -681,24 +694,24 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
681
694
}
682
695
}
683
696
684
- fn maybe_resolve_crate < ' b > (
685
- & ' b mut self ,
697
+ fn maybe_resolve_crate (
698
+ & mut self ,
686
699
name : Symbol ,
687
700
mut dep_kind : CrateDepKind ,
688
- dep_of : Option < ( & ' b CratePaths , & ' b CrateDep ) > ,
701
+ dep_of : Option < DepOf < ' _ > > ,
689
702
) -> Result < CrateNum , CrateError > {
690
703
info ! ( "resolving crate `{}`" , name) ;
691
704
if !name. as_str ( ) . is_ascii ( ) {
692
705
return Err ( CrateError :: NonAsciiName ( name) ) ;
693
706
}
694
707
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 ) ;
697
710
let hash = dep. map ( |d| d. hash ) ;
698
711
let host_hash = dep. map ( |d| d. host_hash ) . flatten ( ) ;
699
712
let extra_filename = dep. map ( |d| & d. extra_filename [ ..] ) ;
700
713
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 ) ;
702
715
703
716
let result = if let Some ( cnum) = self . existing_match ( name, hash, path_kind) {
704
717
( LoadResult :: Previous ( cnum) , None )
@@ -732,22 +745,22 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
732
745
match result {
733
746
( LoadResult :: Previous ( cnum) , None ) => {
734
747
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
736
749
// not specified by `--extern` on command line parameters, it may be
737
750
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
738
751
// `public-dependency` here.
739
- let private_dep = self . is_private_dep ( name, private_dep, dep_root) ;
740
752
let data = self . cstore . get_crate_data_mut ( cnum) ;
741
753
if data. is_proc_macro_crate ( ) {
742
754
dep_kind = CrateDepKind :: MacrosOnly ;
743
755
}
744
756
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 ) ;
746
758
Ok ( cnum)
747
759
}
748
760
( LoadResult :: Loaded ( library) , host_library) => {
749
761
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)
751
764
}
752
765
_ => panic ! ( ) ,
753
766
}
@@ -795,6 +808,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
795
808
metadata : & MetadataBlob ,
796
809
krate : CrateNum ,
797
810
dep_kind : CrateDepKind ,
811
+ crate_root_privacy : DepPrivacy ,
798
812
) -> Result < CrateNumMap , CrateError > {
799
813
debug ! (
800
814
"resolving deps of external crate `{}` with dep root `{}`" ,
@@ -823,7 +837,9 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
823
837
CrateDepKind :: MacrosOnly => CrateDepKind :: MacrosOnly ,
824
838
_ => dep. kind ,
825
839
} ;
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) ) ?;
827
843
crate_num_map. push ( cnum) ;
828
844
}
829
845
0 commit comments