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