Skip to content

Commit 8c39ce5

Browse files
committed
Auto merge of rust-lang#135278 - tgross35:ignore-std-dep-crates, r=SparrowLii
Exclude dependencies of `std` for diagnostics Currently crates in the sysroot can show up in diagnostic suggestions, such as in rust-lang#135232. To prevent this, duplicate `all_traits` into `visible_traits` which only shows traits in non-private crates. Setting `#![feature(rustc_private)]` overrides this and makes items in private crates visible as well, since `rustc_private` enables use of `std`'s private dependencies. This may be reviewed per-commit. Fixes: rust-lang#135232
2 parents c074d8e + ed63539 commit 8c39ce5

File tree

11 files changed

+225
-44
lines changed

11 files changed

+225
-44
lines changed

Diff for: compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
179179
// all visible traits. If there's one clear winner, just suggest that.
180180

181181
let visible_traits: Vec<_> = tcx
182-
.all_traits()
182+
.visible_traits()
183183
.filter(|trait_def_id| {
184184
let viz = tcx.visibility(*trait_def_id);
185185
let def_id = self.item_def_id();

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

+71-34
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,19 +390,51 @@ 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`. 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+
// 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+
}
400432
}
401433

402434
fn register_crate(
403435
&mut self,
404436
host_lib: Option<Library>,
405-
root: Option<&CratePaths>,
437+
dep_root: Option<&CratePaths>,
406438
lib: Library,
407439
dep_kind: CrateDepKind,
408440
name: Symbol,
@@ -414,7 +446,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
414446
let Library { source, metadata } = lib;
415447
let crate_root = metadata.get_root();
416448
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);
449+
let private_dep = self.is_private_dep(name, private_dep, dep_root);
418450

419451
// Claim this crate number and cache it
420452
let feed = self.cstore.intern_stable_crate_id(&crate_root, self.tcx)?;
@@ -430,14 +462,14 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
430462
// Maintain a reference to the top most crate.
431463
// Stash paths for top-most crate locally if necessary.
432464
let crate_paths;
433-
let root = if let Some(root) = root {
434-
root
465+
let dep_root = if let Some(dep_root) = dep_root {
466+
dep_root
435467
} else {
436468
crate_paths = CratePaths::new(crate_root.name(), source.clone());
437469
&crate_paths
438470
};
439471

440-
let cnum_map = self.resolve_crate_deps(root, &crate_root, &metadata, cnum, dep_kind)?;
472+
let cnum_map = self.resolve_crate_deps(dep_root, &crate_root, &metadata, cnum, dep_kind)?;
441473

442474
let raw_proc_macros = if crate_root.is_proc_macro_crate() {
443475
let temp_root;
@@ -559,23 +591,21 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
559591
&'b mut self,
560592
name: Symbol,
561593
mut dep_kind: CrateDepKind,
562-
dep: Option<(&'b CratePaths, &'b CrateDep)>,
594+
dep_of: Option<(&'b CratePaths, &'b CrateDep)>,
563595
) -> Result<CrateNum, CrateError> {
564596
info!("resolving crate `{}`", name);
565597
if !name.as_str().is_ascii() {
566598
return Err(CrateError::NonAsciiName(name));
567599
}
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-
};
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+
579609
let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
580610
(LoadResult::Previous(cnum), None)
581611
} else {
@@ -599,7 +629,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
599629
dep_kind = CrateDepKind::MacrosOnly;
600630
match self.load_proc_macro(&mut locator, path_kind, host_hash)? {
601631
Some(res) => res,
602-
None => return Err(locator.into_error(root.cloned())),
632+
None => return Err(locator.into_error(dep_root.cloned())),
603633
}
604634
}
605635
}
@@ -612,7 +642,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
612642
// not specified by `--extern` on command line parameters, it may be
613643
// `private-dependency` when `register_crate` is called for the first time. Then it must be updated to
614644
// `public-dependency` here.
615-
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);
616646
let data = self.cstore.get_crate_data_mut(cnum);
617647
if data.is_proc_macro_crate() {
618648
dep_kind = CrateDepKind::MacrosOnly;
@@ -623,7 +653,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
623653
}
624654
(LoadResult::Loaded(library), host_library) => {
625655
info!("register newly loaded library for `{}`", name);
626-
self.register_crate(host_library, root, library, dep_kind, name, private_dep)
656+
self.register_crate(host_library, dep_root, library, dep_kind, name, private_dep)
627657
}
628658
_ => panic!(),
629659
}
@@ -663,16 +693,20 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
663693
}))
664694
}
665695

666-
// Go through the crate metadata and load any crates that it references
696+
/// Go through the crate metadata and load any crates that it references.
667697
fn resolve_crate_deps(
668698
&mut self,
669-
root: &CratePaths,
699+
dep_root: &CratePaths,
670700
crate_root: &CrateRoot,
671701
metadata: &MetadataBlob,
672702
krate: CrateNum,
673703
dep_kind: CrateDepKind,
674704
) -> Result<CrateNumMap, CrateError> {
675-
debug!("resolving deps of external crate");
705+
debug!(
706+
"resolving deps of external crate `{}` with dep root `{}`",
707+
crate_root.name(),
708+
dep_root.name
709+
);
676710
if crate_root.is_proc_macro_crate() {
677711
return Ok(CrateNumMap::new());
678712
}
@@ -685,14 +719,17 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
685719
crate_num_map.push(krate);
686720
for dep in deps {
687721
info!(
688-
"resolving dep crate {} hash: `{}` extra filename: `{}`",
689-
dep.name, dep.hash, dep.extra_filename
722+
"resolving dep `{}`->`{}` hash: `{}` extra filename: `{}`",
723+
crate_root.name(),
724+
dep.name,
725+
dep.hash,
726+
dep.extra_filename
690727
);
691728
let dep_kind = match dep_kind {
692729
CrateDepKind::MacrosOnly => CrateDepKind::MacrosOnly,
693730
_ => dep.kind,
694731
};
695-
let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((root, &dep)))?;
732+
let cnum = self.maybe_resolve_crate(dep.name, dep_kind, Some((dep_root, &dep)))?;
696733
crate_num_map.push(cnum);
697734
}
698735

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

+6-6
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

@@ -765,10 +765,10 @@ impl<'a> CrateLocator<'a> {
765765
self.extract_lib(rlibs, rmetas, dylibs).map(|opt| opt.map(|(_, lib)| lib))
766766
}
767767

768-
pub(crate) fn into_error(self, root: Option<CratePaths>) -> CrateError {
768+
pub(crate) fn into_error(self, dep_root: Option<CratePaths>) -> CrateError {
769769
CrateError::LocatorCombined(Box::new(CombinedLocatorError {
770770
crate_name: self.crate_name,
771-
root,
771+
dep_root,
772772
triple: self.tuple,
773773
dll_prefix: self.target.dll_prefix.to_string(),
774774
dll_suffix: self.target.dll_suffix.to_string(),
@@ -914,7 +914,7 @@ struct CrateRejections {
914914
/// otherwise they are ignored.
915915
pub(crate) struct CombinedLocatorError {
916916
crate_name: Symbol,
917-
root: Option<CratePaths>,
917+
dep_root: Option<CratePaths>,
918918
triple: TargetTuple,
919919
dll_prefix: String,
920920
dll_suffix: String,
@@ -987,7 +987,7 @@ impl CrateError {
987987
}
988988
CrateError::LocatorCombined(locator) => {
989989
let crate_name = locator.crate_name;
990-
let add_info = match &locator.root {
990+
let add_info = match &locator.dep_root {
991991
None => String::new(),
992992
Some(r) => format!(" which `{}` depends on", r.name),
993993
};
@@ -1012,7 +1012,7 @@ impl CrateError {
10121012
path.display()
10131013
));
10141014
}
1015-
if let Some(r) = locator.root {
1015+
if let Some(r) = locator.dep_root {
10161016
for path in r.source.paths() {
10171017
found_crates.push_str(&format!(
10181018
"\ncrate `{}`: {}",

Diff for: compiler/rustc_middle/src/query/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -2129,6 +2129,8 @@ rustc_queries! {
21292129
eval_always
21302130
desc { "calculating the stability index for the local crate" }
21312131
}
2132+
/// All available crates in the graph, including those that should not be user-facing
2133+
/// (such as private crates).
21322134
query crates(_: ()) -> &'tcx [CrateNum] {
21332135
eval_always
21342136
desc { "fetching all foreign CrateNum instances" }

Diff for: compiler/rustc_middle/src/ty/context.rs

+11
Original file line numberDiff line numberDiff line change
@@ -2078,12 +2078,23 @@ impl<'tcx> TyCtxt<'tcx> {
20782078
self.limits(()).move_size_limit
20792079
}
20802080

2081+
/// All traits in the crate graph, including those not visible to the user.
20812082
pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
20822083
iter::once(LOCAL_CRATE)
20832084
.chain(self.crates(()).iter().copied())
20842085
.flat_map(move |cnum| self.traits(cnum).iter().copied())
20852086
}
20862087

2088+
/// All traits that are visible within the crate graph (i.e. excluding private dependencies).
2089+
pub fn visible_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
2090+
let visible_crates =
2091+
self.crates(()).iter().copied().filter(move |cnum| self.is_user_visible_dep(*cnum));
2092+
2093+
iter::once(LOCAL_CRATE)
2094+
.chain(visible_crates)
2095+
.flat_map(move |cnum| self.traits(cnum).iter().copied())
2096+
}
2097+
20872098
#[inline]
20882099
pub fn local_visibility(self, def_id: LocalDefId) -> Visibility {
20892100
self.visibility(def_id).expect_local()

Diff for: compiler/rustc_middle/src/ty/util.rs

+5
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,11 @@ impl<'tcx> TyCtxt<'tcx> {
876876
/// [public]: TyCtxt::is_private_dep
877877
/// [direct]: rustc_session::cstore::ExternCrate::is_direct
878878
pub fn is_user_visible_dep(self, key: CrateNum) -> bool {
879+
// `#![rustc_private]` overrides defaults to make private dependencies usable.
880+
if self.features().enabled(sym::rustc_private) {
881+
return true;
882+
}
883+
879884
// | Private | Direct | Visible | |
880885
// |---------|--------|---------|--------------------|
881886
// | Yes | Yes | Yes | !true || true |

Diff for: compiler/rustc_passes/src/diagnostic_items.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,14 @@ fn all_diagnostic_items(tcx: TyCtxt<'_>, (): ()) -> DiagnosticItems {
7979
// Initialize the collector.
8080
let mut items = DiagnosticItems::default();
8181

82-
// Collect diagnostic items in other crates.
83-
for &cnum in tcx.crates(()).iter().chain(std::iter::once(&LOCAL_CRATE)) {
82+
// Collect diagnostic items in visible crates.
83+
for cnum in tcx
84+
.crates(())
85+
.iter()
86+
.copied()
87+
.filter(|cnum| tcx.is_user_visible_dep(*cnum))
88+
.chain(std::iter::once(LOCAL_CRATE))
89+
{
8490
for (&name, &def_id) in &tcx.diagnostic_items(cnum).name_to_id {
8591
collect_item(tcx, &mut items, name, def_id);
8692
}

Diff for: compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2189,7 +2189,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
21892189
let required_trait_path = self.tcx.def_path_str(trait_ref.def_id());
21902190
let traits_with_same_path: UnordSet<_> = self
21912191
.tcx
2192-
.all_traits()
2192+
.visible_traits()
21932193
.filter(|trait_def_id| *trait_def_id != trait_ref.def_id())
21942194
.map(|trait_def_id| (self.tcx.def_path_str(trait_def_id), trait_def_id))
21952195
.filter(|(p, _)| *p == required_trait_path)

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

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
error[E0405]: cannot find trait `Equivalent` in this scope
2+
--> $DIR/sysroot-private.rs:26:18
3+
|
4+
LL | trait Trait2<K>: Equivalent<K> {}
5+
| ^^^^^^^^^^ not found in this scope
6+
7+
error[E0412]: cannot find type `K` in this scope
8+
--> $DIR/sysroot-private.rs:31:35
9+
|
10+
LL | fn trait_member<T>(val: &T, key: &K) -> bool {
11+
| - ^
12+
| |
13+
| similarly named type parameter `T` defined here
14+
|
15+
help: a type parameter with a similar name exists
16+
|
17+
LL | fn trait_member<T>(val: &T, key: &T) -> bool {
18+
| ~
19+
help: you might be missing a type parameter
20+
|
21+
LL | fn trait_member<T, K>(val: &T, key: &K) -> bool {
22+
| +++
23+
24+
error[E0220]: associated type `ExpressionStack` not found for `Trait`
25+
--> $DIR/sysroot-private.rs:21:31
26+
|
27+
LL | type AssociatedTy = dyn Trait<ExpressionStack = i32, Bar = i32>;
28+
| ^^^^^^^^^^^^^^^ help: `Trait` has the following associated type: `Bar`
29+
30+
error[E0425]: cannot find function `memchr2` in this scope
31+
--> $DIR/sysroot-private.rs:39:5
32+
|
33+
LL | memchr2(b'a', b'b', buf)
34+
| ^^^^^^^ not found in this scope
35+
36+
error: aborting due to 4 previous errors
37+
38+
Some errors have detailed explanations: E0220, E0405, E0412, E0425.
39+
For more information about an error, try `rustc --explain E0220`.

0 commit comments

Comments
 (0)