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