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::sso::SsoHashSet;
9use rustc_data_structures::stable_hash::StableHash;
10use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId};
11use rustc_hir::hir_id::OwnerId;
12use rustc_span::{DUMMY_SP, Ident, LocalExpnId, Span, Symbol};
13
14use crate::dep_graph::DepNodeIndex;
15use crate::infer::canonical::CanonicalQueryInput;
16use crate::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 + StableHash;
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    type LocalQueryKey = !;
40
41    /// In the event that a cycle occurs, if no explicit span has been
42    /// given for a query with key `self`, what span should we use?
43    fn default_span(&self, tcx: TyCtxt<'_>) -> Span;
44
45    /// If the key is a [`DefId`] or `DefId`--equivalent, return that `DefId`.
46    /// Otherwise, return `None`.
47    fn key_as_def_id(&self) -> Option<DefId> {
48        None
49    }
50
51    /// Given an instance of this key, what crate is it referring to?
52    /// This is used to find the provider.
53    fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
54        None
55    }
56}
57
58impl QueryKey for () {
59    type Cache<V> = SingleCache<V>;
60
61    fn default_span(&self, _: TyCtxt<'_>) -> Span {
62        DUMMY_SP
63    }
64}
65
66impl<'tcx> QueryKey for ty::ShimKind<'tcx> {
67    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
68        tcx.def_span(self.def_id())
69    }
70}
71
72impl<'tcx> QueryKey for ty::InstanceKind<'tcx> {
73    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
74        tcx.def_span(self.def_id())
75    }
76}
77
78impl<'tcx> QueryKey for ty::Instance<'tcx> {
79    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
80        tcx.def_span(self.def_id())
81    }
82}
83
84impl<'tcx> QueryKey for mir::interpret::GlobalId<'tcx> {
85    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
86        self.instance.default_span(tcx)
87    }
88}
89
90impl<'tcx> QueryKey for (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>) {
91    fn default_span(&self, _: TyCtxt<'_>) -> Span {
92        DUMMY_SP
93    }
94}
95
96impl<'tcx> QueryKey for ty::LitToConstInput<'tcx> {
97    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
98        DUMMY_SP
99    }
100}
101
102impl QueryKey for CrateNum {
103    type Cache<V> = VecCache<Self, V, DepNodeIndex>;
104
105    type LocalQueryKey = LocalCrate;
106
107    fn default_span(&self, _: TyCtxt<'_>) -> Span {
108        DUMMY_SP
109    }
110
111    #[inline(always)]
112    fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
113        (*self == LOCAL_CRATE).then_some(LocalCrate)
114    }
115}
116
117impl QueryKey for OwnerId {
118    type Cache<V> = VecCache<Self, V, DepNodeIndex>;
119
120    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
121        self.to_def_id().default_span(tcx)
122    }
123
124    fn key_as_def_id(&self) -> Option<DefId> {
125        Some(self.to_def_id())
126    }
127}
128
129impl QueryKey for LocalDefId {
130    type Cache<V> = VecCache<Self, V, DepNodeIndex>;
131
132    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
133        self.to_def_id().default_span(tcx)
134    }
135
136    fn key_as_def_id(&self) -> Option<DefId> {
137        Some(self.to_def_id())
138    }
139}
140
141impl QueryKey for DefId {
142    type Cache<V> = DefIdCache<V>;
143    type LocalQueryKey = LocalDefId;
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    #[inline(always)]
155    fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
156        self.as_local()
157    }
158}
159
160impl QueryKey for LocalModDefId {
161    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
162        tcx.def_span(*self)
163    }
164
165    #[inline(always)]
166    fn key_as_def_id(&self) -> Option<DefId> {
167        Some(self.to_def_id())
168    }
169}
170
171impl QueryKey for SimplifiedType {
172    fn default_span(&self, _: TyCtxt<'_>) -> Span {
173        DUMMY_SP
174    }
175}
176
177impl QueryKey for (DefId, DefId) {
178    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
179        self.1.default_span(tcx)
180    }
181}
182
183impl QueryKey for (DefId, Ident) {
184    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
185        tcx.def_span(self.0)
186    }
187
188    #[inline(always)]
189    fn key_as_def_id(&self) -> Option<DefId> {
190        Some(self.0)
191    }
192}
193
194impl QueryKey for (LocalDefId, LocalDefId, Ident) {
195    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
196        self.1.default_span(tcx)
197    }
198}
199
200impl QueryKey for (CrateNum, DefId) {
201    type LocalQueryKey = DefId;
202
203    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
204        self.1.default_span(tcx)
205    }
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    type LocalQueryKey = SimplifiedType;
215
216    fn default_span(&self, _: TyCtxt<'_>) -> Span {
217        DUMMY_SP
218    }
219
220    #[inline(always)]
221    fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
222        (self.0 == LOCAL_CRATE).then(|| self.1)
223    }
224}
225
226impl QueryKey for (DefId, ty::SizedTraitKind) {
227    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
228        self.0.default_span(tcx)
229    }
230}
231
232impl<'tcx> QueryKey for GenericArgsRef<'tcx> {
233    fn default_span(&self, _: TyCtxt<'_>) -> Span {
234        DUMMY_SP
235    }
236}
237
238impl<'tcx> QueryKey for (DefId, GenericArgsRef<'tcx>) {
239    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
240        self.0.default_span(tcx)
241    }
242}
243
244impl<'tcx> QueryKey for ty::TraitRef<'tcx> {
245    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
246        tcx.def_span(self.def_id)
247    }
248}
249
250impl<'tcx> QueryKey for GenericArg<'tcx> {
251    fn default_span(&self, _: TyCtxt<'_>) -> Span {
252        DUMMY_SP
253    }
254}
255
256impl<'tcx> QueryKey for Ty<'tcx> {
257    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
258        def_id_of_type(*self).map(|def_id| tcx.def_span(def_id)).unwrap_or(DUMMY_SP)
259    }
260}
261
262impl<'tcx> QueryKey for (Ty<'tcx>, Ty<'tcx>) {
263    fn default_span(&self, _: TyCtxt<'_>) -> Span {
264        DUMMY_SP
265    }
266}
267
268impl<'tcx> QueryKey for ty::Clauses<'tcx> {
269    fn default_span(&self, _: TyCtxt<'_>) -> Span {
270        DUMMY_SP
271    }
272}
273
274impl<'tcx, T: QueryKey> QueryKey for ty::PseudoCanonicalInput<'tcx, T> {
275    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
276        self.value.default_span(tcx)
277    }
278}
279
280impl QueryKey for Symbol {
281    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
282        DUMMY_SP
283    }
284}
285
286impl QueryKey for Option<Symbol> {
287    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
288        DUMMY_SP
289    }
290}
291
292impl<'tcx> QueryKey for &'tcx OsStr {
293    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
294        DUMMY_SP
295    }
296}
297
298/// Canonical query goals correspond to abstract trait operations that
299/// are not tied to any crate in particular.
300impl<'tcx, T: QueryKeyBounds> QueryKey for CanonicalQueryInput<'tcx, T> {
301    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
302        DUMMY_SP
303    }
304}
305
306impl<'tcx, T: QueryKeyBounds> QueryKey for (CanonicalQueryInput<'tcx, T>, bool) {
307    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
308        DUMMY_SP
309    }
310}
311
312impl<'tcx> QueryKey for (Ty<'tcx>, rustc_abi::VariantIdx) {
313    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
314        DUMMY_SP
315    }
316}
317
318impl<'tcx> QueryKey for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
319    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
320        DUMMY_SP
321    }
322}
323
324impl<'tcx> QueryKey for (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
325    fn default_span(&self, _: TyCtxt<'_>) -> Span {
326        DUMMY_SP
327    }
328}
329
330impl<'tcx> QueryKey for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
331    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
332        self.0.default_span(tcx)
333    }
334}
335
336impl<'tcx> QueryKey for ty::Value<'tcx> {
337    fn default_span(&self, _: TyCtxt<'_>) -> Span {
338        DUMMY_SP
339    }
340}
341
342impl<'tcx> QueryKey for (LocalExpnId, &'tcx TokenStream) {
343    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
344        self.0.expn_data().call_site
345    }
346}
347
348impl<'tcx> QueryKey for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) {
349    // Just forward to `Ty<'tcx>`
350
351    fn default_span(&self, _: TyCtxt<'_>) -> Span {
352        DUMMY_SP
353    }
354}
355
356impl<'tcx> QueryKey for (ty::Instance<'tcx>, CollectionMode) {
357    fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
358        self.0.default_span(tcx)
359    }
360}
361
362/// Gets a `DefId` associated with a type
363///
364/// Visited set is needed to avoid full iteration over
365/// deeply nested tuples that have no DefId.
366fn def_id_of_type_cached<'a>(ty: Ty<'a>, visited: &mut SsoHashSet<Ty<'a>>) -> Option<DefId> {
367    match *ty.kind() {
368        ty::Adt(adt_def, _) => Some(adt_def.did()),
369
370        ty::Dynamic(data, ..) => data.principal_def_id(),
371
372        ty::Pat(subty, _) | ty::Array(subty, _) | ty::Slice(subty) => {
373            def_id_of_type_cached(subty, visited)
374        }
375
376        ty::RawPtr(ty, _) => def_id_of_type_cached(ty, visited),
377
378        ty::Ref(_, ty, _) => def_id_of_type_cached(ty, visited),
379
380        ty::Tuple(tys) => tys.iter().find_map(|ty| {
381            if visited.insert(ty) {
382                return def_id_of_type_cached(ty, visited);
383            }
384            return None;
385        }),
386
387        ty::FnDef(def_id, _)
388        | ty::Closure(def_id, _)
389        | ty::CoroutineClosure(def_id, _)
390        | ty::Coroutine(def_id, _)
391        | ty::CoroutineWitness(def_id, _)
392        | ty::Foreign(def_id) => Some(def_id),
393
394        ty::Alias(_, alias) => match alias.kind {
395            ty::AliasTyKind::Projection { def_id }
396            | ty::AliasTyKind::Inherent { def_id }
397            | ty::AliasTyKind::Opaque { def_id }
398            | ty::AliasTyKind::Free { def_id } => Some(def_id),
399        },
400
401        ty::Bool
402        | ty::Char
403        | ty::Int(_)
404        | ty::Uint(_)
405        | ty::Str
406        | ty::FnPtr(..)
407        | ty::UnsafeBinder(_)
408        | ty::Placeholder(..)
409        | ty::Param(_)
410        | ty::Infer(_)
411        | ty::Bound(..)
412        | ty::Error(_)
413        | ty::Never
414        | ty::Float(_) => None,
415    }
416}
417
418fn def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
419    def_id_of_type_cached(ty, &mut SsoHashSet::new())
420}