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