1use std::cmp::{Ord, PartialOrd};
2
3use derive_generic_visitor::{Drive, DriveMut, DriveTwo};
4use serde::{Deserialize, Serialize};
5use serde_state::{DeserializeState, SerializeState};
6
7use crate::ast::*;
8use macros::{EnumAsGetters, EnumIsA, VariantIndexArity, VariantName};
9
10generate_index_type!(FunDeclId, "Fun");
11generate_index_type!(TypeDeclId, "Adt");
12generate_index_type!(GlobalDeclId, "Global");
13generate_index_type!(TraitDeclId, "TraitDecl");
14generate_index_type!(TraitImplId, "TraitImpl");
15
16#[derive(
18 Copy,
19 Clone,
20 Debug,
21 PartialOrd,
22 Ord,
23 PartialEq,
24 Eq,
25 Hash,
26 EnumIsA,
27 EnumAsGetters,
28 VariantName,
29 VariantIndexArity,
30 Serialize,
31 Deserialize,
32 SerializeState,
33 DeserializeState,
34 Drive,
35 DriveMut,
36 DriveTwo,
37)]
38#[cfg_attr(feature = "charon_on_charon", charon::variants_prefix("Id"))]
39#[serde_state(stateless)]
40pub enum ItemId {
41 Type(TypeDeclId),
42 TraitDecl(TraitDeclId),
43 TraitImpl(TraitImplId),
44 Fun(FunDeclId),
45 Global(GlobalDeclId),
46}
47
48#[derive(
50 Copy,
51 Clone,
52 Debug,
53 PartialOrd,
54 Ord,
55 PartialEq,
56 Eq,
57 Hash,
58 EnumIsA,
59 EnumAsGetters,
60 VariantName,
61 VariantIndexArity,
62 Serialize,
63 Deserialize,
64 SerializeState,
65 DeserializeState,
66 Drive,
67 DriveMut,
68 DriveTwo,
69)]
70#[cfg_attr(feature = "charon_on_charon", charon::variants_prefix("AssocId"))]
71#[serde_state(stateless)]
72pub enum AssocItemId {
73 Type(AssocTypeId),
74 Method(TraitMethodId),
75 Const(AssocConstId),
76}
77
78#[derive(
80 Copy,
81 Clone,
82 Debug,
83 PartialOrd,
84 Ord,
85 PartialEq,
86 Eq,
87 Hash,
88 EnumIsA,
89 EnumAsGetters,
90 VariantName,
91 VariantIndexArity,
92 Serialize,
93 Deserialize,
94 SerializeState,
95 DeserializeState,
96 Drive,
97 DriveMut,
98 DriveTwo,
99)]
100#[cfg_attr(feature = "charon_on_charon", charon::variants_prefix("Item"))]
101#[serde_state(stateless)]
102pub enum MaybeAssocItemId {
103 Free(ItemId),
104 Assoc(TraitDeclId, AssocItemId),
105}
106
107#[derive(
109 Debug,
110 Clone,
111 PartialEq,
112 Eq,
113 PartialOrd,
114 Ord,
115 Hash,
116 SerializeState,
117 DeserializeState,
118 Drive,
119 DriveMut,
120 DriveTwo,
121)]
122pub struct TypeDeclRef {
123 pub id: TypeId,
124 pub generics: BoxedArgs,
125}
126
127#[derive(
131 Debug,
132 PartialEq,
133 Eq,
134 Clone,
135 Copy,
136 VariantName,
137 EnumAsGetters,
138 EnumIsA,
139 SerializeState,
140 DeserializeState,
141 Drive,
142 DriveMut,
143 DriveTwo,
144 Hash,
145 Ord,
146 PartialOrd,
147)]
148#[cfg_attr(feature = "charon_on_charon", charon::variants_prefix("T"))]
149pub enum TypeId {
150 #[cfg_attr(feature = "charon_on_charon", charon::rename("TAdtId"))]
155 Adt(TypeDeclId),
156 #[cfg_attr(feature = "charon_on_charon", charon::rename("TBuiltin"))]
164 #[serde_state(stateless)]
165 Builtin(BuiltinTy),
166}
167
168#[derive(
170 Debug,
171 Clone,
172 PartialEq,
173 Eq,
174 PartialOrd,
175 Ord,
176 Hash,
177 SerializeState,
178 DeserializeState,
179 Drive,
180 DriveMut,
181 DriveTwo,
182)]
183pub struct FunDeclRef {
184 pub id: FunDeclId,
185 pub generics: BoxedArgs,
187}
188
189#[derive(
191 Debug,
192 Clone,
193 PartialEq,
194 Eq,
195 PartialOrd,
196 Ord,
197 Hash,
198 EnumIsA,
199 EnumAsGetters,
200 VariantName,
201 SerializeState,
202 DeserializeState,
203 Drive,
204 DriveMut,
205 DriveTwo,
206)]
207#[cfg_attr(feature = "charon_on_charon", charon::variants_prefix("F"))]
208#[serde_state(stateless)]
209pub enum FunId {
210 Regular(FunDeclId),
213 #[cfg_attr(feature = "charon_on_charon", charon::rename("FBuiltin"))]
217 Builtin(BuiltinFunId),
218}
219
220#[derive(
222 Debug,
223 Clone,
224 Copy,
225 PartialEq,
226 Eq,
227 PartialOrd,
228 Ord,
229 Hash,
230 EnumIsA,
231 EnumAsGetters,
232 VariantName,
233 Serialize,
234 Deserialize,
235 Drive,
236 DriveMut,
237 DriveTwo,
238)]
239pub enum BuiltinFunId {
240 BoxNew,
242 ArrayToSliceShared,
246 ArrayToSliceMut,
250 ArrayRepeat,
254 Index(BuiltinIndexOp),
263 PtrFromParts(RefKind),
268}
269
270#[derive(
272 Debug,
273 Clone,
274 Copy,
275 PartialEq,
276 Eq,
277 PartialOrd,
278 Ord,
279 Hash,
280 Serialize,
281 Deserialize,
282 Drive,
283 DriveMut,
284 DriveTwo,
285)]
286pub struct BuiltinIndexOp {
287 #[drive(skip)]
289 pub is_array: bool,
290 pub mutability: RefKind,
293 #[drive(skip)]
297 pub is_range: bool,
298}
299
300#[derive(
301 Debug,
302 Clone,
303 PartialEq,
304 Eq,
305 PartialOrd,
306 Ord,
307 EnumAsGetters,
308 SerializeState,
309 DeserializeState,
310 Drive,
311 DriveMut,
312 DriveTwo,
313 Hash,
314)]
315pub enum FnPtrKind {
316 #[cfg_attr(feature = "charon_on_charon", charon::rename("FunId"))]
317 Fun(FunId),
318 #[cfg_attr(feature = "charon_on_charon", charon::rename("TraitMethod"))]
320 Trait(TraitRef, TraitMethodId),
321}
322
323#[derive(
325 Debug,
326 PartialEq,
327 Eq,
328 PartialOrd,
329 Ord,
330 Clone,
331 Hash,
332 SerializeState,
333 DeserializeState,
334 Drive,
335 DriveMut,
336 DriveTwo,
337)]
338pub struct FnPtr {
339 pub kind: Box<FnPtrKind>,
340 pub generics: BoxedArgs,
341}
342
343#[derive(
346 Debug, Clone, SerializeState, DeserializeState, PartialEq, Eq, Hash, Drive, DriveMut, DriveTwo,
347)]
348pub struct MaybeBuiltinFunDeclRef {
349 pub id: FunId,
350 pub generics: BoxedArgs,
351 pub trait_ref: Option<TraitRef>,
352}
353
354#[derive(
356 Debug,
357 Clone,
358 PartialEq,
359 Eq,
360 PartialOrd,
361 Ord,
362 Hash,
363 SerializeState,
364 DeserializeState,
365 Drive,
366 DriveMut,
367 DriveTwo,
368)]
369pub struct GlobalDeclRef {
370 pub id: GlobalDeclId,
371 pub generics: BoxedArgs,
372}
373
374#[derive(
383 Debug,
384 Clone,
385 PartialEq,
386 Eq,
387 PartialOrd,
388 Ord,
389 Hash,
390 SerializeState,
391 DeserializeState,
392 Drive,
393 DriveMut,
394 DriveTwo,
395)]
396pub struct TraitDeclRef {
397 pub id: TraitDeclId,
398 pub generics: BoxedArgs,
399}
400
401#[derive(
403 Debug,
404 Clone,
405 PartialEq,
406 Eq,
407 PartialOrd,
408 Ord,
409 Hash,
410 SerializeState,
411 DeserializeState,
412 Drive,
413 DriveMut,
414 DriveTwo,
415)]
416pub struct TraitImplRef {
417 pub id: TraitImplId,
418 pub generics: BoxedArgs,
419}
420
421impl TypeDeclRef {
422 pub fn new(id: TypeId, generics: GenericArgs) -> Self {
423 Self {
424 id,
425 generics: Box::new(generics),
426 }
427 }
428
429 pub fn as_builtin(&self) -> Option<BuiltinTy> {
430 self.id.as_builtin().copied()
431 }
432
433 pub fn as_adt(&self) -> Option<TypeDeclId> {
434 self.id.as_adt().copied()
435 }
436
437 pub fn as_adt_mut(&mut self) -> Option<&mut TypeDeclId> {
438 self.id.as_adt_mut()
439 }
440
441 #[track_caller]
442 pub fn adt_id(&self) -> TypeDeclId {
443 self.as_adt()
444 .expect("called `TypeDeclRef::adt_id` on a builtin type")
445 }
446
447 pub fn is_box(&self) -> bool {
448 self.as_builtin() == Some(BuiltinTy::Box)
449 }
450
451 pub fn is_tuple(&self) -> bool {
452 self.as_builtin() == Some(BuiltinTy::Tuple)
453 }
454
455 pub fn is_str(&self) -> bool {
456 self.as_builtin() == Some(BuiltinTy::Str)
457 }
458}
459
460impl TraitDeclRef {
461 pub fn self_ty<'a>(&'a self, krate: &'a TranslatedCrate) -> Option<&'a Ty> {
462 match self.generics.types.iter().next() {
463 Some(ty) => Some(ty),
464 None => {
466 let name = krate.item_name(self.id);
467 let args = name.name.last()?.as_monomorphized()?;
468 args.types.iter().next()
469 }
470 }
471 }
472}
473
474impl FnPtr {
475 pub fn new(kind: FnPtrKind, generics: impl Into<BoxedArgs>) -> Self {
476 Self {
477 kind: Box::new(kind),
478 generics: generics.into(),
479 }
480 }
481
482 pub fn pre_mono_generics<'a>(&'a self, krate: &'a TranslatedCrate) -> &'a GenericArgs {
484 match *self.kind {
485 FnPtrKind::Fun(FunId::Regular(fun_id)) => krate
486 .item_name(fun_id)
487 .mono_args()
488 .unwrap_or(&self.generics),
489 FnPtrKind::Fun(FunId::Builtin(..)) => &self.generics,
491 FnPtrKind::Trait(..) => &self.generics,
493 }
494 }
495}
496
497impl FnPtrKind {
498 pub fn mk_builtin(aid: BuiltinFunId) -> Self {
499 Self::Fun(FunId::Builtin(aid))
500 }
501}
502
503#[derive(Debug, PartialEq, Eq, Clone, Drive, DriveMut, DriveTwo)]
505pub struct DeclRef<Id> {
506 pub id: Id,
507 pub generics: BoxedArgs,
508 pub trait_ref: Option<TraitRef>,
513}
514
515impl DeclRef<ItemId> {
516 pub fn try_convert_id<Id>(self) -> Result<DeclRef<Id>, <ItemId as TryInto<Id>>::Error>
517 where
518 ItemId: TryInto<Id>,
519 {
520 Ok(DeclRef {
521 id: self.id.try_into()?,
522 generics: self.generics,
523 trait_ref: self.trait_ref,
524 })
525 }
526}
527
528macro_rules! convert_item_ref {
530 ($item_ref_ty:ident($id:ident)) => {
531 impl TryFrom<DeclRef<ItemId>> for $item_ref_ty {
532 type Error = ();
533 fn try_from(item: DeclRef<ItemId>) -> Result<Self, ()> {
534 assert!(item.trait_ref.is_none());
535 Ok($item_ref_ty {
536 id: item.id.try_into()?,
537 generics: item.generics,
538 })
539 }
540 }
541 impl From<DeclRef<$id>> for $item_ref_ty {
542 fn from(item: DeclRef<$id>) -> Self {
543 assert!(item.trait_ref.is_none());
544 $item_ref_ty {
545 id: item.id,
546 generics: item.generics,
547 }
548 }
549 }
550 };
551}
552convert_item_ref!(TypeDeclRef(TypeId));
553convert_item_ref!(FunDeclRef(FunDeclId));
554convert_item_ref!(GlobalDeclRef(GlobalDeclId));
555convert_item_ref!(TraitDeclRef(TraitDeclId));
556convert_item_ref!(TraitImplRef(TraitImplId));
557impl TryFrom<DeclRef<ItemId>> for FnPtr {
558 type Error = ();
559 fn try_from(item: DeclRef<ItemId>) -> Result<Self, ()> {
560 if item.trait_ref.is_some() {
561 panic!(
562 "converting `DeclRef<ItemId>` to `FnPtr` cannot
563 deal with the trait method case."
564 )
565 }
566 let id: FunId = item.id.try_into()?;
567 Ok(FnPtr::new(id.into(), item.generics))
568 }
569}
570impl From<FunDeclRef> for FnPtr {
571 fn from(fn_ref: FunDeclRef) -> Self {
572 FnPtr::new(fn_ref.id.into(), fn_ref.generics)
573 }
574}
575impl TryFrom<DeclRef<ItemId>> for MaybeBuiltinFunDeclRef {
576 type Error = ();
577 fn try_from(item: DeclRef<ItemId>) -> Result<Self, ()> {
578 Ok(item.try_convert_id::<FunId>()?.into())
579 }
580}
581impl From<DeclRef<FunId>> for MaybeBuiltinFunDeclRef {
582 fn from(item: DeclRef<FunId>) -> Self {
583 MaybeBuiltinFunDeclRef {
584 id: item.id,
585 generics: item.generics,
586 trait_ref: item.trait_ref,
587 }
588 }
589}
590
591macro_rules! wrap_unwrap_enum {
593 ($enum:ident::$variant:ident($variant_ty:ident)) => {
594 impl TryFrom<$enum> for $variant_ty {
595 type Error = ();
596 fn try_from(x: $enum) -> Result<Self, Self::Error> {
597 match x {
598 $enum::$variant(x) => Ok(x),
599 _ => Err(()),
600 }
601 }
602 }
603
604 impl From<$variant_ty> for $enum {
605 fn from(x: $variant_ty) -> Self {
606 $enum::$variant(x)
607 }
608 }
609 };
610}
611
612wrap_unwrap_enum!(ItemId::Fun(FunDeclId));
613wrap_unwrap_enum!(ItemId::Global(GlobalDeclId));
614wrap_unwrap_enum!(ItemId::Type(TypeDeclId));
615wrap_unwrap_enum!(ItemId::TraitDecl(TraitDeclId));
616wrap_unwrap_enum!(ItemId::TraitImpl(TraitImplId));
617wrap_unwrap_enum!(AssocItemId::Type(AssocTypeId));
618wrap_unwrap_enum!(AssocItemId::Method(TraitMethodId));
619wrap_unwrap_enum!(AssocItemId::Const(AssocConstId));
620
621impl TryFrom<ItemId> for TypeId {
622 type Error = ();
623 fn try_from(x: ItemId) -> Result<Self, Self::Error> {
624 Ok(TypeId::Adt(x.try_into()?))
625 }
626}
627impl TryFrom<ItemId> for FunId {
628 type Error = ();
629 fn try_from(x: ItemId) -> Result<Self, Self::Error> {
630 Ok(FunId::Regular(x.try_into()?))
631 }
632}
633impl From<FunDeclId> for FunId {
634 fn from(id: FunDeclId) -> Self {
635 Self::Regular(id)
636 }
637}
638impl From<BuiltinFunId> for FunId {
639 fn from(id: BuiltinFunId) -> Self {
640 Self::Builtin(id)
641 }
642}
643impl From<FunDeclId> for FnPtrKind {
644 fn from(id: FunDeclId) -> Self {
645 Self::Fun(id.into())
646 }
647}
648impl From<FunId> for FnPtrKind {
649 fn from(id: FunId) -> Self {
650 Self::Fun(id)
651 }
652}