Skip to content

Commit

Permalink
Auto merge of rust-lang#93511 - cjgillot:query-copy, r=oli-obk
Browse files Browse the repository at this point in the history
Ensure that queries only return Copy types.

This should pervent the perf footgun of returning a result with an expensive `Clone` impl (like a `Vec` of a hash map).

I went for the stupid solution of allocating on an arena everything that was not `Copy`. Some query results could be made Copy easily, but I did not really investigate.
  • Loading branch information
bors committed Feb 10, 2022
2 parents 5d6ee0d + 8edd32c commit 56cd04a
Show file tree
Hide file tree
Showing 27 changed files with 208 additions and 182 deletions.
2 changes: 1 addition & 1 deletion compiler/rustc_attr/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -604,7 +604,7 @@ pub fn eval_condition(
}
}

#[derive(Debug, Encodable, Decodable, Clone, HashStable_Generic)]
#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)]
pub struct Deprecation {
pub since: Option<Symbol>,
/// The note to issue a reason.
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,7 +477,7 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
codegen_worker_receive,
shared_emitter_main,
future: coordinator_thread,
output_filenames: tcx.output_filenames(()),
output_filenames: tcx.output_filenames(()).clone(),
}
}

Expand Down Expand Up @@ -1050,7 +1050,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
cgu_reuse_tracker: sess.cgu_reuse_tracker.clone(),
coordinator_send,
diag_emitter: shared_emitter.clone(),
output_filenames: tcx.output_filenames(()),
output_filenames: tcx.output_filenames(()).clone(),
regular_module_config: regular_config,
metadata_module_config: metadata_config,
allocator_module_config: allocator_config,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_ssa/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -843,7 +843,7 @@ impl CrateInfo {
used_crate_source: Default::default(),
lang_item_to_crate: Default::default(),
missing_lang_items: Default::default(),
dependency_formats: tcx.dependency_formats(()),
dependency_formats: tcx.dependency_formats(()).clone(),
windows_subsystem,
};
let lang_items = tcx.lang_items();
Expand All @@ -860,7 +860,7 @@ impl CrateInfo {
info.native_libraries
.insert(cnum, tcx.native_libraries(cnum).iter().map(Into::into).collect());
info.crate_name.insert(cnum, tcx.crate_name(cnum).to_string());
info.used_crate_source.insert(cnum, tcx.used_crate_source(cnum));
info.used_crate_source.insert(cnum, tcx.used_crate_source(cnum).clone());
if tcx.is_compiler_builtins(cnum) {
info.compiler_builtins = Some(cnum);
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -658,13 +658,13 @@ fn write_out_deps(
boxed_resolver.borrow_mut().access(|resolver| {
for cnum in resolver.cstore().crates_untracked() {
let source = resolver.cstore().crate_source_untracked(cnum);
if let Some((path, _)) = source.dylib {
if let Some((path, _)) = &source.dylib {
files.push(escape_dep_filename(&path.display().to_string()));
}
if let Some((path, _)) = source.rlib {
if let Some((path, _)) = &source.rlib {
files.push(escape_dep_filename(&path.display().to_string()));
}
if let Some((path, _)) = source.rmeta {
if let Some((path, _)) = &source.rmeta {
files.push(escape_dep_filename(&path.display().to_string()));
}
}
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_metadata/src/rmeta/decoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ crate struct CrateMetadata {
/// How to link (or not link) this crate to the currently compiled crate.
dep_kind: Lock<CrateDepKind>,
/// Filesystem location of this crate.
source: CrateSource,
source: Lrc<CrateSource>,
/// Whether or not this crate should be consider a private dependency
/// for purposes of the 'exported_private_dependencies' lint
private_dep: bool,
Expand Down Expand Up @@ -1875,7 +1875,7 @@ impl CrateMetadata {
cnum_map,
dependencies,
dep_kind: Lock::new(dep_kind),
source,
source: Lrc::new(source),
private_dep,
host_hash,
extern_crate: Lock::new(None),
Expand Down Expand Up @@ -1903,7 +1903,7 @@ impl CrateMetadata {
}

crate fn source(&self) -> &CrateSource {
&self.source
&*self.source
}

crate fn dep_kind(&self) -> CrateDepKind {
Expand Down
21 changes: 8 additions & 13 deletions compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ use crate::foreign_modules;
use crate::native_libs;

use rustc_ast as ast;
use rustc_data_structures::stable_map::FxHashMap;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
Expand All @@ -13,7 +12,7 @@ use rustc_middle::middle::stability::DeprecationEntry;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::{self, TyCtxt, Visibility};
use rustc_session::cstore::{CrateSource, CrateStore, ForeignModule};
use rustc_session::cstore::{CrateSource, CrateStore};
use rustc_session::utils::NativeLibKind;
use rustc_session::{Session, StableCrateId};
use rustc_span::hygiene::{ExpnHash, ExpnId};
Expand Down Expand Up @@ -179,10 +178,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,

reachable_non_generics
}
native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess).collect()) }
foreign_modules => {
Lrc::new(cdata.get_foreign_modules(tcx.sess).map(|m| (m.def_id, m)).collect())
}
native_libraries => { cdata.get_native_libraries(tcx.sess).collect() }
foreign_modules => { cdata.get_foreign_modules(tcx.sess).map(|m| (m.def_id, m)).collect() }
crate_hash => { cdata.root.hash }
crate_host_hash => { cdata.host_hash }
crate_name => { cdata.root.name }
Expand Down Expand Up @@ -212,7 +209,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
r
}

used_crate_source => { Lrc::new(cdata.source.clone()) }
used_crate_source => { Lrc::clone(&cdata.source) }

exported_symbols => {
let syms = cdata.exported_symbols(tcx);
Expand Down Expand Up @@ -266,13 +263,11 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
},
native_libraries: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
Lrc::new(native_libs::collect(tcx))
native_libs::collect(tcx)
},
foreign_modules: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE);
let modules: FxHashMap<DefId, ForeignModule> =
foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect();
Lrc::new(modules)
foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect()
},

// Returns a map from a sufficiently visible external item (i.e., an
Expand Down Expand Up @@ -354,7 +349,7 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
visible_parent_map.entry(child).or_insert(parent);
}

Lrc::new(visible_parent_map)
visible_parent_map
},

dependency_formats: |tcx, ()| Lrc::new(crate::dependency_format::calculate(tcx)),
Expand Down Expand Up @@ -438,7 +433,7 @@ impl CStore {
self.get_crate_data(def.krate).get_fn_has_self_parameter(def.index)
}

pub fn crate_source_untracked(&self, cnum: CrateNum) -> CrateSource {
pub fn crate_source_untracked(&self, cnum: CrateNum) -> Lrc<CrateSource> {
self.get_crate_data(cnum).source.clone()
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1742,7 +1742,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
hash: self.tcx.crate_hash(cnum),
host_hash: self.tcx.crate_host_hash(cnum),
kind: self.tcx.dep_kind(cnum),
extra_filename: self.tcx.extra_filename(cnum),
extra_filename: self.tcx.extra_filename(cnum).clone(),
};
(cnum, dep)
})
Expand Down
4 changes: 4 additions & 0 deletions compiler/rustc_middle/src/arena.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ macro_rules! arena_types {
Vec<rustc_middle::traits::query::OutlivesBound<'tcx>>
>
>,
[] dtorck_constraint: rustc_middle::traits::query::DtorckConstraint<'tcx>,
[] candidate_step: rustc_middle::traits::query::CandidateStep<'tcx>,
[] autoderef_bad_ty: rustc_middle::traits::query::MethodAutoderefBadTy<'tcx>,
[] type_op_subtype:
rustc_middle::infer::canonical::Canonical<'tcx,
rustc_middle::infer::canonical::QueryResponse<'tcx, ()>
Expand Down Expand Up @@ -95,6 +98,7 @@ macro_rules! arena_types {
// This is used to decode the &'tcx [Span] for InlineAsm's line_spans.
[decode] span: rustc_span::Span,
[decode] used_trait_imports: rustc_data_structures::fx::FxHashSet<rustc_hir::def_id::LocalDefId>,
[decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>,

[] dep_kind: rustc_middle::dep_graph::DepKindStruct,
]);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/middle/stability.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub enum StabilityLevel {
}

/// An entry in the `depr_map`.
#[derive(Clone, HashStable, Debug)]
#[derive(Copy, Clone, HashStable, Debug)]
pub struct DeprecationEntry {
/// The metadata of the attribute associated with this entry.
pub attr: Deprecation,
Expand Down
49 changes: 33 additions & 16 deletions compiler/rustc_middle/src/query/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,8 @@ rustc_queries! {
desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) }
}

query native_libraries(_: CrateNum) -> Lrc<Vec<NativeLib>> {
query native_libraries(_: CrateNum) -> Vec<NativeLib> {
storage(ArenaCacheSelector<'tcx>)
desc { "looking up the native libraries of a linked crate" }
separate_provide_extern
}
Expand Down Expand Up @@ -254,6 +255,7 @@ rustc_queries! {
/// Create a THIR tree for debugging.
query thir_tree(key: ty::WithOptConstParam<LocalDefId>) -> String {
no_hash
storage(ArenaCacheSelector<'tcx>)
desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) }
}

Expand Down Expand Up @@ -368,6 +370,7 @@ rustc_queries! {
query symbols_for_closure_captures(
key: (LocalDefId, DefId)
) -> Vec<rustc_span::Symbol> {
storage(ArenaCacheSelector<'tcx>)
desc {
|tcx| "symbols for captures of closure `{}` in `{}`",
tcx.def_path_str(key.1),
Expand Down Expand Up @@ -538,7 +541,7 @@ rustc_queries! {

query adt_dtorck_constraint(
key: DefId
) -> Result<DtorckConstraint<'tcx>, NoSolution> {
) -> Result<&'tcx DtorckConstraint<'tcx>, NoSolution> {
desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) }
}

Expand Down Expand Up @@ -646,8 +649,8 @@ rustc_queries! {
/// The map returned for `tcx.impl_item_implementor_ids(impl_id)` would be
///`{ trait_f: impl_f, trait_g: impl_g }`
query impl_item_implementor_ids(impl_id: DefId) -> FxHashMap<DefId, DefId> {
desc { |tcx| "comparing impl items against trait for {}", tcx.def_path_str(impl_id) }
storage(ArenaCacheSelector<'tcx>)
desc { |tcx| "comparing impl items against trait for {}", tcx.def_path_str(impl_id) }
}

/// Given an `impl_id`, return the trait it implements.
Expand Down Expand Up @@ -1042,6 +1045,7 @@ rustc_queries! {
/// Gets the rendered value of the specified constant or associated constant.
/// Used by rustdoc.
query rendered_const(def_id: DefId) -> String {
storage(ArenaCacheSelector<'tcx>)
desc { |tcx| "rendering constant intializer of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern
}
Expand Down Expand Up @@ -1091,7 +1095,7 @@ rustc_queries! {

query codegen_fulfill_obligation(
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
) -> Result<ImplSource<'tcx, ()>, ErrorReported> {
) -> Result<&'tcx ImplSource<'tcx, ()>, ErrorReported> {
cache_on_disk_if { true }
desc { |tcx|
"checking if `{}` fulfills its obligations",
Expand Down Expand Up @@ -1237,6 +1241,7 @@ rustc_queries! {
}

query dependency_formats(_: ()) -> Lrc<crate::middle::dependency_format::Dependencies> {
storage(ArenaCacheSelector<'tcx>)
desc { "get the linkage format of all dependencies" }
}

Expand Down Expand Up @@ -1369,13 +1374,15 @@ rustc_queries! {
/// You likely want to call `Instance::upstream_monomorphization()`
/// instead of invoking this query directly.
query upstream_monomorphizations_for(def_id: DefId)
-> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>> {
desc { |tcx|
"collecting available upstream monomorphizations for `{}`",
tcx.def_path_str(def_id),
}
separate_provide_extern
-> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>>
{
storage(ArenaCacheSelector<'tcx>)
desc { |tcx|
"collecting available upstream monomorphizations for `{}`",
tcx.def_path_str(def_id),
}
separate_provide_extern
}

/// Returns the upstream crate that exports drop-glue for the given
/// type (`substs` is expected to be a single-item list containing the
Expand All @@ -1396,7 +1403,8 @@ rustc_queries! {
desc { "available upstream drop-glue for `{:?}`", substs }
}

query foreign_modules(_: CrateNum) -> Lrc<FxHashMap<DefId, ForeignModule>> {
query foreign_modules(_: CrateNum) -> FxHashMap<DefId, ForeignModule> {
storage(ArenaCacheSelector<'tcx>)
desc { "looking up the foreign modules of a linked crate" }
separate_provide_extern
}
Expand All @@ -1422,11 +1430,13 @@ rustc_queries! {
separate_provide_extern
}
query extra_filename(_: CrateNum) -> String {
storage(ArenaCacheSelector<'tcx>)
eval_always
desc { "looking up the extra filename for a crate" }
separate_provide_extern
}
query crate_extern_paths(_: CrateNum) -> Vec<PathBuf> {
storage(ArenaCacheSelector<'tcx>)
eval_always
desc { "looking up the paths for extern crates" }
separate_provide_extern
Expand Down Expand Up @@ -1478,8 +1488,7 @@ rustc_queries! {
/// for each parameter if a trait object were to be passed for that parameter.
/// For example, for `struct Foo<'a, T, U>`, this would be `['static, 'static]`.
/// For `struct Foo<'a, T: 'a, U>`, this would instead be `['a, 'static]`.
query object_lifetime_defaults_map(_: LocalDefId)
-> Option<Vec<ObjectLifetimeDefault>> {
query object_lifetime_defaults(_: LocalDefId) -> Option<&'tcx [ObjectLifetimeDefault]> {
desc { "looking up lifetime defaults for a region on an item" }
}
query late_bound_vars_map(_: LocalDefId)
Expand All @@ -1488,6 +1497,7 @@ rustc_queries! {
}

query lifetime_scope_map(_: LocalDefId) -> Option<FxHashMap<ItemLocalId, LifetimeScopeForPath>> {
storage(ArenaCacheSelector<'tcx>)
desc { "finds the lifetime scope for an HirId of a PathSegment" }
}

Expand All @@ -1501,7 +1511,7 @@ rustc_queries! {
/// check whether the forest is empty.
query type_uninhabited_from(
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
) -> ty::inhabitedness::DefIdForest {
) -> ty::inhabitedness::DefIdForest<'tcx> {
desc { "computing the inhabitedness of `{:?}`", key }
remap_env_constness
}
Expand Down Expand Up @@ -1566,7 +1576,8 @@ rustc_queries! {
desc { "calculating the missing lang items in a crate" }
separate_provide_extern
}
query visible_parent_map(_: ()) -> Lrc<DefIdMap<DefId>> {
query visible_parent_map(_: ()) -> DefIdMap<DefId> {
storage(ArenaCacheSelector<'tcx>)
desc { "calculating the visible parent map" }
}
query trimmed_def_paths(_: ()) -> FxHashMap<DefId, Symbol> {
Expand All @@ -1579,6 +1590,7 @@ rustc_queries! {
separate_provide_extern
}
query used_crate_source(_: CrateNum) -> Lrc<CrateSource> {
storage(ArenaCacheSelector<'tcx>)
eval_always
desc { "looking at the source for a crate" }
separate_provide_extern
Expand Down Expand Up @@ -1669,7 +1681,11 @@ rustc_queries! {
desc { "optimization level used by backend" }
}

query output_filenames(_: ()) -> Arc<OutputFilenames> {
/// Return the filenames where output artefacts shall be stored.
///
/// This query returns an `&Arc` because codegen backends need the value even after the `TyCtxt`
/// has been destroyed.
query output_filenames(_: ()) -> &'tcx Arc<OutputFilenames> {
eval_always
desc { "output_filenames" }
}
Expand Down Expand Up @@ -1911,6 +1927,7 @@ rustc_queries! {
/// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine,
/// because the `ty::Ty`-based wfcheck is always run.
query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, traits::WellFormedLoc)) -> Option<traits::ObligationCause<'tcx>> {
storage(ArenaCacheSelector<'tcx>)
eval_always
no_hash
desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 }
Expand Down
Loading

0 comments on commit 56cd04a

Please sign in to comment.