1use 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#[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 #[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 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 #[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 #[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 #[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 #[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 self.compatible_cache
113 .insert(key, false)
114 .expect("should work");
115
116 let base_compatible = a.do_compatible_with(b, self);
118
119 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 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 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 (TypeKind::NamedStruct(named_a), TypeKind::NamedStruct(named_b)) => {
249 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 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 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 if sig_a.parameters.len() == sig_b.parameters.len() {
277 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 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 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 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 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 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 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}