Skip to content

Commit c1211a5

Browse files
committed
Introduce the concept of dependencies that should be stdlib-private
Dependencies of `std`, `core` and others are members of the crate graph, but should not be available for access by the local crate or show up in user-facing diagnostics. To support restricting this, introduce a `stdlib_private_dep` field on `CrateMetadata` that contains this information.
1 parent 5276987 commit c1211a5

File tree

3 files changed

+47
-2
lines changed

3 files changed

+47
-2
lines changed

compiler/rustc_metadata/src/creader.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc_session::lint::{self, BuiltinLintDiag};
2929
use rustc_session::output::validate_crate_name;
3030
use rustc_session::search_paths::PathKind;
3131
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};
3333
use rustc_target::spec::{PanicStrategy, Target, TargetTuple};
3434
use tracing::{debug, info, trace};
3535

@@ -416,6 +416,10 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
416416
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
417417
let private_dep = self.is_private_dep(name.as_str(), private_dep);
418418

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+
419423
// Claim this crate number and cache it
420424
let feed = self.cstore.intern_stable_crate_id(&crate_root, self.tcx)?;
421425
let cnum = feed.key();
@@ -465,6 +469,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
465469
dep_kind,
466470
source,
467471
private_dep,
472+
stdlib_private_dep,
468473
host_hash,
469474
);
470475

@@ -533,6 +538,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
533538
}))
534539
}
535540

541+
/// Attempt to resolve the crate but emit an error if it fails.
536542
fn resolve_crate(
537543
&mut self,
538544
name: Symbol,
@@ -613,12 +619,19 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
613619
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
614620
// `public-dependency` here.
615621
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+
616627
let data = self.cstore.get_crate_data_mut(cnum);
617628
if data.is_proc_macro_crate() {
618629
dep_kind = CrateDepKind::MacrosOnly;
619630
}
620631
data.set_dep_kind(cmp::max(data.dep_kind(), dep_kind));
621632
data.update_and_private_dep(private_dep);
633+
data.update_and_stdlib_private_dep(!maybe_stdlib_private);
634+
622635
Ok(cnum)
623636
}
624637
(LoadResult::Loaded(library), host_library) => {
@@ -1123,6 +1136,29 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
11231136
pub fn maybe_process_path_extern(&mut self, name: Symbol) -> Option<CrateNum> {
11241137
self.maybe_resolve_crate(name, CrateDepKind::Explicit, None).ok()
11251138
}
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+
}
11261162
}
11271163

11281164
fn global_allocator_spans(krate: &ast::Crate) -> Vec<Span> {

compiler/rustc_metadata/src/locator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ pub(crate) struct CrateLocator<'a> {
262262

263263
#[derive(Clone)]
264264
pub(crate) struct CratePaths {
265-
name: Symbol,
265+
pub(crate) name: Symbol,
266266
source: CrateSource,
267267
}
268268

compiler/rustc_metadata/src/rmeta/decoder.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,9 @@ pub(crate) struct CrateMetadata {
118118
/// Used by the 'exported_private_dependencies' lint, and for determining
119119
/// whether to emit suggestions that reference this crate.
120120
private_dep: bool,
121+
/// This crate is only used as a dependency of the standard library and by default should
122+
/// not be user-facing (i.e. not shown in diagnostics).
123+
stdlib_private_dep: bool,
121124
/// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
122125
host_hash: Option<Svh>,
123126
/// The crate was used non-speculatively.
@@ -1826,6 +1829,7 @@ impl CrateMetadata {
18261829
dep_kind: CrateDepKind,
18271830
source: CrateSource,
18281831
private_dep: bool,
1832+
stdlib_private_dep: bool,
18291833
host_hash: Option<Svh>,
18301834
) -> CrateMetadata {
18311835
let trait_impls = root
@@ -1857,6 +1861,7 @@ impl CrateMetadata {
18571861
dep_kind,
18581862
source: Lrc::new(source),
18591863
private_dep,
1864+
stdlib_private_dep,
18601865
host_hash,
18611866
used: false,
18621867
extern_crate: None,
@@ -1908,6 +1913,10 @@ impl CrateMetadata {
19081913
self.private_dep &= private_dep;
19091914
}
19101915

1916+
pub(crate) fn update_and_stdlib_private_dep(&mut self, stdlib_private_dep: bool) {
1917+
self.stdlib_private_dep &= stdlib_private_dep;
1918+
}
1919+
19111920
pub(crate) fn used(&self) -> bool {
19121921
self.used
19131922
}

0 commit comments

Comments
 (0)