1use crate::cache::TypeCache;
6use crate::type_kind::TypeKind;
7use crate::Type;
8
9impl Type {
10 pub(crate) fn do_compatible_with(&self, other: &Self, type_cache: &mut TypeCache) -> bool {
11 if self.id == other.id {
12 return true;
13 }
14
15 if matches!(&*other.kind, TypeKind::Never) {
17 return true;
18 }
19
20 if matches!(&*self.kind, TypeKind::Never) {
22 return true;
23 }
24
25 match (&*self.kind, &*other.kind) {
26 (TypeKind::Int, TypeKind::Int) => true,
28 (TypeKind::Float, TypeKind::Float) => true,
29 (TypeKind::Bool, TypeKind::Bool) => true,
30 (TypeKind::Codepoint, TypeKind::Codepoint) => true,
31 (TypeKind::String(..), TypeKind::String(..)) => true,
32 (TypeKind::Unit, TypeKind::Unit) => true,
33
34 (TypeKind::Optional(a), TypeKind::Optional(b)) => type_cache.compatible_with(a, b),
37
38 (TypeKind::VecStorage(a, _), TypeKind::VecStorage(b, _)) => {
39 type_cache.compatible_with(a, b)
40 }
41 (TypeKind::SparseStorage(a, _), TypeKind::SparseStorage(b, _)) => {
42 type_cache.compatible_with(a, b)
43 }
44 (TypeKind::QueueStorage(a, _), TypeKind::QueueStorage(b, _)) => {
45 type_cache.compatible_with(a, b)
46 }
47
48 (TypeKind::StackStorage(a, _), TypeKind::StackStorage(b, _)) => {
49 type_cache.compatible_with(a, b)
50 }
51
52 (TypeKind::MapStorage(a_key, a_value, _), TypeKind::MapStorage(b_key, b_value, _)) => {
53 type_cache.compatible_with(a_key, b_key)
54 && type_cache.compatible_with(a_value, b_value)
55 }
56
57 (
58 TypeKind::GridStorage(a, rows_a, cols_a),
59 TypeKind::GridStorage(b, rows_b, cols_b),
60 ) => rows_a >= rows_b && cols_a >= cols_b && type_cache.compatible_with(a, b),
61
62 (TypeKind::SliceView(a), TypeKind::SliceView(b)) => type_cache.compatible_with(a, b),
63 (TypeKind::SparseView(a), TypeKind::SparseView(b)) => type_cache.compatible_with(a, b),
64 (TypeKind::QueueView(a), TypeKind::QueueView(b)) => type_cache.compatible_with(a, b),
65 (TypeKind::StackView(a), TypeKind::StackView(b)) => type_cache.compatible_with(a, b),
66 (TypeKind::DynamicLengthVecView(a), TypeKind::DynamicLengthVecView(b)) => {
67 type_cache.compatible_with(a, b)
68 }
69 (
70 TypeKind::DynamicLengthMapView(a_key, a_value),
71 TypeKind::DynamicLengthMapView(b_key, b_value),
72 ) => {
73 type_cache.compatible_with(a_key, b_key)
74 && type_cache.compatible_with(a_value, b_value)
75 }
76
77 (
78 TypeKind::FixedCapacityAndLengthArray(a, size_a),
79 TypeKind::FixedCapacityAndLengthArray(b, size_b),
80 ) => {
81 size_a == size_b && type_cache.compatible_with(a, b) }
83
84 (TypeKind::Tuple(elems_a), TypeKind::Tuple(elems_b)) => {
85 elems_a.len() == elems_b.len() }
87
88 (TypeKind::AnonymousStruct(anon_a), TypeKind::AnonymousStruct(anon_b)) => {
89 anon_a.field_name_sorted_fields.len() == anon_b.field_name_sorted_fields.len()
90 && anon_a
91 .field_name_sorted_fields
92 .keys()
93 .all(|key| anon_b.field_name_sorted_fields.contains_key(key))
94 }
95
96 (TypeKind::NamedStruct(named_a), TypeKind::NamedStruct(named_b)) => {
97 named_a.assigned_name == named_b.assigned_name
98 && type_cache.compatible_with(&named_a.anon_struct_type, &named_b.anon_struct_type)
99 }
100
101 (TypeKind::Enum(enum_a), TypeKind::Enum(enum_b)) => {
102 enum_a.assigned_name == enum_b.assigned_name
103 && enum_a.instantiated_type_parameters.len()
104 == enum_b.instantiated_type_parameters.len()
105 }
106
107 (TypeKind::Function(sig_a), TypeKind::Function(sig_b)) => {
108 sig_a.parameters.len() == sig_b.parameters.len()
109 }
110
111 _ => self.compatible_with_storage_and_view(other, type_cache),
113 }
114 }
115
116 #[must_use]
117 pub fn compatible_with_storage_and_view(
118 &self,
119 other_view: &Self,
120 type_cache: &mut TypeCache,
121 ) -> bool {
122 let left_kind = self.lowest_common_denominator_vec_like_view();
123 let right_kind = other_view.lowest_common_denominator_vec_like_view();
124 if left_kind.is_some() && right_kind.is_some() {
125 let left = left_kind.unwrap();
126 let right = right_kind.unwrap();
127 match (left, right) {
128 (TypeKind::SliceView(a), TypeKind::SliceView(b)) => {
129 type_cache.compatible_with(&a, &b)
130 }
131 (TypeKind::DynamicLengthVecView(a), TypeKind::DynamicLengthVecView(b)) => {
132 type_cache.compatible_with(&a, &b)
133 }
134 _ => false,
135 }
136 } else {
137 match (&*self.kind, &*other_view.kind) {
138 (
139 TypeKind::MapStorage(key_a, value_a, _),
140 TypeKind::DynamicLengthMapView(key_b, value_b),
141 )
142 | (
143 TypeKind::DynamicLengthMapView(key_a, value_a),
144 TypeKind::MapStorage(key_b, value_b, _),
145 ) => {
146 type_cache.compatible_with(key_a, key_b)
147 && type_cache.compatible_with(value_a, value_b)
148 }
149 _ => false,
150 }
151 }
152 }
153
154 #[must_use]
156 pub fn lowest_common_denominator_vec_like_view(&self) -> Option<TypeKind> {
157 match &*self.kind {
158 TypeKind::FixedCapacityAndLengthArray(inner, _)
159 | TypeKind::QueueStorage(inner, _)
160 | TypeKind::StackStorage(inner, _)
161 | TypeKind::SparseStorage(inner, _)
162 | TypeKind::StringStorage(inner, _, _)
163 | TypeKind::VecStorage(inner, _) => Some(TypeKind::SliceView(inner.clone())),
164
165 TypeKind::SliceView(inner)
166 | TypeKind::QueueView(inner)
167 | TypeKind::StackView(inner)
168 | TypeKind::SparseView(inner)
169 | TypeKind::String(inner, _)
170 | TypeKind::DynamicLengthVecView(inner) => Some(TypeKind::SliceView(inner.clone())),
171
172 _ => None,
173 }
174 }
175
176 #[must_use]
177 pub fn strict_compatible_with_capacity(&self, other: &Self) -> bool {
178 match (&*self.kind, &*other.kind) {
179 (TypeKind::VecStorage(_, cap_a), TypeKind::VecStorage(_, cap_b)) => cap_a == cap_b,
180 (TypeKind::SparseStorage(_, cap_a), TypeKind::SparseStorage(_, cap_b)) => {
181 cap_a == cap_b
182 }
183 (TypeKind::QueueStorage(_, cap_a), TypeKind::QueueStorage(_, cap_b)) => cap_a == cap_b,
184 (TypeKind::StackStorage(_, cap_a), TypeKind::StackStorage(_, cap_b)) => cap_a == cap_b,
185 (TypeKind::MapStorage(_, _, cap_a), TypeKind::MapStorage(_, _, cap_b)) => {
186 cap_a == cap_b
187 }
188 (
189 TypeKind::GridStorage(_, rows_a, cols_a),
190 TypeKind::GridStorage(_, rows_b, cols_b),
191 ) => rows_a == rows_b && cols_a == cols_b,
192 _ => self.id == other.id,
194 }
195 }
196}