@@ -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
@@ -416,6 +416,10 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
416
416
let host_hash = host_lib. as_ref ( ) . map ( |lib| lib. metadata . get_root ( ) . hash ( ) ) ;
417
417
let private_dep = self . is_private_dep ( name. as_str ( ) , private_dep) ;
418
418
419
+ // At this point there are no other dependencies, so treat dependencies
420
+ // of `std` as stdlib-private.
421
+ let stdlib_private_dep = self . maybe_stdlib_private_dep ( dep_root, name) ;
422
+
419
423
// Claim this crate number and cache it
420
424
let feed = self . cstore . intern_stable_crate_id ( & crate_root, self . tcx ) ?;
421
425
let cnum = feed. key ( ) ;
@@ -465,6 +469,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
465
469
dep_kind,
466
470
source,
467
471
private_dep,
472
+ stdlib_private_dep,
468
473
host_hash,
469
474
) ;
470
475
@@ -533,6 +538,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
533
538
} ) )
534
539
}
535
540
541
+ /// Attempt to resolve the crate but emit an error if it fails.
536
542
fn resolve_crate (
537
543
& mut self ,
538
544
name : Symbol ,
@@ -613,12 +619,19 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
613
619
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
614
620
// `public-dependency` here.
615
621
let private_dep = self . is_private_dep ( name. as_str ( ) , private_dep) ;
622
+
623
+ // If the dependency root is something other than `std`, indicate that the crate
624
+ // should no longer be considered stdlib-private.
625
+ let maybe_stdlib_private = self . maybe_stdlib_private_dep ( dep_root, name) ;
626
+
616
627
let data = self . cstore . get_crate_data_mut ( cnum) ;
617
628
if data. is_proc_macro_crate ( ) {
618
629
dep_kind = CrateDepKind :: MacrosOnly ;
619
630
}
620
631
data. set_dep_kind ( cmp:: max ( data. dep_kind ( ) , dep_kind) ) ;
621
632
data. update_and_private_dep ( private_dep) ;
633
+ data. update_and_stdlib_private_dep ( !maybe_stdlib_private) ;
634
+
622
635
Ok ( cnum)
623
636
}
624
637
( LoadResult :: Loaded ( library) , host_library) => {
@@ -1123,6 +1136,29 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
1123
1136
pub fn maybe_process_path_extern ( & mut self , name : Symbol ) -> Option < CrateNum > {
1124
1137
self . maybe_resolve_crate ( name, CrateDepKind :: Explicit , None ) . ok ( )
1125
1138
}
1139
+
1140
+ /// Return `true` if this is a crate is a dependency of the standard library, `false` otherwise.
1141
+ ///
1142
+ /// This function's result is not absolute, if the same dependency is used by a non-std crate
1143
+ /// then it should not be treated as stdlib-private (hence the "maybe").
1144
+ fn maybe_stdlib_private_dep ( & self , dep_root : Option < & CratePaths > , new_crate : Symbol ) -> bool {
1145
+ // If there is no dependency root, this crate was passed directly.
1146
+ let Some ( dep_root) = dep_root else {
1147
+ return false ;
1148
+ } ;
1149
+
1150
+ // If the new dependency is itself part of the stable stdlib crates (eg. `core` is a dep
1151
+ // of `std`) or if the current crate is the standard library, stdlib-private is not
1152
+ // relevant.
1153
+ if STDLIB_STABLE_CRATES . contains ( & new_crate)
1154
+ || STDLIB_STABLE_CRATES . contains ( & self . crate_name ( LOCAL_CRATE ) )
1155
+ {
1156
+ return false ;
1157
+ }
1158
+
1159
+ // Otherwise, all crates that are a dependency of the standard library are private.
1160
+ STDLIB_STABLE_CRATES . contains ( & dep_root. name )
1161
+ }
1126
1162
}
1127
1163
1128
1164
fn global_allocator_spans ( krate : & ast:: Crate ) -> Vec < Span > {
0 commit comments