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, 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#[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
29pub trait QueryKey: Sized + QueryKeyBounds {
31 type Cache<V> = DefaultCache<Self, V>;
38
39 type LocalQueryKey = !;
40
41 fn default_span(&self, tcx: TyCtxt<'_>) -> Span;
44
45 fn key_as_def_id(&self) -> Option<DefId> {
48 None
49 }
50
51 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> QueryKey for ty::AliasTyKind<'tcx> {
275 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
276 let def_id = match self {
277 ty::AliasTyKind::Projection { def_id }
278 | ty::AliasTyKind::Inherent { def_id }
279 | ty::AliasTyKind::Opaque { def_id }
280 | ty::AliasTyKind::Free { def_id } => def_id,
281 };
282 tcx.def_span(*def_id)
283 }
284}
285
286impl<'tcx, T: QueryKey> QueryKey for ty::PseudoCanonicalInput<'tcx, T> {
287 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
288 self.value.default_span(tcx)
289 }
290}
291
292impl QueryKey for Symbol {
293 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
294 DUMMY_SP
295 }
296}
297
298impl QueryKey for Option<Symbol> {
299 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
300 DUMMY_SP
301 }
302}
303
304impl<'tcx> QueryKey for &'tcx OsStr {
305 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
306 DUMMY_SP
307 }
308}
309
310impl<'tcx, T: QueryKeyBounds> QueryKey for CanonicalQueryInput<'tcx, T> {
313 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
314 DUMMY_SP
315 }
316}
317
318impl<'tcx, T: QueryKeyBounds> QueryKey for (CanonicalQueryInput<'tcx, T>, bool) {
319 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
320 DUMMY_SP
321 }
322}
323
324impl<'tcx> QueryKey for (Ty<'tcx>, rustc_abi::VariantIdx) {
325 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
326 DUMMY_SP
327 }
328}
329
330impl<'tcx> QueryKey for (ty::Predicate<'tcx>, traits::WellFormedLoc) {
331 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
332 DUMMY_SP
333 }
334}
335
336impl<'tcx> QueryKey for (ty::PolyFnSig<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
337 fn default_span(&self, _: TyCtxt<'_>) -> Span {
338 DUMMY_SP
339 }
340}
341
342impl<'tcx> QueryKey for (ty::Instance<'tcx>, &'tcx ty::List<Ty<'tcx>>) {
343 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
344 self.0.default_span(tcx)
345 }
346}
347
348impl<'tcx> QueryKey for ty::Value<'tcx> {
349 fn default_span(&self, _: TyCtxt<'_>) -> Span {
350 DUMMY_SP
351 }
352}
353
354impl<'tcx> QueryKey for (LocalExpnId, &'tcx TokenStream) {
355 fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
356 self.0.expn_data().call_site
357 }
358}
359
360impl<'tcx> QueryKey for (ValidityRequirement, ty::PseudoCanonicalInput<'tcx, Ty<'tcx>>) {
361 fn default_span(&self, _: TyCtxt<'_>) -> Span {
364 DUMMY_SP
365 }
366}
367
368impl<'tcx> QueryKey for (ty::Instance<'tcx>, CollectionMode) {
369 fn default_span(&self, tcx: TyCtxt<'_>) -> Span {
370 self.0.default_span(tcx)
371 }
372}
373
374fn def_id_of_type_cached<'a>(ty: Ty<'a>, visited: &mut SsoHashSet<Ty<'a>>) -> Option<DefId> {
379 match *ty.kind() {
380 ty::Adt(adt_def, _) => Some(adt_def.did()),
381
382 ty::Dynamic(data, ..) => data.principal_def_id(),
383
384 ty::Pat(subty, _) | ty::Array(subty, _) | ty::Slice(subty) => {
385 def_id_of_type_cached(subty, visited)
386 }
387
388 ty::RawPtr(ty, _) => def_id_of_type_cached(ty, visited),
389
390 ty::Ref(_, ty, _) => def_id_of_type_cached(ty, visited),
391
392 ty::Tuple(tys) => tys.iter().find_map(|ty| {
393 if visited.insert(ty) {
394 return def_id_of_type_cached(ty, visited);
395 }
396 return None;
397 }),
398
399 ty::FnDef(def_id, _)
400 | ty::Closure(def_id, _)
401 | ty::CoroutineClosure(def_id, _)
402 | ty::Coroutine(def_id, _)
403 | ty::CoroutineWitness(def_id, _)
404 | ty::Foreign(def_id) => Some(def_id),
405
406 ty::Alias(_, alias) => match alias.kind {
407 ty::AliasTyKind::Projection { def_id }
408 | ty::AliasTyKind::Inherent { def_id }
409 | ty::AliasTyKind::Opaque { def_id }
410 | ty::AliasTyKind::Free { def_id } => Some(def_id),
411 },
412
413 ty::Bool
414 | ty::Char
415 | ty::Int(_)
416 | ty::Uint(_)
417 | ty::Str
418 | ty::FnPtr(..)
419 | ty::UnsafeBinder(_)
420 | ty::Placeholder(..)
421 | ty::Param(_)
422 | ty::Infer(_)
423 | ty::Bound(..)
424 | ty::Error(_)
425 | ty::Never
426 | ty::Float(_) => None,
427 }
428}
429
430fn def_id_of_type(ty: Ty<'_>) -> Option<DefId> {
431 def_id_of_type_cached(ty, &mut SsoHashSet::new())
432}