about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-10 09:37:07 +0000
committerbors <bors@rust-lang.org>2022-02-10 09:37:07 +0000
commit56cd04af5c389b6ab676ba16f59d9f70bc465090 (patch)
treeaf86c44fca9e62cce5d7e5b6701b2227489fe06d
parent5d6ee0db96aada145725838379f909bbb8aa2312 (diff)
parent8edd32c9404f416945d82c438a62acb7f90c2f62 (diff)
downloadrust-56cd04af5c389b6ab676ba16f59d9f70bc465090.tar.gz
rust-56cd04af5c389b6ab676ba16f59d9f70bc465090.zip
Auto merge of #93511 - cjgillot:query-copy, r=oli-obk
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.
-rw-r--r--compiler/rustc_attr/src/builtin.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs4
-rw-r--r--compiler/rustc_interface/src/passes.rs6
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs6
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs21
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_middle/src/arena.rs4
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs49
-rw-r--r--compiler/rustc_middle/src/traits/query.rs9
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs2
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs3
-rw-r--r--compiler/rustc_middle/src/ty/context.rs12
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs34
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/mod.rs12
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs2
-rw-r--r--compiler/rustc_middle/src/ty/query.rs15
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs2
-rw-r--r--compiler/rustc_resolve/src/late/lifetimes.rs153
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/codegen.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_traits/src/dropck_outlives.rs12
-rw-r--r--compiler/rustc_typeck/src/check/method/probe.rs14
-rw-r--r--compiler/rustc_typeck/src/collect.rs2
-rw-r--r--src/librustdoc/clean/inline.rs2
27 files changed, 208 insertions, 182 deletions
diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs
index 8c5beb10258..dca7f5dd487 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<Symbol>,
     /// The note to issue a reason.
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 540979ce02d..f6fddbb509d 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<B: ExtraBackendMethods>(
         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<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,
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 49b785afa69..4a5eabc8755 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_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 7a3d77466c5..f5a4e11de16 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 bb729807cad..87a88fbac71 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<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,
@@ -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 a94c4e2f4e0..ad82165ebd4 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<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
@@ -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<CrateSource> {
         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 3fae652ee2e..c92b3b9434c 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 a936852f4e7..9caf77532a9 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -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, ()>
@@ -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,
         ]);
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 6d531d3e7d6..03cca51dc0b 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/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index e0448c3fe1c..fc2750d2303 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<Vec<NativeLib>> {
+    query native_libraries(_: CrateNum) -> Vec<NativeLib> {
+        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<LocalDefId>) -> 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<rustc_span::Symbol> {
+        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<DtorckConstraint<'tcx>, 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<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.
@@ -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<ImplSource<'tcx, ()>, ErrorReported> {
+    ) -> Result<&'tcx ImplSource<'tcx, ()>, ErrorReported> {
         cache_on_disk_if { true }
         desc { |tcx|
             "checking if `{}` fulfills its obligations",
@@ -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" }
     }
 
@@ -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
@@ -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
     }
@@ -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
@@ -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)
@@ -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" }
     }
 
@@ -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
     }
@@ -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> {
@@ -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
@@ -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" }
     }
@@ -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 }
diff --git a/compiler/rustc_middle/src/traits/query.rs b/compiler/rustc_middle/src/traits/query.rs
index cb35a4005f8..07cfe83b014 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<T>>>;
 
-#[derive(Clone, Debug, HashStable)]
+#[derive(Copy, Clone, Debug, HashStable)]
 pub struct NoSolution;
 
 pub type Fallible<T> = Result<T, NoSolution>;
@@ -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<Vec<CandidateStep<'tcx>>>,
+    pub steps: &'tcx [CandidateStep<'tcx>],
     /// If Some(T), a type autoderef reported an error on.
-    pub opt_bad_ty: Option<Lrc<MethodAutoderefBadTy<'tcx>>>,
+    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 6cec75d36e2..aa264c26de8 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 65b91eedf8a..69b116166e0 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<Ty<'tcx>>,
     &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
+    &'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 543b6fb98eb..b739607c89f 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) -> Option<Vec<ObjectLifetimeDefault>> {
-        self.object_lifetime_defaults_map(id.owner)
-    }
-
     pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
         self.mk_bound_variable_kinds(
             self.late_bound_vars_map(id.owner)
@@ -2728,8 +2724,8 @@ impl<'tcx> TyCtxt<'tcx> {
         )
     }
 
-    pub fn lifetime_scope(self, id: HirId) -> Option<LifetimeScopeForPath> {
-        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 +2898,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/def_id_forest.rs b/compiler/rustc_middle/src/ty/inhabitedness/def_id_forest.rs
index 55807874705..c4ad698ba76 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<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest
+    pub fn intersection<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest<'tcx>
     where
-        I: IntoIterator<Item = DefIdForest>,
+        I: IntoIterator<Item = DefIdForest<'tcx>>,
     {
         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<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest
+    pub fn union<I>(tcx: TyCtxt<'tcx>, iter: I) -> DefIdForest<'tcx>
     where
-        I: IntoIterator<Item = DefIdForest>,
+        I: IntoIterator<Item = DefIdForest<'tcx>>,
     {
         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 167a54e42a0..14ddccbfd83 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,8 +190,8 @@ impl<'tcx> TyS<'tcx> {
         &'tcx self,
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
-    ) -> DefIdForest {
-        tcx.type_uninhabited_from(param_env.and(self))
+    ) -> 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() {
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 87965b06435..c59918df4de 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>),
diff --git a/compiler/rustc_middle/src/ty/query.rs b/compiler/rustc_middle/src/ty/query.rs
index 040e642b7b6..1688e59cdd1 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>(_: &T) {}
 
+/// Helper to ensure that queries only return `Copy` types.
+#[inline(always)]
+fn copy<T: Copy>(x: &T) -> T {
+    *x
+}
+
 macro_rules! query_helper_param_ty {
     (DefId) => { impl IntoQueryParam<DefId> };
     ($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<P> for &'a P {
+        #[inline(always)]
+        fn into_query_param(self) -> P {
+            *self
+        }
+    }
+
     impl IntoQueryParam<DefId> 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 e2a42de71b9..88d994e32fe 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 f3d57139e08..56879ef1808 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<Vec<ObjectLifetimeDefault>> {
+) -> 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<ObjectLifetimeDefault> {
+) -> &'tcx [ObjectLifetimeDefault] {
     fn add_bounds(set: &mut Set1<hir::LifetimeName>, 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, &param.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, &param.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> {
@@ -2509,7 +2503,12 @@ 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.owner)
+                    .unwrap()
+                    .iter()
+                    .map(set_to_region)
+                    .collect()
             } else {
                 let tcx = self.tcx;
                 self.xcrate_object_lifetime_defaults
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 43eb7ab05e0..0870b1054e4 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,
+                });
             }
         }
 
diff --git a/compiler/rustc_trait_selection/src/traits/codegen.rs b/compiler/rustc_trait_selection/src/traits/codegen.rs
index 04a7da06063..138d535a569 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<ImplSource<'tcx, ()>, 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 2cb2ac86661..96671787b31 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 672e149b5fc..087c216af14 100644
--- a/compiler/rustc_traits/src/dropck_outlives.rs
+++ b/compiler/rustc_traits/src/dropck_outlives.rs
@@ -278,9 +278,9 @@ fn dtorck_constraint_for_ty<'tcx>(
                 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
@@ -308,7 +308,7 @@ fn dtorck_constraint_for_ty<'tcx>(
 crate fn adt_dtorck_constraint(
     tcx: TyCtxt<'_>,
     def_id: DefId,
-) -> Result<DtorckConstraint<'_>, 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 b8a45133fd7..2103c12694f 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<Vec<CandidateStep<'tcx>>>,
+    steps: &'tcx [CandidateStep<'tcx>],
 
     inherent_candidates: Vec<Candidate<'tcx>>,
     extension_candidates: Vec<Candidate<'tcx>>,
@@ -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<Ident>,
         return_type: Option<Ty<'tcx>>,
         orig_steps_var_values: OriginalQueryValues<'tcx>,
-        steps: Lrc<Vec<CandidateStep<'tcx>>>,
+        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/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 7b9f1afe271..3f0c3edfe09 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -1696,7 +1696,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;
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index a2e612955b3..f0ae01f3803 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()
     }
 }