1use crate::hax::prelude::*;
2
3use rustc_middle::ty;
4
5pub type TraitRef<'tcx> = ItemRef<'tcx>;
11
12impl<'tcx, S: UnderOwnerState<'tcx>> SInto<S, TraitRef<'tcx>> for ty::TraitRef<'tcx> {
13 fn sinto(&self, s: &S) -> TraitRef<'tcx> {
14 translate_item_ref(s, self.def_id, self.args)
15 }
16}
17
18#[derive(Debug, Clone, PartialEq, Eq, Hash)]
20pub struct AssocItem<'tcx> {
21 pub def_id: DefId,
22 pub name: Option<Symbol>,
24 pub kind: AssocKind,
25 pub container: AssocItemContainer<'tcx>,
26 pub has_value: bool,
29}
30
31impl<'tcx> AssocItem<'tcx> {
32 pub fn sfrom<S: BaseState<'tcx>>(s: &S, item: &ty::AssocItem) -> AssocItem<'tcx> {
33 Self::sfrom_instantiated(s, item, None)
34 }
35
36 pub fn sfrom_instantiated<S: BaseState<'tcx>>(
38 s: &S,
39 item: &ty::AssocItem,
40 item_args: Option<ty::GenericArgsRef<'tcx>>,
41 ) -> AssocItem<'tcx> {
42 let tcx = s.base().tcx;
43 let item_def_id = item.def_id.sinto(s);
45 let s = &s.with_hax_owner(&item_def_id);
46 let item_args = item_args.unwrap_or_else(|| item_def_id.identity_args(s));
47 let container_id = item.container_id(tcx);
48 let container_args = item_args.truncate_to(tcx, tcx.generics_of(container_id));
49 let container = match item.container {
50 ty::AssocContainer::Trait => {
51 let trait_ref =
52 ty::TraitRef::new_from_args(tcx, container_id, container_args).sinto(s);
53 AssocItemContainer::TraitContainer { trait_ref }
54 }
55 ty::AssocContainer::TraitImpl(implemented_item_id) => {
56 let implemented_item_id = implemented_item_id.unwrap();
57 let item = translate_item_ref(s, container_id, container_args);
58 let implemented_trait_ref = tcx
59 .impl_trait_ref(container_id)
60 .instantiate(tcx, container_args);
61 let implemented_trait_ref = normalize(tcx, s.typing_env(), implemented_trait_ref);
62 let implemented_trait_item = {
63 let implemented_item_id = implemented_item_id.sinto(s);
64 let generics =
65 item_args.rebase_onto(tcx, container_id, implemented_trait_ref.args);
66 ItemRef::translate_from_hax_def_id_maybe_resolve(
68 s,
69 implemented_item_id,
70 generics,
71 AssocItemResolution::None,
72 )
73 };
74 AssocItemContainer::TraitImplContainer {
75 impl_: item,
76 implemented_trait_ref: implemented_trait_ref.sinto(s),
77 implemented_trait_item,
78 overrides_default: tcx.defaultness(implemented_item_id).has_value(),
79 }
80 }
81 ty::AssocContainer::InherentImpl => AssocItemContainer::InherentImplContainer {
82 impl_id: container_id.sinto(s),
83 self_ty: inst_binder(
84 tcx,
85 s.typing_env(),
86 Some(container_args),
87 tcx.type_of(container_id),
88 )
89 .sinto(s),
90 },
91 };
92 let name = match item.opt_name() {
93 None if let ty::AssocKind::Type { data } = item.kind
94 && let ty::AssocTypeData::Rpitit(rpitit) = data =>
95 {
96 let (ty::ImplTraitInTraitData::Trait { fn_def_id, .. }
97 | ty::ImplTraitInTraitData::Impl { fn_def_id, .. }) = rpitit;
98 let fn_name = tcx.item_name(fn_def_id);
99 let name = Symbol::intern(&format!("{fn_name}_ty"));
100 Some(name)
101 }
102 opt_name => opt_name,
103 };
104 AssocItem {
105 def_id: item.def_id.sinto(s),
106 name,
107 kind: item.kind.sinto(s),
108 container,
109 has_value: item.defaultness(tcx).has_value(),
110 }
111 }
112
113 pub fn implemented_trait_item_id(&self) -> &DefId {
115 match &self.container {
116 AssocItemContainer::TraitImplContainer {
117 implemented_trait_item,
118 ..
119 } => &implemented_trait_item.def_id,
120 _ => &self.def_id,
121 }
122 }
123}
124
125#[derive(AdtInto)]
127#[args(<'tcx, S: BaseState<'tcx>>, from: ty::AssocKind, state: S as _tcx)]
128#[derive(Debug, Clone, PartialEq, Eq, Hash)]
129pub enum AssocKind {
130 Const { name: Symbol },
131 Fn { name: Symbol, has_self: bool },
132 Type { data: AssocTypeData },
133}
134
135#[derive(AdtInto)]
137#[args(<'tcx, S: BaseState<'tcx>>, from: ty::AssocTypeData, state: S as _tcx)]
138#[derive(Debug, Clone, PartialEq, Eq, Hash)]
139pub enum AssocTypeData {
140 Normal(Symbol),
141 Rpitit(ImplTraitInTraitData),
142}
143
144#[derive(Debug, Clone, PartialEq, Eq, Hash)]
145pub enum AssocItemContainer<'tcx> {
146 TraitContainer {
147 trait_ref: TraitRef<'tcx>,
148 },
149 TraitImplContainer {
150 impl_: ItemRef<'tcx>,
152 implemented_trait_ref: TraitRef<'tcx>,
154 implemented_trait_item: ItemRef<'tcx>,
156 overrides_default: bool,
159 },
160 InherentImplContainer {
161 impl_id: DefId,
162 self_ty: Ty<'tcx>,
164 },
165}
166
167#[derive(AdtInto)]
169#[args(<'tcx, S: BaseState<'tcx>>, from: ty::ImplTraitInTraitData, state: S as _s)]
170#[derive(Debug, Clone, PartialEq, Eq, Hash)]
171pub enum ImplTraitInTraitData {
172 Trait {
173 fn_def_id: DefId,
174 opaque_def_id: DefId,
175 },
176 Impl {
177 fn_def_id: DefId,
178 },
179}