1use 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, LocalModId};
11use rustc_hir::hir_id::OwnerId;
12use rustc_span::def_id::ModId;
13use rustc_span::{DUMMY_SP, Ident, LocalExpnId, Span, Symbol};
14
15use crate::dep_graph::DepNodeIndex;
16use crate::infer::canonical::CanonicalQueryInput;
17use crate::mono::CollectionMode;
18use crate::query::{DefIdCache, DefaultCache, SingleCache, VecCache};
19use crate::ty::fast_reject::SimplifiedType;
20use crate::ty::layout::ValidityRequirement;
21use crate::ty::{self, GenericArg, GenericArgsRef, Ty, TyCtxt};
22use crate::{mir, traits};
23
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)]
26pub struct LocalCrate;
27
28pub trait QueryKeyBounds = Copy + Debug + Eq + Hash + StableHash;
29
30pub trait QueryKey: Sized + QueryKeyBounds {
32 type Cache<V> = DefaultCache<Self, V>;
39
40 type LocalQueryKey = !;
41
42 fn default_span(&self, tcx: TyCtxt<'_>) -> Span;
45
46 fn key_as_def_id(&self) -> Option<DefId> {
49 None
50 }
51
52 fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
55 None
56 }
57}
58
59impl QueryKey for () {
60 type Cache<V> = SingleCache<V>;
61
62 fn default_span(&self, _: TyCtxt<'_>) -> Span {
63 DUMMY_SP
64 }
65}
66
67impl<'tcx> QueryKey for ty::ShimKind<'tcx> {
68 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
69 tcx.def_span(self.def_id())
70 }
71}
72
73impl<'tcx> QueryKey for ty::InstanceKind<'tcx> {
74 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
75 tcx.def_span(self.def_id())
76 }
77}
78
79impl<'tcx> QueryKey for ty::Instance<'tcx> {
80 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
81 tcx.def_span(self.def_id())
82 }
83}
84
85impl<'tcx> QueryKey for mir::interpret::GlobalId<'tcx> {
86 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
87 self.instance.default_span(tcx)
88 }
89}
90
91impl<'tcx> QueryKey for (Ty<'tcx>, Option<ty::ExistentialTraitRef<'tcx>>) {
92 fn default_span(&self, _: TyCtxt<'_>) -> Span {
93 DUMMY_SP
94 }
95}
96
97impl<'tcx> QueryKey for ty::LitToConstInput<'tcx> {
98 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
99 DUMMY_SP
100 }
101}
102
103impl QueryKey for CrateNum {
104 type Cache<V> = VecCache<Self, V, DepNodeIndex>;
105
106 type LocalQueryKey = LocalCrate;
107
108 fn default_span(&self, _: TyCtxt<'_>) -> Span {
109 DUMMY_SP
110 }
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 type LocalQueryKey = LocalDefId;
145
146 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
147 tcx.def_span(*self)
148 }
149
150 #[inline(always)]
151 fn key_as_def_id(&self) -> Option<DefId> {
152 Some(*self)
153 }
154
155 #[inline(always)]
156 fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
157 self.as_local()
158 }
159}
160
161impl QueryKey for ModId {
162 type LocalQueryKey = LocalModId;
163
164 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
165 tcx.def_span(self.to_def_id())
166 }
167
168 #[inline(always)]
169 fn key_as_def_id(&self) -> Option<DefId> {
170 Some(self.to_def_id())
171 }
172
173 #[inline(always)]
174 fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
175 self.as_local()
176 }
177}
178
179impl QueryKey for LocalModId {
180 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
181 tcx.def_span(*self)
182 }
183
184 #[inline(always)]
185 fn key_as_def_id(&self) -> Option<DefId> {
186 Some(self.to_def_id())
187 }
188}
189
190impl QueryKey for SimplifiedType {
191 fn default_span(&self, _: TyCtxt<'_>) -> Span {
192 DUMMY_SP
193 }
194}
195
196impl QueryKey for (DefId, DefId) {
197 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
198 self.1.default_span(tcx)
199 }
200}
201
202impl QueryKey for (DefId, Ident) {
203 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
204 tcx.def_span(self.0)
205 }
206
207 #[inline(always)]
208 fn key_as_def_id(&self) -> Option<DefId> {
209 Some(self.0)
210 }
211}
212
213impl QueryKey for (LocalDefId, LocalDefId, Ident) {
214 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
215 self.1.default_span(tcx)
216 }
217}
218
219impl QueryKey for (CrateNum, DefId) {
220 type LocalQueryKey = DefId;
221
222 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
223 self.1.default_span(tcx)
224 }
225
226 #[inline(always)]
227 fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
228 (self.0 == LOCAL_CRATE).then(|| self.1)
229 }
230}
231
232impl QueryKey for (CrateNum, SimplifiedType) {
233 type LocalQueryKey = SimplifiedType;
234
235 fn default_span(&self, _: TyCtxt<'_>) -> Span {
236 DUMMY_SP
237 }
238
239 #[inline(always)]
240 fn as_local_key(&self) -> Option<Self::LocalQueryKey> {
241 (self.0 == LOCAL_CRATE).then(|| self.1)
242 }
243}
244
245impl QueryKey for (DefId, ty::SizedTraitKind) {
246 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
247 self.0.default_span(tcx)
248 }
249}
250
251impl<'tcx> QueryKey for GenericArgsRef<'tcx> {
252 fn default_span(&self, _: TyCtxt<'_>) -> Span {
253 DUMMY_SP
254 }
255}
256
257impl<'tcx> QueryKey for (DefId, GenericArgsRef<'tcx>) {
258 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
259 self.0.default_span(tcx)
260 }
261}
262
263impl<'tcx> QueryKey for ty::TraitRef<'tcx> {
264 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
265 tcx.def_span(self.def_id)
266 }
267}
268
269impl<'tcx> QueryKey for GenericArg<'tcx> {
270 fn default_span(&self, _: TyCtxt<'_>) -> Span {
271 DUMMY_SP
272 }
273}
274
275impl<'tcx> QueryKey for Ty<'tcx> {
276 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
277 def_id_of_type(*self).map(|def_id| tcx.def_span(def_id)).unwrap_or(DUMMY_SP)
278 }
279}
280
281impl<'tcx> QueryKey for (Ty<'tcx>, Ty<'tcx>) {
282 fn default_span(&self, _: TyCtxt<'_>) -> Span {
283 DUMMY_SP
284 }
285}
286
287impl<'tcx> QueryKey for ty::Clauses<'tcx> {
288 fn default_span(&self, _: TyCtxt<'_>) -> Span {
289 DUMMY_SP
290 }
291}
292
293impl<'tcx> QueryKey for ty::AliasTyKind<'tcx> {
294 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
295 let def_id = match self {
296 ty::AliasTyKind::Projection { def_id }
297 | ty::AliasTyKind::Inherent { def_id }
298 | ty::AliasTyKind::Opaque { def_id }
299 | ty::AliasTyKind::Free { def_id } => def_id,
300 };
301 tcx.def_span(*def_id)
302 }
303}
304
305impl<'tcx, T: QueryKey> QueryKey for ty::PseudoCanonicalInput<'tcx, T> {
306 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
307 self.value.default_span(tcx)
308 }
309}
310
311impl QueryKey for Symbol {
312 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
313 DUMMY_SP
314 }
315}
316
317impl QueryKey for Option<Symbol> {
318 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
319 DUMMY_SP
320 }
321}
322
323impl<'tcx> QueryKey for &'tcx OsStr {
324 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
325 DUMMY_SP
326 }
327}
328
329impl<'tcx, T: QueryKeyBounds> QueryKey for CanonicalQueryInput<'tcx, T> {
332 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
333 DUMMY_SP
334 }
335}
336
337impl<'tcx, T: QueryKeyBounds> QueryKey for (CanonicalQueryInput<'tcx, T>, bool) {
338 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
339 DUMMY_SP
340 }
341}
342
343impl<'tcx, T: QueryKeyBounds> QueryKey for (CanonicalQueryInput<'tcx, T>, usize) {
344 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
345 DUMMY_SP
346 }
347}
348
349impl<'tcx> QueryKey for (Ty<'tcx>, rustc_abi::VariantIdx) {
350 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
351 DUMMY_SP
352 }
353}
354
355impl<'tcx> QueryKey for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
356 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
357 DUMMY_SP
358 }
359}
360
361impl<'tcx> QueryKey for (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
362 fn default_span(&self, _: TyCtxt<'_>) -> Span {
363 DUMMY_SP
364 }
365}
366
367impl<'tcx> QueryKey for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
368 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
369 self.0.default_span(tcx)
370 }
371}
372
373impl<'tcx> QueryKey for ty::Value<'tcx> {
374 fn default_span(&self, _: TyCtxt<'_>) -> Span {
375 DUMMY_SP
376 }
377}
378
379impl<'tcx> QueryKey for (LocalExpnId, &'tcx TokenStream) {
380 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
381 self.0.expn_data().call_site
382 }
383}
384
385impl<'tcx> QueryKey for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) {
386 fn default_span(&self, _: TyCtxt<'_>) -> Span {
389 DUMMY_SP
390 }
391}
392
393impl<'tcx> QueryKey for (ty::Instance<'tcx>, CollectionMode) {
394 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
395 self.0.default_span(tcx)
396 }
397}
398
399fn def_id_of_type_cached<'a>(ty: Ty<'a>, visited: &mut SsoHashSet<Ty<'a>>) -> Option<DefId> {
404 match *ty.kind() {
405 ty::Adt(adt_def, _) => Some(adt_def.did()),
406
407 ty::Dynamic(data, ..) => data.principal_def_id(),
408
409 ty::Pat(subty, _) | ty::Array(subty, _) | ty::Slice(subty) => {
410 def_id_of_type_cached(subty, visited)
411 }
412
413 ty::RawPtr(ty, _) => def_id_of_type_cached(ty, visited),
414
415 ty::Ref(_, ty, _) => def_id_of_type_cached(ty, visited),
416
417 ty::Tuple(tys) => tys.iter().find_map(|ty| {
418 if visited.insert(ty) {
419 return def_id_of_type_cached(ty, visited);
420 }
421 return None;
422 }),
423
424 ty::FnDef(def_id, _)
425 | ty::Closure(def_id, _)
426 | ty::CoroutineClosure(def_id, _)
427 | ty::Coroutine(def_id, _)
428 | ty::CoroutineWitness(def_id, _)
429 | ty::Foreign(def_id) => Some(def_id),
430
431 ty::Alias(_, alias) => match alias.kind {
432 ty::AliasTyKind::Projection { def_id }
433 | ty::AliasTyKind::Inherent { def_id }
434 | ty::AliasTyKind::Opaque { def_id }
435 | ty::AliasTyKind::Free { def_id } => Some(def_id),
436 },
437
438 ty::Bool
439 | ty::Char
440 | ty::Int(_)
441 | ty::Uint(_)
442 | ty::Str
443 | ty::FnPtr(..)
444 | ty::UnsafeBinder(_)
445 | ty::Placeholder(..)
446 | ty::Param(_)
447 | ty::Infer(_)
448 | ty::Bound(..)
449 | ty::Error(_)
450 | ty::Never
451 | ty::Float(_) => None,
452 }
453}
454
455fn def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
456 def_id_of_type_cached(ty, &mut SsoHashSet::new())
457}