]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/query.rs
7151b79c5ab63f4b4b7ba8a56a4e5cd275320889
[rust.git] / compiler / rustc_middle / src / ty / query.rs
1 use crate::dep_graph;
2 use crate::infer::canonical::{self, Canonical};
3 use crate::lint::LintExpectation;
4 use crate::metadata::ModChild;
5 use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
6 use crate::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
7 use crate::middle::lib_features::LibFeatures;
8 use crate::middle::privacy::EffectiveVisibilities;
9 use crate::middle::resolve_lifetime::{ObjectLifetimeDefault, Region, ResolveLifetimes};
10 use crate::middle::stability::{self, DeprecationEntry};
11 use crate::mir;
12 use crate::mir::interpret::GlobalId;
13 use crate::mir::interpret::{
14     ConstValue, EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult,
15 };
16 use crate::mir::interpret::{LitToConstError, LitToConstInput};
17 use crate::mir::mono::CodegenUnit;
18 use crate::query::Key;
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     DropckConstraint, DropckOutlivesResult, MethodAutoderefStepsResult, NormalizationResult,
27     OutlivesBound,
28 };
29 use crate::traits::specialization_graph;
30 use crate::traits::{self, ImplSource};
31 use crate::ty::context::TyCtxtFeed;
32 use crate::ty::fast_reject::SimplifiedType;
33 use crate::ty::layout::TyAndLayout;
34 use crate::ty::subst::{GenericArg, SubstsRef};
35 use crate::ty::util::AlwaysRequiresDrop;
36 use crate::ty::GeneratorDiagnosticData;
37 use crate::ty::{self, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt, UnusedGenericParams};
38 use rustc_ast as ast;
39 use rustc_ast::expand::allocator::AllocatorKind;
40 use rustc_attr as attr;
41 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
42 use rustc_data_structures::steal::Steal;
43 use rustc_data_structures::svh::Svh;
44 use rustc_data_structures::sync::Lrc;
45 use rustc_data_structures::unord::UnordSet;
46 use rustc_errors::ErrorGuaranteed;
47 use rustc_hir as hir;
48 use rustc_hir::def::DefKind;
49 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
50 use rustc_hir::hir_id::OwnerId;
51 use rustc_hir::lang_items::{LangItem, LanguageItems};
52 use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
53 use rustc_index::vec::IndexVec;
54 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
55 use rustc_session::cstore::{CrateDepKind, CrateSource};
56 use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
57 use rustc_session::lint::LintExpectationId;
58 use rustc_session::Limits;
59 use rustc_span::symbol::Symbol;
60 use rustc_span::{Span, DUMMY_SP};
61 use rustc_target::abi;
62 use rustc_target::spec::PanicStrategy;
63 use std::ops::Deref;
64 use std::path::PathBuf;
65 use std::sync::Arc;
66
67 pub(crate) use rustc_query_system::query::QueryJobId;
68 use rustc_query_system::query::*;
69
70 #[derive(Copy, Clone)]
71 pub struct TyCtxtAt<'tcx> {
72     pub tcx: TyCtxt<'tcx>,
73     pub span: Span,
74 }
75
76 impl<'tcx> Deref for TyCtxtAt<'tcx> {
77     type Target = TyCtxt<'tcx>;
78     #[inline(always)]
79     fn deref(&self) -> &Self::Target {
80         &self.tcx
81     }
82 }
83
84 #[derive(Copy, Clone)]
85 pub struct TyCtxtEnsure<'tcx> {
86     pub tcx: TyCtxt<'tcx>,
87 }
88
89 impl<'tcx> TyCtxt<'tcx> {
90     /// Returns a transparent wrapper for `TyCtxt`, which ensures queries
91     /// are executed instead of just returning their results.
92     #[inline(always)]
93     pub fn ensure(self) -> TyCtxtEnsure<'tcx> {
94         TyCtxtEnsure { tcx: self }
95     }
96
97     /// Returns a transparent wrapper for `TyCtxt` which uses
98     /// `span` as the location of queries performed through it.
99     #[inline(always)]
100     pub fn at(self, span: Span) -> TyCtxtAt<'tcx> {
101         TyCtxtAt { tcx: self, span }
102     }
103
104     pub fn try_mark_green(self, dep_node: &dep_graph::DepNode) -> bool {
105         self.queries.try_mark_green(self, dep_node)
106     }
107 }
108
109 macro_rules! query_helper_param_ty {
110     (DefId) => { impl IntoQueryParam<DefId> };
111     (LocalDefId) => { impl IntoQueryParam<LocalDefId> };
112     ($K:ty) => { $K };
113 }
114
115 macro_rules! query_storage {
116     ([][$K:ty, $V:ty]) => {
117         <<$K as Key>::CacheSelector as CacheSelector<'tcx, $V>>::Cache
118     };
119     ([(arena_cache) $($rest:tt)*][$K:ty, $V:ty]) => {
120         <<$K as Key>::CacheSelector as CacheSelector<'tcx, $V>>::ArenaCache
121     };
122     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
123         query_storage!([$($modifiers)*][$($args)*])
124     };
125 }
126
127 macro_rules! separate_provide_extern_decl {
128     ([][$name:ident]) => {
129         ()
130     };
131     ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
132         for<'tcx> fn(
133             TyCtxt<'tcx>,
134             query_keys::$name<'tcx>,
135         ) -> query_values::$name<'tcx>
136     };
137     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
138         separate_provide_extern_decl!([$($modifiers)*][$($args)*])
139     };
140 }
141
142 macro_rules! separate_provide_extern_default {
143     ([][$name:ident]) => {
144         ()
145     };
146     ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
147         |_, key| bug!(
148             "`tcx.{}({:?})` unsupported by its crate; \
149              perhaps the `{}` query was never assigned a provider function",
150             stringify!($name),
151             key,
152             stringify!($name),
153         )
154     };
155     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
156         separate_provide_extern_default!([$($modifiers)*][$($args)*])
157     };
158 }
159
160 macro_rules! opt_remap_env_constness {
161     ([][$name:ident]) => {};
162     ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
163         let $name = $name.without_const();
164     };
165     ([$other:tt $($modifiers:tt)*][$name:ident]) => {
166         opt_remap_env_constness!([$($modifiers)*][$name])
167     };
168 }
169
170 macro_rules! define_callbacks {
171     (
172      $($(#[$attr:meta])*
173         [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
174
175         // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
176         // below, but using type aliases instead of associated types, to bypass
177         // the limitations around normalizing under HRTB - for example, this:
178         // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
179         // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
180         // This is primarily used by the `provide!` macro in `rustc_metadata`.
181         #[allow(nonstandard_style, unused_lifetimes)]
182         pub mod query_keys {
183             use super::*;
184
185             $(pub type $name<'tcx> = $($K)*;)*
186         }
187         #[allow(nonstandard_style, unused_lifetimes)]
188         pub mod query_values {
189             use super::*;
190
191             $(pub type $name<'tcx> = $V;)*
192         }
193         #[allow(nonstandard_style, unused_lifetimes)]
194         pub mod query_storage {
195             use super::*;
196
197             $(pub type $name<'tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
198         }
199         #[allow(nonstandard_style, unused_lifetimes)]
200         pub mod query_stored {
201             use super::*;
202
203             $(pub type $name<'tcx> = <query_storage::$name<'tcx> as QueryStorage>::Stored;)*
204         }
205
206         #[derive(Default)]
207         pub struct QueryCaches<'tcx> {
208             $($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
209         }
210
211         impl<'tcx> TyCtxtEnsure<'tcx> {
212             $($(#[$attr])*
213             #[inline(always)]
214             pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
215                 let key = key.into_query_param();
216                 opt_remap_env_constness!([$($modifiers)*][key]);
217
218                 match try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key) {
219                     Some(_) => return,
220                     None => self.tcx.queries.$name(self.tcx, DUMMY_SP, key, QueryMode::Ensure),
221                 };
222             })*
223         }
224
225         impl<'tcx> TyCtxt<'tcx> {
226             $($(#[$attr])*
227             #[inline(always)]
228             #[must_use]
229             pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
230             {
231                 self.at(DUMMY_SP).$name(key)
232             })*
233         }
234
235         impl<'tcx> TyCtxtAt<'tcx> {
236             $($(#[$attr])*
237             #[inline(always)]
238             pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
239             {
240                 let key = key.into_query_param();
241                 opt_remap_env_constness!([$($modifiers)*][key]);
242
243                 match try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key) {
244                     Some(value) => value,
245                     None => self.tcx.queries.$name(self.tcx, self.span, key, QueryMode::Get).unwrap(),
246                 }
247             })*
248         }
249
250         pub struct Providers {
251             $(pub $name: for<'tcx> fn(
252                 TyCtxt<'tcx>,
253                 query_keys::$name<'tcx>,
254             ) -> query_values::$name<'tcx>,)*
255         }
256
257         pub struct ExternProviders {
258             $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
259         }
260
261         impl Default for Providers {
262             fn default() -> Self {
263                 use crate::query::Key;
264
265                 Providers {
266                     $($name: |_, key| bug!(
267                         "`tcx.{}({:?})` is not supported for {} crate;\n
268                         hint: Queries can be either made to the local crate, or the external crate. This error means you tried to use it for one that's not supported.\n
269                         If that's not the case, {} was likely never assigned to a provider function.\n",
270                         stringify!($name),
271                         key,
272                         if key.query_crate_is_local() { "local" } else { "external" },
273                         stringify!($name),
274                     ),)*
275                 }
276             }
277         }
278
279         impl Default for ExternProviders {
280             fn default() -> Self {
281                 ExternProviders {
282                     $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
283                 }
284             }
285         }
286
287         impl Copy for Providers {}
288         impl Clone for Providers {
289             fn clone(&self) -> Self { *self }
290         }
291
292         impl Copy for ExternProviders {}
293         impl Clone for ExternProviders {
294             fn clone(&self) -> Self { *self }
295         }
296
297         pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
298             fn as_any(&'tcx self) -> &'tcx dyn std::any::Any;
299
300             fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;
301
302             $($(#[$attr])*
303             fn $name(
304                 &'tcx self,
305                 tcx: TyCtxt<'tcx>,
306                 span: Span,
307                 key: query_keys::$name<'tcx>,
308                 mode: QueryMode,
309             ) -> Option<query_stored::$name<'tcx>>;)*
310         }
311     };
312 }
313
314 macro_rules! hash_result {
315     ([]) => {{
316         Some(dep_graph::hash_result)
317     }};
318     ([(no_hash) $($rest:tt)*]) => {{
319         None
320     }};
321     ([$other:tt $($modifiers:tt)*]) => {
322         hash_result!([$($modifiers)*])
323     };
324 }
325
326 macro_rules! define_feedable {
327     ($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
328         $(impl<'tcx, K: IntoQueryParam<$($K)*> + Copy> TyCtxtFeed<'tcx, K> {
329             $(#[$attr])*
330             #[inline(always)]
331             pub fn $name(self, value: $V) -> query_stored::$name<'tcx> {
332                 let key = self.key().into_query_param();
333                 opt_remap_env_constness!([$($modifiers)*][key]);
334
335                 let tcx = self.tcx;
336                 let cache = &tcx.query_caches.$name;
337
338                 match try_get_cached(tcx, cache, &key) {
339                     Some(old) => {
340                         bug!(
341                             "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
342                             stringify!($name),
343                         )
344                     }
345                     None => {
346                         let dep_node = dep_graph::DepNode::construct(tcx, dep_graph::DepKind::$name, &key);
347                         let dep_node_index = tcx.dep_graph.with_feed_task(
348                             dep_node,
349                             tcx,
350                             key,
351                             &value,
352                             hash_result!([$($modifiers)*]),
353                         );
354                         cache.complete(key, value, dep_node_index)
355                     }
356                 }
357             }
358         })*
359     }
360 }
361
362 // Each of these queries corresponds to a function pointer field in the
363 // `Providers` struct for requesting a value of that type, and a method
364 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
365 // which memoizes and does dep-graph tracking, wrapping around the actual
366 // `Providers` that the driver creates (using several `rustc_*` crates).
367 //
368 // The result type of each query must implement `Clone`, and additionally
369 // `ty::query::values::Value`, which produces an appropriate placeholder
370 // (error) value if the query resulted in a query cycle.
371 // Queries marked with `fatal_cycle` do not need the latter implementation,
372 // as they will raise an fatal error on query cycles instead.
373
374 rustc_query_append! { define_callbacks! }
375 rustc_feedable_queries! { define_feedable! }
376
377 mod sealed {
378     use super::{DefId, LocalDefId, OwnerId};
379
380     /// An analogue of the `Into` trait that's intended only for query parameters.
381     ///
382     /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
383     /// user call `to_def_id` to convert between them everywhere else.
384     pub trait IntoQueryParam<P> {
385         fn into_query_param(self) -> P;
386     }
387
388     impl<P> IntoQueryParam<P> for P {
389         #[inline(always)]
390         fn into_query_param(self) -> P {
391             self
392         }
393     }
394
395     impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
396         #[inline(always)]
397         fn into_query_param(self) -> P {
398             *self
399         }
400     }
401
402     impl IntoQueryParam<LocalDefId> for OwnerId {
403         #[inline(always)]
404         fn into_query_param(self) -> LocalDefId {
405             self.def_id
406         }
407     }
408
409     impl IntoQueryParam<DefId> for LocalDefId {
410         #[inline(always)]
411         fn into_query_param(self) -> DefId {
412             self.to_def_id()
413         }
414     }
415
416     impl IntoQueryParam<DefId> for OwnerId {
417         #[inline(always)]
418         fn into_query_param(self) -> DefId {
419             self.to_def_id()
420         }
421     }
422 }
423
424 use sealed::IntoQueryParam;
425
426 impl<'tcx> TyCtxt<'tcx> {
427     pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
428         let def_id = def_id.into_query_param();
429         self.opt_def_kind(def_id)
430             .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
431     }
432
433     pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
434         ty::EarlyBinder(self.type_of(def_id))
435     }
436 }
437
438 impl<'tcx> TyCtxtAt<'tcx> {
439     pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
440         let def_id = def_id.into_query_param();
441         self.opt_def_kind(def_id)
442             .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
443     }
444
445     pub fn bound_type_of(self, def_id: impl IntoQueryParam<DefId>) -> ty::EarlyBinder<Ty<'tcx>> {
446         ty::EarlyBinder(self.type_of(def_id))
447     }
448 }