Skip to content

Commit ad8304a

Browse files
committed
Auto merge of #111076 - notriddle:notriddle/silence-private-dep-trait-impl-suggestions, r=cjgillot
diagnostics: exclude indirect private deps from trait impl suggest Fixes #88696
2 parents e4f7ad8 + 52bd82f commit ad8304a

File tree

21 files changed

+136
-31
lines changed

21 files changed

+136
-31
lines changed

compiler/rustc_data_structures/src/sync.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,14 @@ cfg_if! {
139139

140140
impl Atomic<bool> {
141141
pub fn fetch_or(&self, val: bool, _: Ordering) -> bool {
142-
let result = self.0.get() | val;
143-
self.0.set(val);
144-
result
142+
let old = self.0.get();
143+
self.0.set(val | old);
144+
old
145+
}
146+
pub fn fetch_and(&self, val: bool, _: Ordering) -> bool {
147+
let old = self.0.get();
148+
self.0.set(val & old);
149+
old
145150
}
146151
}
147152

compiler/rustc_metadata/src/creader.rs

+15-5
Original file line numberDiff line numberDiff line change
@@ -365,15 +365,21 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
365365
lib: Library,
366366
dep_kind: CrateDepKind,
367367
name: Symbol,
368+
private_dep: Option<bool>,
368369
) -> Result<CrateNum, CrateError> {
369370
let _prof_timer = self.sess.prof.generic_activity("metadata_register_crate");
370371

371372
let Library { source, metadata } = lib;
372373
let crate_root = metadata.get_root();
373374
let host_hash = host_lib.as_ref().map(|lib| lib.metadata.get_root().hash());
374375

375-
let private_dep =
376-
self.sess.opts.externs.get(name.as_str()).is_some_and(|e| e.is_private_dep);
376+
let private_dep = self
377+
.sess
378+
.opts
379+
.externs
380+
.get(name.as_str())
381+
.map_or(private_dep.unwrap_or(false), |e| e.is_private_dep)
382+
&& private_dep.unwrap_or(true);
377383

378384
// Claim this crate number and cache it
379385
let cnum = self.cstore.intern_stable_crate_id(&crate_root)?;
@@ -518,15 +524,16 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
518524
if !name.as_str().is_ascii() {
519525
return Err(CrateError::NonAsciiName(name));
520526
}
521-
let (root, hash, host_hash, extra_filename, path_kind) = match dep {
527+
let (root, hash, host_hash, extra_filename, path_kind, private_dep) = match dep {
522528
Some((root, dep)) => (
523529
Some(root),
524530
Some(dep.hash),
525531
dep.host_hash,
526532
Some(&dep.extra_filename[..]),
527533
PathKind::Dependency,
534+
Some(dep.is_private),
528535
),
529-
None => (None, None, None, None, PathKind::Crate),
536+
None => (None, None, None, None, PathKind::Crate, None),
530537
};
531538
let result = if let Some(cnum) = self.existing_match(name, hash, path_kind) {
532539
(LoadResult::Previous(cnum), None)
@@ -562,10 +569,13 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
562569
dep_kind = CrateDepKind::MacrosOnly;
563570
}
564571
data.update_dep_kind(|data_dep_kind| cmp::max(data_dep_kind, dep_kind));
572+
if let Some(private_dep) = private_dep {
573+
data.update_and_private_dep(private_dep);
574+
}
565575
Ok(cnum)
566576
}
567577
(LoadResult::Loaded(library), host_library) => {
568-
self.register_crate(host_library, root, library, dep_kind, name)
578+
self.register_crate(host_library, root, library, dep_kind, name, private_dep)
569579
}
570580
_ => panic!(),
571581
}

compiler/rustc_metadata/src/rmeta/decoder.rs

+14-7
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_data_structures::captures::Captures;
99
use rustc_data_structures::fx::FxHashMap;
1010
use rustc_data_structures::owned_slice::OwnedSlice;
1111
use rustc_data_structures::svh::Svh;
12-
use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc, OnceCell};
12+
use rustc_data_structures::sync::{AppendOnlyVec, AtomicBool, Lock, Lrc, OnceCell};
1313
use rustc_data_structures::unhash::UnhashMap;
1414
use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
1515
use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro};
@@ -40,6 +40,7 @@ use proc_macro::bridge::client::ProcMacro;
4040
use std::iter::TrustedLen;
4141
use std::num::NonZeroUsize;
4242
use std::path::Path;
43+
use std::sync::atomic::Ordering;
4344
use std::{io, iter, mem};
4445

4546
pub(super) use cstore_impl::provide;
@@ -112,9 +113,10 @@ pub(crate) struct CrateMetadata {
112113
dep_kind: Lock<CrateDepKind>,
113114
/// Filesystem location of this crate.
114115
source: Lrc<CrateSource>,
115-
/// Whether or not this crate should be consider a private dependency
116-
/// for purposes of the 'exported_private_dependencies' lint
117-
private_dep: bool,
116+
/// Whether or not this crate should be consider a private dependency.
117+
/// Used by the 'exported_private_dependencies' lint, and for determining
118+
/// whether to emit suggestions that reference this crate.
119+
private_dep: AtomicBool,
118120
/// The hash for the host proc macro. Used to support `-Z dual-proc-macro`.
119121
host_hash: Option<Svh>,
120122

@@ -701,12 +703,13 @@ impl MetadataBlob {
701703
writeln!(out, "=External Dependencies=")?;
702704

703705
for (i, dep) in root.crate_deps.decode(self).enumerate() {
704-
let CrateDep { name, extra_filename, hash, host_hash, kind } = dep;
706+
let CrateDep { name, extra_filename, hash, host_hash, kind, is_private } = dep;
705707
let number = i + 1;
706708

707709
writeln!(
708710
out,
709-
"{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?}"
711+
"{number} {name}{extra_filename} hash {hash} host_hash {host_hash:?} kind {kind:?} {privacy}",
712+
privacy = if is_private { "private" } else { "public" }
710713
)?;
711714
}
712715
write!(out, "\n")?;
@@ -1624,7 +1627,7 @@ impl CrateMetadata {
16241627
dependencies,
16251628
dep_kind: Lock::new(dep_kind),
16261629
source: Lrc::new(source),
1627-
private_dep,
1630+
private_dep: AtomicBool::new(private_dep),
16281631
host_hash,
16291632
extern_crate: Lock::new(None),
16301633
hygiene_context: Default::default(),
@@ -1672,6 +1675,10 @@ impl CrateMetadata {
16721675
self.dep_kind.with_lock(|dep_kind| *dep_kind = f(*dep_kind))
16731676
}
16741677

1678+
pub(crate) fn update_and_private_dep(&self, private_dep: bool) {
1679+
self.private_dep.fetch_and(private_dep, Ordering::SeqCst);
1680+
}
1681+
16751682
pub(crate) fn required_panic_strategy(&self) -> Option<PanicStrategy> {
16761683
self.root.required_panic_strategy
16771684
}

compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,13 @@ provide! { tcx, def_id, other, cdata,
285285
is_ctfe_mir_available => { cdata.is_ctfe_mir_available(def_id.index) }
286286

287287
dylib_dependency_formats => { cdata.get_dylib_dependency_formats(tcx) }
288-
is_private_dep => { cdata.private_dep }
288+
is_private_dep => {
289+
// Parallel compiler needs to synchronize type checking and linting (which use this flag)
290+
// so that they happen strictly crate loading. Otherwise, the full list of available
291+
// impls aren't loaded yet.
292+
use std::sync::atomic::Ordering;
293+
cdata.private_dep.load(Ordering::Acquire)
294+
}
289295
is_panic_runtime => { cdata.root.panic_runtime }
290296
is_compiler_builtins => { cdata.root.compiler_builtins }
291297
has_global_allocator => { cdata.root.has_global_allocator }

compiler/rustc_metadata/src/rmeta/encoder.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1883,6 +1883,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
18831883
host_hash: self.tcx.crate_host_hash(cnum),
18841884
kind: self.tcx.dep_kind(cnum),
18851885
extra_filename: self.tcx.extra_filename(cnum).clone(),
1886+
is_private: self.tcx.is_private_dep(cnum),
18861887
};
18871888
(cnum, dep)
18881889
})

compiler/rustc_metadata/src/rmeta/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,7 @@ pub(crate) struct CrateDep {
322322
pub host_hash: Option<Svh>,
323323
pub kind: CrateDepKind,
324324
pub extra_filename: String,
325+
pub is_private: bool,
325326
}
326327

327328
#[derive(MetadataEncodable, MetadataDecodable)]

compiler/rustc_middle/src/ty/util.rs

+21-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
1515
use rustc_errors::ErrorGuaranteed;
1616
use rustc_hir as hir;
1717
use rustc_hir::def::{CtorOf, DefKind, Res};
18-
use rustc_hir::def_id::{DefId, LocalDefId};
18+
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
1919
use rustc_index::bit_set::GrowableBitSet;
2020
use rustc_index::{Idx, IndexVec};
2121
use rustc_macros::HashStable;
@@ -857,6 +857,26 @@ impl<'tcx> TyCtxt<'tcx> {
857857
_ => def_kind.article(),
858858
}
859859
}
860+
861+
/// Return `true` if the supplied `CrateNum` is "user-visible," meaning either a [public]
862+
/// dependency, or a [direct] private dependency. This is used to decide whether the crate can
863+
/// be shown in `impl` suggestions.
864+
///
865+
/// [public]: TyCtxt::is_private_dep
866+
/// [direct]: rustc_session::cstore::ExternCrate::is_direct
867+
pub fn is_user_visible_dep(self, key: CrateNum) -> bool {
868+
// | Private | Direct | Visible | |
869+
// |---------|--------|---------|--------------------|
870+
// | Yes | Yes | Yes | !true || true |
871+
// | No | Yes | Yes | !false || true |
872+
// | Yes | No | No | !true || false |
873+
// | No | No | Yes | !false || false |
874+
!self.is_private_dep(key)
875+
// If `extern_crate` is `None`, then the crate was injected (e.g., by the allocator).
876+
// Treat that kind of crate as "indirect", since it's an implementation detail of
877+
// the language.
878+
|| self.extern_crate(key.as_def_id()).map_or(false, |e| e.is_direct())
879+
}
860880
}
861881

862882
struct OpaqueTypeExpander<'tcx> {

compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1776,6 +1776,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
17761776
|| !trait_pred
17771777
.skip_binder()
17781778
.is_constness_satisfied_by(self.tcx.constness(def_id))
1779+
|| !self.tcx.is_user_visible_dep(def_id.krate)
17791780
{
17801781
return None;
17811782
}

library/std/Cargo.toml

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
cargo-features = ["public-dependency"]
2+
13
[package]
24
name = "std"
35
version = "0.0.0"
@@ -10,12 +12,12 @@ edition = "2021"
1012
crate-type = ["dylib", "rlib"]
1113

1214
[dependencies]
13-
alloc = { path = "../alloc" }
15+
alloc = { path = "../alloc", public = true }
1416
cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
1517
panic_unwind = { path = "../panic_unwind", optional = true }
1618
panic_abort = { path = "../panic_abort" }
17-
core = { path = "../core" }
18-
libc = { version = "0.2.143", default-features = false, features = ['rustc-dep-of-std'] }
19+
core = { path = "../core", public = true }
20+
libc = { version = "0.2.143", default-features = false, features = ['rustc-dep-of-std'], public = true }
1921
compiler_builtins = { version = "0.1.92" }
2022
profiler_builtins = { path = "../profiler_builtins", optional = true }
2123
unwind = { path = "../unwind" }
@@ -25,7 +27,7 @@ std_detect = { path = "../stdarch/crates/std_detect", default-features = false,
2527
# Dependencies of the `backtrace` crate
2628
addr2line = { version = "0.19.0", optional = true, default-features = false }
2729
rustc-demangle = { version = "0.1.21", features = ['rustc-dep-of-std'] }
28-
miniz_oxide = { version = "0.6.0", optional = true, default-features = false }
30+
miniz_oxide = { version = "0.6.0", optional = true, default-features = false, public = false }
2931
[dependencies.object]
3032
version = "0.30.0"
3133
optional = true
@@ -40,7 +42,7 @@ rand_xorshift = "0.3.0"
4042
dlmalloc = { version = "0.2.3", features = ['rustc-dep-of-std'] }
4143

4244
[target.x86_64-fortanix-unknown-sgx.dependencies]
43-
fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'] }
45+
fortanix-sgx-abi = { version = "0.5.0", features = ['rustc-dep-of-std'], public = true }
4446

4547
[target.'cfg(target_os = "hermit")'.dependencies]
4648
hermit-abi = { version = "0.3.0", features = ['rustc-dep-of-std'] }

library/std/src/sys/wasi/fd.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ impl WasiFd {
9696
unsafe { wasi::fd_sync(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
9797
}
9898

99-
pub fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
99+
pub(crate) fn advise(&self, offset: u64, len: u64, advice: wasi::Advice) -> io::Result<()> {
100100
unsafe {
101101
wasi::fd_advise(self.as_raw_fd() as wasi::Fd, offset, len, advice).map_err(err2io)
102102
}
@@ -179,7 +179,7 @@ impl WasiFd {
179179
}
180180
}
181181

182-
pub fn filestat_get(&self) -> io::Result<wasi::Filestat> {
182+
pub(crate) fn filestat_get(&self) -> io::Result<wasi::Filestat> {
183183
unsafe { wasi::fd_filestat_get(self.as_raw_fd() as wasi::Fd).map_err(err2io) }
184184
}
185185

@@ -199,7 +199,7 @@ impl WasiFd {
199199
unsafe { wasi::fd_filestat_set_size(self.as_raw_fd() as wasi::Fd, size).map_err(err2io) }
200200
}
201201

202-
pub fn path_filestat_get(
202+
pub(crate) fn path_filestat_get(
203203
&self,
204204
flags: wasi::Lookupflags,
205205
path: &str,

library/std/src/sys/wasi/fs.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ impl FileAttr {
104104
Ok(SystemTime::from_wasi_timestamp(self.meta.ctim))
105105
}
106106

107-
pub fn as_wasi(&self) -> &wasi::Filestat {
107+
pub(crate) fn as_wasi(&self) -> &wasi::Filestat {
108108
&self.meta
109109
}
110110
}
@@ -142,7 +142,7 @@ impl FileType {
142142
self.bits == wasi::FILETYPE_SYMBOLIC_LINK
143143
}
144144

145-
pub fn bits(&self) -> wasi::Filetype {
145+
pub(crate) fn bits(&self) -> wasi::Filetype {
146146
self.bits
147147
}
148148
}

library/std/tests/common/mod.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ pub(crate) fn test_rng() -> rand_xorshift::XorShiftRng {
2020
}
2121

2222
// Copied from std::sys_common::io
23-
pub struct TempDir(PathBuf);
23+
pub(crate) struct TempDir(PathBuf);
2424

2525
impl TempDir {
26-
pub fn join(&self, path: &str) -> PathBuf {
26+
pub(crate) fn join(&self, path: &str) -> PathBuf {
2727
let TempDir(ref p) = *self;
2828
p.join(path)
2929
}
3030

31-
pub fn path(&self) -> &Path {
31+
pub(crate) fn path(&self) -> &Path {
3232
let TempDir(ref p) = *self;
3333
p
3434
}
@@ -49,7 +49,7 @@ impl Drop for TempDir {
4949
}
5050

5151
#[track_caller] // for `test_rng`
52-
pub fn tmpdir() -> TempDir {
52+
pub(crate) fn tmpdir() -> TempDir {
5353
let p = env::temp_dir();
5454
let mut r = test_rng();
5555
let ret = p.join(&format!("rust-{}", r.next_u32()));

src/bootstrap/dist.rs

+3
Original file line numberDiff line numberDiff line change
@@ -1009,6 +1009,9 @@ impl Step for PlainSourceTarball {
10091009
.arg(builder.src.join("./compiler/rustc_codegen_cranelift/Cargo.toml"))
10101010
.arg("--sync")
10111011
.arg(builder.src.join("./src/bootstrap/Cargo.toml"))
1012+
// Will read the libstd Cargo.toml
1013+
// which uses the unstable `public-dependency` feature.
1014+
.env("RUSTC_BOOTSTRAP", "1")
10121015
.current_dir(&plain_dst_src);
10131016

10141017
let config = if !builder.config.dry_run() {

src/bootstrap/metadata.rs

+3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ fn workspace_members(build: &Build) -> impl Iterator<Item = Package> {
7474
let collect_metadata = |manifest_path| {
7575
let mut cargo = Command::new(&build.initial_cargo);
7676
cargo
77+
// Will read the libstd Cargo.toml
78+
// which uses the unstable `public-dependency` feature.
79+
.env("RUSTC_BOOTSTRAP", "1")
7780
.arg("metadata")
7881
.arg("--format-version")
7982
.arg("1")

src/bootstrap/test.rs

+3
Original file line numberDiff line numberDiff line change
@@ -2499,6 +2499,9 @@ impl Step for Distcheck {
24992499
let toml = dir.join("rust-src/lib/rustlib/src/rust/library/std/Cargo.toml");
25002500
builder.run(
25012501
Command::new(&builder.initial_cargo)
2502+
// Will read the libstd Cargo.toml
2503+
// which uses the unstable `public-dependency` feature.
2504+
.env("RUSTC_BOOTSTRAP", "1")
25022505
.arg("generate-lockfile")
25032506
.arg("--manifest-path")
25042507
.arg(&toml)

src/tools/rust-installer/combine-installers.sh

+4
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,9 @@ abs_path() {
1111
(unset CDPATH && cd "$path" > /dev/null && pwd)
1212
}
1313

14+
# Running cargo will read the libstd Cargo.toml
15+
# which uses the unstable `public-dependency` feature.
16+
export RUSTC_BOOTSTRAP=1
17+
1418
src_dir="$(abs_path $(dirname "$0"))"
1519
$CARGO run --manifest-path="$src_dir/Cargo.toml" -- combine "$@"

src/tools/rust-installer/gen-installer.sh

+4
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,9 @@ abs_path() {
1111
(unset CDPATH && cd "$path" > /dev/null && pwd)
1212
}
1313

14+
# Running cargo will read the libstd Cargo.toml
15+
# which uses the unstable `public-dependency` feature.
16+
export RUSTC_BOOTSTRAP=1
17+
1418
src_dir="$(abs_path $(dirname "$0"))"
1519
$CARGO run --manifest-path="$src_dir/Cargo.toml" -- generate "$@"

src/tools/rust-installer/make-tarballs.sh

+4
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,9 @@ abs_path() {
1111
(unset CDPATH && cd "$path" > /dev/null && pwd)
1212
}
1313

14+
# Running cargo will read the libstd Cargo.toml
15+
# which uses the unstable `public-dependency` feature.
16+
export RUSTC_BOOTSTRAP=1
17+
1418
src_dir="$(abs_path $(dirname "$0"))"
1519
$CARGO run --manifest-path="$src_dir/Cargo.toml" -- tarball "$@"

0 commit comments

Comments
 (0)