]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/query.rs
Move -Z maximal-hir-to-mir-coverage implementation to new `maybe_new_source_scope...
[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};
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::{bit_set::FiniteBitSet, 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 /// Helper for `TyCtxtEnsure` to avoid a closure.
110 #[inline(always)]
111 fn noop<T>(_: &T) {}
112
113 /// Helper to ensure that queries only return `Copy` types.
114 #[inline(always)]
115 fn copy<T: Copy>(x: &T) -> T {
116     *x
117 }
118
119 macro_rules! query_helper_param_ty {
120     (DefId) => { impl IntoQueryParam<DefId> };
121     ($K:ty) => { $K };
122 }
123
124 macro_rules! query_storage {
125     ([][$K:ty, $V:ty]) => {
126         <<$K as Key>::CacheSelector as CacheSelector<'tcx, $V>>::Cache
127     };
128     ([(arena_cache) $($rest:tt)*][$K:ty, $V:ty]) => {
129         <<$K as Key>::CacheSelector as CacheSelector<'tcx, $V>>::ArenaCache
130     };
131     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
132         query_storage!([$($modifiers)*][$($args)*])
133     };
134 }
135
136 macro_rules! separate_provide_extern_decl {
137     ([][$name:ident]) => {
138         ()
139     };
140     ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
141         for<'tcx> fn(
142             TyCtxt<'tcx>,
143             query_keys::$name<'tcx>,
144         ) -> query_values::$name<'tcx>
145     };
146     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
147         separate_provide_extern_decl!([$($modifiers)*][$($args)*])
148     };
149 }
150
151 macro_rules! separate_provide_extern_default {
152     ([][$name:ident]) => {
153         ()
154     };
155     ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
156         |_, key| bug!(
157             "`tcx.{}({:?})` unsupported by its crate; \
158              perhaps the `{}` query was never assigned a provider function",
159             stringify!($name),
160             key,
161             stringify!($name),
162         )
163     };
164     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
165         separate_provide_extern_default!([$($modifiers)*][$($args)*])
166     };
167 }
168
169 macro_rules! opt_remap_env_constness {
170     ([][$name:ident]) => {};
171     ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
172         let $name = $name.without_const();
173     };
174     ([$other:tt $($modifiers:tt)*][$name:ident]) => {
175         opt_remap_env_constness!([$($modifiers)*][$name])
176     };
177 }
178
179 macro_rules! define_callbacks {
180     (
181      $($(#[$attr:meta])*
182         [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
183
184         // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
185         // below, but using type aliases instead of associated types, to bypass
186         // the limitations around normalizing under HRTB - for example, this:
187         // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
188         // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
189         // This is primarily used by the `provide!` macro in `rustc_metadata`.
190         #[allow(nonstandard_style, unused_lifetimes)]
191         pub mod query_keys {
192             use super::*;
193
194             $(pub type $name<'tcx> = $($K)*;)*
195         }
196         #[allow(nonstandard_style, unused_lifetimes)]
197         pub mod query_values {
198             use super::*;
199
200             $(pub type $name<'tcx> = $V;)*
201         }
202         #[allow(nonstandard_style, unused_lifetimes)]
203         pub mod query_storage {
204             use super::*;
205
206             $(pub type $name<'tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
207         }
208         #[allow(nonstandard_style, unused_lifetimes)]
209         pub mod query_stored {
210             use super::*;
211
212             $(pub type $name<'tcx> = <query_storage::$name<'tcx> as QueryStorage>::Stored;)*
213         }
214
215         #[derive(Default)]
216         pub struct QueryCaches<'tcx> {
217             $($(#[$attr])* pub $name: query_storage::$name<'tcx>,)*
218         }
219
220         impl<'tcx> TyCtxtEnsure<'tcx> {
221             $($(#[$attr])*
222             #[inline(always)]
223             pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
224                 let key = key.into_query_param();
225                 opt_remap_env_constness!([$($modifiers)*][key]);
226
227                 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop);
228
229                 match cached {
230                     Ok(()) => return,
231                     Err(()) => (),
232                 }
233
234                 self.tcx.queries.$name(self.tcx, DUMMY_SP, key, QueryMode::Ensure);
235             })*
236         }
237
238         impl<'tcx> TyCtxt<'tcx> {
239             $($(#[$attr])*
240             #[inline(always)]
241             #[must_use]
242             pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
243             {
244                 self.at(DUMMY_SP).$name(key)
245             })*
246         }
247
248         impl<'tcx> TyCtxtAt<'tcx> {
249             $($(#[$attr])*
250             #[inline(always)]
251             pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<'tcx>
252             {
253                 let key = key.into_query_param();
254                 opt_remap_env_constness!([$($modifiers)*][key]);
255
256                 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, copy);
257
258                 match cached {
259                     Ok(value) => return value,
260                     Err(()) => (),
261                 }
262
263                 self.tcx.queries.$name(self.tcx, self.span, key, QueryMode::Get).unwrap()
264             })*
265         }
266
267         pub struct Providers {
268             $(pub $name: for<'tcx> fn(
269                 TyCtxt<'tcx>,
270                 query_keys::$name<'tcx>,
271             ) -> query_values::$name<'tcx>,)*
272         }
273
274         pub struct ExternProviders {
275             $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
276         }
277
278         impl Default for Providers {
279             fn default() -> Self {
280                 use crate::query::Key;
281
282                 Providers {
283                     $($name: |_, key| bug!(
284                         "`tcx.{}({:?})` is not supported for {} crate;\n
285                         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
286                         If that's not the case, {} was likely never assigned to a provider function.\n",
287                         stringify!($name),
288                         key,
289                         if key.query_crate_is_local() { "local" } else { "external" },
290                         stringify!($name),
291                     ),)*
292                 }
293             }
294         }
295
296         impl Default for ExternProviders {
297             fn default() -> Self {
298                 ExternProviders {
299                     $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
300                 }
301             }
302         }
303
304         impl Copy for Providers {}
305         impl Clone for Providers {
306             fn clone(&self) -> Self { *self }
307         }
308
309         impl Copy for ExternProviders {}
310         impl Clone for ExternProviders {
311             fn clone(&self) -> Self { *self }
312         }
313
314         pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
315             fn as_any(&'tcx self) -> &'tcx dyn std::any::Any;
316
317             fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;
318
319             $($(#[$attr])*
320             fn $name(
321                 &'tcx self,
322                 tcx: TyCtxt<'tcx>,
323                 span: Span,
324                 key: query_keys::$name<'tcx>,
325                 mode: QueryMode,
326             ) -> Option<query_stored::$name<'tcx>>;)*
327         }
328     };
329 }
330
331 macro_rules! define_feedable {
332     ($($(#[$attr:meta])* [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
333         impl<'tcx> TyCtxtFeed<'tcx> {
334             $($(#[$attr])*
335             #[inline(always)]
336             pub fn $name(self, value: $V) -> query_stored::$name<'tcx> {
337                 let key = self.def_id().into_query_param();
338                 opt_remap_env_constness!([$($modifiers)*][key]);
339
340                 let tcx = self.tcx;
341                 let cache = &tcx.query_caches.$name;
342
343                 let cached = try_get_cached(tcx, cache, &key, copy);
344
345                 match cached {
346                     Ok(old) => {
347                         bug!(
348                             "Trying to feed an already recorded value for query {} key={key:?}:\nold value: {old:?}\nnew value: {value:?}",
349                             stringify!($name),
350                         );
351                     }
352                     Err(()) => (),
353                 }
354
355                 let dep_node = dep_graph::DepNode::construct(tcx, dep_graph::DepKind::$name, &key);
356                 let dep_node_index = tcx.dep_graph.with_feed_task(
357                     dep_node,
358                     tcx,
359                     key,
360                     &value,
361                     dep_graph::hash_result,
362                 );
363                 cache.complete(key, value, dep_node_index)
364             })*
365         }
366     }
367 }
368
369 // Each of these queries corresponds to a function pointer field in the
370 // `Providers` struct for requesting a value of that type, and a method
371 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
372 // which memoizes and does dep-graph tracking, wrapping around the actual
373 // `Providers` that the driver creates (using several `rustc_*` crates).
374 //
375 // The result type of each query must implement `Clone`, and additionally
376 // `ty::query::values::Value`, which produces an appropriate placeholder
377 // (error) value if the query resulted in a query cycle.
378 // Queries marked with `fatal_cycle` do not need the latter implementation,
379 // as they will raise an fatal error on query cycles instead.
380
381 rustc_query_append! { define_callbacks! }
382 rustc_feedable_queries! { define_feedable! }
383
384 mod sealed {
385     use super::{DefId, LocalDefId, OwnerId};
386
387     /// An analogue of the `Into` trait that's intended only for query parameters.
388     ///
389     /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
390     /// user call `to_def_id` to convert between them everywhere else.
391     pub trait IntoQueryParam<P> {
392         fn into_query_param(self) -> P;
393     }
394
395     impl<P> IntoQueryParam<P> for P {
396         #[inline(always)]
397         fn into_query_param(self) -> P {
398             self
399         }
400     }
401
402     impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
403         #[inline(always)]
404         fn into_query_param(self) -> P {
405             *self
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
434 impl<'tcx> TyCtxtAt<'tcx> {
435     pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
436         let def_id = def_id.into_query_param();
437         self.opt_def_kind(def_id)
438             .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
439     }
440 }