1use crate::flags::TypeFlags;
7use crate::supporting_types::{AnonymousStructType, EnumType, NamedStructType, Signature};
8use crate::type_kind::{TypeKind, TypeRef};
9use crate::{Type, TypeId};
10use seq_map::SeqMap;
11use std::rc::Rc;
12
13#[derive(Debug, Clone)]
15pub struct TypeCache {
16 pub(crate) type_id_to_type: SeqMap<TypeId, Rc<Type>>,
17 pub(crate) kind_to_type_id: SeqMap<TypeKind, TypeId>,
18 pub(crate) compatible_cache: SeqMap<(TypeId, TypeId), bool>,
19 pub(crate) next_id: u32,
20}
21
22impl TypeCache {}
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.insert(id, Rc::clone(&rc_type));
72
73 rc_type
74 }
75
76 fn create_type_mutable(&mut self, kind: TypeKind, is_mutable: bool) -> Rc<Type> {
77 let id = self.next_type_id();
78
79 let flags = TypeFlags::compute_for_type_kind(&kind);
80
81 let type_instance = Type {
82 id,
83 flags,
84 kind: Rc::new(kind),
85 };
86
87 let rc_type = Rc::new(type_instance);
88 self.type_id_to_type.insert(id, Rc::clone(&rc_type));
89
90 rc_type
91 }
92
93 #[inline]
95 fn find_type(&self, kind: &TypeKind) -> Option<Rc<Type>> {
96 self.kind_to_type_id
97 .get(kind)
98 .map(|id| self.type_id_to_type[id].clone())
99 }
100
101 #[inline]
103 fn add_type_to_cache(&mut self, type_: &Rc<Type>) {
104 self.kind_to_type_id.insert((*type_.kind).clone(), type_.id);
105 }
106
107 #[inline]
109 #[must_use]
110 pub fn get_by_id(&self, id: TypeId) -> Option<Rc<Type>> {
111 self.type_id_to_type.get(&id).cloned()
112 }
113
114 #[allow(clippy::too_many_lines)]
116 pub fn compatible_with(&mut self, a: &Type, b: &Type) -> bool {
117 if a.id == b.id {
118 return true;
119 }
120
121 let key = (a.id, b.id);
122
123 if let Some(&result) = self.compatible_cache.get(&key) {
124 return result;
125 }
126
127 self.compatible_cache
129 .insert(key, false)
130 .expect("should work");
131
132 let base_compatible = a.do_compatible_with(b, self);
134
135 if !base_compatible {
137 self.compatible_cache.remove(&key);
138 self.compatible_cache
139 .insert(key, false)
140 .expect("should work to insert again");
141 return false;
142 }
143
144 let result = match (&*a.kind, &*b.kind) {
146 (TypeKind::Optional(inner_a), TypeKind::Optional(inner_b)) => {
147 self.compatible_with(inner_a, inner_b)
148 }
149
150 (TypeKind::VecStorage(elem_a, _), TypeKind::VecStorage(elem_b, _)) => {
151 self.compatible_with(elem_a, elem_b)
152 }
153
154 (TypeKind::SparseStorage(elem_a, _), TypeKind::SparseStorage(elem_b, _)) => {
155 self.compatible_with(elem_a, elem_b)
156 }
157
158 (TypeKind::QueueStorage(elem_a, _), TypeKind::QueueStorage(elem_b, _)) => {
159 self.compatible_with(elem_a, elem_b)
160 }
161
162 (TypeKind::StackStorage(elem_a, _), TypeKind::StackStorage(elem_b, _)) => {
163 self.compatible_with(elem_a, elem_b)
164 }
165
166 (TypeKind::SliceView(elem_a), TypeKind::SliceView(elem_b)) => {
167 self.compatible_with(elem_a, elem_b)
168 }
169
170 (TypeKind::SparseView(elem_a), TypeKind::SparseView(elem_b)) => {
171 self.compatible_with(elem_a, elem_b)
172 }
173
174 (TypeKind::QueueView(elem_a), TypeKind::QueueView(elem_b)) => {
175 self.compatible_with(elem_a, elem_b)
176 }
177
178 (TypeKind::StackView(elem_a), TypeKind::StackView(elem_b)) => {
179 self.compatible_with(elem_a, elem_b)
180 }
181
182 (TypeKind::DynamicLengthVecView(elem_a), TypeKind::DynamicLengthVecView(elem_b)) => {
183 self.compatible_with(elem_a, elem_b)
184 }
185
186 (TypeKind::MapStorage(key_a, val_a, _), TypeKind::MapStorage(key_b, val_b, _)) => {
187 self.compatible_with(key_a, key_b) && self.compatible_with(val_a, val_b)
188 }
189
190 (
191 TypeKind::DynamicLengthMapView(key_a, val_a),
192 TypeKind::DynamicLengthMapView(key_b, val_b),
193 ) => self.compatible_with(key_a, key_b) && self.compatible_with(val_a, val_b),
194
195 (TypeKind::GridStorage(elem_a, _, _), TypeKind::GridStorage(elem_b, _, _)) => {
196 self.compatible_with(elem_a, elem_b)
197 }
198
199 (TypeKind::GridView(elem_a), TypeKind::GridView(elem_b)) => {
200 self.compatible_with(elem_a, elem_b)
201 }
202
203 (TypeKind::Tuple(elems_a), TypeKind::Tuple(elems_b)) => {
204 if elems_a.len() == elems_b.len() {
205 elems_a
206 .iter()
207 .zip(elems_b.iter())
208 .all(|(a, b)| self.compatible_with(a, b))
209 } else {
210 false
211 }
212 }
213
214 (
215 TypeKind::FixedCapacityAndLengthArray(elem_a, size_a),
216 TypeKind::FixedCapacityAndLengthArray(elem_b, size_b),
217 ) => size_a == size_b && self.compatible_with(elem_a, elem_b),
218
219 (TypeKind::AnonymousStruct(anon_a), TypeKind::AnonymousStruct(anon_b)) => {
220 anon_a.field_name_sorted_fields.len() == anon_b.field_name_sorted_fields.len()
222 && anon_a.field_name_sorted_fields.keys().all(|key| {
223 anon_b.field_name_sorted_fields.contains_key(key)
224 && self.compatible_with(
225 &anon_a.field_name_sorted_fields[key].field_type,
226 &anon_b.field_name_sorted_fields[key].field_type,
227 )
228 })
229 }
230
231 (TypeKind::Range(range_a), TypeKind::Range(range_b)) => {
232 let named_a = match &*range_a.kind {
234 TypeKind::NamedStruct(named_struct) => named_struct,
235 _ => return false,
236 };
237 let named_b = match &*range_b.kind {
238 TypeKind::NamedStruct(named_struct) => named_struct,
239 _ => return false,
240 };
241
242 let anon_a = match &*named_a.anon_struct_type.kind {
243 TypeKind::AnonymousStruct(anon_struct) => anon_struct,
244 _ => return false,
245 };
246 let anon_b = match &*named_b.anon_struct_type.kind {
247 TypeKind::AnonymousStruct(anon_struct) => anon_struct,
248 _ => return false,
249 };
250
251 anon_a.field_name_sorted_fields.len() == anon_b.field_name_sorted_fields.len()
253 && anon_a.field_name_sorted_fields.keys().all(|key| {
254 anon_b.field_name_sorted_fields.contains_key(key)
255 && self.compatible_with(
256 &anon_a.field_name_sorted_fields[key].field_type,
257 &anon_b.field_name_sorted_fields[key].field_type,
258 )
259 })
260 }
261
262 (TypeKind::NamedStruct(named_a), TypeKind::NamedStruct(named_b)) => {
263 if named_a.assigned_name != named_b.assigned_name
265 || named_a.instantiated_type_parameters.len()
266 != named_b.instantiated_type_parameters.len()
267 {
268 false
269 } else {
270 named_a
272 .instantiated_type_parameters
273 .iter()
274 .zip(named_b.instantiated_type_parameters.iter())
275 .all(|(a, b)| self.compatible_with(a, b))
276 }
277 }
278
279 (TypeKind::Enum(enum_a), TypeKind::Enum(enum_b)) => {
280 if enum_a.assigned_name != enum_b.assigned_name
282 || enum_a.instantiated_type_parameters.len()
283 != enum_b.instantiated_type_parameters.len()
284 {
285 false
286 } else {
287 enum_a
289 .instantiated_type_parameters
290 .iter()
291 .zip(enum_b.instantiated_type_parameters.iter())
292 .all(|(a, b)| self.compatible_with(a, b))
293 }
294 }
295
296 (TypeKind::Function(sig_a), TypeKind::Function(sig_b)) => {
297 if sig_a.parameters.len() == sig_b.parameters.len() {
299 let params_match = sig_a
301 .parameters
302 .iter()
303 .zip(sig_b.parameters.iter())
304 .all(|(a, b)| self.compatible_with(&a.resolved_type, &b.resolved_type));
305
306 params_match && self.compatible_with(&sig_a.return_type, &sig_b.return_type)
307 } else {
308 false
309 }
310 }
311
312 _ => true,
313 };
314
315 self.compatible_cache.remove(&key);
316 self.compatible_cache
317 .insert(key, result)
318 .unwrap_or_else(|_| panic!("should be able to insert into cache {key:?}"));
319
320 result
321 }
322
323 pub fn clear_compatibility_cache(&mut self) {
325 self.compatible_cache.clear();
326 }
327
328 pub fn byte(&mut self) -> Rc<Type> {
334 let byte_kind = TypeKind::Byte;
335
336 if let Some(existing) = self.find_type(&byte_kind) {
337 return existing;
338 }
339
340 let byte_type = self.create_type(byte_kind);
341 self.add_type_to_cache(&byte_type);
342 byte_type
343 }
344
345 pub fn int(&mut self) -> Rc<Type> {
346 let int_kind = TypeKind::Int;
347
348 if let Some(existing) = self.find_type(&int_kind) {
349 return existing;
350 }
351
352 let int_type = self.create_type(int_kind);
353 self.add_type_to_cache(&int_type);
354 int_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 string(&mut self) -> Rc<Type> {
370 let string_kind = TypeKind::String;
371
372 if let Some(existing) = self.find_type(&string_kind) {
373 return existing;
374 }
375
376 let string_type = self.create_type(string_kind);
377 self.add_type_to_cache(&string_type);
378 string_type
379 }
380
381 pub fn bool(&mut self) -> Rc<Type> {
382 let bool_kind = TypeKind::Bool;
383
384 if let Some(existing) = self.find_type(&bool_kind) {
385 return existing;
386 }
387
388 let bool_type = self.create_type(bool_kind);
389 self.add_type_to_cache(&bool_type);
390 bool_type
391 }
392
393 pub fn unit(&mut self) -> Rc<Type> {
394 let unit_kind = TypeKind::Unit;
395
396 if let Some(existing) = self.find_type(&unit_kind) {
397 return existing;
398 }
399
400 let unit_type = self.create_type(unit_kind);
401 self.add_type_to_cache(&unit_type);
402 unit_type
403 }
404
405 pub fn optional(&mut self, inner_type: &Rc<Type>) -> Rc<Type> {
410 let optional_kind = TypeKind::Optional(Rc::clone(inner_type));
411
412 if let Some(existing) = self.find_type(&optional_kind) {
413 return existing;
414 }
415
416 let optional_type = self.create_type(optional_kind);
417 self.add_type_to_cache(&optional_type);
418 optional_type
419 }
420
421 pub fn tuple(&mut self, element_types: Vec<Rc<Type>>) -> Rc<Type> {
422 let tuple_kind = TypeKind::Tuple(element_types);
423
424 if let Some(existing) = self.find_type(&tuple_kind) {
425 return existing;
426 }
427
428 let tuple_type = self.create_type(tuple_kind);
429 self.add_type_to_cache(&tuple_type);
430 tuple_type
431 }
432
433 pub fn string_storage(&mut self, capacity: usize) -> Rc<Type> {
434 let string_kind = TypeKind::StringStorage(self.byte(), capacity);
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 named_struct(&mut self, named_struct: NamedStructType) -> Rc<Type> {
650 let struct_kind = TypeKind::NamedStruct(named_struct);
651
652 if let Some(existing) = self.find_type(&struct_kind) {
653 return existing;
654 }
655
656 let struct_type = self.create_type(struct_kind);
657 self.add_type_to_cache(&struct_type);
658 struct_type
659 }
660
661 pub fn enum_type(&mut self, enum_type: EnumType) -> Rc<Type> {
662 let enum_kind = TypeKind::Enum(enum_type);
663
664 if let Some(existing) = self.find_type(&enum_kind) {
665 return existing;
666 }
667
668 let enum_type = self.create_type(enum_kind);
669 self.add_type_to_cache(&enum_type);
670 enum_type
671 }
672
673 pub fn function(&mut self, signature: Signature) -> Rc<Type> {
674 let function_kind = TypeKind::Function(signature);
675
676 if let Some(existing) = self.find_type(&function_kind) {
677 return existing;
678 }
679
680 let function_type = self.create_type(function_kind);
681 self.add_type_to_cache(&function_type);
682 function_type
683 }
684}