1
Fork 0

Rollup merge of #124976 - petrochenkov:usedcrates, r=oli-obk

rustc: Use `tcx.used_crates(())` more

And explain when it should be used.

Addresses comments from https://github.com/rust-lang/rust/pull/121167.
This commit is contained in:
Matthias Krüger 2024-05-23 14:09:23 +02:00 committed by GitHub
commit eda4a35f36
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
23 changed files with 54 additions and 47 deletions

View file

@ -399,7 +399,7 @@ fn upstream_monomorphizations_provider(
tcx: TyCtxt<'_>,
(): (),
) -> DefIdMap<UnordMap<GenericArgsRef<'_>, CrateNum>> {
let cnums = tcx.crates(());
let cnums = tcx.used_crates(());
let mut instances: DefIdMap<UnordMap<_, _>> = Default::default();

View file

@ -539,7 +539,7 @@ pub fn collect_debugger_visualizers_transitive(
tcx.debugger_visualizers(LOCAL_CRATE)
.iter()
.chain(
tcx.crates(())
tcx.used_crates(())
.iter()
.filter(|&cnum| {
let used_crate_source = tcx.used_crate_source(*cnum);
@ -849,7 +849,7 @@ impl CrateInfo {
// `compiler_builtins` are always placed last to ensure that they're linked correctly.
used_crates.extend(compiler_builtins);
let crates = tcx.crates(());
let crates = tcx.used_crates(());
let n_crates = crates.len();
let mut info = CrateInfo {
target_cpu,

View file

@ -458,7 +458,7 @@ fn write_out_deps(tcx: TyCtxt<'_>, outputs: &OutputFilenames, out_filenames: &[P
}
}
for &cnum in tcx.crates(()) {
for &cnum in tcx.crates_including_speculative(()) {
let source = tcx.used_crate_source(cnum);
if let Some((path, _)) = &source.dylib {
files.push(escape_dep_filename(&path.display().to_string()));

View file

@ -143,7 +143,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
&& sess.crt_static(Some(ty))
&& !sess.target.crt_static_allows_dylibs)
{
for &cnum in tcx.crates(()).iter() {
for &cnum in tcx.used_crates(()).iter() {
if tcx.dep_kind(cnum).macros_only() {
continue;
}
@ -164,7 +164,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
// Sweep all crates for found dylibs. Add all dylibs, as well as their
// dependencies, ensuring there are no conflicts. The only valid case for a
// dependency to be relied upon twice is for both cases to rely on a dylib.
for &cnum in tcx.crates(()).iter() {
for &cnum in tcx.used_crates(()).iter() {
if tcx.dep_kind(cnum).macros_only() {
continue;
}
@ -182,7 +182,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
}
// Collect what we've got so far in the return vector.
let last_crate = tcx.crates(()).len();
let last_crate = tcx.used_crates(()).len();
let mut ret = (1..last_crate + 1)
.map(|cnum| match formats.get(&CrateNum::new(cnum)) {
Some(&RequireDynamic) => Linkage::Dynamic,
@ -196,7 +196,7 @@ fn calculate_type(tcx: TyCtxt<'_>, ty: CrateType) -> DependencyList {
//
// If the crate hasn't been included yet and it's not actually required
// (e.g., it's an allocator) then we skip it here as well.
for &cnum in tcx.crates(()).iter() {
for &cnum in tcx.used_crates(()).iter() {
let src = tcx.used_crate_source(cnum);
if src.dylib.is_none()
&& !formats.contains_key(&cnum)
@ -284,7 +284,7 @@ fn add_library(
fn attempt_static(tcx: TyCtxt<'_>, unavailable: &mut Vec<CrateNum>) -> Option<DependencyList> {
let all_crates_available_as_rlib = tcx
.crates(())
.used_crates(())
.iter()
.copied()
.filter_map(|cnum| {
@ -305,7 +305,7 @@ fn attempt_static(tcx: TyCtxt<'_>, unavailable: &mut Vec<CrateNum>) -> Option<De
// All crates are available in an rlib format, so we're just going to link
// everything in explicitly so long as it's actually required.
let mut ret = tcx
.crates(())
.used_crates(())
.iter()
.map(|&cnum| match tcx.dep_kind(cnum) {
CrateDepKind::Explicit => Linkage::Static,

View file

@ -435,7 +435,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
// traversal, but not globally minimal across all crates.
let bfs_queue = &mut VecDeque::new();
for &cnum in tcx.crates(()) {
for &cnum in tcx.crates_including_speculative(()) {
// Ignore crates without a corresponding local `extern crate` item.
if tcx.missing_extern_crate_item(cnum) {
continue;
@ -505,7 +505,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
tcx.arena
.alloc_slice(&CStore::from_tcx(tcx).crate_dependencies_in_postorder(LOCAL_CRATE))
},
crates: |tcx, ()| {
crates_including_speculative: |tcx, ()| {
// The list of loaded crates is now frozen in query cache,
// so make sure cstore is not mutably accessed from here on.
tcx.untracked().cstore.freeze();

View file

@ -1898,7 +1898,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let deps = self
.tcx
.crates(())
.crates_including_speculative(())
.iter()
.map(|&cnum| {
let dep = CrateDep {

View file

@ -1016,7 +1016,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
let krate = tcx.hir_crate(());
let hir_body_hash = krate.opt_hir_hash.expect("HIR hash missing while computing crate hash");
let upstream_crates = upstream_crates(tcx);
let upstream_crates = upstream_crates_for_hashing(tcx);
let resolutions = tcx.resolutions(());
@ -1085,9 +1085,9 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, _: LocalCrate) -> Svh {
Svh::new(crate_hash)
}
fn upstream_crates(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
fn upstream_crates_for_hashing(tcx: TyCtxt<'_>) -> Vec<(StableCrateId, Svh)> {
let mut upstream_crates: Vec<_> = tcx
.crates(())
.crates_including_speculative(())
.iter()
.map(|&cnum| {
let stable_crate_id = tcx.stable_crate_id(cnum);

View file

@ -1860,13 +1860,22 @@ rustc_queries! {
eval_always
desc { "calculating the stability index for the local crate" }
}
query crates(_: ()) -> &'tcx [CrateNum] {
/// All loaded crates, including those loaded purely for doc links or diagnostics.
/// (Diagnostics include lints, so speculatively loaded crates may occur in successful
/// compilation even without doc links.)
/// Should be used when encoding crate metadata (and therefore when generating crate hash,
/// depinfo and similar things), to avoid dangling crate references in other encoded data,
/// like source maps.
/// May also be used for diagnostics - if we are loading a crate anyway we can suggest some
/// items from it as well.
/// But otherwise, `used_crates` should generally be used.
query crates_including_speculative(_: ()) -> &'tcx [CrateNum] {
eval_always
desc { "fetching all foreign CrateNum instances" }
}
// Crates that are loaded non-speculatively (not for diagnostics or doc links).
// FIXME: This is currently only used for collecting lang items, but should be used instead of
// `crates` in most other cases too.
/// Crates that are loaded non-speculatively (not for diagnostics or doc links).
/// Should be used to maintain observable language behavior, for example when collecting lang
/// items or impls from all crates, or collecting libraries to link.
query used_crates(_: ()) -> &'tcx [CrateNum] {
eval_always
desc { "fetching `CrateNum`s for all crates loaded non-speculatively" }

View file

@ -1611,7 +1611,7 @@ impl<'tcx> TyCtxt<'tcx> {
pub fn all_traits(self) -> impl Iterator<Item = DefId> + 'tcx {
iter::once(LOCAL_CRATE)
.chain(self.crates(()).iter().copied())
.chain(self.used_crates(()).iter().copied())
.flat_map(move |cnum| self.traits(cnum).iter().copied())
}

View file

@ -3258,7 +3258,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
let queue = &mut Vec::new();
let mut seen_defs: DefIdSet = Default::default();
for &cnum in tcx.crates(()).iter() {
for &cnum in tcx.crates_including_speculative(()).iter() {
let def_id = cnum.as_def_id();
// Ignore crates that are not direct dependencies.

View file

@ -205,7 +205,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
// Traits defined in the current crate can't have impls in upstream
// crates, so we don't bother querying the cstore.
if !trait_id.is_local() {
for &cnum in tcx.crates(()).iter() {
for &cnum in tcx.used_crates(()).iter() {
for &(impl_def_id, simplified_self_ty) in
tcx.implementations_of_trait((cnum, trait_id)).iter()
{
@ -247,7 +247,7 @@ pub(super) fn incoherent_impls_provider(
let mut impls = Vec::new();
let mut res = Ok(());
for cnum in iter::once(LOCAL_CRATE).chain(tcx.crates(()).iter().copied()) {
for cnum in iter::once(LOCAL_CRATE).chain(tcx.used_crates(()).iter().copied()) {
let incoherent_impls = match tcx.crate_incoherent_impls((cnum, simp)) {
Ok(impls) => impls,
Err(e) => {

View file

@ -82,7 +82,7 @@ fn all_diagnostic_items(tcx: TyCtxt<'_>, (): ()) -> DiagnosticItems {
let mut items = DiagnosticItems::default();
// Collect diagnostic items in other crates.
for &cnum in tcx.crates(()).iter().chain(std::iter::once(&LOCAL_CRATE)) {
for &cnum in tcx.crates_including_speculative(()).iter().chain(std::iter::once(&LOCAL_CRATE)) {
for (&name, &def_id) in &tcx.diagnostic_items(cnum).name_to_id {
collect_item(tcx, &mut items, name, def_id);
}

View file

@ -1020,7 +1020,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
// stabilization diagnostic, but it can be avoided when there are no
// `remaining_lib_features`.
let mut all_implications = remaining_implications.clone();
for &cnum in tcx.crates(()) {
for &cnum in tcx.used_crates(()) {
all_implications
.extend_unord(tcx.stability_implications(cnum).items().map(|(k, v)| (*k, *v)));
}
@ -1033,7 +1033,7 @@ pub fn check_unused_or_stable_features(tcx: TyCtxt<'_>) {
&all_implications,
);
for &cnum in tcx.crates(()) {
for &cnum in tcx.used_crates(()) {
if remaining_lib_features.is_empty() && remaining_implications.is_empty() {
break;
}

View file

@ -68,7 +68,7 @@ fn verify(tcx: TyCtxt<'_>, items: &lang_items::LanguageItems) {
}
let mut missing = FxHashSet::default();
for &cnum in tcx.crates(()).iter() {
for &cnum in tcx.used_crates(()).iter() {
for &item in tcx.missing_lang_items(cnum).iter() {
missing.insert(item);
}

View file

@ -126,7 +126,7 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
let mut tables = self.0.borrow_mut();
let tcx = tables.tcx;
iter::once(LOCAL_CRATE)
.chain(tables.tcx.crates(()).iter().copied())
.chain(tables.tcx.used_crates(()).iter().copied())
.flat_map(|cnum| tcx.trait_impls_in_crate(cnum).iter())
.map(|impl_def_id| tables.impl_def(*impl_def_id))
.collect()
@ -201,14 +201,19 @@ impl<'tcx> Context for TablesWrapper<'tcx> {
fn external_crates(&self) -> Vec<stable_mir::Crate> {
let tables = self.0.borrow();
tables.tcx.crates(()).iter().map(|crate_num| smir_crate(tables.tcx, *crate_num)).collect()
tables
.tcx
.used_crates(())
.iter()
.map(|crate_num| smir_crate(tables.tcx, *crate_num))
.collect()
}
fn find_crates(&self, name: &str) -> Vec<stable_mir::Crate> {
let tables = self.0.borrow();
let crates: Vec<stable_mir::Crate> = [LOCAL_CRATE]
.iter()
.chain(tables.tcx.crates(()).iter())
.chain(tables.tcx.used_crates(()).iter())
.filter_map(|crate_num| {
let crate_name = tables.tcx.crate_name(*crate_num).to_string();
(name == crate_name).then(|| smir_crate(tables.tcx, *crate_num))