swamp_types/
cache.rs

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