1use crate::Type;
7use crate::type_kind::TypeKind;
8
9impl Type {
10 pub(crate) fn do_compatible_with(&self, other: &Self) -> bool {
11 if self.id == other.id {
12 return true;
13 }
14
15 match (&*self.kind, &*other.kind) {
16 (TypeKind::Int, TypeKind::Int) => true,
18 (TypeKind::Float, TypeKind::Float) => true,
19 (TypeKind::Bool, TypeKind::Bool) => true,
20 (TypeKind::String, TypeKind::String) => true,
21 (TypeKind::Unit, TypeKind::Unit) => true,
22
23 (TypeKind::Optional(_), TypeKind::Optional(_)) => true,
26
27 (TypeKind::VecStorage(_, cap_a), TypeKind::VecStorage(_, cap_b)) => {
28 true }
30 (TypeKind::SparseStorage(_, cap_a), TypeKind::SparseStorage(_, cap_b)) => {
31 true }
33 (TypeKind::QueueStorage(_, cap_a), TypeKind::QueueStorage(_, cap_b)) => true,
34
35 (TypeKind::StackStorage(_, cap_a), TypeKind::StackStorage(_, cap_b)) => true,
36
37 (TypeKind::MapStorage(_, _, cap_a), TypeKind::MapStorage(_, _, cap_b)) => true,
38
39 (
40 TypeKind::GridStorage(_, rows_a, cols_a),
41 TypeKind::GridStorage(_, rows_b, cols_b),
42 ) => rows_a >= rows_b && cols_a >= cols_b,
43
44 (TypeKind::SliceView(_), TypeKind::SliceView(_)) => true,
45 (TypeKind::SparseView(_), TypeKind::SparseView(_)) => true,
46 (TypeKind::QueueView(_), TypeKind::QueueView(_)) => true,
47 (TypeKind::StackView(_), TypeKind::StackView(_)) => true,
48 (TypeKind::DynamicLengthVecView(_), TypeKind::DynamicLengthVecView(_)) => true,
49 (TypeKind::DynamicLengthMapView(_, _), TypeKind::DynamicLengthMapView(_, _)) => true,
50
51 (
52 TypeKind::FixedCapacityAndLengthArray(_, size_a),
53 TypeKind::FixedCapacityAndLengthArray(_, size_b),
54 ) => {
55 size_a == size_b }
57
58 (TypeKind::Tuple(elems_a), TypeKind::Tuple(elems_b)) => {
59 elems_a.len() == elems_b.len() }
61
62 (TypeKind::AnonymousStruct(anon_a), TypeKind::AnonymousStruct(anon_b)) => {
63 anon_a.field_name_sorted_fields.len() == anon_b.field_name_sorted_fields.len()
64 && anon_a
65 .field_name_sorted_fields
66 .keys()
67 .all(|key| anon_b.field_name_sorted_fields.contains_key(key))
68 }
69
70 (TypeKind::NamedStruct(named_a), TypeKind::NamedStruct(named_b)) => {
71 named_a.assigned_name == named_b.assigned_name
72 && named_a.instantiated_type_parameters.len()
73 == named_b.instantiated_type_parameters.len()
74 }
75
76 (TypeKind::Enum(enum_a), TypeKind::Enum(enum_b)) => {
77 enum_a.assigned_name == enum_b.assigned_name
78 && enum_a.instantiated_type_parameters.len()
79 == enum_b.instantiated_type_parameters.len()
80 }
81
82 (TypeKind::Function(sig_a), TypeKind::Function(sig_b)) => {
83 sig_a.parameters.len() == sig_b.parameters.len()
84 }
85
86 _ => self.compatible_with_storage_and_view(other),
88 }
89 }
90
91 #[must_use]
92 pub fn compatible_with_storage_and_view(&self, other_view: &Self) -> bool {
93 let left_kind = self.lowest_common_denominator_vec_like_view();
94 let right_kind = self.lowest_common_denominator_vec_like_view();
95 if left_kind.is_some() && right_kind.is_some() {
96 let left = left_kind.unwrap();
97 let right = right_kind.unwrap();
98
99 return left == right;
100 }
101
102 match (&*self.kind, &*other_view.kind) {
103 (
104 TypeKind::MapStorage(key_a, value_a, _),
105 TypeKind::DynamicLengthMapView(key_b, value_b),
106 )
107 | (
108 TypeKind::DynamicLengthMapView(key_a, value_a),
109 TypeKind::MapStorage(key_b, value_b, _),
110 ) => key_a.do_compatible_with(key_b) && value_a.do_compatible_with(value_b),
111 _ => false,
112 }
113 }
114
115 #[must_use]
117 pub fn lowest_common_denominator_vec_like_view(&self) -> Option<TypeKind> {
118 match &*self.kind {
119 TypeKind::FixedCapacityAndLengthArray(inner, _size)
120 | TypeKind::QueueStorage(inner, _size)
121 | TypeKind::StackStorage(inner, _size)
122 | TypeKind::SparseStorage(inner, _size)
123 | TypeKind::VecStorage(inner, _size) => Some(TypeKind::SliceView(inner.clone())),
124
125 TypeKind::SliceView(inner)
126 | TypeKind::QueueView(inner)
127 | TypeKind::StackView(inner)
128 | TypeKind::SparseView(inner)
129 | TypeKind::DynamicLengthVecView(inner) => Some(TypeKind::SliceView(inner.clone())),
130
131 _ => None,
132 }
133 }
134
135 #[must_use]
136 pub fn strict_compatible_with_capacity(&self, other: &Self) -> bool {
137 match (&*self.kind, &*other.kind) {
138 (TypeKind::VecStorage(_, cap_a), TypeKind::VecStorage(_, cap_b)) => cap_a == cap_b,
139 (TypeKind::SparseStorage(_, cap_a), TypeKind::SparseStorage(_, cap_b)) => {
140 cap_a == cap_b
141 }
142 (TypeKind::QueueStorage(_, cap_a), TypeKind::QueueStorage(_, cap_b)) => cap_a == cap_b,
143 (TypeKind::StackStorage(_, cap_a), TypeKind::StackStorage(_, cap_b)) => cap_a == cap_b,
144 (TypeKind::MapStorage(_, _, cap_a), TypeKind::MapStorage(_, _, cap_b)) => {
145 cap_a == cap_b
146 }
147 (
148 TypeKind::GridStorage(_, rows_a, cols_a),
149 TypeKind::GridStorage(_, rows_b, cols_b),
150 ) => rows_a == rows_b && cols_a == cols_b,
151 _ => self.id == other.id,
153 }
154 }
155}