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