Skip to main content

rustc_middle/query/
keys.rs

1//! Defines the set of legal keys that can be used in queries.
2
3use std::ffi::OsStr;
4use std::fmt::Debug;
5use std::hash::Hash;
6
7use rustc_ast::tokenstream::TokenStream;
8use rustc_data_structures::stable_hasher::HashStable;
9use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
10use rustc_hir::hir_id::OwnerId;
11use rustc_span::{DUMMY_SP, Ident, LocalExpnId, Span, Symbol};
12
13use crate::dep_graph::DepNodeIndex;
14use crate::ich::StableHashingContext;
15use crate::infer::canonical::CanonicalQueryInput;
16use crate::mir::mono::CollectionMode;
17use crate::query::{DefIdCache, DefaultCache, SingleCache, VecCache};
18use crate::ty::fast_reject::SimplifiedType;
19use crate::ty::layout::ValidityRequirement;
20use crate::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt};
21use crate::{mir, traits};
22
23/// Placeholder for `CrateNum`'s "local" counterpart
24#[derive(#[automatically_derived]
impl ::core::marker::Copy for LocalCrate { }Copy, #[automatically_derived]
impl ::core::clone::Clone for LocalCrate {
    #[inline]
    fn clone(&self) -> LocalCrate { *self }
}Clone, #[automatically_derived]
impl ::core::fmt::Debug for LocalCrate {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f, "LocalCrate")
    }
}Debug)]
25pub struct LocalCrate;
26
27pub trait QueryKeyBounds = Copy + Debug + Eq + Hash + for<'a> HashStable<StableHashingContext<'a>>;
28
29/// Controls what types can legally be used as the key for a query.
30pub trait QueryKey: Sized + QueryKeyBounds {
31    /// The type of in-memory cache to use for queries with this key type.
32    ///
33    /// In practice the cache type must implement [`QueryCache`], though that
34    /// constraint is not enforced here.
35    ///
36    /// [`QueryCache`]: rustc_middle::query::QueryCache
37    type Cache<V> = DefaultCache<Self, V>;
38
39    /// In the event that a cycle occurs, if no explicit span has been
40    /// given for a query with key `self`, what span should we use?
41    fn default_span(&self, tcx: TyCtxt<'_>) -> Span;
42
43    /// If the key is a [`DefId`] or `DefId`--equivalent, return that `DefId`.
44    /// Otherwise, return `None`.
45    fn key_as_def_id(&self) -> Option<DefId> {
46        None
47    }
48
49    /// Used to detect when ADT def ids are used as keys in a cycle for better error reporting.
50    fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
51        None
52    }
53}
54
55pub trait AsLocalQueryKey: QueryKey {
56    type LocalQueryKey;
57
58    /// Given an instance of this key, what crate is it referring to?
59    /// This is used to find the provider.
60    fn as_local_key(&self) -> Option<Self::LocalQueryKey>;
61}
62
63impl QueryKey for () {
64    type Cache<V> = SingleCache<V>;
65
66    fn default_span(&self, _: TyCtxt<'_>) -> Span {
67        DUMMY_SP
68    }
69}
70
71impl<'tcx> QueryKey for ty::InstanceKind<'tcx> {
72    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
73        tcx.def_span(self.def_id())
74    }
75}
76
77impl<'tcx> QueryKey for ty::Instance<'tcx> {
78    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
79        tcx.def_span(self.def_id())
80    }
81}
82
83impl<'tcx> QueryKey for mir::interpret::GlobalId<'tcx> {
84    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
85        self.instance.default_span(tcx)
86    }
87}
88
89impl<'tcx> QueryKey for (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>) {
90    fn default_span(&self, _: TyCtxt<'_>) -> Span {
91        DUMMY_SP
92    }
93}
94
95impl<'tcx> QueryKey for ty::LitToConstInput<'tcx> {
96    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
97        DUMMY_SP
98    }
99}
100
101impl QueryKey for CrateNum {
102    type Cache<V> = VecCache<Self, V, DepNodeIndex>;
103
104    fn default_span(&self, _: TyCtxt<'_>) -> Span {
105        DUMMY_SP
106    }
107}
108
109impl AsLocalQueryKey for CrateNum {
110    type LocalQueryKey = LocalCrate;
111
112    #[inline(always)]
113    fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
114        (*self == LOCAL_CRATE).then_some(LocalCrate)
115    }
116}
117
118impl QueryKey for OwnerId {
119    type Cache<V> = VecCache<Self, V, DepNodeIndex>;
120
121    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
122        self.to_def_id().default_span(tcx)
123    }
124
125    fn key_as_def_id(&self) -> Option<DefId> {
126        Some(self.to_def_id())
127    }
128}
129
130impl QueryKey for LocalDefId {
131    type Cache<V> = VecCache<Self, V, DepNodeIndex>;
132
133    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
134        self.to_def_id().default_span(tcx)
135    }
136
137    fn key_as_def_id(&self) -> Option<DefId> {
138        Some(self.to_def_id())
139    }
140}
141
142impl QueryKey for DefId {
143    type Cache<V> = DefIdCache<V>;
144
145    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
146        tcx.def_span(*self)
147    }
148
149    #[inline(always)]
150    fn key_as_def_id(&self) -> Option<DefId> {
151        Some(*self)
152    }
153}
154
155impl AsLocalQueryKey for DefId {
156    type LocalQueryKey = LocalDefId;
157
158    #[inline(always)]
159    fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
160        self.as_local()
161    }
162}
163
164impl QueryKey for LocalModDefId {
165    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
166        tcx.def_span(*self)
167    }
168
169    #[inline(always)]
170    fn key_as_def_id(&self) -> Option<DefId> {
171        Some(self.to_def_id())
172    }
173}
174
175impl QueryKey for SimplifiedType {
176    fn default_span(&self, _: TyCtxt<'_>) -> Span {
177        DUMMY_SP
178    }
179}
180
181impl QueryKey for (DefId, DefId) {
182    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
183        self.1.default_span(tcx)
184    }
185}
186
187impl QueryKey for (DefId, Ident) {
188    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
189        tcx.def_span(self.0)
190    }
191
192    #[inline(always)]
193    fn key_as_def_id(&self) -> Option<DefId> {
194        Some(self.0)
195    }
196}
197
198impl QueryKey for (LocalDefId, LocalDefId, Ident) {
199    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
200        self.1.default_span(tcx)
201    }
202}
203
204impl QueryKey for (CrateNum, DefId) {
205    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
206        self.1.default_span(tcx)
207    }
208}
209
210impl AsLocalQueryKey for (CrateNum, DefId) {
211    type LocalQueryKey = DefId;
212
213    #[inline(always)]
214    fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
215        (self.0 == LOCAL_CRATE).then(|| self.1)
216    }
217}
218
219impl QueryKey for (CrateNum, SimplifiedType) {
220    fn default_span(&self, _: TyCtxt<'_>) -> Span {
221        DUMMY_SP
222    }
223}
224
225impl AsLocalQueryKey for (CrateNum, SimplifiedType) {
226    type LocalQueryKey = SimplifiedType;
227
228    #[inline(always)]
229    fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
230        (self.0 == LOCAL_CRATE).then(|| self.1)
231    }
232}
233
234impl QueryKey for (DefId, ty::SizedTraitKind) {
235    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
236        self.0.default_span(tcx)
237    }
238}
239
240impl<'tcx> QueryKey for GenericArgsRef<'tcx> {
241    fn default_span(&self, _: TyCtxt<'_>) -> Span {
242        DUMMY_SP
243    }
244}
245
246impl<'tcx> QueryKey for (DefId, GenericArgsRef<'tcx>) {
247    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
248        self.0.default_span(tcx)
249    }
250}
251
252impl<'tcx> QueryKey for ty::TraitRef<'tcx> {
253    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
254        tcx.def_span(self.def_id)
255    }
256}
257
258impl<'tcx> QueryKey for GenericArg<'tcx> {
259    fn default_span(&self, _: TyCtxt<'_>) -> Span {
260        DUMMY_SP
261    }
262}
263
264impl<'tcx> QueryKey for Ty<'tcx> {
265    fn default_span(&self, _: TyCtxt<'_>) -> Span {
266        DUMMY_SP
267    }
268
269    fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
270        match *self.kind() {
271            ty::Adt(adt, _) => Some(adt.did()),
272            ty::Coroutine(def_id, ..) => Some(def_id),
273            _ => None,
274        }
275    }
276}
277
278impl<'tcx> QueryKey for (Ty<'tcx>, Ty<'tcx>) {
279    fn default_span(&self, _: TyCtxt<'_>) -> Span {
280        DUMMY_SP
281    }
282}
283
284impl<'tcx> QueryKey for ty::Clauses<'tcx> {
285    fn default_span(&self, _: TyCtxt<'_>) -> Span {
286        DUMMY_SP
287    }
288}
289
290impl<'tcx, T: QueryKey> QueryKey for ty::PseudoCanonicalInput<'tcx, T> {
291    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
292        self.value.default_span(tcx)
293    }
294
295    fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
296        self.value.def_id_for_ty_in_cycle()
297    }
298}
299
300impl QueryKey for Symbol {
301    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
302        DUMMY_SP
303    }
304}
305
306impl QueryKey for Option<Symbol> {
307    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
308        DUMMY_SP
309    }
310}
311
312impl<'tcx> QueryKey for &'tcx OsStr {
313    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
314        DUMMY_SP
315    }
316}
317
318/// Canonical query goals correspond to abstract trait operations that
319/// are not tied to any crate in particular.
320impl<'tcx, T: QueryKeyBounds> QueryKey for CanonicalQueryInput<'tcx, T> {
321    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
322        DUMMY_SP
323    }
324}
325
326impl<'tcx, T: QueryKeyBounds> QueryKey for (CanonicalQueryInput<'tcx, T>, bool) {
327    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
328        DUMMY_SP
329    }
330}
331
332impl<'tcx> QueryKey for (Ty<'tcx>, rustc_abi::VariantIdx) {
333    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
334        DUMMY_SP
335    }
336}
337
338impl<'tcx> QueryKey for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
339    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
340        DUMMY_SP
341    }
342}
343
344impl<'tcx> QueryKey for (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
345    fn default_span(&self, _: TyCtxt<'_>) -> Span {
346        DUMMY_SP
347    }
348}
349
350impl<'tcx> QueryKey for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
351    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
352        self.0.default_span(tcx)
353    }
354}
355
356impl<'tcx> QueryKey for ty::Value<'tcx> {
357    fn default_span(&self, _: TyCtxt<'_>) -> Span {
358        DUMMY_SP
359    }
360}
361
362impl<'tcx> QueryKey for (LocalExpnId, &'tcx TokenStream) {
363    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
364        self.0.expn_data().call_site
365    }
366}
367
368impl<'tcx> QueryKey for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) {
369    // Just forward to `Ty<'tcx>`
370
371    fn default_span(&self, _: TyCtxt<'_>) -> Span {
372        DUMMY_SP
373    }
374
375    fn def_id_for_ty_in_cycle(&self) -> Option<DefId> {
376        match self.1.value.kind() {
377            ty::Adt(adt, _) => Some(adt.did()),
378            _ => None,
379        }
380    }
381}
382
383impl<'tcx> QueryKey for (ty::Instance<'tcx>, CollectionMode) {
384    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
385        self.0.default_span(tcx)
386    }
387}