]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_middle/src/ty/query.rs
Provide a better diagnostic on failure to meet send bound on futures in a foreign...
[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::LintLevelMap;
4 use crate::metadata::ModChild;
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     DropckConstraint, DropckOutlivesResult, MethodAutoderefStepsResult, NormalizationResult,
27     OutlivesBound,
28 };
29 use crate::traits::specialization_graph;
30 use crate::traits::{self, ImplSource};
31 use crate::ty::fast_reject::SimplifiedType;
32 use crate::ty::subst::{GenericArg, SubstsRef};
33 use crate::ty::util::AlwaysRequiresDrop;
34 use crate::ty::GeneratorDiagnosticData;
35 use crate::ty::{self, AdtSizedConstraint, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt};
36 use rustc_ast as ast;
37 use rustc_ast::expand::allocator::AllocatorKind;
38 use rustc_attr as attr;
39 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
40 use rustc_data_structures::steal::Steal;
41 use rustc_data_structures::svh::Svh;
42 use rustc_data_structures::sync::Lrc;
43 use rustc_errors::ErrorGuaranteed;
44 use rustc_hir as hir;
45 use rustc_hir::def::DefKind;
46 use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, DefIdSet, LocalDefId};
47 use rustc_hir::lang_items::{LangItem, LanguageItems};
48 use rustc_hir::{Crate, ItemLocalId, TraitCandidate};
49 use rustc_index::{bit_set::FiniteBitSet, vec::IndexVec};
50 use rustc_session::config::{EntryFnType, OptLevel, OutputFilenames, SymbolManglingVersion};
51 use rustc_session::cstore::{CrateDepKind, CrateSource};
52 use rustc_session::cstore::{ExternCrate, ForeignModule, LinkagePreference, NativeLib};
53 use rustc_session::utils::NativeLibKind;
54 use rustc_session::Limits;
55 use rustc_span::symbol::Symbol;
56 use rustc_span::{Span, DUMMY_SP};
57 use rustc_target::abi;
58 use rustc_target::spec::PanicStrategy;
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<'tcx> 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<'tcx> 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 /// Helper to ensure that queries only return `Copy` types.
110 #[inline(always)]
111 fn copy<T: Copy>(x: &T) -> T {
112     *x
113 }
114
115 macro_rules! query_helper_param_ty {
116     (DefId) => { impl IntoQueryParam<DefId> };
117     ($K:ty) => { $K };
118 }
119
120 macro_rules! query_storage {
121     ([][$K:ty, $V:ty]) => {
122         <DefaultCacheSelector as CacheSelector<$K, $V>>::Cache
123     };
124     ([(storage $ty:ty) $($rest:tt)*][$K:ty, $V:ty]) => {
125         <$ty as CacheSelector<$K, $V>>::Cache
126     };
127     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
128         query_storage!([$($modifiers)*][$($args)*])
129     };
130 }
131
132 macro_rules! separate_provide_extern_decl {
133     ([][$name:ident]) => {
134         ()
135     };
136     ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
137         for<'tcx> fn(
138             TyCtxt<'tcx>,
139             query_keys::$name<'tcx>,
140         ) -> query_values::$name<'tcx>
141     };
142     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
143         separate_provide_extern_decl!([$($modifiers)*][$($args)*])
144     };
145 }
146
147 macro_rules! separate_provide_extern_default {
148     ([][$name:ident]) => {
149         ()
150     };
151     ([(separate_provide_extern) $($rest:tt)*][$name:ident]) => {
152         |_, key| bug!(
153             "`tcx.{}({:?})` unsupported by its crate; \
154              perhaps the `{}` query was never assigned a provider function",
155             stringify!($name),
156             key,
157             stringify!($name),
158         )
159     };
160     ([$other:tt $($modifiers:tt)*][$($args:tt)*]) => {
161         separate_provide_extern_default!([$($modifiers)*][$($args)*])
162     };
163 }
164
165 macro_rules! opt_remap_env_constness {
166     ([][$name:ident]) => {};
167     ([(remap_env_constness) $($rest:tt)*][$name:ident]) => {
168         let $name = $name.without_const();
169     };
170     ([$other:tt $($modifiers:tt)*][$name:ident]) => {
171         opt_remap_env_constness!([$($modifiers)*][$name])
172     };
173 }
174
175 macro_rules! define_callbacks {
176     (<$tcx:tt>
177      $($(#[$attr:meta])*
178         [$($modifiers:tt)*] fn $name:ident($($K:tt)*) -> $V:ty,)*) => {
179
180         // HACK(eddyb) this is like the `impl QueryConfig for queries::$name`
181         // below, but using type aliases instead of associated types, to bypass
182         // the limitations around normalizing under HRTB - for example, this:
183         // `for<'tcx> fn(...) -> <queries::$name<'tcx> as QueryConfig<TyCtxt<'tcx>>>::Value`
184         // doesn't currently normalize to `for<'tcx> fn(...) -> query_values::$name<'tcx>`.
185         // This is primarily used by the `provide!` macro in `rustc_metadata`.
186         #[allow(nonstandard_style, unused_lifetimes)]
187         pub mod query_keys {
188             use super::*;
189
190             $(pub type $name<$tcx> = $($K)*;)*
191         }
192         #[allow(nonstandard_style, unused_lifetimes)]
193         pub mod query_values {
194             use super::*;
195
196             $(pub type $name<$tcx> = $V;)*
197         }
198         #[allow(nonstandard_style, unused_lifetimes)]
199         pub mod query_storage {
200             use super::*;
201
202             $(pub type $name<$tcx> = query_storage!([$($modifiers)*][$($K)*, $V]);)*
203         }
204         #[allow(nonstandard_style, unused_lifetimes)]
205         pub mod query_stored {
206             use super::*;
207
208             $(pub type $name<$tcx> = <query_storage::$name<$tcx> as QueryStorage>::Stored;)*
209         }
210
211         #[derive(Default)]
212         pub struct QueryCaches<$tcx> {
213             $($(#[$attr])* pub $name: query_storage::$name<$tcx>,)*
214         }
215
216         impl<$tcx> TyCtxtEnsure<$tcx> {
217             $($(#[$attr])*
218             #[inline(always)]
219             pub fn $name(self, key: query_helper_param_ty!($($K)*)) {
220                 let key = key.into_query_param();
221                 opt_remap_env_constness!([$($modifiers)*][key]);
222
223                 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, noop);
224
225                 match cached {
226                     Ok(()) => return,
227                     Err(()) => (),
228                 }
229
230                 self.tcx.queries.$name(self.tcx, DUMMY_SP, key, QueryMode::Ensure);
231             })*
232         }
233
234         impl<$tcx> TyCtxt<$tcx> {
235             $($(#[$attr])*
236             #[inline(always)]
237             #[must_use]
238             pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
239             {
240                 self.at(DUMMY_SP).$name(key)
241             })*
242         }
243
244         impl<$tcx> TyCtxtAt<$tcx> {
245             $($(#[$attr])*
246             #[inline(always)]
247             pub fn $name(self, key: query_helper_param_ty!($($K)*)) -> query_stored::$name<$tcx>
248             {
249                 let key = key.into_query_param();
250                 opt_remap_env_constness!([$($modifiers)*][key]);
251
252                 let cached = try_get_cached(self.tcx, &self.tcx.query_caches.$name, &key, copy);
253
254                 match cached {
255                     Ok(value) => return value,
256                     Err(()) => (),
257                 }
258
259                 self.tcx.queries.$name(self.tcx, self.span, key, QueryMode::Get).unwrap()
260             })*
261         }
262
263         pub struct Providers {
264             $(pub $name: for<'tcx> fn(
265                 TyCtxt<'tcx>,
266                 query_keys::$name<'tcx>,
267             ) -> query_values::$name<'tcx>,)*
268         }
269
270         pub struct ExternProviders {
271             $(pub $name: separate_provide_extern_decl!([$($modifiers)*][$name]),)*
272         }
273
274         impl Default for Providers {
275             fn default() -> Self {
276                 Providers {
277                     $($name: |_, key| bug!(
278                         "`tcx.{}({:?})` unsupported by its crate; \
279                          perhaps the `{}` query was never assigned a provider function",
280                         stringify!($name),
281                         key,
282                         stringify!($name),
283                     ),)*
284                 }
285             }
286         }
287
288         impl Default for ExternProviders {
289             fn default() -> Self {
290                 ExternProviders {
291                     $($name: separate_provide_extern_default!([$($modifiers)*][$name]),)*
292                 }
293             }
294         }
295
296         impl Copy for Providers {}
297         impl Clone for Providers {
298             fn clone(&self) -> Self { *self }
299         }
300
301         impl Copy for ExternProviders {}
302         impl Clone for ExternProviders {
303             fn clone(&self) -> Self { *self }
304         }
305
306         pub trait QueryEngine<'tcx>: rustc_data_structures::sync::Sync {
307             fn as_any(&'tcx self) -> &'tcx dyn std::any::Any;
308
309             fn try_mark_green(&'tcx self, tcx: TyCtxt<'tcx>, dep_node: &dep_graph::DepNode) -> bool;
310
311             $($(#[$attr])*
312             fn $name(
313                 &'tcx self,
314                 tcx: TyCtxt<$tcx>,
315                 span: Span,
316                 key: query_keys::$name<$tcx>,
317                 mode: QueryMode,
318             ) -> Option<query_stored::$name<$tcx>>;)*
319         }
320     };
321 }
322
323 // Each of these queries corresponds to a function pointer field in the
324 // `Providers` struct for requesting a value of that type, and a method
325 // on `tcx: TyCtxt` (and `tcx.at(span)`) for doing that request in a way
326 // which memoizes and does dep-graph tracking, wrapping around the actual
327 // `Providers` that the driver creates (using several `rustc_*` crates).
328 //
329 // The result type of each query must implement `Clone`, and additionally
330 // `ty::query::values::Value`, which produces an appropriate placeholder
331 // (error) value if the query resulted in a query cycle.
332 // Queries marked with `fatal_cycle` do not need the latter implementation,
333 // as they will raise an fatal error on query cycles instead.
334
335 rustc_query_append! { [define_callbacks!][<'tcx>] }
336
337 mod sealed {
338     use super::{DefId, LocalDefId};
339
340     /// An analogue of the `Into` trait that's intended only for query parameters.
341     ///
342     /// This exists to allow queries to accept either `DefId` or `LocalDefId` while requiring that the
343     /// user call `to_def_id` to convert between them everywhere else.
344     pub trait IntoQueryParam<P> {
345         fn into_query_param(self) -> P;
346     }
347
348     impl<P> IntoQueryParam<P> for P {
349         #[inline(always)]
350         fn into_query_param(self) -> P {
351             self
352         }
353     }
354
355     impl<'a, P: Copy> IntoQueryParam<P> for &'a P {
356         #[inline(always)]
357         fn into_query_param(self) -> P {
358             *self
359         }
360     }
361
362     impl IntoQueryParam<DefId> for LocalDefId {
363         #[inline(always)]
364         fn into_query_param(self) -> DefId {
365             self.to_def_id()
366         }
367     }
368 }
369
370 use sealed::IntoQueryParam;
371
372 impl<'tcx> TyCtxt<'tcx> {
373     pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
374         let def_id = def_id.into_query_param();
375         self.opt_def_kind(def_id)
376             .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
377     }
378 }
379
380 impl<'tcx> TyCtxtAt<'tcx> {
381     pub fn def_kind(self, def_id: impl IntoQueryParam<DefId>) -> DefKind {
382         let def_id = def_id.into_query_param();
383         self.opt_def_kind(def_id)
384             .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id))
385     }
386 }