1use crate::hax::AdtInto;
10use crate::hax::prelude::*;
11use charon_lib::ast::HashConsed;
12
13use itertools::Itertools;
14pub use rustc_middle::mir::Promoted as PromotedId;
15pub use rustc_middle::mir::interpret::AllocId as RAllocId;
16use rustc_span::DUMMY_SP;
17use rustc_trait_elaboration::param_env_from_clauses;
18use {rustc_hir as hir, rustc_hir::def_id::DefId as RDefId, rustc_middle::ty};
19
20sinto_reexport!(hir::Safety);
21sinto_reexport!(hir::Mutability);
22sinto_reexport!(hir::def::CtorKind);
23sinto_reexport!(hir::def::MacroKinds);
24sinto_reexport!(hir::def::CtorOf);
25sinto_reexport!(rustc_span::symbol::Symbol);
26sinto_reexport!(rustc_span::symbol::ByteSymbol);
27
28#[derive(AdtInto)]
30#[args(<S>, from: rustc_hir::def::DefKind, state: S as tcx)]
31#[derive(Debug, Clone, PartialEq, Eq, Hash)]
32pub enum DefKind {
33 Mod,
34 Struct,
35 Union,
36 Enum,
37 Variant,
38 Trait,
39 TyAlias,
40 ForeignTy,
41 TraitAlias,
42 AssocTy,
43 TyParam,
44 Fn,
45 #[disable_mapping]
46 FnPtr,
47 Const,
48 ConstParam,
49 Static {
50 safety: Safety,
51 mutability: Mutability,
52 nested: bool,
53 },
54 Ctor(CtorOf, CtorKind),
55 AssocFn,
56 AssocConst,
57 Macro(MacroKinds),
58 ExternCrate,
59 Use,
60 ForeignMod,
61 AnonConst,
62 #[disable_mapping]
63 PromotedConst,
65 OpaqueTy,
66 Field,
67 LifetimeParam,
68 GlobalAsm,
69 Impl {
70 of_trait: bool,
71 },
72 Closure,
73 SyntheticCoroutineBody,
74 TestBinderConstraints,
75}
76
77const SYNTHETIC_CRATE_NAME: &str = "<synthetic>";
79
80#[derive(Clone, PartialEq, Eq)]
83pub struct DefId {
84 pub(crate) contents: HashConsed<DefIdContents>,
85}
86
87#[derive(Debug, Clone, PartialEq, Eq, Hash)]
88pub struct DefIdContents {
89 pub base: DefIdBase,
90 pub kind: crate::hax::DefKind,
92}
93
94#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
95pub enum DefIdBase {
96 Real(RDefId),
97 Promoted(RDefId, PromotedId),
98 ImplAssocItem(VirtualImplAssocItem),
102 Synthetic(SyntheticItem),
105 Alloc(RAllocId),
108}
109
110#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
111pub struct VirtualImplAssocItem {
112 pub trait_impl_id: RDefId,
114 pub item_decl_id: RDefId,
116 pub item_impl_id: RDefId,
118}
119
120impl VirtualImplAssocItem {
121 pub fn new(trait_impl_id: RDefId, item_decl_id: RDefId, item_impl_id: RDefId) -> Self {
122 Self {
123 trait_impl_id,
124 item_decl_id,
125 item_impl_id,
126 }
127 }
128
129 fn own_args<'tcx>(&self, s: &impl BaseState<'tcx>) -> Vec<ty::GenericArg<'tcx>> {
132 let tcx = s.base().tcx;
133 DefId::make_assoc_item_impl(s, *self)
134 .generics_of(s)
135 .own_params
136 .iter()
137 .map(|param| tcx.mk_param_from_def(param))
138 .collect()
139 }
140
141 pub fn args_for_item_decl<'tcx>(
143 &self,
144 s: &impl BaseState<'tcx>,
145 trait_args: ty::GenericArgsRef<'tcx>,
146 ) -> ty::GenericArgsRef<'tcx> {
147 let tcx = s.base().tcx;
148 tcx.mk_args_from_iter(trait_args.iter().chain(self.own_args(s)))
149 }
150
151 pub fn args_for_item_impl<'tcx>(
153 &self,
154 s: &impl BaseState<'tcx>,
155 impl_args: ty::GenericArgsRef<'tcx>,
156 ) -> ty::GenericArgsRef<'tcx> {
157 let tcx = s.base().tcx;
158 tcx.mk_args_from_iter(impl_args.iter().chain(self.own_args(s)))
159 }
160
161 pub fn identity_args_for_item_decl<'tcx>(
163 &self,
164 s: &impl BaseState<'tcx>,
165 ) -> ty::GenericArgsRef<'tcx> {
166 let tcx = s.base().tcx;
167 let impl_trait_ref = tcx
168 .impl_trait_ref(self.trait_impl_id)
169 .instantiate_identity()
170 .skip_normalization();
171 self.args_for_item_decl(s, impl_trait_ref.args)
172 }
173}
174
175impl DefIdContents {
176 pub fn make_def_id<'tcx, S: BaseState<'tcx>>(self, _s: &S) -> DefId {
177 let contents = HashConsed::new(self);
178 DefId { contents }
179 }
180}
181
182impl rustc_trait_elaboration::ItemId for DefId {
183 type State<'tcx> = StateWithBase<'tcx>;
184
185 fn from_rust_def_id<'tcx>(s: &Self::State<'tcx>, def_id: RDefId) -> Self {
186 def_id.sinto(s)
187 }
188
189 fn generics_of<'tcx>(&self, s: &Self::State<'tcx>) -> &'tcx ty::Generics {
190 DefId::generics_of(self, s)
191 }
192
193 fn param_env<'tcx>(&self, s: &Self::State<'tcx>) -> ty::ParamEnv<'tcx> {
194 DefId::param_env(self, s)
195 }
196
197 fn predicates_defined_on<'tcx>(
198 &self,
199 s: &Self::State<'tcx>,
200 direction: PredicateDirection,
201 ) -> ItemPredicates<'tcx, Self> {
202 let tcx = s.base().tcx;
203 match self.base {
204 DefIdBase::Real(def_id) => ItemPredicates::defined_on(tcx, s, def_id, direction),
205 DefIdBase::ImplAssocItem(id) => {
206 let item_args = id.identity_args_for_item_decl(s);
207 ItemPredicates::defined_on(tcx, s, id.item_decl_id, direction)
208 .instantiate(tcx, item_args)
209 }
210 DefIdBase::Synthetic(synthetic) => {
211 synthetic.predicates_defined_on(s, self.clone(), direction)
212 }
213 DefIdBase::Promoted(..) | DefIdBase::Alloc(..) => {
214 ItemPredicates::new_unmapped(DUMMY_SP, [])
215 }
216 }
217 }
218
219 fn self_pred<'tcx>(&self, s: &Self::State<'tcx>) -> Option<ty::PolyTraitRef<'tcx>> {
220 let tcx = s.base().tcx;
221 match self.base {
222 DefIdBase::Real(def_id) => def_id.self_pred(&tcx),
223 _ => None,
224 }
225 }
226
227 fn as_identity_assoc_ty<'tcx>(&self, s: &Self::State<'tcx>) -> Option<ty::Ty<'tcx>> {
228 let tcx = s.base().tcx;
229 match self.base {
230 DefIdBase::Real(def_id) => def_id.as_identity_assoc_ty(&tcx),
231 _ => None,
232 }
233 }
234
235 fn typeck_parent<'tcx>(&self, s: &Self::State<'tcx>) -> Option<Self> {
236 let tcx = s.base().tcx;
237 match self.base {
238 DefIdBase::Real(def_id) => def_id.typeck_parent(&tcx).map(|def_id| def_id.sinto(s)),
239 DefIdBase::Promoted(def_id, ..) => Some(tcx.typeck_root_def_id(def_id).sinto(s)),
240 DefIdBase::ImplAssocItem(..) | DefIdBase::Synthetic(..) | DefIdBase::Alloc(..) => None,
241 }
242 }
243
244 fn parent_of_assoc<'tcx>(&self, s: &Self::State<'tcx>) -> Option<Self> {
245 let tcx = s.base().tcx;
246 match self.base {
247 DefIdBase::Real(def_id) => def_id.parent_of_assoc(&tcx).map(|def_id| def_id.sinto(s)),
248 DefIdBase::ImplAssocItem(id) => Some(id.trait_impl_id.sinto(s)),
249 _ => None,
250 }
251 }
252
253 fn parent_for_clauses<'tcx>(&self, s: &Self::State<'tcx>) -> Option<Self> {
254 let tcx = s.base().tcx;
255 match self.base {
256 DefIdBase::Real(def_id) => def_id
257 .parent_for_clauses(&tcx)
258 .map(|def_id| def_id.sinto(s)),
259 DefIdBase::ImplAssocItem(id) => Some(id.trait_impl_id.sinto(s)),
260 DefIdBase::Promoted(def_id, _) => Some(def_id.sinto(s)),
261 DefIdBase::Synthetic(..) | DefIdBase::Alloc(..) => None,
262 }
263 }
264
265 fn takes_explicit_self_clause<'tcx>(&self, s: &Self::State<'tcx>) -> bool {
266 let tcx = s.base().tcx;
267 match self.base {
268 DefIdBase::Real(def_id) | DefIdBase::Promoted(def_id, ..) => {
269 def_id.takes_explicit_self_clause(&tcx)
270 }
271 DefIdBase::ImplAssocItem(id) => id.item_decl_id.takes_explicit_self_clause(&tcx),
272 DefIdBase::Synthetic(..) | DefIdBase::Alloc(..) => false,
273 }
274 }
275
276 fn find_in_impl<'tcx>(&self, s: &Self::State<'tcx>, trait_impl: &Self) -> Option<Self> {
277 let tcx = s.base().tcx;
278 let trait_impl = trait_impl.as_real_def_id()?;
279 match self.base {
280 DefIdBase::Real(def_id) => def_id
281 .find_in_impl(&tcx, &trait_impl)
282 .map(|def_id| def_id.sinto(s)),
283 _ => None,
284 }
285 }
286}
287
288impl DefId {
289 pub fn as_real_def_id(&self) -> Option<RDefId> {
292 match self.base {
293 DefIdBase::Real(did) => Some(did),
294 _ => None,
295 }
296 }
297 pub fn real_rust_def_id(&self) -> RDefId {
299 self.as_real_def_id().unwrap()
300 }
301 pub fn as_real_or_promoted(&self) -> Option<RDefId> {
303 match self.base {
304 DefIdBase::Real(did) | DefIdBase::Promoted(did, ..) => Some(did),
305 _ => None,
306 }
307 }
308 pub fn promoted_id(&self) -> Option<PromotedId> {
309 match self.base {
310 DefIdBase::Promoted(_, promoted) => Some(promoted),
311 _ => None,
312 }
313 }
314 pub fn as_synthetic<'tcx>(&self, _s: &impl BaseState<'tcx>) -> Option<SyntheticItem> {
316 match self.base {
317 DefIdBase::Synthetic(v) => Some(v),
318 _ => None,
319 }
320 }
321
322 pub fn is_local(&self) -> bool {
323 match self.base {
324 DefIdBase::Real(did) | DefIdBase::Promoted(did, ..) => did.is_local(),
325 DefIdBase::ImplAssocItem(id) => id.trait_impl_id.is_local(),
326 DefIdBase::Synthetic(..) => false,
327 DefIdBase::Alloc(..) => true,
328 }
329 }
330 pub fn is_typeck_child<'tcx>(&self, s: &impl BaseState<'tcx>) -> bool {
331 match self.base {
332 DefIdBase::Real(did) => s.base().tcx.is_typeck_child(did),
333 _ => false,
334 }
335 }
336
337 fn make<'tcx, S: BaseState<'tcx>>(s: &S, def_id: RDefId) -> Self {
338 let base = DefIdBase::Real(def_id);
339 let tcx = s.base().tcx;
340 let contents = DefIdContents {
341 base,
342 kind: get_def_kind(tcx, def_id).sinto(s),
343 };
344 contents.make_def_id(s)
345 }
346
347 pub fn make_synthetic<'tcx, S: BaseState<'tcx>>(s: &S, synthetic: SyntheticItem) -> Self {
348 let kind = match synthetic {
349 SyntheticItem::FnPtr(_) => DefKind::FnPtr,
350 _ => DefKind::Struct,
351 };
352 let contents = DefIdContents {
353 base: DefIdBase::Synthetic(synthetic),
354 kind,
355 };
356 contents.make_def_id(s)
357 }
358
359 pub fn make_promoted_child<'tcx, S: BaseState<'tcx>>(
362 &self,
363 s: &S,
364 promoted_id: PromotedId,
365 ) -> Self {
366 let contents = DefIdContents {
367 base: DefIdBase::Promoted(self.real_rust_def_id(), promoted_id),
368 kind: DefKind::PromotedConst,
369 };
370 contents.make_def_id(s)
371 }
372
373 pub fn make_assoc_item_impl<'tcx, S: BaseState<'tcx>>(
374 s: &S,
375 vitem: VirtualImplAssocItem,
376 ) -> Self {
377 let tcx = s.base().tcx;
378 let contents = DefIdContents {
379 base: DefIdBase::ImplAssocItem(vitem),
380 kind: get_def_kind(tcx, vitem.item_decl_id).sinto(s),
381 };
382 contents.make_def_id(s)
383 }
384
385 pub fn make_anon_alloc<'tcx, S: BaseState<'tcx>>(s: &S, alloc_id: RAllocId) -> Self {
387 let tcx = s.base().tcx;
388 s.with_global_cache(|cache| cache.anon_allocs.insert(alloc_id));
389 let mutability = GlobalRef::Alloc(alloc_id).mutability(tcx);
390 let contents = DefIdContents {
391 base: DefIdBase::Alloc(alloc_id),
392 kind: DefKind::Static {
393 safety: Safety::Safe,
394 mutability,
395 nested: true,
396 },
397 };
398 contents.make_def_id(s)
399 }
400}
401
402impl DefId {
403 fn crate_name_and_disambig<'tcx>(&self, s: &impl BaseState<'tcx>) -> (Symbol, u32) {
404 let tcx = s.base().tcx;
405 match self.base {
406 DefIdBase::Real(def_id)
407 | DefIdBase::Promoted(def_id, ..)
408 | DefIdBase::ImplAssocItem(VirtualImplAssocItem {
409 trait_impl_id: def_id,
410 ..
411 }) => s.with_global_cache(|cache| cache.crate_name(tcx, def_id.krate)),
412 DefIdBase::Synthetic(..) => (Symbol::intern(SYNTHETIC_CRATE_NAME), 0),
413 DefIdBase::Alloc(..) => {
414 s.with_global_cache(|cache| cache.crate_name(tcx, rustc_hir::def_id::LOCAL_CRATE))
415 }
416 }
417 }
418
419 pub fn crate_name<'tcx>(&self, s: &impl BaseState<'tcx>) -> Symbol {
420 self.crate_name_and_disambig(s).0
421 }
422
423 pub fn def_span<'tcx>(&self, s: &impl BaseState<'tcx>) -> Span {
426 use DefKind::*;
427 let tcx = s.base().tcx;
428 match self.base {
429 DefIdBase::Real(def_id) | DefIdBase::Promoted(def_id, ..) => {
430 if let ForeignMod = &self.kind {
431 rustc_span::DUMMY_SP
433 } else if let Some(ldid) = def_id.as_local()
434 && let hir_id = tcx.local_def_id_to_hir_id(ldid)
435 && matches!(tcx.hir_node(hir_id), rustc_hir::Node::Synthetic)
436 {
437 rustc_span::DUMMY_SP
439 } else {
440 tcx.def_span(def_id)
441 }
442 }
443 DefIdBase::ImplAssocItem(id) => tcx.def_span(id.item_impl_id),
444 DefIdBase::Synthetic(..) | DefIdBase::Alloc(..) => rustc_span::DUMMY_SP,
445 }
446 .sinto(s)
447 }
448
449 pub fn path_item<'tcx>(&self, s: &impl BaseState<'tcx>) -> DisambiguatedDefPathItem {
451 match self.base {
452 DefIdBase::Real(def_id) => {
453 let tcx = s.base().tcx;
454 let s = &s.with_hax_owner(self);
456 tcx.def_path(def_id)
457 .data
458 .last()
459 .map(|x| x.sinto(s))
460 .unwrap_or_else(|| {
461 let (name, disambiguator) = self.crate_name_and_disambig(s);
462 DisambiguatedDefPathItem {
463 disambiguator,
464 data: DefPathItem::CrateRoot { name },
465 }
466 })
467 }
468 DefIdBase::Promoted(_, id) => DisambiguatedDefPathItem {
469 data: DefPathItem::PromotedConst,
470 disambiguator: id.as_u32(),
472 },
473 DefIdBase::ImplAssocItem(id) => {
474 let s = &s.with_hax_owner(self);
475 s.base()
476 .tcx
477 .def_path(id.item_decl_id)
478 .data
479 .last()
480 .map(|x| x.sinto(s))
481 .unwrap()
482 }
483 DefIdBase::Synthetic(synthetic) => DisambiguatedDefPathItem {
484 disambiguator: 0,
485 data: DefPathItem::TypeNs(Symbol::intern(&synthetic.name())),
486 },
487 DefIdBase::Alloc(alloc_id) => DisambiguatedDefPathItem {
488 data: DefPathItem::PromotedConst,
489 disambiguator: s.with_global_cache(|cache| {
491 cache.anon_allocs.get_index_of(&alloc_id).unwrap() as u32
492 }),
493 },
494 }
495 }
496
497 pub fn parent<'tcx>(&self, s: &impl BaseState<'tcx>) -> Option<DefId> {
498 match self.base {
499 DefIdBase::Real(def_id) => s.tcx().opt_parent(def_id),
500 DefIdBase::Promoted(def_id, _) => Some(def_id),
501 DefIdBase::ImplAssocItem(id) => Some(id.trait_impl_id),
502 DefIdBase::Synthetic(..) | DefIdBase::Alloc(..) => {
503 Some(rustc_span::def_id::CRATE_DEF_ID.to_def_id())
504 }
505 }
506 .sinto(s)
507 }
508}
509
510impl DefId {
511 pub fn can_have_generics<'tcx>(&self, s: &impl BaseState<'tcx>) -> bool {
512 let tcx = s.base().tcx;
513 match self.base {
514 DefIdBase::Real(def_id)
515 | DefIdBase::Promoted(def_id, ..)
516 | DefIdBase::ImplAssocItem(VirtualImplAssocItem {
517 item_decl_id: def_id,
518 ..
519 }) => can_have_generics(tcx, def_id),
520 DefIdBase::Synthetic(synthetic) => synthetic.can_have_generics(s),
521 DefIdBase::Alloc(..) => false,
522 }
523 }
524
525 pub fn generics_of<'tcx>(&self, s: &impl BaseState<'tcx>) -> &'tcx ty::Generics {
526 let tcx = s.base().tcx;
527 match self.base {
528 DefIdBase::Real(def_id) => tcx.generics_of(def_id),
529 DefIdBase::Synthetic(synthetic) => synthetic.generics_of(s),
530 DefIdBase::Promoted(..) | DefIdBase::Alloc(..) => s.with_item_cache(self, |cache| {
531 if let Some(generics) = cache.virtual_generics {
532 return generics;
533 }
534 let parent = match self.base {
535 DefIdBase::Promoted(def_id, ..) => Some(def_id),
536 _ => None,
537 };
538 let generics = Box::leak(Box::new(ty::Generics {
539 parent,
540 parent_count: parent.map_or(0, |p| tcx.generics_of(p).count()),
541 own_params: Default::default(),
542 param_def_id_to_index: Default::default(),
543 has_self: false,
544 has_late_bound_regions: None,
545 }));
546 cache.virtual_generics = Some(generics);
547 generics
548 }),
549 DefIdBase::ImplAssocItem(id) => s.with_item_cache(self, |cache| {
550 if let Some(generics) = cache.virtual_generics {
551 return generics;
552 }
553 let item_id = id.item_impl_id;
555 let decl_generics = tcx.generics_of(item_id);
556 let parent_count = tcx.generics_of(id.trait_impl_id).count();
557 let own_params = tcx
558 .generics_of(id.item_decl_id)
559 .own_params
560 .iter()
561 .cloned()
562 .enumerate()
563 .map(|(i, mut param)| {
564 param.index = parent_count as u32 + i as u32;
565 param
566 })
567 .collect_vec();
568 let param_def_id_to_index = own_params
569 .iter()
570 .map(|param| (param.def_id, param.index))
571 .collect();
572 let generics = Box::leak(Box::new(ty::Generics {
573 parent: Some(id.trait_impl_id),
574 parent_count,
575 own_params,
576 param_def_id_to_index,
577 has_self: decl_generics.has_self,
578 has_late_bound_regions: decl_generics.has_late_bound_regions,
579 }));
580 cache.virtual_generics = Some(generics);
581 generics
582 }),
583 }
584 }
585
586 pub fn identity_args<'tcx>(&self, s: &impl BaseState<'tcx>) -> ty::GenericArgsRef<'tcx> {
587 let tcx = s.base().tcx;
588 match self.base {
589 DefIdBase::Real(def_id) | DefIdBase::Promoted(def_id, ..) => {
590 if can_have_generics(tcx, def_id) {
591 identity_args_with_inferred(tcx, def_id)
592 } else {
593 ty::GenericArgsRef::default()
594 }
595 }
596 DefIdBase::Synthetic(synthetic) => synthetic.identity_args(s),
597 DefIdBase::Alloc(..) => ty::GenericArgsRef::default(),
598 DefIdBase::ImplAssocItem(_) => panic!(
599 "virtual trait impl associated items do not have a \
600 sensible `identity_args`. consider `identity_args_for_item_decl`"
601 ),
602 }
603 }
604
605 pub fn param_env<'tcx>(&self, s: &impl BaseState<'tcx>) -> ty::ParamEnv<'tcx> {
606 let tcx = s.base().tcx;
607 match self.base {
608 DefIdBase::ImplAssocItem(id) => {
609 let item_args = id.identity_args_for_item_decl(s);
610 let impl_predicates = tcx.param_env(id.trait_impl_id).caller_bounds();
611 let item_predicates = tcx
612 .clauses_of(id.item_decl_id)
613 .instantiate_own(tcx, item_args)
614 .map(|(predicate, _)| predicate.skip_normalization());
615 param_env_from_clauses(tcx, impl_predicates.chain(item_predicates))
616 }
617 DefIdBase::Real(def_id) | DefIdBase::Promoted(def_id, ..) => {
618 if can_have_generics(tcx, def_id) {
619 tcx.param_env(def_id)
620 } else {
621 ty::ParamEnv::empty()
622 }
623 }
624 DefIdBase::Synthetic(synthetic) => synthetic.param_env(s),
625 DefIdBase::Alloc(..) => ty::ParamEnv::empty(),
626 }
627 }
628
629 pub fn typing_env<'tcx>(&self, s: &impl BaseState<'tcx>) -> ty::TypingEnv<'tcx> {
630 ty::TypingEnv::new(self.param_env(s), ty::TypingMode::PostAnalysis)
631 }
632
633 pub fn required_predicates<'tcx, S: BaseState<'tcx>>(
634 &self,
635 s: &S,
636 ) -> ItemPredicates<'tcx, Self> {
637 let state = s.base_state();
638 ItemPredicates::required(s.base().elab_ctx, &state, self.clone())
639 }
640
641 pub fn type_of<'tcx, S: BaseState<'tcx>>(&self, s: &S) -> ty::EarlyBinder<'tcx, ty::Ty<'tcx>> {
642 let tcx: ty::TyCtxt<'tcx> = s.base().tcx;
643 match self.base {
644 DefIdBase::Real(def_id) | DefIdBase::Promoted(def_id, ..) => tcx.type_of(def_id),
645 DefIdBase::Synthetic(synthetic) => synthetic.type_of(s),
646 DefIdBase::ImplAssocItem(id) => tcx.type_of(id.item_decl_id),
647 DefIdBase::Alloc(alloc_id) => s.with_global_cache(|cache| {
648 ty::EarlyBinder::bind(tcx, cache.alloc_types.ty(tcx, alloc_id))
649 }),
650 }
651 }
652}
653
654impl DefId {
655 pub fn visibility<'tcx>(&self, tcx: ty::TyCtxt<'tcx>) -> Option<bool> {
658 use DefKind::*;
659 match self.kind {
660 AssocConst { .. }
661 | AssocFn
662 | Const { .. }
663 | Enum
664 | Field
665 | Fn
666 | ForeignTy
667 | Macro { .. }
668 | Mod
669 | Static { .. }
670 | Struct
671 | Trait
672 | TraitAlias
673 | TyAlias { .. }
674 | Union
675 | Use
676 | Variant => {
677 let def_id = self.as_real_def_id()?;
678 Some(tcx.visibility(def_id).is_public())
679 }
680 AnonConst
682 | AssocTy
683 | Closure
684 | ConstParam
685 | Ctor { .. }
686 | ExternCrate
687 | ForeignMod
688 | GlobalAsm
689 | Impl { .. }
690 | PromotedConst
691 | FnPtr
692 | LifetimeParam
693 | OpaqueTy
694 | SyntheticCoroutineBody
695 | TestBinderConstraints
696 | TyParam => None,
697 }
698 }
699
700 pub fn attrs<'tcx>(&self, tcx: ty::TyCtxt<'tcx>) -> &'tcx [rustc_hir::Attribute] {
702 use DefKind::*;
703 match self.kind {
704 ConstParam | LifetimeParam | TyParam | ForeignMod => &[],
706 _ => {
707 if let Some(def_id) = self.as_real_def_id() {
708 if let Some(ldid) = def_id.as_local() {
709 tcx.hir_attrs(tcx.local_def_id_to_hir_id(ldid))
710 } else if matches!(self.kind, AnonConst) {
711 &[]
714 } else {
715 tcx.attrs_for_def(def_id)
716 }
717 } else {
718 &[]
719 }
720 }
721 }
722 }
723}
724
725impl std::ops::Deref for DefId {
726 type Target = DefIdContents;
727 fn deref(&self) -> &Self::Target {
728 &self.contents
729 }
730}
731
732impl std::fmt::Debug for DefId {
733 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
734 match self.base {
735 DefIdBase::Real(def_id) => write!(f, "{def_id:?}"),
736 DefIdBase::Promoted(def_id, promoted) => {
737 write!(f, "{def_id:?}::promoted#{}", promoted.as_u32())
738 }
739 DefIdBase::Synthetic(item) => write!(f, "{}", item.name()),
740 DefIdBase::Alloc(alloc_id) => write!(f, "{alloc_id:?}"),
741 DefIdBase::ImplAssocItem(id) => {
742 write!(f, "{:?}::{:?}", id.trait_impl_id, id.item_decl_id)
743 }
744 }
745 }
746}
747
748impl std::hash::Hash for DefId {
749 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
750 self.base.hash(state);
751 }
752}
753
754pub(crate) fn get_def_kind<'tcx>(tcx: ty::TyCtxt<'tcx>, def_id: RDefId) -> hir::def::DefKind {
757 if def_id == rustc_span::def_id::CRATE_DEF_ID.to_def_id() {
758 let _ = tcx.def_span(def_id);
761 };
762 tcx.def_kind(def_id)
763}
764
765impl<'s, S: BaseState<'s>> SInto<S, DefId> for RDefId {
766 fn sinto(&self, s: &S) -> DefId {
767 if let Some(def_id) = s.with_global_cache(|cache| cache.def_ids.get(self).cloned()) {
768 return def_id;
769 }
770 let def_id = DefId::make(s, *self);
771 s.with_global_cache(|cache| {
772 cache.def_ids.insert(*self, def_id.clone());
773 });
774 def_id
775 }
776}
777
778impl<S> SInto<S, DefId> for DefId {
779 fn sinto(&self, _s: &S) -> DefId {
780 self.clone()
781 }
782}
783
784#[derive(Debug, Clone, PartialEq, Eq, Hash)]
786#[derive(AdtInto)]
787#[args(<'ctx, S: UnderOwnerState<'ctx>>, from: rustc_hir::definitions::DefPathData, state: S as s)]
788pub enum DefPathItem {
789 CrateRoot {
790 #[value(s.owner().crate_name(s))]
791 name: Symbol,
792 },
793 Impl,
794 ForeignMod,
795 Use,
796 GlobalAsm,
797 TypeNs(Symbol),
798 ValueNs(Symbol),
799 MacroNs(Symbol),
800 LifetimeNs(Symbol),
801 Closure,
802 TestBinderConstraints,
803 Ctor,
804 AnonConst,
805 #[disable_mapping]
806 PromotedConst,
807 OpaqueTy,
808 OpaqueLifetime(Symbol),
809 AnonAssocTy(Symbol),
810 SyntheticCoroutineBody,
811 NestedStatic,
812}
813
814#[derive(Debug, Clone, PartialEq, Eq, Hash)]
815#[derive(AdtInto)]
816#[args(<'a, S: UnderOwnerState<'a>>, from: rustc_hir::definitions::DisambiguatedDefPathData, state: S as s)]
817pub struct DisambiguatedDefPathItem {
819 pub data: DefPathItem,
820 pub disambiguator: u32,
821}