1
Fork 0

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.
This commit is contained in:
bors 2022-02-10 09:37:07 +00:00
commit 56cd04af5c
27 changed files with 208 additions and 182 deletions

View file

@ -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 struct Deprecation {
pub since: Option<Symbol>, pub since: Option<Symbol>,
/// The note to issue a reason. /// The note to issue a reason.

View file

@ -477,7 +477,7 @@ pub fn start_async_codegen<B: ExtraBackendMethods>(
codegen_worker_receive, codegen_worker_receive,
shared_emitter_main, shared_emitter_main,
future: coordinator_thread, 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(), cgu_reuse_tracker: sess.cgu_reuse_tracker.clone(),
coordinator_send, coordinator_send,
diag_emitter: shared_emitter.clone(), diag_emitter: shared_emitter.clone(),
output_filenames: tcx.output_filenames(()), output_filenames: tcx.output_filenames(()).clone(),
regular_module_config: regular_config, regular_module_config: regular_config,
metadata_module_config: metadata_config, metadata_module_config: metadata_config,
allocator_module_config: allocator_config, allocator_module_config: allocator_config,

View file

@ -843,7 +843,7 @@ impl CrateInfo {
used_crate_source: Default::default(), used_crate_source: Default::default(),
lang_item_to_crate: Default::default(), lang_item_to_crate: Default::default(),
missing_lang_items: Default::default(), missing_lang_items: Default::default(),
dependency_formats: tcx.dependency_formats(()), dependency_formats: tcx.dependency_formats(()).clone(),
windows_subsystem, windows_subsystem,
}; };
let lang_items = tcx.lang_items(); let lang_items = tcx.lang_items();
@ -860,7 +860,7 @@ impl CrateInfo {
info.native_libraries info.native_libraries
.insert(cnum, tcx.native_libraries(cnum).iter().map(Into::into).collect()); .insert(cnum, tcx.native_libraries(cnum).iter().map(Into::into).collect());
info.crate_name.insert(cnum, tcx.crate_name(cnum).to_string()); 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) { if tcx.is_compiler_builtins(cnum) {
info.compiler_builtins = Some(cnum); info.compiler_builtins = Some(cnum);
} }

View file

@ -658,13 +658,13 @@ fn write_out_deps(
boxed_resolver.borrow_mut().access(|resolver| { boxed_resolver.borrow_mut().access(|resolver| {
for cnum in resolver.cstore().crates_untracked() { for cnum in resolver.cstore().crates_untracked() {
let source = resolver.cstore().crate_source_untracked(cnum); 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())); 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())); 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())); files.push(escape_dep_filename(&path.display().to_string()));
} }
} }

View file

@ -120,7 +120,7 @@ crate struct CrateMetadata {
/// How to link (or not link) this crate to the currently compiled crate. /// How to link (or not link) this crate to the currently compiled crate.
dep_kind: Lock<CrateDepKind>, dep_kind: Lock<CrateDepKind>,
/// Filesystem location of this crate. /// Filesystem location of this crate.
source: CrateSource, source: Lrc<CrateSource>,
/// Whether or not this crate should be consider a private dependency /// Whether or not this crate should be consider a private dependency
/// for purposes of the 'exported_private_dependencies' lint /// for purposes of the 'exported_private_dependencies' lint
private_dep: bool, private_dep: bool,
@ -1875,7 +1875,7 @@ impl CrateMetadata {
cnum_map, cnum_map,
dependencies, dependencies,
dep_kind: Lock::new(dep_kind), dep_kind: Lock::new(dep_kind),
source, source: Lrc::new(source),
private_dep, private_dep,
host_hash, host_hash,
extern_crate: Lock::new(None), extern_crate: Lock::new(None),
@ -1903,7 +1903,7 @@ impl CrateMetadata {
} }
crate fn source(&self) -> &CrateSource { crate fn source(&self) -> &CrateSource {
&self.source &*self.source
} }
crate fn dep_kind(&self) -> CrateDepKind { crate fn dep_kind(&self) -> CrateDepKind {

View file

@ -3,7 +3,6 @@ use crate::foreign_modules;
use crate::native_libs; use crate::native_libs;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_data_structures::stable_map::FxHashMap;
use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, CRATE_DEF_INDEX, LOCAL_CRATE};
use rustc_hir::definitions::{DefKey, DefPath, DefPathHash}; 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::fast_reject::SimplifiedType;
use rustc_middle::ty::query::{ExternProviders, Providers}; use rustc_middle::ty::query::{ExternProviders, Providers};
use rustc_middle::ty::{self, TyCtxt, Visibility}; 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::utils::NativeLibKind;
use rustc_session::{Session, StableCrateId}; use rustc_session::{Session, StableCrateId};
use rustc_span::hygiene::{ExpnHash, ExpnId}; use rustc_span::hygiene::{ExpnHash, ExpnId};
@ -179,10 +178,8 @@ provide! { <'tcx> tcx, def_id, other, cdata,
reachable_non_generics reachable_non_generics
} }
native_libraries => { Lrc::new(cdata.get_native_libraries(tcx.sess).collect()) } native_libraries => { cdata.get_native_libraries(tcx.sess).collect() }
foreign_modules => { foreign_modules => { cdata.get_foreign_modules(tcx.sess).map(|m| (m.def_id, m)).collect() }
Lrc::new(cdata.get_foreign_modules(tcx.sess).map(|m| (m.def_id, m)).collect())
}
crate_hash => { cdata.root.hash } crate_hash => { cdata.root.hash }
crate_host_hash => { cdata.host_hash } crate_host_hash => { cdata.host_hash }
crate_name => { cdata.root.name } crate_name => { cdata.root.name }
@ -212,7 +209,7 @@ provide! { <'tcx> tcx, def_id, other, cdata,
r r
} }
used_crate_source => { Lrc::new(cdata.source.clone()) } used_crate_source => { Lrc::clone(&cdata.source) }
exported_symbols => { exported_symbols => {
let syms = cdata.exported_symbols(tcx); let syms = cdata.exported_symbols(tcx);
@ -266,13 +263,11 @@ pub(in crate::rmeta) fn provide(providers: &mut Providers) {
}, },
native_libraries: |tcx, cnum| { native_libraries: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE); assert_eq!(cnum, LOCAL_CRATE);
Lrc::new(native_libs::collect(tcx)) native_libs::collect(tcx)
}, },
foreign_modules: |tcx, cnum| { foreign_modules: |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE); assert_eq!(cnum, LOCAL_CRATE);
let modules: FxHashMap<DefId, ForeignModule> = foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect()
foreign_modules::collect(tcx).into_iter().map(|m| (m.def_id, m)).collect();
Lrc::new(modules)
}, },
// Returns a map from a sufficiently visible external item (i.e., an // 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); 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)), 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) 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() self.get_crate_data(cnum).source.clone()
} }

View file

@ -1742,7 +1742,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
hash: self.tcx.crate_hash(cnum), hash: self.tcx.crate_hash(cnum),
host_hash: self.tcx.crate_host_hash(cnum), host_hash: self.tcx.crate_host_hash(cnum),
kind: self.tcx.dep_kind(cnum), kind: self.tcx.dep_kind(cnum),
extra_filename: self.tcx.extra_filename(cnum), extra_filename: self.tcx.extra_filename(cnum).clone(),
}; };
(cnum, dep) (cnum, dep)
}) })

View file

@ -52,6 +52,9 @@ macro_rules! arena_types {
Vec<rustc_middle::traits::query::OutlivesBound<'tcx>> 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: [] type_op_subtype:
rustc_middle::infer::canonical::Canonical<'tcx, rustc_middle::infer::canonical::Canonical<'tcx,
rustc_middle::infer::canonical::QueryResponse<'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. // This is used to decode the &'tcx [Span] for InlineAsm's line_spans.
[decode] span: rustc_span::Span, [decode] span: rustc_span::Span,
[decode] used_trait_imports: rustc_data_structures::fx::FxHashSet<rustc_hir::def_id::LocalDefId>, [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, [] dep_kind: rustc_middle::dep_graph::DepKindStruct,
]); ]);

View file

@ -29,7 +29,7 @@ pub enum StabilityLevel {
} }
/// An entry in the `depr_map`. /// An entry in the `depr_map`.
#[derive(Clone, HashStable, Debug)] #[derive(Copy, Clone, HashStable, Debug)]
pub struct DeprecationEntry { pub struct DeprecationEntry {
/// The metadata of the attribute associated with this entry. /// The metadata of the attribute associated with this entry.
pub attr: Deprecation, pub attr: Deprecation,

View file

@ -215,7 +215,8 @@ rustc_queries! {
desc { |tcx| "elaborating item bounds for `{}`", tcx.def_path_str(key) } 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" } desc { "looking up the native libraries of a linked crate" }
separate_provide_extern separate_provide_extern
} }
@ -254,6 +255,7 @@ rustc_queries! {
/// Create a THIR tree for debugging. /// Create a THIR tree for debugging.
query thir_tree(key: ty::WithOptConstParam<LocalDefId>) -> String { query thir_tree(key: ty::WithOptConstParam<LocalDefId>) -> String {
no_hash no_hash
storage(ArenaCacheSelector<'tcx>)
desc { |tcx| "constructing THIR tree for `{}`", tcx.def_path_str(key.did.to_def_id()) } 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( query symbols_for_closure_captures(
key: (LocalDefId, DefId) key: (LocalDefId, DefId)
) -> Vec<rustc_span::Symbol> { ) -> Vec<rustc_span::Symbol> {
storage(ArenaCacheSelector<'tcx>)
desc { desc {
|tcx| "symbols for captures of closure `{}` in `{}`", |tcx| "symbols for captures of closure `{}` in `{}`",
tcx.def_path_str(key.1), tcx.def_path_str(key.1),
@ -538,7 +541,7 @@ rustc_queries! {
query adt_dtorck_constraint( query adt_dtorck_constraint(
key: DefId key: DefId
) -> Result<DtorckConstraint<'tcx>, NoSolution> { ) -> Result<&'tcx DtorckConstraint<'tcx>, NoSolution> {
desc { |tcx| "computing drop-check constraints for `{}`", tcx.def_path_str(key) } 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 /// The map returned for `tcx.impl_item_implementor_ids(impl_id)` would be
///`{ trait_f: impl_f, trait_g: impl_g }` ///`{ trait_f: impl_f, trait_g: impl_g }`
query impl_item_implementor_ids(impl_id: DefId) -> FxHashMap<DefId, DefId> { 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>) 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. /// 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. /// Gets the rendered value of the specified constant or associated constant.
/// Used by rustdoc. /// Used by rustdoc.
query rendered_const(def_id: DefId) -> String { query rendered_const(def_id: DefId) -> String {
storage(ArenaCacheSelector<'tcx>)
desc { |tcx| "rendering constant intializer of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "rendering constant intializer of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern separate_provide_extern
} }
@ -1091,7 +1095,7 @@ rustc_queries! {
query codegen_fulfill_obligation( query codegen_fulfill_obligation(
key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>) key: (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'tcx>)
) -> Result<ImplSource<'tcx, ()>, ErrorReported> { ) -> Result<&'tcx ImplSource<'tcx, ()>, ErrorReported> {
cache_on_disk_if { true } cache_on_disk_if { true }
desc { |tcx| desc { |tcx|
"checking if `{}` fulfills its obligations", "checking if `{}` fulfills its obligations",
@ -1237,6 +1241,7 @@ rustc_queries! {
} }
query dependency_formats(_: ()) -> Lrc<crate::middle::dependency_format::Dependencies> { query dependency_formats(_: ()) -> Lrc<crate::middle::dependency_format::Dependencies> {
storage(ArenaCacheSelector<'tcx>)
desc { "get the linkage format of all dependencies" } desc { "get the linkage format of all dependencies" }
} }
@ -1369,13 +1374,15 @@ rustc_queries! {
/// You likely want to call `Instance::upstream_monomorphization()` /// You likely want to call `Instance::upstream_monomorphization()`
/// instead of invoking this query directly. /// instead of invoking this query directly.
query upstream_monomorphizations_for(def_id: DefId) query upstream_monomorphizations_for(def_id: DefId)
-> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>> { -> Option<&'tcx FxHashMap<SubstsRef<'tcx>, CrateNum>>
desc { |tcx| {
"collecting available upstream monomorphizations for `{}`", storage(ArenaCacheSelector<'tcx>)
tcx.def_path_str(def_id), desc { |tcx|
} "collecting available upstream monomorphizations for `{}`",
separate_provide_extern tcx.def_path_str(def_id),
} }
separate_provide_extern
}
/// Returns the upstream crate that exports drop-glue for the given /// Returns the upstream crate that exports drop-glue for the given
/// type (`substs` is expected to be a single-item list containing the /// 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 } 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" } desc { "looking up the foreign modules of a linked crate" }
separate_provide_extern separate_provide_extern
} }
@ -1422,11 +1430,13 @@ rustc_queries! {
separate_provide_extern separate_provide_extern
} }
query extra_filename(_: CrateNum) -> String { query extra_filename(_: CrateNum) -> String {
storage(ArenaCacheSelector<'tcx>)
eval_always eval_always
desc { "looking up the extra filename for a crate" } desc { "looking up the extra filename for a crate" }
separate_provide_extern separate_provide_extern
} }
query crate_extern_paths(_: CrateNum) -> Vec<PathBuf> { query crate_extern_paths(_: CrateNum) -> Vec<PathBuf> {
storage(ArenaCacheSelector<'tcx>)
eval_always eval_always
desc { "looking up the paths for extern crates" } desc { "looking up the paths for extern crates" }
separate_provide_extern separate_provide_extern
@ -1478,8 +1488,7 @@ rustc_queries! {
/// for each parameter if a trait object were to be passed for that parameter. /// 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 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]`. /// For `struct Foo<'a, T: 'a, U>`, this would instead be `['a, 'static]`.
query object_lifetime_defaults_map(_: LocalDefId) query object_lifetime_defaults(_: LocalDefId) -> Option<&'tcx [ObjectLifetimeDefault]> {
-> Option<Vec<ObjectLifetimeDefault>> {
desc { "looking up lifetime defaults for a region on an item" } desc { "looking up lifetime defaults for a region on an item" }
} }
query late_bound_vars_map(_: LocalDefId) query late_bound_vars_map(_: LocalDefId)
@ -1488,6 +1497,7 @@ rustc_queries! {
} }
query lifetime_scope_map(_: LocalDefId) -> Option<FxHashMap<ItemLocalId, LifetimeScopeForPath>> { query lifetime_scope_map(_: LocalDefId) -> Option<FxHashMap<ItemLocalId, LifetimeScopeForPath>> {
storage(ArenaCacheSelector<'tcx>)
desc { "finds the lifetime scope for an HirId of a PathSegment" } desc { "finds the lifetime scope for an HirId of a PathSegment" }
} }
@ -1501,7 +1511,7 @@ rustc_queries! {
/// check whether the forest is empty. /// check whether the forest is empty.
query type_uninhabited_from( query type_uninhabited_from(
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>> key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>
) -> ty::inhabitedness::DefIdForest { ) -> ty::inhabitedness::DefIdForest<'tcx> {
desc { "computing the inhabitedness of `{:?}`", key } desc { "computing the inhabitedness of `{:?}`", key }
remap_env_constness remap_env_constness
} }
@ -1566,7 +1576,8 @@ rustc_queries! {
desc { "calculating the missing lang items in a crate" } desc { "calculating the missing lang items in a crate" }
separate_provide_extern 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" } desc { "calculating the visible parent map" }
} }
query trimmed_def_paths(_: ()) -> FxHashMap<DefId, Symbol> { query trimmed_def_paths(_: ()) -> FxHashMap<DefId, Symbol> {
@ -1579,6 +1590,7 @@ rustc_queries! {
separate_provide_extern separate_provide_extern
} }
query used_crate_source(_: CrateNum) -> Lrc<CrateSource> { query used_crate_source(_: CrateNum) -> Lrc<CrateSource> {
storage(ArenaCacheSelector<'tcx>)
eval_always eval_always
desc { "looking at the source for a crate" } desc { "looking at the source for a crate" }
separate_provide_extern separate_provide_extern
@ -1669,7 +1681,11 @@ rustc_queries! {
desc { "optimization level used by backend" } 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 eval_always
desc { "output_filenames" } desc { "output_filenames" }
} }
@ -1911,6 +1927,7 @@ rustc_queries! {
/// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine, /// all of the cases that the normal `ty::Ty`-based wfcheck does. This is fine,
/// because the `ty::Ty`-based wfcheck is always run. /// because the `ty::Ty`-based wfcheck is always run.
query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, traits::WellFormedLoc)) -> Option<traits::ObligationCause<'tcx>> { query diagnostic_hir_wf_check(key: (ty::Predicate<'tcx>, traits::WellFormedLoc)) -> Option<traits::ObligationCause<'tcx>> {
storage(ArenaCacheSelector<'tcx>)
eval_always eval_always
no_hash no_hash
desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 } desc { "performing HIR wf-checking for predicate {:?} at item {:?}", key.0, key.1 }

View file

@ -11,7 +11,6 @@ use crate::ty::subst::GenericArg;
use crate::ty::{self, Ty, TyCtxt}; use crate::ty::{self, Ty, TyCtxt};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
use rustc_data_structures::sync::Lrc;
use rustc_errors::struct_span_err; use rustc_errors::struct_span_err;
use rustc_query_system::ich::StableHashingContext; use rustc_query_system::ich::StableHashingContext;
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
@ -97,7 +96,7 @@ pub type CanonicalTypeOpProvePredicateGoal<'tcx> =
pub type CanonicalTypeOpNormalizeGoal<'tcx, T> = pub type CanonicalTypeOpNormalizeGoal<'tcx, T> =
Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>; Canonical<'tcx, ty::ParamEnvAnd<'tcx, type_op::Normalize<T>>>;
#[derive(Clone, Debug, HashStable)] #[derive(Copy, Clone, Debug, HashStable)]
pub struct NoSolution; pub struct NoSolution;
pub type Fallible<T> = Result<T, NoSolution>; pub type Fallible<T> = Result<T, NoSolution>;
@ -191,12 +190,12 @@ pub struct CandidateStep<'tcx> {
pub unsize: bool, pub unsize: bool,
} }
#[derive(Clone, Debug, HashStable)] #[derive(Copy, Clone, Debug, HashStable)]
pub struct MethodAutoderefStepsResult<'tcx> { pub struct MethodAutoderefStepsResult<'tcx> {
/// The valid autoderef steps that could be find. /// 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. /// 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 /// If `true`, `steps` has been truncated due to reaching the
/// recursion limit. /// recursion limit.
pub reached_recursion_limit: bool, pub reached_recursion_limit: bool,

View file

@ -26,7 +26,7 @@ use super::{
Destructor, FieldDef, GenericPredicates, ReprOptions, Ty, TyCtxt, VariantDef, VariantDiscr, 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>]); pub struct AdtSizedConstraint<'tcx>(pub &'tcx [Ty<'tcx>]);
bitflags! { bitflags! {

View file

@ -13,6 +13,7 @@ use crate::mir::{
interpret::{AllocId, Allocation}, interpret::{AllocId, Allocation},
}; };
use crate::thir; use crate::thir;
use crate::traits;
use crate::ty::subst::SubstsRef; use crate::ty::subst::SubstsRef;
use crate::ty::{self, Ty, TyCtxt}; use crate::ty::{self, Ty, TyCtxt};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
@ -156,6 +157,7 @@ macro_rules! encodable_via_deref {
encodable_via_deref! { encodable_via_deref! {
&'tcx ty::TypeckResults<'tcx>, &'tcx ty::TypeckResults<'tcx>,
ty::Region<'tcx>, ty::Region<'tcx>,
&'tcx traits::ImplSource<'tcx, ()>,
&'tcx mir::Body<'tcx>, &'tcx mir::Body<'tcx>,
&'tcx mir::UnsafetyCheckResult, &'tcx mir::UnsafetyCheckResult,
&'tcx mir::BorrowCheckResult<'tcx>, &'tcx mir::BorrowCheckResult<'tcx>,
@ -385,6 +387,7 @@ impl_decodable_via_ref! {
&'tcx ty::TypeckResults<'tcx>, &'tcx ty::TypeckResults<'tcx>,
&'tcx ty::List<Ty<'tcx>>, &'tcx ty::List<Ty<'tcx>>,
&'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>, &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
&'tcx traits::ImplSource<'tcx, ()>,
&'tcx Allocation, &'tcx Allocation,
&'tcx mir::Body<'tcx>, &'tcx mir::Body<'tcx>,
&'tcx mir::UnsafetyCheckResult, &'tcx mir::UnsafetyCheckResult,

View file

@ -5,7 +5,7 @@ use crate::dep_graph::{DepGraph, DepKind, DepKindStruct};
use crate::hir::place::Place as HirPlace; use crate::hir::place::Place as HirPlace;
use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos}; use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource}; 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::middle::stability;
use crate::mir::interpret::{self, Allocation, ConstValue, Scalar}; use crate::mir::interpret::{self, Allocation, ConstValue, Scalar};
use crate::mir::{Body, Field, Local, Place, PlaceElem, ProjectionKind, Promoted}; 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)) .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> { pub fn late_bound_vars(self, id: HirId) -> &'tcx List<ty::BoundVariableKind> {
self.mk_bound_variable_kinds( self.mk_bound_variable_kinds(
self.late_bound_vars_map(id.owner) self.late_bound_vars_map(id.owner)
@ -2728,8 +2724,8 @@ impl<'tcx> TyCtxt<'tcx> {
) )
} }
pub fn lifetime_scope(self, id: HirId) -> Option<LifetimeScopeForPath> { pub fn lifetime_scope(self, id: HirId) -> Option<&'tcx LifetimeScopeForPath> {
self.lifetime_scope_map(id.owner).and_then(|mut map| map.remove(&id.local_id)) 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 /// 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()); |tcx, id| tcx.stability().local_deprecation_entry(id.expect_local());
providers.extern_mod_stmt_cnum = providers.extern_mod_stmt_cnum =
|tcx, id| tcx.resolutions(()).extern_crate_map.get(&id).cloned(); |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.features_query = |tcx, ()| tcx.sess.features_untracked();
providers.is_panic_runtime = |tcx, cnum| { providers.is_panic_runtime = |tcx, cnum| {
assert_eq!(cnum, LOCAL_CRATE); assert_eq!(cnum, LOCAL_CRATE);

View file

@ -3,7 +3,6 @@ use crate::ty::{DefId, DefIdTree};
use rustc_span::def_id::CRATE_DEF_ID; use rustc_span::def_id::CRATE_DEF_ID;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::mem; use std::mem;
use std::sync::Arc;
use DefIdForest::*; 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 /// 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 /// `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. /// used with `type_uninhabited_from`, there will very rarely be more than one `DefId` stored.
#[derive(Clone, HashStable, Debug)] #[derive(Copy, Clone, HashStable, Debug)]
pub enum DefIdForest { pub enum DefIdForest<'a> {
Empty, Empty,
Single(DefId), Single(DefId),
/// This variant is very rare. /// This variant is very rare.
/// Invariant: >1 elements /// Invariant: >1 elements
/// We use `Arc` because this is used in the output of a query. Multiple(&'a [DefId]),
Multiple(Arc<[DefId]>),
} }
/// Tests whether a slice of roots contains a given 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)) slice.iter().any(|root_id| tcx.is_descendant_of(id, *root_id))
} }
impl<'tcx> DefIdForest { impl<'tcx> DefIdForest<'tcx> {
/// Creates an empty forest. /// Creates an empty forest.
pub fn empty() -> DefIdForest { pub fn empty() -> DefIdForest<'tcx> {
DefIdForest::Empty DefIdForest::Empty
} }
/// Creates a forest consisting of a single tree representing the entire /// Creates a forest consisting of a single tree representing the entire
/// crate. /// crate.
#[inline] #[inline]
pub fn full() -> DefIdForest { pub fn full() -> DefIdForest<'tcx> {
DefIdForest::from_id(CRATE_DEF_ID.to_def_id()) DefIdForest::from_id(CRATE_DEF_ID.to_def_id())
} }
/// Creates a forest containing a `DefId` and all its descendants. /// 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) DefIdForest::Single(id)
} }
@ -61,11 +59,11 @@ impl<'tcx> DefIdForest {
} }
// Only allocates in the rare `Multiple` case. // Only allocates in the rare `Multiple` case.
fn from_slice(root_ids: &[DefId]) -> DefIdForest { fn from_vec(tcx: TyCtxt<'tcx>, root_ids: SmallVec<[DefId; 1]>) -> DefIdForest<'tcx> {
match root_ids { match &root_ids[..] {
[] => Empty, [] => Empty,
[id] => Single(*id), [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. /// 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 where
I: IntoIterator<Item = DefIdForest>, I: IntoIterator<Item = DefIdForest<'tcx>>,
{ {
let mut iter = iter.into_iter(); let mut iter = iter.into_iter();
let mut ret: SmallVec<[_; 1]> = if let Some(first) = iter.next() { 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); mem::swap(&mut next_ret, &mut ret);
next_ret.clear(); next_ret.clear();
} }
DefIdForest::from_slice(&ret) DefIdForest::from_vec(tcx, ret)
} }
/// Calculate the union of a collection of forests. /// 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 where
I: IntoIterator<Item = DefIdForest>, I: IntoIterator<Item = DefIdForest<'tcx>>,
{ {
let mut ret: SmallVec<[_; 1]> = SmallVec::new(); let mut ret: SmallVec<[_; 1]> = SmallVec::new();
let mut next_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); mem::swap(&mut next_ret, &mut ret);
next_ret.clear(); next_ret.clear();
} }
DefIdForest::from_slice(&ret) DefIdForest::from_vec(tcx, ret)
} }
} }

View file

@ -112,7 +112,7 @@ impl<'tcx> AdtDef {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> DefIdForest { ) -> DefIdForest<'tcx> {
// Non-exhaustive ADTs from other crates are always considered inhabited. // Non-exhaustive ADTs from other crates are always considered inhabited.
if self.is_variant_list_non_exhaustive() && !self.did.is_local() { if self.is_variant_list_non_exhaustive() && !self.did.is_local() {
DefIdForest::empty() DefIdForest::empty()
@ -135,7 +135,7 @@ impl<'tcx> VariantDef {
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
adt_kind: AdtKind, adt_kind: AdtKind,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> DefIdForest { ) -> DefIdForest<'tcx> {
let is_enum = match adt_kind { let is_enum = match adt_kind {
// For now, `union`s are never considered uninhabited. // For now, `union`s are never considered uninhabited.
// The precise semantics of inhabitedness with respect to unions is currently undecided. // The precise semantics of inhabitedness with respect to unions is currently undecided.
@ -163,7 +163,7 @@ impl<'tcx> FieldDef {
substs: SubstsRef<'tcx>, substs: SubstsRef<'tcx>,
is_enum: bool, is_enum: bool,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> DefIdForest { ) -> DefIdForest<'tcx> {
let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx, param_env); let data_uninhabitedness = move || self.ty(tcx, substs).uninhabited_from(tcx, param_env);
// FIXME(canndrew): Currently enum fields are (incorrectly) stored with // FIXME(canndrew): Currently enum fields are (incorrectly) stored with
// `Visibility::Invisible` so we need to override `self.vis` if we're // `Visibility::Invisible` so we need to override `self.vis` if we're
@ -190,8 +190,8 @@ impl<'tcx> TyS<'tcx> {
&'tcx self, &'tcx self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> DefIdForest { ) -> DefIdForest<'tcx> {
tcx.type_uninhabited_from(param_env.and(self)) tcx.type_uninhabited_from(param_env.and(self)).clone()
} }
} }
@ -199,7 +199,7 @@ impl<'tcx> TyS<'tcx> {
pub(crate) fn type_uninhabited_from<'tcx>( pub(crate) fn type_uninhabited_from<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>, key: ty::ParamEnvAnd<'tcx, Ty<'tcx>>,
) -> DefIdForest { ) -> DefIdForest<'tcx> {
let ty = key.value; let ty = key.value;
let param_env = key.param_env; let param_env = key.param_env;
match *ty.kind() { match *ty.kind() {

View file

@ -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`. /// Error produced by attempting to compute or adjust a `FnAbi`.
#[derive(Clone, Debug, HashStable)] #[derive(Copy, Clone, Debug, HashStable)]
pub enum FnAbiError<'tcx> { pub enum FnAbiError<'tcx> {
/// Error produced by a `layout_of` call, while computing `FnAbi` initially. /// Error produced by a `layout_of` call, while computing `FnAbi` initially.
Layout(LayoutError<'tcx>), Layout(LayoutError<'tcx>),

View file

@ -106,6 +106,12 @@ impl<'tcx> TyCtxt<'tcx> {
#[inline(always)] #[inline(always)]
fn noop<T>(_: &T) {} 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 { macro_rules! query_helper_param_ty {
(DefId) => { impl IntoQueryParam<DefId> }; (DefId) => { impl IntoQueryParam<DefId> };
($K:ty) => { $K }; ($K:ty) => { $K };
@ -243,7 +249,7 @@ macro_rules! define_callbacks {
let key = key.into_query_param(); let key = key.into_query_param();
opt_remap_env_constness!([$($modifiers)*][key]); 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 { let lookup = match cached {
Ok(value) => return value, 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 { impl IntoQueryParam<DefId> for LocalDefId {
#[inline(always)] #[inline(always)]
fn into_query_param(self) -> DefId { fn into_query_param(self) -> DefId {

View file

@ -935,7 +935,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
}; };
self.var_debug_info.push(VarDebugInfo { self.var_debug_info.push(VarDebugInfo {
name: sym, name: *sym,
source_info: SourceInfo::outermost(tcx_hir.span(var_id)), source_info: SourceInfo::outermost(tcx_hir.span(var_id)),
value: VarDebugInfoContents::Place(Place { value: VarDebugInfoContents::Place(Place {
local: ty::CAPTURE_STRUCT_LOCAL, local: ty::CAPTURE_STRUCT_LOCAL,

View file

@ -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), named_region_map: |tcx, id| resolve_lifetimes_for(tcx, id).defs.get(&id),
is_late_bound_map, 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), Some(Node::Item(item)) => compute_object_lifetime_defaults(tcx, item),
_ => None, _ => None,
}, },
@ -1673,10 +1673,10 @@ fn extract_labels(ctxt: &mut LifetimeContext<'_, '_>, body: &hir::Body<'_>) {
} }
} }
fn compute_object_lifetime_defaults( fn compute_object_lifetime_defaults<'tcx>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
item: &hir::Item<'_>, item: &hir::Item<'_>,
) -> Option<Vec<ObjectLifetimeDefault>> { ) -> Option<&'tcx [ObjectLifetimeDefault]> {
match item.kind { match item.kind {
hir::ItemKind::Struct(_, ref generics) hir::ItemKind::Struct(_, ref generics)
| hir::ItemKind::Union(_, 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 /// Scan the bounds and where-clauses on parameters to extract bounds
/// of the form `T:'a` so as to determine the `ObjectLifetimeDefault` /// of the form `T:'a` so as to determine the `ObjectLifetimeDefault`
/// for each type parameter. /// for each type parameter.
fn object_lifetime_defaults_for_item( fn object_lifetime_defaults_for_item<'tcx>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'tcx>,
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
) -> Vec<ObjectLifetimeDefault> { ) -> &'tcx [ObjectLifetimeDefault] {
fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound<'_>]) { fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::GenericBound<'_>]) {
for bound in bounds { for bound in bounds {
if let hir::GenericBound::Outlives(ref lifetime) = *bound { if let hir::GenericBound::Outlives(ref lifetime) = *bound {
@ -1741,81 +1741,75 @@ fn object_lifetime_defaults_for_item(
} }
} }
generics let process_param = |param: &hir::GenericParam<'_>| match param.kind {
.params GenericParamKind::Lifetime { .. } => None,
.iter() GenericParamKind::Type { .. } => {
.filter_map(|param| match param.kind { let mut set = Set1::Empty;
GenericParamKind::Lifetime { .. } => None,
GenericParamKind::Type { .. } => {
let mut set = Set1::Empty;
add_bounds(&mut set, &param.bounds); add_bounds(&mut set, &param.bounds);
let param_def_id = tcx.hir().local_def_id(param.hir_id); let param_def_id = tcx.hir().local_def_id(param.hir_id);
for predicate in generics.where_clause.predicates { for predicate in generics.where_clause.predicates {
// Look for `type: ...` where clauses. // Look for `type: ...` where clauses.
let data = match *predicate { let data = match *predicate {
hir::WherePredicate::BoundPredicate(ref data) => data, hir::WherePredicate::BoundPredicate(ref data) => data,
_ => continue, _ => continue,
}; };
// Ignore `for<'a> type: ...` as they can change what // Ignore `for<'a> type: ...` as they can change what
// lifetimes mean (although we could "just" handle it). // lifetimes mean (although we could "just" handle it).
if !data.bound_generic_params.is_empty() { if !data.bound_generic_params.is_empty() {
continue; continue;
}
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);
}
} }
Some(match set { let res = match data.bounded_ty.kind {
Set1::Empty => Set1::Empty, hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.res,
Set1::One(name) => { _ => continue,
if name == hir::LifetimeName::Static { };
Set1::One(Region::Static)
} else { if res == Res::Def(DefKind::TyParam, param_def_id.to_def_id()) {
generics add_bounds(&mut set, &data.bounds);
.params }
.iter() }
.filter_map(|param| match param.kind {
GenericParamKind::Lifetime { .. } => Some(( Some(match set {
param.hir_id, Set1::Empty => Set1::Empty,
hir::LifetimeName::Param(param.name), Set1::One(name) => {
LifetimeDefOrigin::from_param(param), if name == hir::LifetimeName::Static {
)), Set1::One(Region::Static)
_ => None, } else {
}) generics
.enumerate() .params
.find(|&(_, (_, lt_name, _))| lt_name == name) .iter()
.map_or(Set1::Many, |(i, (id, _, origin))| { .filter_map(|param| match param.kind {
let def_id = tcx.hir().local_def_id(id); GenericParamKind::Lifetime { .. } => Some((
Set1::One(Region::EarlyBound( param.hir_id,
i as u32, hir::LifetimeName::Param(param.name),
def_id.to_def_id(), LifetimeDefOrigin::from_param(param),
origin, )),
)) _ => 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, }
}) Set1::Many => Set1::Many,
} })
GenericParamKind::Const { .. } => { }
// Generic consts don't impose any constraints. GenericParamKind::Const { .. } => {
// // Generic consts don't impose any constraints.
// We still store a dummy value here to allow generic parameters //
// in an arbitrary order. // We still store a dummy value here to allow generic parameters
Some(Set1::Empty) // in an arbitrary order.
} Some(Set1::Empty)
}) }
.collect() };
tcx.arena.alloc_from_iter(generics.params.iter().filter_map(process_param))
} }
impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { 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() { if let Some(def_id) = def_id.as_local() {
let id = self.tcx.hir().local_def_id_to_hir_id(def_id); 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 { } else {
let tcx = self.tcx; let tcx = self.tcx;
self.xcrate_object_lifetime_defaults self.xcrate_object_lifetime_defaults

View file

@ -1,6 +1,7 @@
use crate::abi::{self, Abi, Align, FieldsShape, Size}; use crate::abi::{self, Abi, Align, FieldsShape, Size};
use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout}; use crate::abi::{HasDataLayout, TyAbiInterface, TyAndLayout};
use crate::spec::{self, HasTargetSpec}; use crate::spec::{self, HasTargetSpec};
use rustc_span::Symbol;
use std::fmt; use std::fmt;
mod aarch64; mod aarch64;
@ -623,10 +624,10 @@ pub struct FnAbi<'a, Ty> {
} }
/// Error produced by attempting to adjust a `FnAbi`, for a "foreign" ABI. /// 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 { pub enum AdjustForForeignAbiError {
/// Target architecture doesn't support "foreign" (i.e. non-Rust) ABIs. /// 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 { impl fmt::Display for AdjustForForeignAbiError {
@ -703,7 +704,10 @@ impl<'a, Ty> FnAbi<'a, Ty> {
"asmjs" => wasm::compute_c_abi_info(cx, self), "asmjs" => wasm::compute_c_abi_info(cx, self),
"bpf" => bpf::compute_abi_info(self), "bpf" => bpf::compute_abi_info(self),
arch => { arch => {
return Err(AdjustForForeignAbiError::Unsupported { arch: arch.to_string(), abi }); return Err(AdjustForForeignAbiError::Unsupported {
arch: Symbol::intern(arch),
abi,
});
} }
} }

View file

@ -22,7 +22,7 @@ use rustc_middle::ty::{self, TyCtxt};
pub fn codegen_fulfill_obligation<'tcx>( pub fn codegen_fulfill_obligation<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
(param_env, trait_ref): (ty::ParamEnv<'tcx>, ty::PolyTraitRef<'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. // Remove any references to regions; this helps improve caching.
let trait_ref = tcx.erase_regions(trait_ref); let trait_ref = tcx.erase_regions(trait_ref);
// We expect the input to be fully normalized. // 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()); drop(infcx.inner.borrow_mut().opaque_type_storage.take_opaque_types());
debug!("Cache miss: {:?} => {:?}", trait_ref, impl_source); debug!("Cache miss: {:?} => {:?}", trait_ref, impl_source);
Ok(impl_source) Ok(&*tcx.arena.alloc(impl_source))
}) })
} }

View file

@ -262,7 +262,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
.tcx .tcx
.diagnostic_hir_wf_check((tcx.erase_regions(obligation.predicate), *wf_loc)) .diagnostic_hir_wf_check((tcx.erase_regions(obligation.predicate), *wf_loc))
{ {
obligation.cause = cause; obligation.cause = cause.clone();
span = obligation.cause.span; span = obligation.cause.span;
} }
} }

View file

@ -278,9 +278,9 @@ fn dtorck_constraint_for_ty<'tcx>(
tcx.at(span).adt_dtorck_constraint(def.did)?; tcx.at(span).adt_dtorck_constraint(def.did)?;
// FIXME: we can try to recursively `dtorck_constraint_on_ty` // FIXME: we can try to recursively `dtorck_constraint_on_ty`
// there, but that needs some way to handle cycles. // there, but that needs some way to handle cycles.
constraints.dtorck_types.extend(dtorck_types.subst(tcx, substs)); constraints.dtorck_types.extend(dtorck_types.iter().map(|t| t.subst(tcx, substs)));
constraints.outlives.extend(outlives.subst(tcx, substs)); constraints.outlives.extend(outlives.iter().map(|t| t.subst(tcx, substs)));
constraints.overflows.extend(overflows.subst(tcx, substs)); constraints.overflows.extend(overflows.iter().map(|t| t.subst(tcx, substs)));
} }
// Objects must be alive in order for their destructor // Objects must be alive in order for their destructor
@ -308,7 +308,7 @@ fn dtorck_constraint_for_ty<'tcx>(
crate fn adt_dtorck_constraint( crate fn adt_dtorck_constraint(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
def_id: DefId, def_id: DefId,
) -> Result<DtorckConstraint<'_>, NoSolution> { ) -> Result<&DtorckConstraint<'_>, NoSolution> {
let def = tcx.adt_def(def_id); let def = tcx.adt_def(def_id);
let span = tcx.def_span(def_id); let span = tcx.def_span(def_id);
debug!("dtorck_constraint: {:?}", def); debug!("dtorck_constraint: {:?}", def);
@ -324,7 +324,7 @@ crate fn adt_dtorck_constraint(
overflows: vec![], overflows: vec![],
}; };
debug!("dtorck_constraint: {:?} => {:?}", def, result); debug!("dtorck_constraint: {:?} => {:?}", def, result);
return Ok(result); return Ok(tcx.arena.alloc(result));
} }
let mut result = DtorckConstraint::empty(); let mut result = DtorckConstraint::empty();
@ -337,7 +337,7 @@ crate fn adt_dtorck_constraint(
debug!("dtorck_constraint: {:?} => {:?}", def, result); debug!("dtorck_constraint: {:?} => {:?}", def, result);
Ok(result) Ok(tcx.arena.alloc(result))
} }
fn dedup_dtorck_constraint(c: &mut DtorckConstraint<'_>) { fn dedup_dtorck_constraint(c: &mut DtorckConstraint<'_>) {

View file

@ -9,7 +9,6 @@ use crate::hir::def::DefKind;
use crate::hir::def_id::DefId; use crate::hir::def_id::DefId;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::sync::Lrc;
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Namespace; use rustc_hir::def::Namespace;
@ -59,7 +58,7 @@ struct ProbeContext<'a, 'tcx> {
/// This is the OriginalQueryValues for the steps queries /// This is the OriginalQueryValues for the steps queries
/// that are answered in steps. /// that are answered in steps.
orig_steps_var_values: OriginalQueryValues<'tcx>, orig_steps_var_values: OriginalQueryValues<'tcx>,
steps: Lrc<Vec<CandidateStep<'tcx>>>, steps: &'tcx [CandidateStep<'tcx>],
inherent_candidates: Vec<Candidate<'tcx>>, inherent_candidates: Vec<Candidate<'tcx>>,
extension_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 param_env_and_self_ty, self_ty
); );
MethodAutoderefStepsResult { MethodAutoderefStepsResult {
steps: Lrc::new(vec![CandidateStep { steps: infcx.tcx.arena.alloc_from_iter([CandidateStep {
self_ty: self.make_query_response_ignoring_pending_obligations( self_ty: self.make_query_response_ignoring_pending_obligations(
canonical_inference_vars, canonical_inference_vars,
self_ty, self_ty,
@ -533,8 +532,8 @@ fn method_autoderef_steps<'tcx>(
debug!("method_autoderef_steps: steps={:?} opt_bad_ty={:?}", steps, opt_bad_ty); debug!("method_autoderef_steps: steps={:?} opt_bad_ty={:?}", steps, opt_bad_ty);
MethodAutoderefStepsResult { MethodAutoderefStepsResult {
steps: Lrc::new(steps), steps: tcx.arena.alloc_from_iter(steps),
opt_bad_ty: opt_bad_ty.map(Lrc::new), opt_bad_ty: opt_bad_ty.map(|ty| &*tcx.arena.alloc(ty)),
reached_recursion_limit: autoderef.reached_recursion_limit(), reached_recursion_limit: autoderef.reached_recursion_limit(),
} }
}) })
@ -548,7 +547,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
method_name: Option<Ident>, method_name: Option<Ident>,
return_type: Option<Ty<'tcx>>, return_type: Option<Ty<'tcx>>,
orig_steps_var_values: OriginalQueryValues<'tcx>, orig_steps_var_values: OriginalQueryValues<'tcx>,
steps: Lrc<Vec<CandidateStep<'tcx>>>, steps: &'tcx [CandidateStep<'tcx>],
is_suggestion: IsSuggestion, is_suggestion: IsSuggestion,
scope_expr_id: hir::HirId, scope_expr_id: hir::HirId,
) -> ProbeContext<'a, 'tcx> { ) -> ProbeContext<'a, 'tcx> {
@ -605,8 +604,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
} }
fn assemble_inherent_candidates(&mut self) { fn assemble_inherent_candidates(&mut self) {
let steps = Lrc::clone(&self.steps); for step in self.steps.iter() {
for step in steps.iter() {
self.assemble_probe(&step.self_ty); self.assemble_probe(&step.self_ty);
} }
} }

View file

@ -1696,7 +1696,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::Generics {
kind: ty::GenericParamDefKind::Lifetime, 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. // Now create the real type and const parameters.
let type_start = own_start - has_self as u32 + params.len() as u32; let type_start = own_start - has_self as u32 + params.len() as u32;

View file

@ -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); let hir_id = tcx.hir().local_def_id_to_hir_id(did);
rustc_hir_pretty::id_to_string(&tcx.hir(), hir_id) rustc_hir_pretty::id_to_string(&tcx.hir(), hir_id)
} else { } else {
tcx.rendered_const(did) tcx.rendered_const(did).clone()
} }
} }