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