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