]> git.proxmox.com Git - rustc.git/blame - src/librustc_middle/ty/query/mod.rs
New upstream version 1.46.0~beta.2+dfsg1
[rustc.git] / src / librustc_middle / ty / query / mod.rs
CommitLineData
f9f354fc 1use crate::dep_graph::{self, DepNode, DepNodeParams};
dfeec247 2use crate::hir::exports::Export;
ba9703b0 3use crate::hir::map;
9fa01778 4use crate::infer::canonical::{self, Canonical};
dfeec247
XL
5use crate::lint::LintLevelMap;
6use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
f9f354fc
XL
7use crate::middle::cstore::{CrateSource, DepKind};
8use crate::middle::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
dfeec247 9use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
dfeec247 10use crate::middle::lib_features::LibFeatures;
9fa01778 11use crate::middle::privacy::AccessLevels;
9fa01778 12use crate::middle::region;
dfeec247 13use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
9fa01778 14use crate::middle::stability::{self, DeprecationEntry};
9fa01778
XL
15use crate::mir;
16use crate::mir::interpret::GlobalId;
74b04a01 17use crate::mir::interpret::{ConstEvalRawResult, ConstEvalResult, ConstValue};
dfeec247
XL
18use crate::mir::interpret::{LitToConstError, LitToConstInput};
19use crate::mir::mono::CodegenUnit;
dfeec247
XL
20use crate::traits::query::{
21 CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
22 CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
23 CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution,
24};
74b04a01
XL
25use crate::traits::query::{
26 DropckOutlivesResult, DtorckConstraint, MethodAutoderefStepsResult, NormalizationResult,
27 OutlivesBound,
28};
9fa01778 29use crate::traits::specialization_graph;
f035d41b 30use crate::traits::{self, ImplSource};
9fa01778 31use crate::ty::steal::Steal;
ba9703b0 32use crate::ty::subst::{GenericArg, SubstsRef};
74b04a01 33use crate::ty::util::AlwaysRequiresDrop;
dfeec247 34use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
dfeec247
XL
35use rustc_data_structures::fingerprint::Fingerprint;
36use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
60c5eb7d 37use rustc_data_structures::profiling::ProfileCategory::*;
ea8adc8c 38use rustc_data_structures::stable_hasher::StableVec;
dfeec247 39use rustc_data_structures::svh::Svh;
0bf4aa26 40use rustc_data_structures::sync::Lrc;
ba9703b0 41use rustc_errors::ErrorReported;
dfeec247
XL
42use rustc_hir as hir;
43use rustc_hir::def::DefKind;
ba9703b0
XL
44use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
45use rustc_hir::lang_items::{LangItem, LanguageItems};
74b04a01 46use rustc_hir::{Crate, HirIdSet, ItemLocalId, TraitCandidate};
dfeec247 47use rustc_index::vec::IndexVec;
ba9703b0 48use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
f9f354fc 49use rustc_session::utils::NativeLibKind;
ba9703b0 50use rustc_session::CrateDisambiguator;
0bf4aa26 51use rustc_target::spec::PanicStrategy;
ea8adc8c 52
74b04a01
XL
53use rustc_ast::ast;
54use rustc_attr as attr;
dfeec247
XL
55use rustc_span::symbol::Symbol;
56use rustc_span::{Span, DUMMY_SP};
0bf4aa26 57use std::borrow::Cow;
ba9703b0 58use std::collections::BTreeMap;
ea8adc8c 59use std::ops::Deref;
f035d41b 60use std::path::PathBuf;
ea8adc8c 61use std::sync::Arc;
ea8adc8c
XL
62
63#[macro_use]
64mod plumbing;
ba9703b0
XL
65pub(crate) use rustc_query_system::query::CycleError;
66use rustc_query_system::query::*;
74b04a01
XL
67
68mod stats;
69pub use self::stats::print_stats;
ea8adc8c 70
ba9703b0 71#[cfg(parallel_compiler)]
83c7162d 72mod job;
9fa01778 73#[cfg(parallel_compiler)]
94b46f34 74pub use self::job::handle_deadlock;
ba9703b0 75pub use rustc_query_system::query::{QueryInfo, QueryJob, QueryJobId};
83c7162d 76
ea8adc8c 77mod keys;
94b46f34 78use self::keys::Key;
ea8adc8c
XL
79
80mod values;
81use self::values::Value;
82
ba9703b0
XL
83use rustc_query_system::query::QueryAccessors;
84pub use rustc_query_system::query::QueryConfig;
85pub(crate) use rustc_query_system::query::QueryDescription;
ea8adc8c 86
abe05a73
XL
87mod on_disk_cache;
88pub use self::on_disk_cache::OnDiskCache;
89
dfeec247
XL
90mod profiling_support;
91pub use self::profiling_support::{IntoSelfProfilingString, QueryKeyStringBuilder};
92
532ac7d7 93// Each of these queries corresponds to a function pointer field in the
94b46f34
XL
94// `Providers` struct for requesting a value of that type, and a method
95// on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
96// which memoizes and does dep-graph tracking, wrapping around the actual
97// `Providers` that the driver creates (using several `rustc_*` crates).
0531ce1d 98//
94b46f34
XL
99// The result type of each query must implement `Clone`, and additionally
100// `ty::query::values::Value`, which produces an appropriate placeholder
101// (error) value if the query resulted in a query cycle.
102// Queries marked with `fatal_cycle` do not need the latter implementation,
0531ce1d 103// as they will raise an fatal error on query cycles instead.
8faf50e0 104
74b04a01
XL
105rustc_query_append! { [define_queries!][<'tcx>] }
106
107/// The red/green evaluation system will try to mark a specific DepNode in the
108/// dependency graph as green by recursively trying to mark the dependencies of
109/// that `DepNode` as green. While doing so, it will sometimes encounter a `DepNode`
110/// where we don't know if it is red or green and we therefore actually have
111/// to recompute its value in order to find out. Since the only piece of
112/// information that we have at that point is the `DepNode` we are trying to
113/// re-evaluate, we need some way to re-run a query from just that. This is what
114/// `force_from_dep_node()` implements.
115///
116/// In the general case, a `DepNode` consists of a `DepKind` and an opaque
117/// GUID/fingerprint that will uniquely identify the node. This GUID/fingerprint
118/// is usually constructed by computing a stable hash of the query-key that the
119/// `DepNode` corresponds to. Consequently, it is not in general possible to go
120/// back from hash to query-key (since hash functions are not reversible). For
121/// this reason `force_from_dep_node()` is expected to fail from time to time
122/// because we just cannot find out, from the `DepNode` alone, what the
123/// corresponding query-key is and therefore cannot re-run the query.
124///
125/// The system deals with this case letting `try_mark_green` fail which forces
126/// the root query to be re-evaluated.
127///
128/// Now, if `force_from_dep_node()` would always fail, it would be pretty useless.
129/// Fortunately, we can use some contextual information that will allow us to
130/// reconstruct query-keys for certain kinds of `DepNode`s. In particular, we
131/// enforce by construction that the GUID/fingerprint of certain `DepNode`s is a
132/// valid `DefPathHash`. Since we also always build a huge table that maps every
133/// `DefPathHash` in the current codebase to the corresponding `DefId`, we have
134/// everything we need to re-run the query.
135///
136/// Take the `mir_validated` query as an example. Like many other queries, it
137/// just has a single parameter: the `DefId` of the item it will compute the
138/// validated MIR for. Now, when we call `force_from_dep_node()` on a `DepNode`
139/// with kind `MirValidated`, we know that the GUID/fingerprint of the `DepNode`
140/// is actually a `DefPathHash`, and can therefore just look up the corresponding
141/// `DefId` in `tcx.def_path_hash_to_def_id`.
142///
143/// When you implement a new query, it will likely have a corresponding new
144/// `DepKind`, and you'll have to support it here in `force_from_dep_node()`. As
ba9703b0 145/// a rule of thumb, if your query takes a `DefId` or `LocalDefId` as sole parameter,
74b04a01
XL
146/// then `force_from_dep_node()` should not fail for it. Otherwise, you can just
147/// add it to the "We don't have enough information to reconstruct..." group in
148/// the match below.
149pub fn force_from_dep_node<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) -> bool {
74b04a01
XL
150 // We must avoid ever having to call `force_from_dep_node()` for a
151 // `DepNode::codegen_unit`:
152 // Since we cannot reconstruct the query key of a `DepNode::codegen_unit`, we
153 // would always end up having to evaluate the first caller of the
154 // `codegen_unit` query that *is* reconstructible. This might very well be
155 // the `compile_codegen_unit` query, thus re-codegenning the whole CGU just
156 // to re-trigger calling the `codegen_unit` query with the right key. At
157 // that point we would already have re-done all the work we are trying to
158 // avoid doing in the first place.
159 // The solution is simple: Just explicitly call the `codegen_unit` query for
160 // each CGU, right after partitioning. This way `try_mark_green` will always
161 // hit the cache instead of having to go through `force_from_dep_node`.
162 // This assertion makes sure, we actually keep applying the solution above.
163 debug_assert!(
ba9703b0 164 dep_node.kind != crate::dep_graph::DepKind::codegen_unit,
74b04a01
XL
165 "calling force_from_dep_node() on DepKind::codegen_unit"
166 );
167
168 if !dep_node.kind.can_reconstruct_query_key() {
169 return false;
170 }
171
172 rustc_dep_node_force!([dep_node, tcx]
173 // These are inputs that are expected to be pre-allocated and that
174 // should therefore always be red or green already.
ba9703b0 175 crate::dep_graph::DepKind::CrateMetadata |
74b04a01
XL
176
177 // These are anonymous nodes.
ba9703b0 178 crate::dep_graph::DepKind::TraitSelect |
74b04a01
XL
179
180 // We don't have enough information to reconstruct the query key of
181 // these.
ba9703b0 182 crate::dep_graph::DepKind::CompileCodegenUnit => {
74b04a01
XL
183 bug!("force_from_dep_node: encountered {:?}", dep_node)
184 }
185 );
186
187 false
188}
189
ba9703b0
XL
190pub(crate) fn try_load_from_on_disk_cache<'tcx>(tcx: TyCtxt<'tcx>, dep_node: &DepNode) {
191 rustc_dep_node_try_load_from_on_disk_cache!(dep_node, tcx)
192}
193
194mod sealed {
195 use super::{DefId, LocalDefId};
196
197 /// An analogue of the `Into` trait that's intended only for query paramaters.
198 ///
199 /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
200 /// user call `to_def_id` to convert between them everywhere else.
201 pub trait IntoQueryParam<P> {
202 fn into_query_param(self) -> P;
203 }
204
205 impl<P> IntoQueryParam<P> for P {
206 #[inline(always)]
207 fn into_query_param(self) -> P {
208 self
209 }
210 }
74b04a01 211
ba9703b0
XL
212 impl IntoQueryParam<DefId> for LocalDefId {
213 #[inline(always)]
214 fn into_query_param(self) -> DefId {
215 self.to_def_id()
216 }
74b04a01
XL
217 }
218}
ba9703b0
XL
219
220use sealed::IntoQueryParam;