From 6c2ee885e635a411946329e974d6be3d94d3b715 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Mon, 31 Jan 2022 19:55:34 +0100 Subject: [PATCH 1/6] Ensure that queries only return Copy types. --- compiler/rustc_attr/src/builtin.rs | 2 +- .../rustc_codegen_cranelift/src/common.rs | 4 +- compiler/rustc_codegen_gcc/src/builder.rs | 2 +- compiler/rustc_codegen_gcc/src/context.rs | 2 +- compiler/rustc_codegen_llvm/src/builder.rs | 2 +- compiler/rustc_codegen_llvm/src/context.rs | 2 +- compiler/rustc_codegen_ssa/src/back/write.rs | 4 +- compiler/rustc_codegen_ssa/src/base.rs | 4 +- .../src/interpret/eval_context.rs | 4 +- compiler/rustc_interface/src/passes.rs | 6 +-- compiler/rustc_metadata/src/rmeta/decoder.rs | 6 +-- .../src/rmeta/decoder/cstore_impl.rs | 21 ++++---- compiler/rustc_metadata/src/rmeta/encoder.rs | 2 +- compiler/rustc_middle/src/arena.rs | 4 ++ compiler/rustc_middle/src/middle/stability.rs | 2 +- .../rustc_middle/src/mir/interpret/error.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 48 +++++++++++++------ compiler/rustc_middle/src/traits/query.rs | 9 ++-- compiler/rustc_middle/src/ty/adt.rs | 2 +- compiler/rustc_middle/src/ty/codec.rs | 3 ++ compiler/rustc_middle/src/ty/context.rs | 8 ++-- .../rustc_middle/src/ty/inhabitedness/mod.rs | 2 +- compiler/rustc_middle/src/ty/layout.rs | 41 +++++++++------- compiler/rustc_middle/src/ty/query.rs | 15 +++++- compiler/rustc_mir_build/src/build/mod.rs | 2 +- compiler/rustc_resolve/src/late/lifetimes.rs | 8 +++- .../src/traits/codegen.rs | 4 +- .../src/traits/error_reporting/mod.rs | 2 +- compiler/rustc_traits/src/dropck_outlives.rs | 8 ++-- .../rustc_typeck/src/check/method/probe.rs | 14 +++--- src/librustdoc/clean/inline.rs | 2 +- 31 files changed, 141 insertions(+), 96 deletions(-) diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index 8c5beb1025803..dca7f5dd48769 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -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, /// The note to issue a reason. diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 3b6025c73d10b..79d8555451409 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -274,7 +274,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: FnAbiError<'tcx>, + err: &'tcx FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { @@ -396,7 +396,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: FnAbiError<'tcx>, + err: &'tcx FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index ffb77e16a1486..8e4b31642754c 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -354,7 +354,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: FnAbiError<'tcx>, + err: &'tcx FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index dfcd1b6231216..6cf67e9186dac 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -397,7 +397,7 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: FnAbiError<'tcx>, + err: &'tcx FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index c9a04e6280f40..1a0d8ec425a71 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -105,7 +105,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: FnAbiError<'tcx>, + err: &'tcx FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index 8672459b5da3a..ed59b89c4f6a0 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -920,7 +920,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: FnAbiError<'tcx>, + err: &'tcx FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs index 540979ce02d8f..f6fddbb509dc8 100644 --- a/compiler/rustc_codegen_ssa/src/back/write.rs +++ b/compiler/rustc_codegen_ssa/src/back/write.rs @@ -477,7 +477,7 @@ pub fn start_async_codegen( codegen_worker_receive, shared_emitter_main, future: coordinator_thread, - output_filenames: tcx.output_filenames(()), + output_filenames: tcx.output_filenames(()).clone(), } } @@ -1050,7 +1050,7 @@ fn start_executing_work( 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, diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs index 49b785afa69e9..4a5eabc87554c 100644 --- a/compiler/rustc_codegen_ssa/src/base.rs +++ b/compiler/rustc_codegen_ssa/src/base.rs @@ -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(); @@ -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); } diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 0a8112da2aba8..93dfc8de5b175 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -341,12 +341,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> FnAbiOfHelpers<'tcx> for InterpCx fn handle_fn_abi_err( &self, - err: FnAbiError<'tcx>, + err: &'tcx FnAbiError<'tcx>, _span: Span, _fn_abi_request: FnAbiRequest<'tcx>, ) -> InterpErrorInfo<'tcx> { match err { - FnAbiError::Layout(err) => err_inval!(Layout(err)).into(), + FnAbiError::Layout(err) => err_inval!(Layout(*err)).into(), FnAbiError::AdjustForForeignAbi(err) => { err_inval!(FnAbiAdjustForForeignAbi(err)).into() } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 7a3d77466c55f..f5a4e11de16c0 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -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())); } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index bb729807cad9a..87a88fbac7123 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -120,7 +120,7 @@ crate struct CrateMetadata { /// How to link (or not link) this crate to the currently compiled crate. dep_kind: Lock, /// Filesystem location of this crate. - source: CrateSource, + source: Lrc, /// Whether or not this crate should be consider a private dependency /// for purposes of the 'exported_private_dependencies' lint private_dep: bool, @@ -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), @@ -1903,7 +1903,7 @@ impl CrateMetadata { } crate fn source(&self) -> &CrateSource { - &self.source + &*self.source } crate fn dep_kind(&self) -> CrateDepKind { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index a94c4e2f4e0e8..ad82165ebd485 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -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}; @@ -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}; @@ -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 } @@ -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); @@ -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 = - 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 @@ -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)), @@ -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 { self.get_crate_data(cnum).source.clone() } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 3fae652ee2e97..c92b3b9434c2b 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -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) }) diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs index a936852f4e7af..9caf77532a9f9 100644 --- a/compiler/rustc_middle/src/arena.rs +++ b/compiler/rustc_middle/src/arena.rs @@ -52,6 +52,9 @@ macro_rules! arena_types { Vec> > >, + [] 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, ()> @@ -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, + [decode] impl_source: rustc_middle::traits::ImplSource<'tcx, ()>, [] dep_kind: rustc_middle::dep_graph::DepKindStruct, ]); diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 6d531d3e7d620..03cca51dc0b54 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -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, diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index e9a857d09124f..00963190ca909 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -144,7 +144,7 @@ pub enum InvalidProgramInfo<'tcx> { /// An error occurred during FnAbi computation: the passed --target lacks FFI support /// (which unfortunately typeck does not reject). /// Not using `FnAbiError` as that contains a nested `LayoutError`. - FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError), + FnAbiAdjustForForeignAbi(&'tcx call::AdjustForForeignAbiError), /// An invalid transmute happened. TransmuteSizeDiff(Ty<'tcx>, Ty<'tcx>), /// SizeOf of unsized type was requested. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index e0448c3fe1c43..b7ee5268f4993 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -215,7 +215,8 @@ rustc_queries! { desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) } } - query native_libraries(_: CrateNum) -> Lrc> { + query native_libraries(_: CrateNum) -> Vec { + storage(ArenaCacheSelector<'tcx>) desc { "looking up the native libraries of a linked crate" } separate_provide_extern } @@ -254,6 +255,7 @@ rustc_queries! { /// Create a THIR tree for debugging. query thir_tree(key: ty::WithOptConstParam) -> String { no_hash + storage(ArenaCacheSelector<'tcx>) desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) } } @@ -368,6 +370,7 @@ rustc_queries! { query symbols_for_closure_captures( key: (LocalDefId, DefId) ) -> Vec { + storage(ArenaCacheSelector<'tcx>) desc { |tcx| "symbols for captures of closure `{}` in `{}`", tcx.def_path_str(key.1), @@ -538,7 +541,7 @@ rustc_queries! { query adt_dtorck_constraint( key: DefId - ) -> Result, NoSolution> { + ) -> Result<&'tcx DtorckConstraint<'tcx>, NoSolution> { desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) } } @@ -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 { - 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. @@ -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 } @@ -1091,7 +1095,7 @@ rustc_queries! { query codegen_fulfill_obligation( key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) - ) -> Result, ErrorReported> { + ) -> Result<&'tcx ImplSource<'tcx, ()>, ErrorReported> { cache_on_disk_if { true } desc { |tcx| "checking if `{}` fulfills its obligations", @@ -1213,7 +1217,8 @@ rustc_queries! { /// instead, where the instance is an `InstanceDef::Virtual`. query fn_abi_of_fn_ptr( key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)> - ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> { + ) -> Result>, ty::layout::FnAbiError<'tcx>> { + storage(ArenaCacheSelector<'tcx>) desc { "computing call ABI of `{}` function pointers", key.value.0 } remap_env_constness } @@ -1225,7 +1230,8 @@ rustc_queries! { /// to an `InstanceDef::Virtual` instance (of `::fn`). query fn_abi_of_instance( key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List>)> - ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> { + ) -> Result>, ty::layout::FnAbiError<'tcx>> { + storage(ArenaCacheSelector<'tcx>) desc { "computing call ABI of `{}`", key.value.0 } remap_env_constness } @@ -1237,6 +1243,7 @@ rustc_queries! { } query dependency_formats(_: ()) -> Lrc { + storage(ArenaCacheSelector<'tcx>) desc { "get the linkage format of all dependencies" } } @@ -1369,13 +1376,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, CrateNum>> { - desc { |tcx| - "collecting available upstream monomorphizations for `{}`", - tcx.def_path_str(def_id), - } - separate_provide_extern + -> Option<&'tcx FxHashMap, 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 @@ -1396,7 +1405,8 @@ rustc_queries! { desc { "available upstream drop-glue for `{:?}`", substs } } - query foreign_modules(_: CrateNum) -> Lrc> { + query foreign_modules(_: CrateNum) -> FxHashMap { + storage(ArenaCacheSelector<'tcx>) desc { "looking up the foreign modules of a linked crate" } separate_provide_extern } @@ -1422,11 +1432,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 { + storage(ArenaCacheSelector<'tcx>) eval_always desc { "looking up the paths for extern crates" } separate_provide_extern @@ -1480,6 +1492,7 @@ rustc_queries! { /// For `struct Foo<'a, T: 'a, U>`, this would instead be `['a, 'static]`. query object_lifetime_defaults_map(_: LocalDefId) -> Option> { + storage(ArenaCacheSelector<'tcx>) desc { "looking up lifetime defaults for a region on an item" } } query late_bound_vars_map(_: LocalDefId) @@ -1488,6 +1501,7 @@ rustc_queries! { } query lifetime_scope_map(_: LocalDefId) -> Option> { + storage(ArenaCacheSelector<'tcx>) desc { "finds the lifetime scope for an HirId of a PathSegment" } } @@ -1502,6 +1516,7 @@ rustc_queries! { query type_uninhabited_from( key: ty::ParamEnvAnd<'tcx, Ty<'tcx>> ) -> ty::inhabitedness::DefIdForest { + storage(ArenaCacheSelector<'tcx>) desc { "computing the inhabitedness of `{:?}`", key } remap_env_constness } @@ -1566,7 +1581,8 @@ rustc_queries! { desc { "calculating the missing lang items in a crate" } separate_provide_extern } - query visible_parent_map(_: ()) -> Lrc> { + query visible_parent_map(_: ()) -> DefIdMap { + storage(ArenaCacheSelector<'tcx>) desc { "calculating the visible parent map" } } query trimmed_def_paths(_: ()) -> FxHashMap { @@ -1579,6 +1595,7 @@ rustc_queries! { separate_provide_extern } query used_crate_source(_: CrateNum) -> Lrc { + storage(ArenaCacheSelector<'tcx>) eval_always desc { "looking at the source for a crate" } separate_provide_extern @@ -1669,7 +1686,7 @@ rustc_queries! { desc { "optimization level used by backend" } } - query output_filenames(_: ()) -> Arc { + query output_filenames(_: ()) -> &'tcx Arc { eval_always desc { "output_filenames" } } @@ -1911,6 +1928,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> { + storage(ArenaCacheSelector<'tcx>) eval_always no_hash desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 } diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs index cb35a4005f8c2..07cfe83b01438 100644 --- a/compiler/rustc_middle/src/traits/query.rs +++ b/compiler/rustc_middle/src/traits/query.rs @@ -11,7 +11,6 @@ use crate::ty::subst::GenericArg; use crate::ty::{self, Ty, TyCtxt}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::Lrc; use rustc_errors::struct_span_err; use rustc_query_system::ich::StableHashingContext; use rustc_span::source_map::Span; @@ -97,7 +96,7 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> = pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize>>; -#[derive(Clone, Debug, HashStable)] +#[derive(Copy, Clone, Debug, HashStable)] pub struct NoSolution; pub type Fallible = Result; @@ -191,12 +190,12 @@ pub struct CandidateStep<'tcx> { pub unsize: bool, } -#[derive(Clone, Debug, HashStable)] +#[derive(Copy, Clone, Debug, HashStable)] pub struct MethodAutoderefStepsResult<'tcx> { /// The valid autoderef steps that could be find. - pub steps: Lrc>>, + pub steps: &'tcx [CandidateStep<'tcx>], /// If Some(T), a type autoderef reported an error on. - pub opt_bad_ty: Option>>, + pub opt_bad_ty: Option<&'tcx MethodAutoderefBadTy<'tcx>>, /// If `true`, `steps` has been truncated due to reaching the /// recursion limit. pub reached_recursion_limit: bool, diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs index 6cec75d36e2c2..aa264c26de88f 100644 --- a/compiler/rustc_middle/src/ty/adt.rs +++ b/compiler/rustc_middle/src/ty/adt.rs @@ -26,7 +26,7 @@ use super::{ Destructor, FieldDef, GenericPredicates, ReprOptions, Ty, TyCtxt, VariantDef, VariantDiscr, }; -#[derive(Clone, HashStable, Debug)] +#[derive(Copy, Clone, HashStable, Debug)] pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]); bitflags! { diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 65b91eedf8a27..69b116166e065 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -13,6 +13,7 @@ use crate::mir::{ interpret::{AllocId, Allocation}, }; use crate::thir; +use crate::traits; use crate::ty::subst::SubstsRef; use crate::ty::{self, Ty, TyCtxt}; use rustc_data_structures::fx::FxHashMap; @@ -156,6 +157,7 @@ macro_rules! encodable_via_deref { encodable_via_deref! { &'tcx ty::TypeckResults<'tcx>, ty::Region<'tcx>, + &'tcx traits::ImplSource<'tcx, ()>, &'tcx mir::Body<'tcx>, &'tcx mir::UnsafetyCheckResult, &'tcx mir::BorrowCheckResult<'tcx>, @@ -385,6 +387,7 @@ impl_decodable_via_ref! { &'tcx ty::TypeckResults<'tcx>, &'tcx ty::List>, &'tcx ty::List>>, + &'tcx traits::ImplSource<'tcx, ()>, &'tcx Allocation, &'tcx mir::Body<'tcx>, &'tcx mir::UnsafetyCheckResult, diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 694b7d2b817cf..39f82f82763ca 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2713,7 +2713,7 @@ impl<'tcx> TyCtxt<'tcx> { .map_or(false, |(owner, set)| owner == id.owner && set.contains(&id.local_id)) } - pub fn object_lifetime_defaults(self, id: HirId) -> Option> { + pub fn object_lifetime_defaults(self, id: HirId) -> &'tcx Option> { self.object_lifetime_defaults_map(id.owner) } @@ -2728,8 +2728,8 @@ impl<'tcx> TyCtxt<'tcx> { ) } - pub fn lifetime_scope(self, id: HirId) -> Option { - self.lifetime_scope_map(id.owner).and_then(|mut map| map.remove(&id.local_id)) + pub fn lifetime_scope(self, id: HirId) -> Option<&'tcx LifetimeScopeForPath> { + self.lifetime_scope_map(id.owner).as_ref().and_then(|map| map.get(&id.local_id)) } /// Whether the `def_id` counts as const fn in the current crate, considering all active @@ -2902,7 +2902,7 @@ pub fn provide(providers: &mut ty::query::Providers) { |tcx, id| tcx.stability().local_deprecation_entry(id.expect_local()); providers.extern_mod_stmt_cnum = |tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned(); - providers.output_filenames = |tcx, ()| tcx.output_filenames.clone(); + providers.output_filenames = |tcx, ()| &tcx.output_filenames; providers.features_query = |tcx, ()| tcx.sess.features_untracked(); providers.is_panic_runtime = |tcx, cnum| { assert_eq!(cnum, LOCAL_CRATE); diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index 167a54e42a015..ca053d704ebca 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -191,7 +191,7 @@ impl<'tcx> TyS<'tcx> { tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> DefIdForest { - tcx.type_uninhabited_from(param_env.and(self)) + tcx.type_uninhabited_from(param_env.and(self)).clone() } } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 87965b06435dd..c095b1a5dd5a3 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2893,7 +2893,7 @@ pub trait FnAbiOfHelpers<'tcx>: LayoutOfHelpers<'tcx> { /// (and any `FnAbiError`s are turned into fatal errors or ICEs). fn handle_fn_abi_err( &self, - err: FnAbiError<'tcx>, + err: &'tcx FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> >>>::Error; @@ -2915,9 +2915,11 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> { let span = self.layout_tcx_at_span(); let tcx = self.tcx().at(span); - MaybeResult::from(tcx.fn_abi_of_fn_ptr(self.param_env().and((sig, extra_args))).map_err( - |err| self.handle_fn_abi_err(err, span, FnAbiRequest::OfFnPtr { sig, extra_args }), - )) + MaybeResult::from( + tcx.fn_abi_of_fn_ptr(self.param_env().and((sig, extra_args))).as_ref().map_err(|err| { + self.handle_fn_abi_err(err, span, FnAbiRequest::OfFnPtr { sig, extra_args }) + }), + ) } /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for @@ -2936,14 +2938,21 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> { let tcx = self.tcx().at(span); MaybeResult::from( - tcx.fn_abi_of_instance(self.param_env().and((instance, extra_args))).map_err(|err| { - // HACK(eddyb) at least for definitions of/calls to `Instance`s, - // we can get some kind of span even if one wasn't provided. - // However, we don't do this early in order to avoid calling - // `def_span` unconditionally (which may have a perf penalty). - let span = if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) }; - self.handle_fn_abi_err(err, span, FnAbiRequest::OfInstance { instance, extra_args }) - }), + tcx.fn_abi_of_instance(self.param_env().and((instance, extra_args))).as_ref().map_err( + |err| { + // HACK(eddyb) at least for definitions of/calls to `Instance`s, + // we can get some kind of span even if one wasn't provided. + // However, we don't do this early in order to avoid calling + // `def_span` unconditionally (which may have a perf penalty). + let span = + if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) }; + self.handle_fn_abi_err( + err, + span, + FnAbiRequest::OfInstance { instance, extra_args }, + ) + }, + ), ) } } @@ -2953,7 +2962,7 @@ impl<'tcx, C: FnAbiOfHelpers<'tcx>> FnAbiOf<'tcx> for C {} fn fn_abi_of_fn_ptr<'tcx>( tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)>, -) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { +) -> Result>, FnAbiError<'tcx>> { let (param_env, (sig, extra_args)) = query.into_parts(); LayoutCx { tcx, param_env }.fn_abi_new_uncached( @@ -2968,7 +2977,7 @@ fn fn_abi_of_fn_ptr<'tcx>( fn fn_abi_of_instance<'tcx>( tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List>)>, -) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { +) -> Result>, FnAbiError<'tcx>> { let (param_env, (instance, extra_args)) = query.into_parts(); let sig = instance.fn_sig_for_fn_abi(tcx, param_env); @@ -3001,7 +3010,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { codegen_fn_attr_flags: CodegenFnAttrFlags, // FIXME(eddyb) replace this with something typed, like an `enum`. force_thin_self_ptr: bool, - ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { + ) -> Result>, FnAbiError<'tcx>> { debug!("fn_abi_new_uncached({:?}, {:?})", sig, extra_args); let sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, sig); @@ -3165,7 +3174,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { }; self.fn_abi_adjust_for_abi(&mut fn_abi, sig.abi)?; debug!("fn_abi_new_uncached = {:?}", fn_abi); - Ok(self.tcx.arena.alloc(fn_abi)) + Ok(fn_abi) } fn fn_abi_adjust_for_abi( diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs index 040e642b7b6d6..1688e59cdd12f 100644 --- a/compiler/rustc_middle/src/ty/query.rs +++ b/compiler/rustc_middle/src/ty/query.rs @@ -106,6 +106,12 @@ impl<'tcx> TyCtxt<'tcx> { #[inline(always)] fn noop(_: &T) {} +/// Helper to ensure that queries only return `Copy` types. +#[inline(always)] +fn copy(x: &T) -> T { + *x +} + macro_rules! query_helper_param_ty { (DefId) => { impl IntoQueryParam }; ($K:ty) => { $K }; @@ -243,7 +249,7 @@ macro_rules! define_callbacks { let key = key.into_query_param(); opt_remap_env_constness!([$($modifiers)*][key]); - let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, Clone::clone); + let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, copy); let lookup = match cached { Ok(value) => return value, @@ -347,6 +353,13 @@ mod sealed { } } + impl<'a, P: Copy> IntoQueryParam

for &'a P { + #[inline(always)] + fn into_query_param(self) -> P { + *self + } + } + impl IntoQueryParam for LocalDefId { #[inline(always)] fn into_query_param(self) -> DefId { diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs index e2a42de71b956..88d994e32fe0c 100644 --- a/compiler/rustc_mir_build/src/build/mod.rs +++ b/compiler/rustc_mir_build/src/build/mod.rs @@ -935,7 +935,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> { }; self.var_debug_info.push(VarDebugInfo { - name: sym, + name: *sym, source_info: SourceInfo::outermost(tcx_hir.span(var_id)), value: VarDebugInfoContents::Place(Place { local: ty::CAPTURE_STRUCT_LOCAL, diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index f3d57139e0817..cb1ea4499cbf5 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -2509,7 +2509,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { }; if let Some(def_id) = def_id.as_local() { let id = self.tcx.hir().local_def_id_to_hir_id(def_id); - self.tcx.object_lifetime_defaults(id).unwrap().iter().map(set_to_region).collect() + self.tcx + .object_lifetime_defaults(id) + .as_ref() + .unwrap() + .iter() + .map(set_to_region) + .collect() } else { let tcx = self.tcx; self.xcrate_object_lifetime_defaults diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs index 04a7da06063ba..138d535a5694d 100644 --- a/compiler/rustc_trait_selection/src/traits/codegen.rs +++ b/compiler/rustc_trait_selection/src/traits/codegen.rs @@ -22,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt}; pub fn codegen_fulfill_obligation<'tcx>( tcx: TyCtxt<'tcx>, (param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>), -) -> Result, ErrorReported> { +) -> Result<&'tcx ImplSource<'tcx, ()>, ErrorReported> { // Remove any references to regions; this helps improve caching. let trait_ref = tcx.erase_regions(trait_ref); // We expect the input to be fully normalized. @@ -96,7 +96,7 @@ pub fn codegen_fulfill_obligation<'tcx>( drop(infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types()); debug!("Cache miss: {:?} => {:?}", trait_ref, impl_source); - Ok(impl_source) + Ok(&*tcx.arena.alloc(impl_source)) }) } diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 2cb2ac8666120..96671787b3163 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -262,7 +262,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { .tcx .diagnostic_hir_wf_check((tcx.erase_regions(obligation.predicate), *wf_loc)) { - obligation.cause = cause; + obligation.cause = cause.clone(); span = obligation.cause.span; } } diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 672e149b5fc96..147d99ff1dd42 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -275,7 +275,7 @@ fn dtorck_constraint_for_ty<'tcx>( ty::Adt(def, substs) => { let DtorckConstraint { dtorck_types, outlives, overflows } = - tcx.at(span).adt_dtorck_constraint(def.did)?; + tcx.at(span).adt_dtorck_constraint(def.did)?.clone(); // FIXME: we can try to recursively `dtorck_constraint_on_ty` // there, but that needs some way to handle cycles. constraints.dtorck_types.extend(dtorck_types.subst(tcx, substs)); @@ -308,7 +308,7 @@ fn dtorck_constraint_for_ty<'tcx>( crate fn adt_dtorck_constraint( tcx: TyCtxt<'_>, def_id: DefId, -) -> Result, NoSolution> { +) -> Result<&DtorckConstraint<'_>, NoSolution> { let def = tcx.adt_def(def_id); let span = tcx.def_span(def_id); debug!("dtorck_constraint: {:?}", def); @@ -324,7 +324,7 @@ crate fn adt_dtorck_constraint( overflows: vec![], }; debug!("dtorck_constraint: {:?} => {:?}", def, result); - return Ok(result); + return Ok(tcx.arena.alloc(result)); } let mut result = DtorckConstraint::empty(); @@ -337,7 +337,7 @@ crate fn adt_dtorck_constraint( debug!("dtorck_constraint: {:?} => {:?}", def, result); - Ok(result) + Ok(tcx.arena.alloc(result)) } fn dedup_dtorck_constraint(c: &mut DtorckConstraint<'_>) { diff --git a/compiler/rustc_typeck/src/check/method/probe.rs b/compiler/rustc_typeck/src/check/method/probe.rs index b8a45133fd7ea..2103c12694f10 100644 --- a/compiler/rustc_typeck/src/check/method/probe.rs +++ b/compiler/rustc_typeck/src/check/method/probe.rs @@ -9,7 +9,6 @@ use crate::hir::def::DefKind; use crate::hir::def_id::DefId; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::sync::Lrc; use rustc_errors::Applicability; use rustc_hir as hir; use rustc_hir::def::Namespace; @@ -59,7 +58,7 @@ struct ProbeContext<'a, 'tcx> { /// This is the OriginalQueryValues for the steps queries /// that are answered in steps. orig_steps_var_values: OriginalQueryValues<'tcx>, - steps: Lrc>>, + steps: &'tcx [CandidateStep<'tcx>], inherent_candidates: Vec>, extension_candidates: Vec>, @@ -364,7 +363,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { param_env_and_self_ty, self_ty ); MethodAutoderefStepsResult { - steps: Lrc::new(vec![CandidateStep { + steps: infcx.tcx.arena.alloc_from_iter([CandidateStep { self_ty: self.make_query_response_ignoring_pending_obligations( canonical_inference_vars, self_ty, @@ -533,8 +532,8 @@ fn method_autoderef_steps<'tcx>( debug!("method_autoderef_steps: steps={:?} opt_bad_ty={:?}", steps, opt_bad_ty); MethodAutoderefStepsResult { - steps: Lrc::new(steps), - opt_bad_ty: opt_bad_ty.map(Lrc::new), + steps: tcx.arena.alloc_from_iter(steps), + opt_bad_ty: opt_bad_ty.map(|ty| &*tcx.arena.alloc(ty)), reached_recursion_limit: autoderef.reached_recursion_limit(), } }) @@ -548,7 +547,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { method_name: Option, return_type: Option>, orig_steps_var_values: OriginalQueryValues<'tcx>, - steps: Lrc>>, + steps: &'tcx [CandidateStep<'tcx>], is_suggestion: IsSuggestion, scope_expr_id: hir::HirId, ) -> ProbeContext<'a, 'tcx> { @@ -605,8 +604,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { } fn assemble_inherent_candidates(&mut self) { - let steps = Lrc::clone(&self.steps); - for step in steps.iter() { + for step in self.steps.iter() { self.assemble_probe(&step.self_ty); } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index a2e612955b349..f0ae01f3803f4 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -564,7 +564,7 @@ crate fn print_inlined_const(tcx: TyCtxt<'_>, did: DefId) -> String { let hir_id = tcx.hir().local_def_id_to_hir_id(did); rustc_hir_pretty::id_to_string(&tcx.hir(), hir_id) } else { - tcx.rendered_const(did) + tcx.rendered_const(did).clone() } } From f72f15ca2861f8635f6240b083952f3bd3b78dee Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 1 Feb 2022 18:27:49 +0100 Subject: [PATCH 2/6] Use a slice in DefIdForest. --- compiler/rustc_middle/src/query/mod.rs | 3 +- .../src/ty/inhabitedness/def_id_forest.rs | 34 +++++++++---------- .../rustc_middle/src/ty/inhabitedness/mod.rs | 10 +++--- 3 files changed, 22 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index b7ee5268f4993..387db37f7832e 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1515,8 +1515,7 @@ rustc_queries! { /// check whether the forest is empty. query type_uninhabited_from( key: ty::ParamEnvAnd<'tcx, Ty<'tcx>> - ) -> ty::inhabitedness::DefIdForest { - storage(ArenaCacheSelector<'tcx>) + ) -> ty::inhabitedness::DefIdForest<'tcx> { desc { "computing the inhabitedness of `{:?}`", key } remap_env_constness } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs b/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs index 55807874705f6..c4ad698ba7635 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs @@ -3,7 +3,6 @@ use crate::ty::{DefId, DefIdTree}; use rustc_span::def_id::CRATE_DEF_ID; use smallvec::SmallVec; use std::mem; -use std::sync::Arc; use DefIdForest::*; @@ -18,14 +17,13 @@ use DefIdForest::*; /// We store the minimal set of `DefId`s required to represent the whole set. If A and B are /// `DefId`s in the `DefIdForest`, and A is a parent of B, then only A will be stored. When this is /// used with `type_uninhabited_from`, there will very rarely be more than one `DefId` stored. -#[derive(Clone, HashStable, Debug)] -pub enum DefIdForest { +#[derive(Copy, Clone, HashStable, Debug)] +pub enum DefIdForest<'a> { Empty, Single(DefId), /// This variant is very rare. /// Invariant: >1 elements - /// We use `Arc` because this is used in the output of a query. - Multiple(Arc<[DefId]>), + Multiple(&'a [DefId]), } /// Tests whether a slice of roots contains a given DefId. @@ -34,21 +32,21 @@ fn slice_contains<'tcx>(tcx: TyCtxt<'tcx>, slice: &[DefId], id: DefId) -> bool { slice.iter().any(|root_id| tcx.is_descendant_of(id, *root_id)) } -impl<'tcx> DefIdForest { +impl<'tcx> DefIdForest<'tcx> { /// Creates an empty forest. - pub fn empty() -> DefIdForest { + pub fn empty() -> DefIdForest<'tcx> { DefIdForest::Empty } /// Creates a forest consisting of a single tree representing the entire /// crate. #[inline] - pub fn full() -> DefIdForest { + pub fn full() -> DefIdForest<'tcx> { DefIdForest::from_id(CRATE_DEF_ID.to_def_id()) } /// Creates a forest containing a `DefId` and all its descendants. - pub fn from_id(id: DefId) -> DefIdForest { + pub fn from_id(id: DefId) -> DefIdForest<'tcx> { DefIdForest::Single(id) } @@ -61,11 +59,11 @@ impl<'tcx> DefIdForest { } // Only allocates in the rare `Multiple` case. - fn from_slice(root_ids: &[DefId]) -> DefIdForest { - match root_ids { + fn from_vec(tcx: TyCtxt<'tcx>, root_ids: SmallVec<[DefId; 1]>) -> DefIdForest<'tcx> { + match &root_ids[..] { [] => Empty, [id] => Single(*id), - _ => DefIdForest::Multiple(root_ids.into()), + _ => DefIdForest::Multiple(tcx.arena.alloc_from_iter(root_ids)), } } @@ -88,9 +86,9 @@ impl<'tcx> DefIdForest { } /// Calculate the intersection of a collection of forests. - pub fn intersection(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest + pub fn intersection(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest<'tcx> where - I: IntoIterator, + I: IntoIterator>, { let mut iter = iter.into_iter(); let mut ret: SmallVec<[_; 1]> = if let Some(first) = iter.next() { @@ -114,13 +112,13 @@ impl<'tcx> DefIdForest { mem::swap(&mut next_ret, &mut ret); next_ret.clear(); } - DefIdForest::from_slice(&ret) + DefIdForest::from_vec(tcx, ret) } /// Calculate the union of a collection of forests. - pub fn union(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest + pub fn union(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest<'tcx> where - I: IntoIterator, + I: IntoIterator>, { let mut ret: SmallVec<[_; 1]> = SmallVec::new(); let mut next_ret: SmallVec<[_; 1]> = SmallVec::new(); @@ -142,6 +140,6 @@ impl<'tcx> DefIdForest { mem::swap(&mut next_ret, &mut ret); next_ret.clear(); } - DefIdForest::from_slice(&ret) + DefIdForest::from_vec(tcx, ret) } } diff --git a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs index ca053d704ebca..14ddccbfd83ae 100644 --- a/compiler/rustc_middle/src/ty/inhabitedness/mod.rs +++ b/compiler/rustc_middle/src/ty/inhabitedness/mod.rs @@ -112,7 +112,7 @@ impl<'tcx> AdtDef { tcx: TyCtxt<'tcx>, substs: SubstsRef<'tcx>, param_env: ty::ParamEnv<'tcx>, - ) -> DefIdForest { + ) -> DefIdForest<'tcx> { // Non-exhaustive ADTs from other crates are always considered inhabited. if self.is_variant_list_non_exhaustive() && !self.did.is_local() { DefIdForest::empty() @@ -135,7 +135,7 @@ impl<'tcx> VariantDef { substs: SubstsRef<'tcx>, adt_kind: AdtKind, param_env: ty::ParamEnv<'tcx>, - ) -> DefIdForest { + ) -> DefIdForest<'tcx> { let is_enum = match adt_kind { // For now, `union`s are never considered uninhabited. // The precise semantics of inhabitedness with respect to unions is currently undecided. @@ -163,7 +163,7 @@ impl<'tcx> FieldDef { substs: SubstsRef<'tcx>, is_enum: bool, param_env: ty::ParamEnv<'tcx>, - ) -> DefIdForest { + ) -> DefIdForest<'tcx> { let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx, param_env); // FIXME(canndrew): Currently enum fields are (incorrectly) stored with // `Visibility::Invisible` so we need to override `self.vis` if we're @@ -190,7 +190,7 @@ impl<'tcx> TyS<'tcx> { &'tcx self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>, - ) -> DefIdForest { + ) -> DefIdForest<'tcx> { tcx.type_uninhabited_from(param_env.and(self)).clone() } } @@ -199,7 +199,7 @@ impl<'tcx> TyS<'tcx> { pub(crate) fn type_uninhabited_from<'tcx>( tcx: TyCtxt<'tcx>, key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, -) -> DefIdForest { +) -> DefIdForest<'tcx> { let ty = key.value; let param_env = key.param_env; match *ty.kind() { From e52131efad56b2c55a3ca2a09011d71f1ae358a5 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 1 Feb 2022 18:28:24 +0100 Subject: [PATCH 3/6] Use a slice for object_lifetime_defaults. --- compiler/rustc_middle/src/query/mod.rs | 4 +- compiler/rustc_middle/src/ty/context.rs | 6 +- compiler/rustc_resolve/src/late/lifetimes.rs | 149 +++++++++---------- compiler/rustc_typeck/src/collect.rs | 2 +- 4 files changed, 74 insertions(+), 87 deletions(-) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 387db37f7832e..f6963cf110b1d 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1490,9 +1490,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> { - storage(ArenaCacheSelector<'tcx>) + 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) diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 39f82f82763ca..05165b7773caf 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -5,7 +5,7 @@ use crate::dep_graph::{DepGraph, DepKind, DepKindStruct}; use crate::hir::place::Place as HirPlace; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource}; -use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath, ObjectLifetimeDefault}; +use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath}; use crate::middle::stability; use crate::mir::interpret::{self, Allocation, ConstValue, Scalar}; use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted}; @@ -2713,10 +2713,6 @@ impl<'tcx> TyCtxt<'tcx> { .map_or(false, |(owner, set)| owner == id.owner && set.contains(&id.local_id)) } - pub fn object_lifetime_defaults(self, id: HirId) -> &'tcx Option> { - self.object_lifetime_defaults_map(id.owner) - } - pub fn late_bound_vars(self, id: HirId) -> &'tcx List { self.mk_bound_variable_kinds( self.late_bound_vars_map(id.owner) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index cb1ea4499cbf5..56879ef1808f6 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -377,7 +377,7 @@ pub fn provide(providers: &mut ty::query::Providers) { named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id), is_late_bound_map, - object_lifetime_defaults_map: |tcx, id| match tcx.hir().find_by_def_id(id) { + object_lifetime_defaults: |tcx, id| match tcx.hir().find_by_def_id(id) { Some(Node::Item(item)) => compute_object_lifetime_defaults(tcx, item), _ => None, }, @@ -1673,10 +1673,10 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) { } } -fn compute_object_lifetime_defaults( - tcx: TyCtxt<'_>, +fn compute_object_lifetime_defaults<'tcx>( + tcx: TyCtxt<'tcx>, item: &hir::Item<'_>, -) -> Option> { +) -> Option<&'tcx [ObjectLifetimeDefault]> { match item.kind { hir::ItemKind::Struct(_, ref generics) | hir::ItemKind::Union(_, ref generics) @@ -1729,10 +1729,10 @@ fn compute_object_lifetime_defaults( /// Scan the bounds and where-clauses on parameters to extract bounds /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault` /// for each type parameter. -fn object_lifetime_defaults_for_item( - tcx: TyCtxt<'_>, +fn object_lifetime_defaults_for_item<'tcx>( + tcx: TyCtxt<'tcx>, generics: &hir::Generics<'_>, -) -> Vec { +) -> &'tcx [ObjectLifetimeDefault] { fn add_bounds(set: &mut Set1, bounds: &[hir::GenericBound<'_>]) { for bound in bounds { if let hir::GenericBound::Outlives(ref lifetime) = *bound { @@ -1741,81 +1741,75 @@ fn object_lifetime_defaults_for_item( } } - generics - .params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => None, - GenericParamKind::Type { .. } => { - let mut set = Set1::Empty; - - add_bounds(&mut set, ¶m.bounds); - - let param_def_id = tcx.hir().local_def_id(param.hir_id); - for predicate in generics.where_clause.predicates { - // Look for `type: ...` where clauses. - let data = match *predicate { - hir::WherePredicate::BoundPredicate(ref data) => data, - _ => continue, - }; + let process_param = |param: &hir::GenericParam<'_>| match param.kind { + GenericParamKind::Lifetime { .. } => None, + GenericParamKind::Type { .. } => { + let mut set = Set1::Empty; - // Ignore `for<'a> type: ...` as they can change what - // lifetimes mean (although we could "just" handle it). - if !data.bound_generic_params.is_empty() { - continue; - } + add_bounds(&mut set, ¶m.bounds); - let res = match data.bounded_ty.kind { - hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.res, - _ => continue, - }; + let param_def_id = tcx.hir().local_def_id(param.hir_id); + for predicate in generics.where_clause.predicates { + // Look for `type: ...` where clauses. + let data = match *predicate { + hir::WherePredicate::BoundPredicate(ref data) => data, + _ => continue, + }; - if res == Res::Def(DefKind::TyParam, param_def_id.to_def_id()) { - add_bounds(&mut set, &data.bounds); - } + // Ignore `for<'a> type: ...` as they can change what + // lifetimes mean (although we could "just" handle it). + if !data.bound_generic_params.is_empty() { + continue; } - Some(match set { - Set1::Empty => Set1::Empty, - Set1::One(name) => { - if name == hir::LifetimeName::Static { - Set1::One(Region::Static) - } else { - generics - .params - .iter() - .filter_map(|param| match param.kind { - GenericParamKind::Lifetime { .. } => Some(( - param.hir_id, - hir::LifetimeName::Param(param.name), - LifetimeDefOrigin::from_param(param), - )), - _ => None, - }) - .enumerate() - .find(|&(_, (_, lt_name, _))| lt_name == name) - .map_or(Set1::Many, |(i, (id, _, origin))| { - let def_id = tcx.hir().local_def_id(id); - Set1::One(Region::EarlyBound( - i as u32, - def_id.to_def_id(), - origin, - )) - }) - } - } - Set1::Many => Set1::Many, - }) - } - GenericParamKind::Const { .. } => { - // Generic consts don't impose any constraints. - // - // We still store a dummy value here to allow generic parameters - // in an arbitrary order. - Some(Set1::Empty) + let res = match data.bounded_ty.kind { + hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.res, + _ => continue, + }; + + if res == Res::Def(DefKind::TyParam, param_def_id.to_def_id()) { + add_bounds(&mut set, &data.bounds); + } } - }) - .collect() + + Some(match set { + Set1::Empty => Set1::Empty, + Set1::One(name) => { + if name == hir::LifetimeName::Static { + Set1::One(Region::Static) + } else { + generics + .params + .iter() + .filter_map(|param| match param.kind { + GenericParamKind::Lifetime { .. } => Some(( + param.hir_id, + hir::LifetimeName::Param(param.name), + LifetimeDefOrigin::from_param(param), + )), + _ => None, + }) + .enumerate() + .find(|&(_, (_, lt_name, _))| lt_name == name) + .map_or(Set1::Many, |(i, (id, _, origin))| { + let def_id = tcx.hir().local_def_id(id); + Set1::One(Region::EarlyBound(i as u32, def_id.to_def_id(), origin)) + }) + } + } + Set1::Many => Set1::Many, + }) + } + GenericParamKind::Const { .. } => { + // Generic consts don't impose any constraints. + // + // We still store a dummy value here to allow generic parameters + // in an arbitrary order. + Some(Set1::Empty) + } + }; + + tcx.arena.alloc_from_iter(generics.params.iter().filter_map(process_param)) } impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { @@ -2510,8 +2504,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { if let Some(def_id) = def_id.as_local() { let id = self.tcx.hir().local_def_id_to_hir_id(def_id); self.tcx - .object_lifetime_defaults(id) - .as_ref() + .object_lifetime_defaults(id.owner) .unwrap() .iter() .map(set_to_region) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 7c8a47d5d6524..e61b76a9b0c1c 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1695,7 +1695,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics { kind: ty::GenericParamDefKind::Lifetime, })); - let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id); + let object_lifetime_defaults = tcx.object_lifetime_defaults(hir_id.owner); // Now create the real type and const parameters. let type_start = own_start - has_self as u32 + params.len() as u32; From 4435dfec0f1180411ac85a9def504ecbf5dd82ad Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 1 Feb 2022 18:44:45 +0100 Subject: [PATCH 4/6] Make FnAbiError Copy. --- .../rustc_codegen_cranelift/src/common.rs | 4 +- compiler/rustc_codegen_gcc/src/builder.rs | 2 +- compiler/rustc_codegen_gcc/src/context.rs | 2 +- compiler/rustc_codegen_llvm/src/builder.rs | 2 +- compiler/rustc_codegen_llvm/src/context.rs | 2 +- .../src/interpret/eval_context.rs | 4 +- .../rustc_middle/src/mir/interpret/error.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 6 +-- compiler/rustc_middle/src/ty/layout.rs | 43 ++++++++----------- compiler/rustc_target/src/abi/call/mod.rs | 10 +++-- 10 files changed, 35 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs index 79d8555451409..3b6025c73d10b 100644 --- a/compiler/rustc_codegen_cranelift/src/common.rs +++ b/compiler/rustc_codegen_cranelift/src/common.rs @@ -274,7 +274,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: &'tcx FnAbiError<'tcx>, + err: FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { @@ -396,7 +396,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: &'tcx FnAbiError<'tcx>, + err: FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs index 8e4b31642754c..ffb77e16a1486 100644 --- a/compiler/rustc_codegen_gcc/src/builder.rs +++ b/compiler/rustc_codegen_gcc/src/builder.rs @@ -354,7 +354,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: &'tcx FnAbiError<'tcx>, + err: FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs index 6cf67e9186dac..dfcd1b6231216 100644 --- a/compiler/rustc_codegen_gcc/src/context.rs +++ b/compiler/rustc_codegen_gcc/src/context.rs @@ -397,7 +397,7 @@ impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: &'tcx FnAbiError<'tcx>, + err: FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs index 1a0d8ec425a71..c9a04e6280f40 100644 --- a/compiler/rustc_codegen_llvm/src/builder.rs +++ b/compiler/rustc_codegen_llvm/src/builder.rs @@ -105,7 +105,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: &'tcx FnAbiError<'tcx>, + err: FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs index ed59b89c4f6a0..8672459b5da3a 100644 --- a/compiler/rustc_codegen_llvm/src/context.rs +++ b/compiler/rustc_codegen_llvm/src/context.rs @@ -920,7 +920,7 @@ impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> { #[inline] fn handle_fn_abi_err( &self, - err: &'tcx FnAbiError<'tcx>, + err: FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> ! { diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs index 93dfc8de5b175..0a8112da2aba8 100644 --- a/compiler/rustc_const_eval/src/interpret/eval_context.rs +++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs @@ -341,12 +341,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> FnAbiOfHelpers<'tcx> for InterpCx fn handle_fn_abi_err( &self, - err: &'tcx FnAbiError<'tcx>, + err: FnAbiError<'tcx>, _span: Span, _fn_abi_request: FnAbiRequest<'tcx>, ) -> InterpErrorInfo<'tcx> { match err { - FnAbiError::Layout(err) => err_inval!(Layout(*err)).into(), + FnAbiError::Layout(err) => err_inval!(Layout(err)).into(), FnAbiError::AdjustForForeignAbi(err) => { err_inval!(FnAbiAdjustForForeignAbi(err)).into() } diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs index 00963190ca909..e9a857d09124f 100644 --- a/compiler/rustc_middle/src/mir/interpret/error.rs +++ b/compiler/rustc_middle/src/mir/interpret/error.rs @@ -144,7 +144,7 @@ pub enum InvalidProgramInfo<'tcx> { /// An error occurred during FnAbi computation: the passed --target lacks FFI support /// (which unfortunately typeck does not reject). /// Not using `FnAbiError` as that contains a nested `LayoutError`. - FnAbiAdjustForForeignAbi(&'tcx call::AdjustForForeignAbiError), + FnAbiAdjustForForeignAbi(call::AdjustForForeignAbiError), /// An invalid transmute happened. TransmuteSizeDiff(Ty<'tcx>, Ty<'tcx>), /// SizeOf of unsized type was requested. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f6963cf110b1d..1861f547fca14 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1217,8 +1217,7 @@ rustc_queries! { /// instead, where the instance is an `InstanceDef::Virtual`. query fn_abi_of_fn_ptr( key: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)> - ) -> Result>, ty::layout::FnAbiError<'tcx>> { - storage(ArenaCacheSelector<'tcx>) + ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> { desc { "computing call ABI of `{}` function pointers", key.value.0 } remap_env_constness } @@ -1230,8 +1229,7 @@ rustc_queries! { /// to an `InstanceDef::Virtual` instance (of `::fn`). query fn_abi_of_instance( key: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List>)> - ) -> Result>, ty::layout::FnAbiError<'tcx>> { - storage(ArenaCacheSelector<'tcx>) + ) -> Result<&'tcx abi::call::FnAbi<'tcx, Ty<'tcx>>, ty::layout::FnAbiError<'tcx>> { desc { "computing call ABI of `{}`", key.value.0 } remap_env_constness } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index c095b1a5dd5a3..c59918df4de5b 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2839,7 +2839,7 @@ pub fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi) -> Conv { } /// Error produced by attempting to compute or adjust a `FnAbi`. -#[derive(Clone, Debug, HashStable)] +#[derive(Copy, Clone, Debug, HashStable)] pub enum FnAbiError<'tcx> { /// Error produced by a `layout_of` call, while computing `FnAbi` initially. Layout(LayoutError<'tcx>), @@ -2893,7 +2893,7 @@ pub trait FnAbiOfHelpers<'tcx>: LayoutOfHelpers<'tcx> { /// (and any `FnAbiError`s are turned into fatal errors or ICEs). fn handle_fn_abi_err( &self, - err: &'tcx FnAbiError<'tcx>, + err: FnAbiError<'tcx>, span: Span, fn_abi_request: FnAbiRequest<'tcx>, ) -> >>>::Error; @@ -2915,11 +2915,9 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> { let span = self.layout_tcx_at_span(); let tcx = self.tcx().at(span); - MaybeResult::from( - tcx.fn_abi_of_fn_ptr(self.param_env().and((sig, extra_args))).as_ref().map_err(|err| { - self.handle_fn_abi_err(err, span, FnAbiRequest::OfFnPtr { sig, extra_args }) - }), - ) + MaybeResult::from(tcx.fn_abi_of_fn_ptr(self.param_env().and((sig, extra_args))).map_err( + |err| self.handle_fn_abi_err(err, span, FnAbiRequest::OfFnPtr { sig, extra_args }), + )) } /// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for @@ -2938,21 +2936,14 @@ pub trait FnAbiOf<'tcx>: FnAbiOfHelpers<'tcx> { let tcx = self.tcx().at(span); MaybeResult::from( - tcx.fn_abi_of_instance(self.param_env().and((instance, extra_args))).as_ref().map_err( - |err| { - // HACK(eddyb) at least for definitions of/calls to `Instance`s, - // we can get some kind of span even if one wasn't provided. - // However, we don't do this early in order to avoid calling - // `def_span` unconditionally (which may have a perf penalty). - let span = - if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) }; - self.handle_fn_abi_err( - err, - span, - FnAbiRequest::OfInstance { instance, extra_args }, - ) - }, - ), + tcx.fn_abi_of_instance(self.param_env().and((instance, extra_args))).map_err(|err| { + // HACK(eddyb) at least for definitions of/calls to `Instance`s, + // we can get some kind of span even if one wasn't provided. + // However, we don't do this early in order to avoid calling + // `def_span` unconditionally (which may have a perf penalty). + let span = if !span.is_dummy() { span } else { tcx.def_span(instance.def_id()) }; + self.handle_fn_abi_err(err, span, FnAbiRequest::OfInstance { instance, extra_args }) + }), ) } } @@ -2962,7 +2953,7 @@ impl<'tcx, C: FnAbiOfHelpers<'tcx>> FnAbiOf<'tcx> for C {} fn fn_abi_of_fn_ptr<'tcx>( tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, (ty::PolyFnSig<'tcx>, &'tcx ty::List>)>, -) -> Result>, FnAbiError<'tcx>> { +) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { let (param_env, (sig, extra_args)) = query.into_parts(); LayoutCx { tcx, param_env }.fn_abi_new_uncached( @@ -2977,7 +2968,7 @@ fn fn_abi_of_fn_ptr<'tcx>( fn fn_abi_of_instance<'tcx>( tcx: TyCtxt<'tcx>, query: ty::ParamEnvAnd<'tcx, (ty::Instance<'tcx>, &'tcx ty::List>)>, -) -> Result>, FnAbiError<'tcx>> { +) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { let (param_env, (instance, extra_args)) = query.into_parts(); let sig = instance.fn_sig_for_fn_abi(tcx, param_env); @@ -3010,7 +3001,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { codegen_fn_attr_flags: CodegenFnAttrFlags, // FIXME(eddyb) replace this with something typed, like an `enum`. force_thin_self_ptr: bool, - ) -> Result>, FnAbiError<'tcx>> { + ) -> Result<&'tcx FnAbi<'tcx, Ty<'tcx>>, FnAbiError<'tcx>> { debug!("fn_abi_new_uncached({:?}, {:?})", sig, extra_args); let sig = self.tcx.normalize_erasing_late_bound_regions(self.param_env, sig); @@ -3174,7 +3165,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> { }; self.fn_abi_adjust_for_abi(&mut fn_abi, sig.abi)?; debug!("fn_abi_new_uncached = {:?}", fn_abi); - Ok(fn_abi) + Ok(self.tcx.arena.alloc(fn_abi)) } fn fn_abi_adjust_for_abi( diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index 43eb7ab05e0bf..0870b1054e430 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -1,6 +1,7 @@ use crate::abi::{self, Abi, Align, FieldsShape, Size}; use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout}; use crate::spec::{self, HasTargetSpec}; +use rustc_span::Symbol; use std::fmt; mod aarch64; @@ -623,10 +624,10 @@ pub struct FnAbi<'a, Ty> { } /// Error produced by attempting to adjust a `FnAbi`, for a "foreign" ABI. -#[derive(Clone, Debug, HashStable_Generic)] +#[derive(Copy, Clone, Debug, HashStable_Generic)] pub enum AdjustForForeignAbiError { /// Target architecture doesn't support "foreign" (i.e. non-Rust) ABIs. - Unsupported { arch: String, abi: spec::abi::Abi }, + Unsupported { arch: Symbol, abi: spec::abi::Abi }, } impl fmt::Display for AdjustForForeignAbiError { @@ -703,7 +704,10 @@ impl<'a, Ty> FnAbi<'a, Ty> { "asmjs" => wasm::compute_c_abi_info(cx, self), "bpf" => bpf::compute_abi_info(self), arch => { - return Err(AdjustForForeignAbiError::Unsupported { arch: arch.to_string(), abi }); + return Err(AdjustForForeignAbiError::Unsupported { + arch: Symbol::intern(arch), + abi, + }); } } From e1a72c29aaef3b3145296dfc9e24201b3c655768 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 1 Feb 2022 18:46:04 +0100 Subject: [PATCH 5/6] Explain &Arc. --- compiler/rustc_middle/src/query/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 1861f547fca14..fc2750d230395 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1681,6 +1681,10 @@ rustc_queries! { desc { "optimization level used by backend" } } + /// 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 { eval_always desc { "output_filenames" } From 8edd32c9404f416945d82c438a62acb7f90c2f62 Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Tue, 1 Feb 2022 18:52:22 +0100 Subject: [PATCH 6/6] Avoid clone. --- compiler/rustc_traits/src/dropck_outlives.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_traits/src/dropck_outlives.rs b/compiler/rustc_traits/src/dropck_outlives.rs index 147d99ff1dd42..087c216af1416 100644 --- a/compiler/rustc_traits/src/dropck_outlives.rs +++ b/compiler/rustc_traits/src/dropck_outlives.rs @@ -275,12 +275,12 @@ fn dtorck_constraint_for_ty<'tcx>( ty::Adt(def, substs) => { let DtorckConstraint { dtorck_types, outlives, overflows } = - tcx.at(span).adt_dtorck_constraint(def.did)?.clone(); + tcx.at(span).adt_dtorck_constraint(def.did)?; // FIXME: we can try to recursively `dtorck_constraint_on_ty` // there, but that needs some way to handle cycles. - constraints.dtorck_types.extend(dtorck_types.subst(tcx, substs)); - constraints.outlives.extend(outlives.subst(tcx, substs)); - constraints.overflows.extend(overflows.subst(tcx, substs)); + constraints.dtorck_types.extend(dtorck_types.iter().map(|t| t.subst(tcx, substs))); + constraints.outlives.extend(outlives.iter().map(|t| t.subst(tcx, substs))); + constraints.overflows.extend(overflows.iter().map(|t| t.subst(tcx, substs))); } // Objects must be alive in order for their destructor