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:
commit
56cd04af5c
27 changed files with 208 additions and 182 deletions
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
})
|
})
|
||||||
|
|
|
@ -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,
|
||||||
]);
|
]);
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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 }
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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! {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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>),
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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, ¶m.bounds);
|
add_bounds(&mut set, ¶m.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
|
||||||
|
|
|
@ -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,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<'_>) {
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue