1use derive_generic_visitor::*;
2use macros::{EnumAsGetters, EnumIsA};
3use serde::{Deserialize, Serialize};
4use serde_state::{DeserializeState, SerializeState};
5
6use crate::ast::*;
7use crate::ids::IndexVec;
8use crate::utils::serialize_map_to_array::SeqHashMapToArray;
9
10#[derive(Debug, Clone, SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
24#[serde_state(state_implements = DedupSerializerState)]
25pub struct TypeDecl {
26 pub def_id: TypeDeclId,
27 pub item_meta: ItemMeta,
29 pub generics: GenericParams,
30 pub src: TypeSource,
32 pub kind: TypeDeclKind,
34 #[serde(with = "SeqHashMapToArray::<TargetTriple, Layout>")]
37 pub layout: SeqHashMap<TargetTriple, Layout>,
38 pub ptr_metadata: PtrMetadata,
40}
41
42generate_index_type!(VariantId, "Variant");
43generate_index_type!(FieldId, "Field");
44
45#[derive(
46 Debug,
47 Clone,
48 EnumIsA,
49 EnumAsGetters,
50 SerializeState,
51 DeserializeState,
52 Drive,
53 DriveMut,
54 DriveTwo,
55)]
56pub enum TypeDeclKind {
57 Struct(IndexVec<FieldId, Field>),
58 Enum(IndexVec<VariantId, Variant>),
59 Union(IndexVec<FieldId, Field>),
60 Opaque,
64 Alias(Ty),
67 #[cfg_attr(feature = "charon_on_charon", charon::rename("TDeclError"))]
70 Error(String),
71}
72
73#[derive(Debug, Clone, SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
74#[serde_state(stateless)]
75pub struct Variant {
76 pub id: VariantId,
77 pub span: Span,
78 pub attr_info: AttrInfo,
79 #[cfg_attr(feature = "charon_on_charon", charon::rename("variant_name"))]
80 pub name: String,
81 #[serde_state(stateful)]
82 pub fields: IndexVec<FieldId, Field>,
83 pub discriminant: IntegerValue,
87}
88
89#[derive(Debug, Clone, SerializeState, DeserializeState, Drive, DriveMut, DriveTwo)]
90#[serde_state(stateless)]
91pub struct Field {
92 pub span: Span,
93 pub attr_info: AttrInfo,
94 #[cfg_attr(feature = "charon_on_charon", charon::rename("field_name"))]
95 pub name: String,
96 pub is_positional: bool,
99 #[cfg_attr(feature = "charon_on_charon", charon::rename("field_ty"))]
100 #[serde_state(stateful)]
101 pub ty: Ty,
102}
103
104#[derive(
108 Debug,
109 Clone,
110 PartialEq,
111 Eq,
112 PartialOrd,
113 Ord,
114 Hash,
115 SerializeState,
116 DeserializeState,
117 Drive,
118 DriveMut,
119 DriveTwo,
120)]
121#[serde_state(default_state = ())]
122pub enum PtrMetadata {
123 #[cfg_attr(feature = "charon_on_charon", charon::rename("NoMetadata"))]
125 None,
126 Length,
132 VTable(TypeDeclRef),
134 InheritFrom(Ty),
138}
139
140#[derive(
142 Debug,
143 Clone,
144 SerializeState,
145 DeserializeState,
146 Drive,
147 DriveMut,
148 DriveTwo,
149 EnumIsA,
150 EnumAsGetters,
151)]
152#[cfg_attr(feature = "charon_on_charon", charon::variants_suffix("Type"))]
153pub enum TypeSource {
154 Normal,
156 Closure { info: ClosureInfo },
158 VTable {
160 dyn_predicate: DynPredicate,
162 field_map: IndexVec<FieldId, VTableField>,
164 supertrait_map: IndexVec<TraitClauseId, Option<FieldId>>,
167 },
168 Builtin(BuiltinAdt),
170}
171
172#[derive(
173 Debug, Clone, SerializeState, DeserializeState, Drive, DriveMut, DriveTwo, PartialEq, Eq,
174)]
175#[cfg_attr(feature = "charon_on_charon", charon::variants_prefix("VTable"))]
176pub enum VTableField {
177 Size,
178 Align,
179 Drop,
180 Method(TraitMethodId),
181 SuperTrait(TraitClauseId),
182}
183
184#[derive(
186 Debug,
187 Clone,
188 PartialEq,
189 Eq,
190 PartialOrd,
191 Ord,
192 SerializeState,
193 DeserializeState,
194 Drive,
195 DriveMut,
196 DriveTwo,
197)]
198pub struct ClosureInfo {
199 #[serde_state(stateless)]
200 pub kind: ClosureKind,
201 pub fn_once_impl: RegionBinder<TraitImplRef>,
203 pub fn_mut_impl: Option<RegionBinder<TraitImplRef>>,
205 pub fn_impl: Option<RegionBinder<TraitImplRef>>,
207 pub signature: RegionBinder<FunSig>,
209}
210
211#[derive(
212 Debug,
213 Copy,
214 Clone,
215 PartialEq,
216 Eq,
217 PartialOrd,
218 Ord,
219 Hash,
220 Serialize,
221 Deserialize,
222 Drive,
223 DriveMut,
224 DriveTwo,
225)]
226pub enum ClosureKind {
227 Fn,
228 FnMut,
229 FnOnce,
230}
231
232impl TypeDecl {
233 pub fn get_field(&self, variant: Option<VariantId>, field: FieldId) -> Option<&Field> {
234 let fields = match &self.kind {
235 TypeDeclKind::Struct(fields) | TypeDeclKind::Union(fields) => fields,
236 TypeDeclKind::Enum(variants) => &variants[variant.unwrap()].fields,
237 _ => return None,
238 };
239 fields.get(field)
240 }
241
242 pub fn get_field_by_name(
243 &self,
244 variant: Option<VariantId>,
245 field_name: &str,
246 ) -> Option<(FieldId, &Field)> {
247 let fields = match &self.kind {
248 TypeDeclKind::Struct(fields) | TypeDeclKind::Union(fields) => fields,
249 TypeDeclKind::Enum(variants) => &variants[variant.unwrap()].fields,
250 _ => return None,
251 };
252 fields
253 .iter_enumerated()
254 .find(|(_, field)| field.name == field_name)
255 }
256}
257
258impl Variant {
259 pub fn renamed_name(&self) -> &str {
262 self.attr_info
263 .rename
264 .as_deref()
265 .unwrap_or(self.name.as_ref())
266 }
267
268 pub fn is_opaque(&self) -> bool {
270 self.attr_info
271 .attributes
272 .iter()
273 .any(|attr| attr.is_opaque())
274 }
275}
276
277impl Field {
278 pub fn renamed_name(&self) -> &str {
280 self.attr_info.rename.as_deref().unwrap_or(&self.name)
281 }
282
283 pub fn is_opaque(&self) -> bool {
285 self.attr_info
286 .attributes
287 .iter()
288 .any(|attr| attr.is_opaque())
289 }
290}
291
292impl ClosureKind {
293 pub fn method_name(self) -> &'static str {
295 match self {
296 ClosureKind::FnOnce => "call_once",
297 ClosureKind::FnMut => "call_mut",
298 ClosureKind::Fn => "call",
299 }
300 }
301}
302
303impl PtrMetadata {
304 pub fn into_type(self) -> Ty {
305 match self {
306 PtrMetadata::None => Ty::mk_unit(),
307 PtrMetadata::Length => Ty::mk_usize(),
308 PtrMetadata::VTable(type_decl_ref) => Ty::new(TyKind::Ref(
309 Region::Static,
310 Ty::new(TyKind::Adt(type_decl_ref)),
311 RefKind::Shared,
312 )),
313 PtrMetadata::InheritFrom(ty) => Ty::new(TyKind::PtrMetadata(ty)),
314 }
315 }
316}