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