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