@@ -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,15 +390,45 @@ 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`. 
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). 
395399/// 
396400/// Sometimes the directly dependent crate is not specified by `--extern`, in this case, 
397401/// `private-dep` is none during loading. This is equivalent to the scenario where the 
398402/// command parameter is set to `public-dependency` 
399- fn  is_private_dep ( & self ,  name :  & str ,  private_dep :  Option < bool > )  -> bool  { 
400-         self . sess . opts . externs . get ( name) . map_or ( private_dep. unwrap_or ( false ) ,  |e| e. is_private_dep ) 
401-             && private_dep. unwrap_or ( true ) 
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+         } 
402432    } 
403433
404434    fn  register_crate ( 
@@ -416,7 +446,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
416446        let  Library  {  source,  metadata }  = lib; 
417447        let  crate_root = metadata. get_root ( ) ; 
418448        let  host_hash = host_lib. as_ref ( ) . map ( |lib| lib. metadata . get_root ( ) . hash ( ) ) ; 
419-         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 ) ; 
420450
421451        // Claim this crate number and cache it 
422452        let  feed = self . cstore . intern_stable_crate_id ( & crate_root,  self . tcx ) ?; 
@@ -567,17 +597,15 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
567597        if  !name. as_str ( ) . is_ascii ( )  { 
568598            return  Err ( CrateError :: NonAsciiName ( name) ) ; 
569599        } 
570-         let  ( dep_root,  hash,  host_hash,  extra_filename,  path_kind,  private_dep)  = match  dep_of { 
571-             Some ( ( dep_root,  dep) )  => ( 
572-                 Some ( dep_root) , 
573-                 Some ( dep. hash ) , 
574-                 dep. host_hash , 
575-                 Some ( & dep. extra_filename [ ..] ) , 
576-                 PathKind :: Dependency , 
577-                 Some ( dep. is_private ) , 
578-             ) , 
579-             None  => ( None ,  None ,  None ,  None ,  PathKind :: Crate ,  None ) , 
580-         } ; 
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+ 
581609        let  result = if  let  Some ( cnum)  = self . existing_match ( name,  hash,  path_kind)  { 
582610            ( LoadResult :: Previous ( cnum) ,  None ) 
583611        }  else  { 
@@ -614,7 +642,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
614642                // not specified by `--extern` on command line parameters, it may be 
615643                // `private-dependency` when `register_crate` is called for the first time. Then it must be updated to 
616644                // `public-dependency` here. 
617-                 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 ) ; 
618646                let  data = self . cstore . get_crate_data_mut ( cnum) ; 
619647                if  data. is_proc_macro_crate ( )  { 
620648                    dep_kind = CrateDepKind :: MacrosOnly ; 
0 commit comments