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