@@ -29,7 +29,7 @@ use rustc_session::lint::{self, BuiltinLintDiag};
29
29
use rustc_session:: output:: validate_crate_name;
30
30
use rustc_session:: search_paths:: PathKind ;
31
31
use 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} ;
33
33
use rustc_target:: spec:: { PanicStrategy , Target , TargetTuple } ;
34
34
use tracing:: { debug, info, trace} ;
35
35
@@ -390,19 +390,58 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
390
390
None
391
391
}
392
392
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
+ match ( extern_private, private_dep) {
418
+ // If the crate is marked private via extern and the crate would also otherwise
419
+ // be private, then keep this crate private.
420
+ ( Some ( true ) , Some ( true ) | None ) => true ,
421
+
422
+ // Any descendants of `std` should be private. These crates are usually not marked
423
+ // private in metadata, so we ignore that field.
424
+ ( None , _) if dep_root. map_or ( false , |d| STDLIB_STABLE_CRATES . contains ( & d. name ) ) => true ,
425
+
426
+ // If no visibility override is given via extern, defer to what the parent requests.
427
+ ( None , Some ( v) ) => v,
428
+
429
+ // Crate was requested via `--extern` and should be public.
430
+ ( Some ( false ) , _) => false ,
431
+
432
+ // Not a private dependency, keep it public.
433
+ ( _, Some ( false ) ) => false ,
434
+
435
+ // Not passed via extern and no metadata available. Not sure how we got here, but
436
+ // default to public.
437
+ ( None , None ) => false ,
438
+ }
400
439
}
401
440
402
441
fn register_crate (
403
442
& mut self ,
404
443
host_lib : Option < Library > ,
405
- root : Option < & CratePaths > ,
444
+ dep_root : Option < & CratePaths > ,
406
445
lib : Library ,
407
446
dep_kind : CrateDepKind ,
408
447
name : Symbol ,
@@ -414,7 +453,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
414
453
let Library { source, metadata } = lib;
415
454
let crate_root = metadata. get_root ( ) ;
416
455
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) ;
456
+ let private_dep = self . is_private_dep ( name, private_dep, dep_root ) ;
418
457
419
458
// Claim this crate number and cache it
420
459
let feed = self . cstore . intern_stable_crate_id ( & crate_root, self . tcx ) ?;
@@ -430,14 +469,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
430
469
// Maintain a reference to the top most crate.
431
470
// Stash paths for top-most crate locally if necessary.
432
471
let crate_paths;
433
- let root = if let Some ( root ) = root {
434
- root
472
+ let dep_root = if let Some ( dep_root ) = dep_root {
473
+ dep_root
435
474
} else {
436
475
crate_paths = CratePaths :: new ( crate_root. name ( ) , source. clone ( ) ) ;
437
476
& crate_paths
438
477
} ;
439
478
440
- let cnum_map = self . resolve_crate_deps ( root , & crate_root, & metadata, cnum, dep_kind) ?;
479
+ let cnum_map = self . resolve_crate_deps ( dep_root , & crate_root, & metadata, cnum, dep_kind) ?;
441
480
442
481
let raw_proc_macros = if crate_root. is_proc_macro_crate ( ) {
443
482
let temp_root;
@@ -559,23 +598,21 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
559
598
& ' b mut self ,
560
599
name : Symbol ,
561
600
mut dep_kind : CrateDepKind ,
562
- dep : Option < ( & ' b CratePaths , & ' b CrateDep ) > ,
601
+ dep_of : Option < ( & ' b CratePaths , & ' b CrateDep ) > ,
563
602
) -> Result < CrateNum , CrateError > {
564
603
info ! ( "resolving crate `{}`" , name) ;
565
604
if !name. as_str ( ) . is_ascii ( ) {
566
605
return Err ( CrateError :: NonAsciiName ( name) ) ;
567
606
}
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
- } ;
607
+
608
+ let dep_root = dep_of. map ( |d| d. 0 ) ;
609
+ let dep = dep_of. map ( |d| d. 1 ) ;
610
+ let hash = dep. map ( |d| d. hash ) ;
611
+ let host_hash = dep. map ( |d| d. host_hash ) . flatten ( ) ;
612
+ let extra_filename = dep. map ( |d| & d. extra_filename [ ..] ) ;
613
+ let path_kind = if dep. is_some ( ) { PathKind :: Dependency } else { PathKind :: Crate } ;
614
+ let private_dep = dep. map ( |d| d. is_private ) ;
615
+
579
616
let result = if let Some ( cnum) = self . existing_match ( name, hash, path_kind) {
580
617
( LoadResult :: Previous ( cnum) , None )
581
618
} else {
@@ -599,7 +636,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
599
636
dep_kind = CrateDepKind :: MacrosOnly ;
600
637
match self . load_proc_macro ( & mut locator, path_kind, host_hash) ? {
601
638
Some ( res) => res,
602
- None => return Err ( locator. into_error ( root . cloned ( ) ) ) ,
639
+ None => return Err ( locator. into_error ( dep_root . cloned ( ) ) ) ,
603
640
}
604
641
}
605
642
}
@@ -612,7 +649,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
612
649
// not specified by `--extern` on command line parameters, it may be
613
650
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
614
651
// `public-dependency` here.
615
- let private_dep = self . is_private_dep ( name. as_str ( ) , private_dep) ;
652
+ let private_dep = self . is_private_dep ( name, private_dep, dep_root ) ;
616
653
let data = self . cstore . get_crate_data_mut ( cnum) ;
617
654
if data. is_proc_macro_crate ( ) {
618
655
dep_kind = CrateDepKind :: MacrosOnly ;
@@ -623,7 +660,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
623
660
}
624
661
( LoadResult :: Loaded ( library) , host_library) => {
625
662
info ! ( "register newly loaded library for `{}`" , name) ;
626
- self . register_crate ( host_library, root , library, dep_kind, name, private_dep)
663
+ self . register_crate ( host_library, dep_root , library, dep_kind, name, private_dep)
627
664
}
628
665
_ => panic ! ( ) ,
629
666
}
@@ -663,16 +700,20 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
663
700
} ) )
664
701
}
665
702
666
- // Go through the crate metadata and load any crates that it references
703
+ /// Go through the crate metadata and load any crates that it references.
667
704
fn resolve_crate_deps (
668
705
& mut self ,
669
- root : & CratePaths ,
706
+ dep_root : & CratePaths ,
670
707
crate_root : & CrateRoot ,
671
708
metadata : & MetadataBlob ,
672
709
krate : CrateNum ,
673
710
dep_kind : CrateDepKind ,
674
711
) -> Result < CrateNumMap , CrateError > {
675
- debug ! ( "resolving deps of external crate" ) ;
712
+ debug ! (
713
+ "resolving deps of external crate `{}` with dep root `{}`" ,
714
+ crate_root. name( ) ,
715
+ dep_root. name
716
+ ) ;
676
717
if crate_root. is_proc_macro_crate ( ) {
677
718
return Ok ( CrateNumMap :: new ( ) ) ;
678
719
}
@@ -685,14 +726,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
685
726
crate_num_map. push ( krate) ;
686
727
for dep in deps {
687
728
info ! (
688
- "resolving dep crate {} hash: `{}` extra filename: `{}`" ,
689
- dep. name, dep. hash, dep. extra_filename
729
+ "resolving dep `{}`->`{}` hash: `{}` extra filename: `{}`" ,
730
+ crate_root. name( ) ,
731
+ dep. name,
732
+ dep. hash,
733
+ dep. extra_filename
690
734
) ;
691
735
let dep_kind = match dep_kind {
692
736
CrateDepKind :: MacrosOnly => CrateDepKind :: MacrosOnly ,
693
737
_ => dep. kind ,
694
738
} ;
695
- let cnum = self . maybe_resolve_crate ( dep. name , dep_kind, Some ( ( root , & dep) ) ) ?;
739
+ let cnum = self . maybe_resolve_crate ( dep. name , dep_kind, Some ( ( dep_root , & dep) ) ) ?;
696
740
crate_num_map. push ( cnum) ;
697
741
}
698
742
0 commit comments