]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/query.rs
Merge commit '8da837185714cefbb261e93e9846afb11c1dc60e' into sync-rustfmt-subtree
[rust.git] / compiler / rustc_middle / src / ty / query.rs
1 use crate::dep_graph;
2 use crate::hir::exports::Export;
3 use crate::infer::canonical::{self, Canonical};
4 use crate::lint::LintLevelMap;
5 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
6 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportLevel};
7 use crate::middle::lib_features::LibFeatures;
8 use crate::middle::privacy::AccessLevels;
9 use crate::middle::region;
10 use crate::middle::resolve_lifetime::{
11     LifetimeScopeForPath, ObjectLifetimeDefault, Region, ResolveLifetimes,
12 };
13 use crate::middle::stability::{self, DeprecationEntry};
14 use crate::mir;
15 use crate::mir::interpret::GlobalId;
16 use crate::mir::interpret::{ConstAlloc, LitToConstError, LitToConstInput};
17 use crate::mir::interpret::{ConstValue, EvalToAllocationRawResult, EvalToConstValueResult};
18 use crate::mir::mono::CodegenUnit;
19 use crate::thir;
20 use crate::traits::query::{
21     CanonicalPredicateGoal, CanonicalProjectionGoal, CanonicalTyGoal,
22     CanonicalTypeOpAscribeUserTypeGoal, CanonicalTypeOpEqGoal, CanonicalTypeOpNormalizeGoal,
23     CanonicalTypeOpProvePredicateGoal, CanonicalTypeOpSubtypeGoal, NoSolution,
24 };
25 use crate::traits::query::{
26     DropckOutlivesResult, DtorckConstraint, MethodAutoderefStepsResult, NormalizationResult,
27     OutlivesBound,
28 };
29 use crate::traits::specialization_graph;
30 use crate::traits::{self, ImplSource};
31 use crate::ty::subst::{GenericArg, SubstsRef};
32 use crate::ty::util::AlwaysRequiresDrop;
33 use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
34 use rustc_ast::expand::allocator::AllocatorKind;
35 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
36 use rustc_data_structures::steal::Steal;
37 use rustc_data_structures::svh::Svh;
38 use rustc_data_structures::sync::Lrc;
39 use rustc_errors::ErrorReported;
40 use rustc_hir as hir;
41 use rustc_hir::def::DefKind;
42 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
43 use rustc_hir::lang_items::{LangItem, LanguageItems};
44 use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
45 use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
46 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
47 use rustc_session::cstore::{CrateDepKind, CrateSource};
48 use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
49 use rustc_session::utils::NativeLibKind;
50 use rustc_session::Limits;
51 use rustc_target::abi;
52 use rustc_target::spec::PanicStrategy;
53
54 use rustc_ast as ast;
55 use rustc_attr as attr;
56 use rustc_span::symbol::Symbol;
57 use rustc_span::{Span, DUMMY_SP};
58 use std::collections::BTreeMap;
59 use std::ops::Deref;
60 use std::path::PathBuf;
61 use std::sync::Arc;
62
63 pub(crate) use rustc_query_system::query::QueryJobId;
64 use rustc_query_system::query::*;
65
66 #[derive(Copy, Clone)]
67 pub struct TyCtxtAt<'tcx> {
68     pub tcx: TyCtxt<'tcx>,
69     pub span: Span,
70 }
71
72 impl Deref for TyCtxtAt<'tcx> {
73     type Target = TyCtxt<'tcx>;
74     #[inline(always)]
75     fn deref(&self) -> &Self::Target {
76         &self.tcx
77     }
78 }
79
80 #[derive(Copy, Clone)]
81 pub struct TyCtxtEnsure<'tcx> {
82     pub tcx: TyCtxt<'tcx>,
83 }
84
85 impl TyCtxt<'tcx> {
86     /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
87     /// are executed instead of just returning their results.
88     #[inline(always)]
89     pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
90         TyCtxtEnsure { tcx: self }
91     }
92
93     /// Returns a transparent wrapper for `TyCtxt` which uses
94     /// `span` as the location of queries performed through it.
95     #[inline(always)]
96     pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
97         TyCtxtAt { tcx: self, span }
98     }
99
100     pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
101         self.queries.try_mark_green(self, dep_node)
102     }
103 }
104
105 /// Helper for `TyCtxtEnsure` to avoid a closure.
106 #[inline(always)]
107 fn noop<T>(_: &T) {}
108
109 macro_rules! query_helper_param_ty {
110     (DefId) => { impl IntoQueryParam<DefId> };
111     ($K:ty) => { $K };
112 }
113
114 macro_rules! query_storage {
115     ([][$K:ty, $V:ty]) => {
116         <DefaultCacheSelector as CacheSelector<$K, $V>>::Cache
117     };
118     ([(storage $ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
119         <$ty as CacheSelector<$K, $V>>::Cache
120     };
121     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
122         query_storage!([$($modifiers)*][$($args)*])
123     };
124 }
125
126 macro_rules! separate_provide_extern_decl {
127     ([][$name:ident]) => {
128         ()
129     };
130     ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
131         for<'tcx> fn(
132             TyCtxt<'tcx>,
133             query_keys::$name<'tcx>,
134         ) -> query_values::$name<'tcx>
135     };
136     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
137         separate_provide_extern_decl!([$($modifiers)*][$($args)*])
138     };
139 }
140
141 macro_rules! separate_provide_extern_default {
142     ([][$name:ident]) => {
143         ()
144     };
145     ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
146         |_, key| bug!(
147             "`tcx.{}({:?})` unsupported by its crate; \
148              perhaps the `{}` query was never assigned a provider function",
149             stringify!($name),
150             key,
151             stringify!($name),
152         )
153     };
154     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
155         separate_provide_extern_default!([$($modifiers)*][$($args)*])
156     };
157 }
158
159 macro_rules! define_callbacks {
160     (<$tcx:tt>
161      $($(#[$attr:meta])*
162         [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
163
164         // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
165         // below, but using type aliases instead of associated types, to bypass
166         // the limitations around normalizing under HRTB - for example, this:
167         // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
168         // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
169         // This is primarily used by the `provide!` macro in `rustc_metadata`.
170         #[allow(nonstandard_style, unused_lifetimes)]
171         pub mod query_keys {
172             use super::*;
173
174             $(pub type $name<$tcx> = $($K)*;)*
175         }
176         #[allow(nonstandard_style, unused_lifetimes)]
177         pub mod query_values {
178             use super::*;
179
180             $(pub type $name<$tcx> = $V;)*
181         }
182         #[allow(nonstandard_style, unused_lifetimes)]
183         pub mod query_storage {
184             use super::*;
185
186             $(pub type $name<$tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
187         }
188         #[allow(nonstandard_style, unused_lifetimes)]
189         pub mod query_stored {
190             use super::*;
191
192             $(pub type $name<$tcx> = <query_storage::$name<$tcx> as QueryStorage>::Stored;)*
193         }
194
195         #[derive(Default)]
196         pub struct QueryCaches<$tcx> {
197             $($(#[$attr])* pub $name: QueryCacheStore<query_storage::$name<$tcx>>,)*
198         }
199
200         impl TyCtxtEnsure<$tcx> {
201             $($(#[$attr])*
202             #[inline(always)]
203             pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
204                 let key = key.into_query_param();
205                 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop);
206
207                 let lookup = match cached {
208                     Ok(()) => return,
209                     Err(lookup) => lookup,
210                 };
211
212                 self.tcx.queries.$name(self.tcx, DUMMY_SP, key, lookup, QueryMode::Ensure);
213             })*
214         }
215
216         impl TyCtxt<$tcx> {
217             $($(#[$attr])*
218             #[inline(always)]
219             #[must_use]
220             pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
221             {
222                 self.at(DUMMY_SP).$name(key)
223             })*
224         }
225
226         impl TyCtxtAt<$tcx> {
227             $($(#[$attr])*
228             #[inline(always)]
229             pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
230             {
231                 let key = key.into_query_param();
232                 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, Clone::clone);
233
234                 let lookup = match cached {
235                     Ok(value) => return value,
236                     Err(lookup) => lookup,
237                 };
238
239                 self.tcx.queries.$name(self.tcx, self.span, key, lookup, QueryMode::Get).unwrap()
240             })*
241         }
242
243         pub struct Providers {
244             $(pub $name: for<'tcx> fn(
245                 TyCtxt<'tcx>,
246                 query_keys::$name<'tcx>,
247             ) -> query_values::$name<'tcx>,)*
248         }
249
250         pub struct ExternProviders {
251             $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
252         }
253
254         impl Default for Providers {
255             fn default() -> Self {
256                 Providers {
257                     $($name: |_, key| bug!(
258                         "`tcx.{}({:?})` unsupported by its crate; \
259                          perhaps the `{}` query was never assigned a provider function",
260                         stringify!($name),
261                         key,
262                         stringify!($name),
263                     ),)*
264                 }
265             }
266         }
267
268         impl Default for ExternProviders {
269             fn default() -> Self {
270                 ExternProviders {
271                     $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
272                 }
273             }
274         }
275
276         impl Copy for Providers {}
277         impl Clone for Providers {
278             fn clone(&self) -> Self { *self }
279         }
280
281         impl Copy for ExternProviders {}
282         impl Clone for ExternProviders {
283             fn clone(&self) -> Self { *self }
284         }
285
286         pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
287             fn as_any(&'tcx self) -> &'tcx dyn std::any::Any;
288
289             fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;
290
291             $($(#[$attr])*
292             fn $name(
293                 &'tcx self,
294                 tcx: TyCtxt<$tcx>,
295                 span: Span,
296                 key: query_keys::$name<$tcx>,
297                 lookup: QueryLookup,
298                 mode: QueryMode,
299             ) -> Option<query_stored::$name<$tcx>>;)*
300         }
301     };
302 }
303
304 // Each of these queries corresponds to a function pointer field in the
305 // `Providers` struct for requesting a value of that type, and a method
306 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
307 // which memoizes and does dep-graph tracking, wrapping around the actual
308 // `Providers` that the driver creates (using several `rustc_*` crates).
309 //
310 // The result type of each query must implement `Clone`, and additionally
311 // `ty::query::values::Value`, which produces an appropriate placeholder
312 // (error) value if the query resulted in a query cycle.
313 // Queries marked with `fatal_cycle` do not need the latter implementation,
314 // as they will raise an fatal error on query cycles instead.
315
316 rustc_query_append! { [define_callbacks!][<'tcx>] }
317
318 mod sealed {
319     use super::{DefId, LocalDefId};
320
321     /// An analogue of the `Into` trait that's intended only for query paramaters.
322     ///
323     /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
324     /// user call `to_def_id` to convert between them everywhere else.
325     pub trait IntoQueryParam<P> {
326         fn into_query_param(self) -> P;
327     }
328
329     impl<P> IntoQueryParam<P> for P {
330         #[inline(always)]
331         fn into_query_param(self) -> P {
332             self
333         }
334     }
335
336     impl IntoQueryParam<DefId> for LocalDefId {
337         #[inline(always)]
338         fn into_query_param(self) -> DefId {
339             self.to_def_id()
340         }
341     }
342 }
343
344 use sealed::IntoQueryParam;
345
346 impl TyCtxt<'tcx> {
347     pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
348         let def_id = def_id.into_query_param();
349         self.opt_def_kind(def_id)
350             .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
351     }
352 }
353
354 impl TyCtxtAt<'tcx> {
355     pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
356         let def_id = def_id.into_query_param();
357         self.opt_def_kind(def_id)
358             .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
359     }
360 }