swamp_types/
cache.rs

1/*
2 * Copyright (c) Peter Bjorklund. All rights reserved. https://github.com/swamp/types
3 * Licensed under the MIT License. See LICENSE in the project root for license information.
4 */
5use crate::flags::TypeFlags;
6use crate::supporting_types::{AnonymousStructType, EnumType, NamedStructType, Signature};
7use crate::type_kind::{TypeKind, TypeRef};
8use crate::{Type, TypeId};
9use seq_map::SeqMap;
10use std::rc::Rc;
11
12/// Type cache for interning and deduplicating types in the system
13#[derive(Debug, Clone)]
14pub struct TypeCache {
15    pub(crate) type_id_to_type: SeqMap<TypeId, Rc<Type>>,
16    pub(crate) kind_to_type_id: SeqMap<TypeKind, TypeId>,
17    pub(crate) compatible_cache: SeqMap<(TypeId, TypeId), bool>,
18    pub(crate) next_id: u32,
19}
20
21impl Default for TypeCache {
22    fn default() -> Self {
23        Self::new()
24    }
25}
26
27impl TypeCache {
28    /// Create a new empty type cache
29    #[must_use]
30    pub fn new() -> Self {
31        Self {
32            type_id_to_type: SeqMap::new(),
33            kind_to_type_id: SeqMap::new(),
34            compatible_cache: SeqMap::new(),
35            next_id: 0,
36        }
37    }
38
39    #[must_use]
40    pub const fn type_id_to_type(&self) -> &SeqMap<TypeId, Rc<Type>> {
41        &self.type_id_to_type
42    }
43
44    #[must_use]
45    pub const fn compatible_cache(&self) -> &SeqMap<(TypeId, TypeId), bool> {
46        &self.compatible_cache
47    }
48
49    const fn next_type_id(&mut self) -> TypeId {
50        let id = TypeId(self.next_id);
51        self.next_id += 1;
52        id
53    }
54
55    /// Create a new type instance with the given kind
56    fn create_type(&mut self, kind: TypeKind) -> Rc<Type> {
57        let id = self.next_type_id();
58
59        let flags = TypeFlags::compute_for_type_kind(&kind);
60
61        let type_instance = Type {
62            id,
63            flags,
64            kind: Rc::new(kind),
65        };
66
67        let rc_type = Rc::new(type_instance);
68        self.type_id_to_type
69            .insert(id, Rc::clone(&rc_type))
70            .unwrap();
71
72        rc_type
73    }
74
75    /// Find an existing type in the cache by its kind
76    #[inline]
77    fn find_type(&self, kind: &TypeKind) -> Option<Rc<Type>> {
78        self.kind_to_type_id
79            .get(kind)
80            .map(|id| self.type_id_to_type[id].clone())
81    }
82
83    /// Add a type to the cache for future lookups
84    #[inline]
85    fn add_type_to_cache(&mut self, type_: &Rc<Type>) {
86        self.kind_to_type_id
87            .insert((*type_.kind).clone(), type_.id)
88            .unwrap();
89    }
90
91    /// Get a type by its ID
92    #[inline]
93    #[must_use]
94    pub fn get_by_id(&self, id: TypeId) -> Option<Rc<Type>> {
95        self.type_id_to_type.get(&id).cloned()
96    }
97
98    /// Check if two types are compatible
99    #[allow(clippy::too_many_lines)]
100    pub fn compatible_with(&mut self, a: &Type, b: &Type) -> bool {
101        if a.id == b.id {
102            return true;
103        }
104
105        let key = (a.id, b.id);
106
107        if let Some(&result) = self.compatible_cache.get(&key) {
108            return result;
109        }
110
111        // HACK: Mark as being processed (optimistically), this is to avoid recursion
112        self.compatible_cache
113            .insert(key, false)
114            .expect("should work");
115
116        // Make the slow compatible check
117        let base_compatible = a.do_compatible_with(b, self);
118
119        // If not base compatible, we can return early
120        if !base_compatible {
121            self.compatible_cache.remove(&key);
122            self.compatible_cache
123                .insert(key, false)
124                .expect("should work to insert again");
125            return false;
126        }
127
128        // Now check inner types if needed
129        let result = match (&*a.kind, &*b.kind) {
130            (TypeKind::Optional(inner_a), TypeKind::Optional(inner_b)) => {
131                self.compatible_with(inner_a, inner_b)
132            }
133
134            (TypeKind::VecStorage(elem_a, _), TypeKind::VecStorage(elem_b, _)) => {
135                self.compatible_with(elem_a, elem_b)
136            }
137
138            (TypeKind::SparseStorage(elem_a, _), TypeKind::SparseStorage(elem_b, _)) => {
139                self.compatible_with(elem_a, elem_b)
140            }
141
142            (TypeKind::QueueStorage(elem_a, _), TypeKind::QueueStorage(elem_b, _)) => {
143                self.compatible_with(elem_a, elem_b)
144            }
145
146            (TypeKind::StackStorage(elem_a, _), TypeKind::StackStorage(elem_b, _)) => {
147                self.compatible_with(elem_a, elem_b)
148            }
149
150            (TypeKind::SliceView(elem_a), TypeKind::SliceView(elem_b)) => {
151                self.compatible_with(elem_a, elem_b)
152            }
153
154            (TypeKind::SparseView(elem_a), TypeKind::SparseView(elem_b)) => {
155                self.compatible_with(elem_a, elem_b)
156            }
157
158            (TypeKind::QueueView(elem_a), TypeKind::QueueView(elem_b)) => {
159                self.compatible_with(elem_a, elem_b)
160            }
161
162            (TypeKind::StackView(elem_a), TypeKind::StackView(elem_b)) => {
163                self.compatible_with(elem_a, elem_b)
164            }
165
166            (TypeKind::DynamicLengthVecView(elem_a), TypeKind::DynamicLengthVecView(elem_b)) => {
167                self.compatible_with(elem_a, elem_b)
168            }
169
170            (TypeKind::MapStorage(key_a, val_a, _), TypeKind::MapStorage(key_b, val_b, _)) => {
171                self.compatible_with(key_a, key_b) && self.compatible_with(val_a, val_b)
172            }
173
174            (
175                TypeKind::DynamicLengthMapView(key_a, val_a),
176                TypeKind::DynamicLengthMapView(key_b, val_b),
177            ) => self.compatible_with(key_a, key_b) && self.compatible_with(val_a, val_b),
178
179            (TypeKind::GridStorage(elem_a, _, _), TypeKind::GridStorage(elem_b, _, _)) => {
180                self.compatible_with(elem_a, elem_b)
181            }
182
183            (TypeKind::GridView(elem_a), TypeKind::GridView(elem_b)) => {
184                self.compatible_with(elem_a, elem_b)
185            }
186
187            (TypeKind::Tuple(elems_a), TypeKind::Tuple(elems_b)) => {
188                if elems_a.len() == elems_b.len() {
189                    elems_a
190                        .iter()
191                        .zip(elems_b.iter())
192                        .all(|(a, b)| self.compatible_with(a, b))
193                } else {
194                    false
195                }
196            }
197
198            (
199                TypeKind::FixedCapacityAndLengthArray(elem_a, size_a),
200                TypeKind::FixedCapacityAndLengthArray(elem_b, size_b),
201            ) => size_a == size_b && self.compatible_with(elem_a, elem_b),
202
203            (TypeKind::AnonymousStruct(anon_a), TypeKind::AnonymousStruct(anon_b)) => {
204                // Check if fields match
205                anon_a.field_name_sorted_fields.len() == anon_b.field_name_sorted_fields.len()
206                    && anon_a.field_name_sorted_fields.keys().all(|key| {
207                        anon_b.field_name_sorted_fields.contains_key(key)
208                            && self.compatible_with(
209                                &anon_a.field_name_sorted_fields[key].field_type,
210                                &anon_b.field_name_sorted_fields[key].field_type,
211                            )
212                    })
213            }
214            /*
215
216            (TypeKind::Range(range_a), TypeKind::Range(range_b)) => {
217                // Extract NamedStructType from TypeRef, then AnonymousStructType from that
218                let named_a = match &*range_a.kind {
219                    TypeKind::NamedStruct(named_struct) => named_struct,
220                    _ => return false,
221                };
222                let named_b = match &*range_b.kind {
223                    TypeKind::NamedStruct(named_struct) => named_struct,
224                    _ => return false,
225                };
226
227                let anon_a = match &*named_a.anon_struct_type.kind {
228                    TypeKind::AnonymousStruct(anon_struct) => anon_struct,
229                    _ => return false,
230                };
231                let anon_b = match &*named_b.anon_struct_type.kind {
232                    TypeKind::AnonymousStruct(anon_struct) => anon_struct,
233                    _ => return false,
234                };
235
236                // Compare range types
237                anon_a.field_name_sorted_fields.len() == anon_b.field_name_sorted_fields.len()
238                    && anon_a.field_name_sorted_fields.keys().all(|key| {
239                        anon_b.field_name_sorted_fields.contains_key(key)
240                            && self.compatible_with(
241                                &anon_a.field_name_sorted_fields[key].field_type,
242                                &anon_b.field_name_sorted_fields[key].field_type,
243                            )
244                    })
245            }
246
247             */
248            (TypeKind::NamedStruct(named_a), TypeKind::NamedStruct(named_b)) => {
249                // Check named struct compatibility
250                if named_a.assigned_name == named_b.assigned_name {
251                    self.compatible_with(&named_a.anon_struct_type, &named_b.anon_struct_type)
252                } else {
253                    false
254                }
255            }
256
257            (TypeKind::Enum(enum_a), TypeKind::Enum(enum_b)) => {
258                // Check enum compatibility
259                if enum_a.assigned_name != enum_b.assigned_name
260                    || enum_a.instantiated_type_parameters.len()
261                        != enum_b.instantiated_type_parameters.len()
262                {
263                    false
264                } else {
265                    // Check type parameters compatibility
266                    enum_a
267                        .instantiated_type_parameters
268                        .iter()
269                        .zip(enum_b.instantiated_type_parameters.iter())
270                        .all(|(a, b)| self.compatible_with(a, b))
271                }
272            }
273
274            (TypeKind::Function(sig_a), TypeKind::Function(sig_b)) => {
275                // Compare function signatures
276                if sig_a.parameters.len() == sig_b.parameters.len() {
277                    // Check parameters and return type
278                    let params_match = sig_a
279                        .parameters
280                        .iter()
281                        .zip(sig_b.parameters.iter())
282                        .all(|(a, b)| self.compatible_with(&a.resolved_type, &b.resolved_type));
283
284                    params_match && self.compatible_with(&sig_a.return_type, &sig_b.return_type)
285                } else {
286                    false
287                }
288            }
289
290            _ => true,
291        };
292
293        self.compatible_cache.remove(&key);
294        self.compatible_cache
295            .insert(key, result)
296            .unwrap_or_else(|_| panic!("should be able to insert into cache {key:?}"));
297
298        result
299    }
300
301    /// Clear the compatibility cache
302    pub fn clear_compatibility_cache(&mut self) {
303        self.compatible_cache.clear();
304    }
305
306    pub fn never(&mut self) -> Rc<Type> {
307        let never_kind = TypeKind::Never;
308
309        if let Some(existing) = self.find_type(&never_kind) {
310            return existing;
311        }
312
313        let never_type = self.create_type(never_kind);
314        self.add_type_to_cache(&never_type);
315        never_type
316    }
317
318    //
319    // Primitive helpers
320    // TODO: Maybe just add the primitives at creation instead
321    //
322
323    pub fn byte(&mut self) -> Rc<Type> {
324        let byte_kind = TypeKind::Byte;
325
326        if let Some(existing) = self.find_type(&byte_kind) {
327            return existing;
328        }
329
330        let byte_type = self.create_type(byte_kind);
331        self.add_type_to_cache(&byte_type);
332        byte_type
333    }
334
335    pub fn short(&mut self) -> Rc<Type> {
336        let short_kind = TypeKind::Short;
337
338        if let Some(existing) = self.find_type(&short_kind) {
339            return existing;
340        }
341
342        let short_type = self.create_type(short_kind);
343        self.add_type_to_cache(&short_type);
344        short_type
345    }
346
347    pub fn int(&mut self) -> Rc<Type> {
348        let int_kind = TypeKind::Int;
349
350        if let Some(existing) = self.find_type(&int_kind) {
351            return existing;
352        }
353
354        let int_type = self.create_type(int_kind);
355        self.add_type_to_cache(&int_type);
356        int_type
357    }
358
359    pub fn codepoint(&mut self) -> Rc<Type> {
360        let char_kind = TypeKind::Codepoint;
361
362        if let Some(existing) = self.find_type(&char_kind) {
363            return existing;
364        }
365
366        let char_type = self.create_type(char_kind);
367        self.add_type_to_cache(&char_type);
368        char_type
369    }
370
371    pub fn float(&mut self) -> Rc<Type> {
372        let float_kind = TypeKind::Float;
373
374        if let Some(existing) = self.find_type(&float_kind) {
375            return existing;
376        }
377
378        let float_type = self.create_type(float_kind);
379        self.add_type_to_cache(&float_type);
380        float_type
381    }
382
383    pub fn bool(&mut self) -> Rc<Type> {
384        let bool_kind = TypeKind::Bool;
385
386        if let Some(existing) = self.find_type(&bool_kind) {
387            return existing;
388        }
389
390        let bool_type = self.create_type(bool_kind);
391        self.add_type_to_cache(&bool_type);
392        bool_type
393    }
394
395    pub fn unit(&mut self) -> Rc<Type> {
396        let unit_kind = TypeKind::Unit;
397
398        if let Some(existing) = self.find_type(&unit_kind) {
399            return existing;
400        }
401
402        let unit_type = self.create_type(unit_kind);
403        self.add_type_to_cache(&unit_type);
404        unit_type
405    }
406
407    //
408    // Container type helpers
409    //
410
411    pub fn optional(&mut self, inner_type: &Rc<Type>) -> Rc<Type> {
412        let optional_kind = TypeKind::Optional(Rc::clone(inner_type));
413
414        if let Some(existing) = self.find_type(&optional_kind) {
415            return existing;
416        }
417
418        let optional_type = self.create_type(optional_kind);
419        self.add_type_to_cache(&optional_type);
420        optional_type
421    }
422
423    pub fn tuple(&mut self, element_types: Vec<Rc<Type>>) -> Rc<Type> {
424        let tuple_kind = TypeKind::Tuple(element_types);
425
426        if let Some(existing) = self.find_type(&tuple_kind) {
427            return existing;
428        }
429
430        let tuple_type = self.create_type(tuple_kind);
431        self.add_type_to_cache(&tuple_type);
432        tuple_type
433    }
434
435    pub fn string_storage(&mut self, capacity: usize) -> Rc<Type> {
436        let string_kind = TypeKind::StringStorage(self.byte(), self.codepoint(), capacity);
437
438        if let Some(existing) = self.find_type(&string_kind) {
439            return existing;
440        }
441
442        let string_type = self.create_type(string_kind);
443        self.add_type_to_cache(&string_type);
444        string_type
445    }
446
447    pub fn string(&mut self) -> Rc<Type> {
448        let string_kind = TypeKind::StringView(self.byte(), self.codepoint());
449
450        if let Some(existing) = self.find_type(&string_kind) {
451            return existing;
452        }
453
454        let string_type = self.create_type(string_kind);
455        self.add_type_to_cache(&string_type);
456        string_type
457    }
458
459    pub fn ptr(&mut self, inner_type: TypeRef) -> Rc<Type> {
460        let ptr_kind = TypeKind::Pointer(Rc::clone(&inner_type));
461
462        if let Some(existing) = self.find_type(&ptr_kind) {
463            return existing;
464        }
465
466        let new_ptr_type = self.create_type(ptr_kind);
467        self.add_type_to_cache(&new_ptr_type);
468        new_ptr_type
469    }
470
471    // TODO: Maybe use a shared function for types with one element type
472    pub fn vec_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
473        let vec_kind = TypeKind::VecStorage(Rc::clone(element_type), capacity);
474
475        if let Some(existing) = self.find_type(&vec_kind) {
476            return existing;
477        }
478
479        let vec_type = self.create_type(vec_kind);
480        self.add_type_to_cache(&vec_type);
481        vec_type
482    }
483
484    pub fn sparse_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
485        let sparse_kind = TypeKind::SparseStorage(Rc::clone(element_type), capacity);
486
487        if let Some(existing) = self.find_type(&sparse_kind) {
488            return existing;
489        }
490
491        let sparse_type = self.create_type(sparse_kind);
492        self.add_type_to_cache(&sparse_type);
493        sparse_type
494    }
495
496    pub fn queue_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
497        let queue_kind = TypeKind::QueueStorage(Rc::clone(element_type), capacity);
498
499        if let Some(existing) = self.find_type(&queue_kind) {
500            return existing;
501        }
502
503        let queue_type = self.create_type(queue_kind);
504        self.add_type_to_cache(&queue_type);
505        queue_type
506    }
507
508    pub fn stack_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
509        let stack_kind = TypeKind::StackStorage(Rc::clone(element_type), capacity);
510
511        if let Some(existing) = self.find_type(&stack_kind) {
512            return existing;
513        }
514
515        let stack_type = self.create_type(stack_kind);
516        self.add_type_to_cache(&stack_type);
517        stack_type
518    }
519
520    pub fn map_storage(
521        &mut self,
522        key_type: &Rc<Type>,
523        value_type: &Rc<Type>,
524        capacity: usize,
525    ) -> Rc<Type> {
526        let map_kind = TypeKind::MapStorage(Rc::clone(key_type), Rc::clone(value_type), capacity);
527
528        if let Some(existing) = self.find_type(&map_kind) {
529            return existing;
530        }
531
532        let map_type = self.create_type(map_kind);
533        self.add_type_to_cache(&map_type);
534        map_type
535    }
536
537    pub fn grid_storage(&mut self, element_type: &Rc<Type>, rows: usize, cols: usize) -> Rc<Type> {
538        let grid_kind = TypeKind::GridStorage(Rc::clone(element_type), rows, cols);
539
540        if let Some(existing) = self.find_type(&grid_kind) {
541            return existing;
542        }
543
544        let grid_type = self.create_type(grid_kind);
545        self.add_type_to_cache(&grid_type);
546        grid_type
547    }
548
549    pub fn fixed_array(&mut self, element_type: &Rc<Type>, size: usize) -> Rc<Type> {
550        let array_kind = TypeKind::FixedCapacityAndLengthArray(Rc::clone(element_type), size);
551
552        if let Some(existing) = self.find_type(&array_kind) {
553            return existing;
554        }
555
556        let array_type = self.create_type(array_kind);
557        self.add_type_to_cache(&array_type);
558        array_type
559    }
560
561    pub fn slice_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
562        let slice_kind = TypeKind::SliceView(Rc::clone(element_type));
563
564        if let Some(existing) = self.find_type(&slice_kind) {
565            return existing;
566        }
567
568        let slice_type = self.create_type(slice_kind);
569        self.add_type_to_cache(&slice_type);
570        slice_type
571    }
572
573    pub fn sparse_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
574        let sparse_kind = TypeKind::SparseView(Rc::clone(element_type));
575
576        if let Some(existing) = self.find_type(&sparse_kind) {
577            return existing;
578        }
579
580        let sparse_type = self.create_type(sparse_kind);
581        self.add_type_to_cache(&sparse_type);
582        sparse_type
583    }
584
585    pub fn queue_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
586        let queue_kind = TypeKind::QueueView(Rc::clone(element_type));
587
588        if let Some(existing) = self.find_type(&queue_kind) {
589            return existing;
590        }
591
592        let queue_type = self.create_type(queue_kind);
593        self.add_type_to_cache(&queue_type);
594        queue_type
595    }
596
597    pub fn stack_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
598        let stack_kind = TypeKind::StackView(Rc::clone(element_type));
599
600        if let Some(existing) = self.find_type(&stack_kind) {
601            return existing;
602        }
603
604        let stack_type = self.create_type(stack_kind);
605        self.add_type_to_cache(&stack_type);
606        stack_type
607    }
608
609    pub fn any(&mut self) -> Rc<Type> {
610        let any_kind = TypeKind::Any;
611
612        if let Some(existing) = self.find_type(&any_kind) {
613            return existing;
614        }
615
616        let any_type = self.create_type(any_kind);
617        self.add_type_to_cache(&any_type);
618        any_type
619    }
620
621    pub fn dynamic_vec_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
622        let vec_view_kind = TypeKind::DynamicLengthVecView(Rc::clone(element_type));
623
624        if let Some(existing) = self.find_type(&vec_view_kind) {
625            return existing;
626        }
627
628        let vec_view_type = self.create_type(vec_view_kind);
629        self.add_type_to_cache(&vec_view_type);
630        vec_view_type
631    }
632
633    pub fn dynamic_map_view(&mut self, key_type: &Rc<Type>, value_type: &Rc<Type>) -> Rc<Type> {
634        let map_view_kind =
635            TypeKind::DynamicLengthMapView(Rc::clone(key_type), Rc::clone(value_type));
636
637        if let Some(existing) = self.find_type(&map_view_kind) {
638            return existing;
639        }
640
641        let map_view_type = self.create_type(map_view_kind);
642        self.add_type_to_cache(&map_view_type);
643        map_view_type
644    }
645
646    pub fn grid_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
647        let grid_view_kind = TypeKind::GridView(Rc::clone(element_type));
648
649        if let Some(existing) = self.find_type(&grid_view_kind) {
650            return existing;
651        }
652
653        let grid_view_type = self.create_type(grid_view_kind);
654        self.add_type_to_cache(&grid_view_type);
655        grid_view_type
656    }
657
658    //
659    // Complex type helpers
660    //
661
662    /// Create an anonymous struct type
663    pub fn anonymous_struct(&mut self, anon_struct: AnonymousStructType) -> Rc<Type> {
664        let struct_kind = TypeKind::AnonymousStruct(anon_struct);
665
666        if let Some(existing) = self.find_type(&struct_kind) {
667            return existing;
668        }
669
670        let struct_type = self.create_type(struct_kind);
671        self.add_type_to_cache(&struct_type);
672        struct_type
673    }
674
675    /*
676    pub fn range(&mut self, range_struct_ref: TypeRef) -> Rc<Type> {
677        let range_kind = TypeKind::Range(range_struct_ref);
678
679        if let Some(existing) = self.find_type(&range_kind) {
680            return existing;
681        }
682
683        let range_type = self.create_type(range_kind);
684        self.add_type_to_cache(&range_type);
685        range_type
686    }
687
688     */
689
690    /*
691    pub fn range_int(&mut self) -> Rc<Type> {
692        let int_type = self.int();
693        let bool_type = self.bool();
694
695        // Create an anonymous struct for the Range type: {min: int, max: int, inclusive: bool}
696        let mut range_fields = SeqMap::new();
697        let _ = range_fields.insert(
698            "start".to_string(),
699            StructTypeField {
700                symbol_id: SymbolHandle::new_illegal(),
701                identifier: None,
702                field_type: int_type.clone(),
703            },
704        );
705        let _ = range_fields.insert(
706            "end".to_string(),
707            StructTypeField {
708                symbol_id: SymbolHandle::new_illegal(),
709                identifier: None,
710                field_type: int_type,
711            },
712        );
713        let _ = range_fields.insert(
714            "is_inclusive".to_string(),
715            StructTypeField {
716                symbol_id: SymbolHandle::new_illegal(),
717                identifier: None,
718                field_type: bool_type,
719            },
720        );
721
722        let anon_struct = AnonymousStructType::new(range_fields);
723        let anon_struct_ref = self.anonymous_struct(anon_struct);
724        /*
725               // Create a NamedStructType for Range
726               let range_named_struct = NamedStructType::new(
727                   Node::default(),
728                   "Range",
729                   anon_struct_ref,
730                   &["core".to_string()],
731               );
732
733        */
734
735        //let named_struct_ref1 = self.named_struct(range_named_struct.clone());
736
737        self.range(anon_struct_ref)
738    }
739
740     */
741
742    pub fn named_struct(&mut self, named_struct: NamedStructType) -> Rc<Type> {
743        let struct_kind = TypeKind::NamedStruct(named_struct);
744
745        if let Some(existing) = self.find_type(&struct_kind) {
746            return existing;
747        }
748
749        let struct_type = self.create_type(struct_kind);
750        self.add_type_to_cache(&struct_type);
751        struct_type
752    }
753
754    pub fn enum_type(&mut self, enum_type: EnumType) -> Rc<Type> {
755        let enum_kind = TypeKind::Enum(enum_type);
756
757        if let Some(existing) = self.find_type(&enum_kind) {
758            return existing;
759        }
760
761        let enum_type = self.create_type(enum_kind);
762        self.add_type_to_cache(&enum_type);
763        enum_type
764    }
765
766    pub fn function(&mut self, signature: Signature) -> Rc<Type> {
767        let function_kind = TypeKind::Function(signature);
768
769        if let Some(existing) = self.find_type(&function_kind) {
770            return existing;
771        }
772
773        let function_type = self.create_type(function_kind);
774        self.add_type_to_cache(&function_type);
775        function_type
776    }
777}