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::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
292impl<'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 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
356fn 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}