1use 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#[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 #[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 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 #[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 #[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 #[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 #[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 self.compatible_cache
119 .insert(key, false)
120 .expect("should work");
121
122 let base_compatible = a.do_compatible_with(b, self);
124
125 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 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 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 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 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 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 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 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 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 if sig_a.parameters.len() == sig_b.parameters.len() {
289 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 pub fn clear_compatibility_cache(&mut self) {
315 self.compatible_cache.clear();
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 int(&mut self) -> Rc<Type> {
336 let int_kind = TypeKind::Int;
337
338 if let Some(existing) = self.find_type(&int_kind) {
339 return existing;
340 }
341
342 let int_type = self.create_type(int_kind);
343 self.add_type_to_cache(&int_type);
344 int_type
345 }
346
347 pub fn codepoint(&mut self) -> Rc<Type> {
348 let char_kind = TypeKind::Codepoint;
349
350 if let Some(existing) = self.find_type(&char_kind) {
351 return existing;
352 }
353
354 let char_type = self.create_type(char_kind);
355 self.add_type_to_cache(&char_type);
356 char_type
357 }
358
359 pub fn float(&mut self) -> Rc<Type> {
360 let float_kind = TypeKind::Float;
361
362 if let Some(existing) = self.find_type(&float_kind) {
363 return existing;
364 }
365
366 let float_type = self.create_type(float_kind);
367 self.add_type_to_cache(&float_type);
368 float_type
369 }
370
371 pub fn bool(&mut self) -> Rc<Type> {
372 let bool_kind = TypeKind::Bool;
373
374 if let Some(existing) = self.find_type(&bool_kind) {
375 return existing;
376 }
377
378 let bool_type = self.create_type(bool_kind);
379 self.add_type_to_cache(&bool_type);
380 bool_type
381 }
382
383 pub fn unit(&mut self) -> Rc<Type> {
384 let unit_kind = TypeKind::Unit;
385
386 if let Some(existing) = self.find_type(&unit_kind) {
387 return existing;
388 }
389
390 let unit_type = self.create_type(unit_kind);
391 self.add_type_to_cache(&unit_type);
392 unit_type
393 }
394
395 pub fn optional(&mut self, inner_type: &Rc<Type>) -> Rc<Type> {
400 let optional_kind = TypeKind::Optional(Rc::clone(inner_type));
401
402 if let Some(existing) = self.find_type(&optional_kind) {
403 return existing;
404 }
405
406 let optional_type = self.create_type(optional_kind);
407 self.add_type_to_cache(&optional_type);
408 optional_type
409 }
410
411 pub fn tuple(&mut self, element_types: Vec<Rc<Type>>) -> Rc<Type> {
412 let tuple_kind = TypeKind::Tuple(element_types);
413
414 if let Some(existing) = self.find_type(&tuple_kind) {
415 return existing;
416 }
417
418 let tuple_type = self.create_type(tuple_kind);
419 self.add_type_to_cache(&tuple_type);
420 tuple_type
421 }
422
423 pub fn string_storage(&mut self, capacity: usize) -> Rc<Type> {
424 let string_kind = TypeKind::StringStorage(self.byte(), self.codepoint(), capacity);
425
426 if let Some(existing) = self.find_type(&string_kind) {
427 return existing;
428 }
429
430 let string_type = self.create_type(string_kind);
431 self.add_type_to_cache(&string_type);
432 string_type
433 }
434
435 pub fn string(&mut self) -> Rc<Type> {
436 let string_kind = TypeKind::String(self.byte(), self.codepoint());
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 vec_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
449 let vec_kind = TypeKind::VecStorage(Rc::clone(element_type), capacity);
450
451 if let Some(existing) = self.find_type(&vec_kind) {
452 return existing;
453 }
454
455 let vec_type = self.create_type(vec_kind);
456 self.add_type_to_cache(&vec_type);
457 vec_type
458 }
459
460 pub fn sparse_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
461 let sparse_kind = TypeKind::SparseStorage(Rc::clone(element_type), capacity);
462
463 if let Some(existing) = self.find_type(&sparse_kind) {
464 return existing;
465 }
466
467 let sparse_type = self.create_type(sparse_kind);
468 self.add_type_to_cache(&sparse_type);
469 sparse_type
470 }
471
472 pub fn queue_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
473 let queue_kind = TypeKind::QueueStorage(Rc::clone(element_type), capacity);
474
475 if let Some(existing) = self.find_type(&queue_kind) {
476 return existing;
477 }
478
479 let queue_type = self.create_type(queue_kind);
480 self.add_type_to_cache(&queue_type);
481 queue_type
482 }
483
484 pub fn stack_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
485 let stack_kind = TypeKind::StackStorage(Rc::clone(element_type), capacity);
486
487 if let Some(existing) = self.find_type(&stack_kind) {
488 return existing;
489 }
490
491 let stack_type = self.create_type(stack_kind);
492 self.add_type_to_cache(&stack_type);
493 stack_type
494 }
495
496 pub fn map_storage(
497 &mut self,
498 key_type: &Rc<Type>,
499 value_type: &Rc<Type>,
500 capacity: usize,
501 ) -> Rc<Type> {
502 let map_kind = TypeKind::MapStorage(Rc::clone(key_type), Rc::clone(value_type), capacity);
503
504 if let Some(existing) = self.find_type(&map_kind) {
505 return existing;
506 }
507
508 let map_type = self.create_type(map_kind);
509 self.add_type_to_cache(&map_type);
510 map_type
511 }
512
513 pub fn grid_storage(&mut self, element_type: &Rc<Type>, rows: usize, cols: usize) -> Rc<Type> {
514 let grid_kind = TypeKind::GridStorage(Rc::clone(element_type), rows, cols);
515
516 if let Some(existing) = self.find_type(&grid_kind) {
517 return existing;
518 }
519
520 let grid_type = self.create_type(grid_kind);
521 self.add_type_to_cache(&grid_type);
522 grid_type
523 }
524
525 pub fn fixed_array(&mut self, element_type: &Rc<Type>, size: usize) -> Rc<Type> {
526 let array_kind = TypeKind::FixedCapacityAndLengthArray(Rc::clone(element_type), size);
527
528 if let Some(existing) = self.find_type(&array_kind) {
529 return existing;
530 }
531
532 let array_type = self.create_type(array_kind);
533 self.add_type_to_cache(&array_type);
534 array_type
535 }
536
537 pub fn slice_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
538 let slice_kind = TypeKind::SliceView(Rc::clone(element_type));
539
540 if let Some(existing) = self.find_type(&slice_kind) {
541 return existing;
542 }
543
544 let slice_type = self.create_type(slice_kind);
545 self.add_type_to_cache(&slice_type);
546 slice_type
547 }
548
549 pub fn sparse_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
550 let sparse_kind = TypeKind::SparseView(Rc::clone(element_type));
551
552 if let Some(existing) = self.find_type(&sparse_kind) {
553 return existing;
554 }
555
556 let sparse_type = self.create_type(sparse_kind);
557 self.add_type_to_cache(&sparse_type);
558 sparse_type
559 }
560
561 pub fn queue_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
562 let queue_kind = TypeKind::QueueView(Rc::clone(element_type));
563
564 if let Some(existing) = self.find_type(&queue_kind) {
565 return existing;
566 }
567
568 let queue_type = self.create_type(queue_kind);
569 self.add_type_to_cache(&queue_type);
570 queue_type
571 }
572
573 pub fn stack_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
574 let stack_kind = TypeKind::StackView(Rc::clone(element_type));
575
576 if let Some(existing) = self.find_type(&stack_kind) {
577 return existing;
578 }
579
580 let stack_type = self.create_type(stack_kind);
581 self.add_type_to_cache(&stack_type);
582 stack_type
583 }
584
585 pub fn any(&mut self) -> Rc<Type> {
586 let any_kind = TypeKind::Any;
587
588 if let Some(existing) = self.find_type(&any_kind) {
589 return existing;
590 }
591
592 let any_type = self.create_type(any_kind);
593 self.add_type_to_cache(&any_type);
594 any_type
595 }
596
597 pub fn dynamic_vec_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
598 let vec_view_kind = TypeKind::DynamicLengthVecView(Rc::clone(element_type));
599
600 if let Some(existing) = self.find_type(&vec_view_kind) {
601 return existing;
602 }
603
604 let vec_view_type = self.create_type(vec_view_kind);
605 self.add_type_to_cache(&vec_view_type);
606 vec_view_type
607 }
608
609 pub fn dynamic_map_view(&mut self, key_type: &Rc<Type>, value_type: &Rc<Type>) -> Rc<Type> {
610 let map_view_kind =
611 TypeKind::DynamicLengthMapView(Rc::clone(key_type), Rc::clone(value_type));
612
613 if let Some(existing) = self.find_type(&map_view_kind) {
614 return existing;
615 }
616
617 let map_view_type = self.create_type(map_view_kind);
618 self.add_type_to_cache(&map_view_type);
619 map_view_type
620 }
621
622 pub fn grid_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
623 let grid_view_kind = TypeKind::GridView(Rc::clone(element_type));
624
625 if let Some(existing) = self.find_type(&grid_view_kind) {
626 return existing;
627 }
628
629 let grid_view_type = self.create_type(grid_view_kind);
630 self.add_type_to_cache(&grid_view_type);
631 grid_view_type
632 }
633
634 pub fn anonymous_struct(&mut self, anon_struct: AnonymousStructType) -> Rc<Type> {
640 let struct_kind = TypeKind::AnonymousStruct(anon_struct);
641
642 if let Some(existing) = self.find_type(&struct_kind) {
643 return existing;
644 }
645
646 let struct_type = self.create_type(struct_kind);
647 self.add_type_to_cache(&struct_type);
648 struct_type
649 }
650
651 pub fn range(&mut self, range_struct_ref: TypeRef) -> Rc<Type> {
652 let range_kind = TypeKind::Range(range_struct_ref);
653
654 if let Some(existing) = self.find_type(&range_kind) {
655 return existing;
656 }
657
658 let range_type = self.create_type(range_kind);
659 self.add_type_to_cache(&range_type);
660 range_type
661 }
662
663 pub fn range_int(&mut self) -> Rc<Type> {
664 let int_type = self.int();
665 let bool_type = self.bool();
666
667 let mut range_fields = SeqMap::new();
669 let _ = range_fields.insert(
670 "start".to_string(),
671 StructTypeField {
672 identifier: None,
673 field_type: int_type.clone(),
674 },
675 );
676 let _ = range_fields.insert(
677 "end".to_string(),
678 StructTypeField {
679 identifier: None,
680 field_type: int_type,
681 },
682 );
683 let _ = range_fields.insert(
684 "is_inclusive".to_string(),
685 StructTypeField {
686 identifier: None,
687 field_type: bool_type,
688 },
689 );
690
691 let anon_struct = AnonymousStructType::new(range_fields);
692 let anon_struct_ref = self.anonymous_struct(anon_struct);
693 self.range(anon_struct_ref)
707 }
708
709 pub fn named_struct(&mut self, named_struct: NamedStructType) -> Rc<Type> {
710 let struct_kind = TypeKind::NamedStruct(named_struct);
711
712 if let Some(existing) = self.find_type(&struct_kind) {
713 return existing;
714 }
715
716 let struct_type = self.create_type(struct_kind);
717 self.add_type_to_cache(&struct_type);
718 struct_type
719 }
720
721 pub fn enum_type(&mut self, enum_type: EnumType) -> Rc<Type> {
722 let enum_kind = TypeKind::Enum(enum_type);
723
724 if let Some(existing) = self.find_type(&enum_kind) {
725 return existing;
726 }
727
728 let enum_type = self.create_type(enum_kind);
729 self.add_type_to_cache(&enum_type);
730 enum_type
731 }
732
733 pub fn function(&mut self, signature: Signature) -> Rc<Type> {
734 let function_kind = TypeKind::Function(signature);
735
736 if let Some(existing) = self.find_type(&function_kind) {
737 return existing;
738 }
739
740 let function_type = self.create_type(function_kind);
741 self.add_type_to_cache(&function_type);
742 function_type
743 }
744}