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, 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
298impl<'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 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
362fn 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}