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
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 || named_a.instantiated_type_parameters.len()
253 != named_b.instantiated_type_parameters.len()
254 {
255 false
256 } else {
257 named_a
259 .instantiated_type_parameters
260 .iter()
261 .zip(named_b.instantiated_type_parameters.iter())
262 .all(|(a, b)| self.compatible_with(a, b))
263 }
264 }
265
266 (TypeKind::Enum(enum_a), TypeKind::Enum(enum_b)) => {
267 if enum_a.assigned_name != enum_b.assigned_name
269 || enum_a.instantiated_type_parameters.len()
270 != enum_b.instantiated_type_parameters.len()
271 {
272 false
273 } else {
274 enum_a
276 .instantiated_type_parameters
277 .iter()
278 .zip(enum_b.instantiated_type_parameters.iter())
279 .all(|(a, b)| self.compatible_with(a, b))
280 }
281 }
282
283 (TypeKind::Function(sig_a), TypeKind::Function(sig_b)) => {
284 if sig_a.parameters.len() == sig_b.parameters.len() {
286 let params_match = sig_a
288 .parameters
289 .iter()
290 .zip(sig_b.parameters.iter())
291 .all(|(a, b)| self.compatible_with(&a.resolved_type, &b.resolved_type));
292
293 params_match && self.compatible_with(&sig_a.return_type, &sig_b.return_type)
294 } else {
295 false
296 }
297 }
298
299 _ => true,
300 };
301
302 self.compatible_cache.remove(&key);
303 self.compatible_cache
304 .insert(key, result)
305 .unwrap_or_else(|_| panic!("should be able to insert into cache {key:?}"));
306
307 result
308 }
309
310 pub fn clear_compatibility_cache(&mut self) {
312 self.compatible_cache.clear();
313 }
314
315 pub fn byte(&mut self) -> Rc<Type> {
321 let byte_kind = TypeKind::Byte;
322
323 if let Some(existing) = self.find_type(&byte_kind) {
324 return existing;
325 }
326
327 let byte_type = self.create_type(byte_kind);
328 self.add_type_to_cache(&byte_type);
329 byte_type
330 }
331
332 pub fn int(&mut self) -> Rc<Type> {
333 let int_kind = TypeKind::Int;
334
335 if let Some(existing) = self.find_type(&int_kind) {
336 return existing;
337 }
338
339 let int_type = self.create_type(int_kind);
340 self.add_type_to_cache(&int_type);
341 int_type
342 }
343
344 pub fn codepoint(&mut self) -> Rc<Type> {
345 let char_kind = TypeKind::Codepoint;
346
347 if let Some(existing) = self.find_type(&char_kind) {
348 return existing;
349 }
350
351 let char_type = self.create_type(char_kind);
352 self.add_type_to_cache(&char_type);
353 char_type
354 }
355
356 pub fn float(&mut self) -> Rc<Type> {
357 let float_kind = TypeKind::Float;
358
359 if let Some(existing) = self.find_type(&float_kind) {
360 return existing;
361 }
362
363 let float_type = self.create_type(float_kind);
364 self.add_type_to_cache(&float_type);
365 float_type
366 }
367
368 pub fn bool(&mut self) -> Rc<Type> {
369 let bool_kind = TypeKind::Bool;
370
371 if let Some(existing) = self.find_type(&bool_kind) {
372 return existing;
373 }
374
375 let bool_type = self.create_type(bool_kind);
376 self.add_type_to_cache(&bool_type);
377 bool_type
378 }
379
380 pub fn unit(&mut self) -> Rc<Type> {
381 let unit_kind = TypeKind::Unit;
382
383 if let Some(existing) = self.find_type(&unit_kind) {
384 return existing;
385 }
386
387 let unit_type = self.create_type(unit_kind);
388 self.add_type_to_cache(&unit_type);
389 unit_type
390 }
391
392 pub fn optional(&mut self, inner_type: &Rc<Type>) -> Rc<Type> {
397 let optional_kind = TypeKind::Optional(Rc::clone(inner_type));
398
399 if let Some(existing) = self.find_type(&optional_kind) {
400 return existing;
401 }
402
403 let optional_type = self.create_type(optional_kind);
404 self.add_type_to_cache(&optional_type);
405 optional_type
406 }
407
408 pub fn tuple(&mut self, element_types: Vec<Rc<Type>>) -> Rc<Type> {
409 let tuple_kind = TypeKind::Tuple(element_types);
410
411 if let Some(existing) = self.find_type(&tuple_kind) {
412 return existing;
413 }
414
415 let tuple_type = self.create_type(tuple_kind);
416 self.add_type_to_cache(&tuple_type);
417 tuple_type
418 }
419
420 pub fn string_storage(&mut self, capacity: usize) -> Rc<Type> {
421 let string_kind = TypeKind::StringStorage(self.byte(), self.codepoint(), capacity);
422
423 if let Some(existing) = self.find_type(&string_kind) {
424 return existing;
425 }
426
427 let string_type = self.create_type(string_kind);
428 self.add_type_to_cache(&string_type);
429 string_type
430 }
431
432 pub fn string(&mut self) -> Rc<Type> {
433 let string_kind = TypeKind::String(self.byte(), self.codepoint());
434
435 if let Some(existing) = self.find_type(&string_kind) {
436 return existing;
437 }
438
439 let string_type = self.create_type(string_kind);
440 self.add_type_to_cache(&string_type);
441 string_type
442 }
443
444 pub fn vec_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
446 let vec_kind = TypeKind::VecStorage(Rc::clone(element_type), capacity);
447
448 if let Some(existing) = self.find_type(&vec_kind) {
449 return existing;
450 }
451
452 let vec_type = self.create_type(vec_kind);
453 self.add_type_to_cache(&vec_type);
454 vec_type
455 }
456
457 pub fn sparse_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
458 let sparse_kind = TypeKind::SparseStorage(Rc::clone(element_type), capacity);
459
460 if let Some(existing) = self.find_type(&sparse_kind) {
461 return existing;
462 }
463
464 let sparse_type = self.create_type(sparse_kind);
465 self.add_type_to_cache(&sparse_type);
466 sparse_type
467 }
468
469 pub fn queue_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
470 let queue_kind = TypeKind::QueueStorage(Rc::clone(element_type), capacity);
471
472 if let Some(existing) = self.find_type(&queue_kind) {
473 return existing;
474 }
475
476 let queue_type = self.create_type(queue_kind);
477 self.add_type_to_cache(&queue_type);
478 queue_type
479 }
480
481 pub fn stack_storage(&mut self, element_type: &Rc<Type>, capacity: usize) -> Rc<Type> {
482 let stack_kind = TypeKind::StackStorage(Rc::clone(element_type), capacity);
483
484 if let Some(existing) = self.find_type(&stack_kind) {
485 return existing;
486 }
487
488 let stack_type = self.create_type(stack_kind);
489 self.add_type_to_cache(&stack_type);
490 stack_type
491 }
492
493 pub fn map_storage(
494 &mut self,
495 key_type: &Rc<Type>,
496 value_type: &Rc<Type>,
497 capacity: usize,
498 ) -> Rc<Type> {
499 let map_kind = TypeKind::MapStorage(Rc::clone(key_type), Rc::clone(value_type), capacity);
500
501 if let Some(existing) = self.find_type(&map_kind) {
502 return existing;
503 }
504
505 let map_type = self.create_type(map_kind);
506 self.add_type_to_cache(&map_type);
507 map_type
508 }
509
510 pub fn grid_storage(&mut self, element_type: &Rc<Type>, rows: usize, cols: usize) -> Rc<Type> {
511 let grid_kind = TypeKind::GridStorage(Rc::clone(element_type), rows, cols);
512
513 if let Some(existing) = self.find_type(&grid_kind) {
514 return existing;
515 }
516
517 let grid_type = self.create_type(grid_kind);
518 self.add_type_to_cache(&grid_type);
519 grid_type
520 }
521
522 pub fn fixed_array(&mut self, element_type: &Rc<Type>, size: usize) -> Rc<Type> {
523 let array_kind = TypeKind::FixedCapacityAndLengthArray(Rc::clone(element_type), size);
524
525 if let Some(existing) = self.find_type(&array_kind) {
526 return existing;
527 }
528
529 let array_type = self.create_type(array_kind);
530 self.add_type_to_cache(&array_type);
531 array_type
532 }
533
534 pub fn slice_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
535 let slice_kind = TypeKind::SliceView(Rc::clone(element_type));
536
537 if let Some(existing) = self.find_type(&slice_kind) {
538 return existing;
539 }
540
541 let slice_type = self.create_type(slice_kind);
542 self.add_type_to_cache(&slice_type);
543 slice_type
544 }
545
546 pub fn sparse_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
547 let sparse_kind = TypeKind::SparseView(Rc::clone(element_type));
548
549 if let Some(existing) = self.find_type(&sparse_kind) {
550 return existing;
551 }
552
553 let sparse_type = self.create_type(sparse_kind);
554 self.add_type_to_cache(&sparse_type);
555 sparse_type
556 }
557
558 pub fn queue_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
559 let queue_kind = TypeKind::QueueView(Rc::clone(element_type));
560
561 if let Some(existing) = self.find_type(&queue_kind) {
562 return existing;
563 }
564
565 let queue_type = self.create_type(queue_kind);
566 self.add_type_to_cache(&queue_type);
567 queue_type
568 }
569
570 pub fn stack_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
571 let stack_kind = TypeKind::StackView(Rc::clone(element_type));
572
573 if let Some(existing) = self.find_type(&stack_kind) {
574 return existing;
575 }
576
577 let stack_type = self.create_type(stack_kind);
578 self.add_type_to_cache(&stack_type);
579 stack_type
580 }
581
582 pub fn dynamic_vec_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
583 let vec_view_kind = TypeKind::DynamicLengthVecView(Rc::clone(element_type));
584
585 if let Some(existing) = self.find_type(&vec_view_kind) {
586 return existing;
587 }
588
589 let vec_view_type = self.create_type(vec_view_kind);
590 self.add_type_to_cache(&vec_view_type);
591 vec_view_type
592 }
593
594 pub fn dynamic_map_view(&mut self, key_type: &Rc<Type>, value_type: &Rc<Type>) -> Rc<Type> {
595 let map_view_kind =
596 TypeKind::DynamicLengthMapView(Rc::clone(key_type), Rc::clone(value_type));
597
598 if let Some(existing) = self.find_type(&map_view_kind) {
599 return existing;
600 }
601
602 let map_view_type = self.create_type(map_view_kind);
603 self.add_type_to_cache(&map_view_type);
604 map_view_type
605 }
606
607 pub fn grid_view(&mut self, element_type: &Rc<Type>) -> Rc<Type> {
608 let grid_view_kind = TypeKind::GridView(Rc::clone(element_type));
609
610 if let Some(existing) = self.find_type(&grid_view_kind) {
611 return existing;
612 }
613
614 let grid_view_type = self.create_type(grid_view_kind);
615 self.add_type_to_cache(&grid_view_type);
616 grid_view_type
617 }
618
619 pub fn anonymous_struct(&mut self, anon_struct: AnonymousStructType) -> Rc<Type> {
625 let struct_kind = TypeKind::AnonymousStruct(anon_struct);
626
627 if let Some(existing) = self.find_type(&struct_kind) {
628 return existing;
629 }
630
631 let struct_type = self.create_type(struct_kind);
632 self.add_type_to_cache(&struct_type);
633 struct_type
634 }
635
636 pub fn range(&mut self, range_struct_ref: TypeRef) -> Rc<Type> {
637 let range_kind = TypeKind::Range(range_struct_ref);
638
639 if let Some(existing) = self.find_type(&range_kind) {
640 return existing;
641 }
642
643 let range_type = self.create_type(range_kind);
644 self.add_type_to_cache(&range_type);
645 range_type
646 }
647
648 pub fn named_struct(&mut self, named_struct: NamedStructType) -> Rc<Type> {
649 let struct_kind = TypeKind::NamedStruct(named_struct);
650
651 if let Some(existing) = self.find_type(&struct_kind) {
652 return existing;
653 }
654
655 let struct_type = self.create_type(struct_kind);
656 self.add_type_to_cache(&struct_type);
657 struct_type
658 }
659
660 pub fn enum_type(&mut self, enum_type: EnumType) -> Rc<Type> {
661 let enum_kind = TypeKind::Enum(enum_type);
662
663 if let Some(existing) = self.find_type(&enum_kind) {
664 return existing;
665 }
666
667 let enum_type = self.create_type(enum_kind);
668 self.add_type_to_cache(&enum_type);
669 enum_type
670 }
671
672 pub fn function(&mut self, signature: Signature) -> Rc<Type> {
673 let function_kind = TypeKind::Function(signature);
674
675 if let Some(existing) = self.find_type(&function_kind) {
676 return existing;
677 }
678
679 let function_type = self.create_type(function_kind);
680 self.add_type_to_cache(&function_type);
681 function_type
682 }
683}