Skip to content

Commit ed63539

Browse files
committed
Mark dependencies of the standard library as private by default
In order to avoid diagnostics suggesting stdlib-private dependencies, make everything that is a direct dependency of any `std` crates private by default. Note that this will be overridden, if the same crate is public elsewhere in the crate graph then that overrides the private default. It may also be feasible to do this in the library crate, marking `std`'s dependencies private via Cargo. However, given that the feature is still rather unstable, doing this within the compiler seems more straightforward. Fixes: #135232 [1]
1 parent 2da9acc commit ed63539

File tree

3 files changed

+49
-21
lines changed

3 files changed

+49
-21
lines changed

Diff for: compiler/rustc_metadata/src/creader.rs

+47-19
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

@@ -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;

Diff for: tests/ui/privacy/sysroot-private.default.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ error[E0220]: associated type `ExpressionStack` not found for `Trait`
2525
--> $DIR/sysroot-private.rs:21:31
2626
|
2727
LL | type AssociatedTy = dyn Trait<ExpressionStack = i32, Bar = i32>;
28-
| ^^^^^^^^^^^^^^^ there is an associated type `ExpressionStack` in the trait `gimli::read::op::EvaluationStorage`
28+
| ^^^^^^^^^^^^^^^ help: `Trait` has the following associated type: `Bar`
2929

3030
error[E0425]: cannot find function `memchr2` in this scope
3131
--> $DIR/sysroot-private.rs:39:5

Diff for: tests/ui/privacy/sysroot-private.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ trait Trait { type Bar; }
2020
// present in diagnostics (it is a dependency of the compiler).
2121
type AssociatedTy = dyn Trait<ExpressionStack = i32, Bar = i32>;
2222
//~^ ERROR associated type `ExpressionStack` not found
23-
//~| NOTE there is an associated type `ExpressionStack` in the trait `gimli::read::op::EvaluationStorage`
23+
//[rustc_private_enabled]~| NOTE there is an associated type `ExpressionStack` in the trait `gimli::read::op::EvaluationStorage`
2424

2525
// Attempt to get a suggestion for `hashbrown::Equivalent`
2626
trait Trait2<K>: Equivalent<K> {}

0 commit comments

Comments
 (0)