1use crate::{
2 env::Env, expr::ModPath, format_with_flags, PrintFlag, Rt, UserEvent, PRINT_FLAGS,
3};
4use crate::{errf, CAST_ERR_TAG};
5use anyhow::{anyhow, bail, Result};
6use arcstr::ArcStr;
7use enumflags2::bitflags;
8use enumflags2::BitFlags;
9use fxhash::{FxHashMap, FxHashSet};
10use immutable_chunkmap::map::Map;
11use netidx::{
12 publisher::{Typ, Value},
13 utils::Either,
14};
15use netidx_value::ValArray;
16use poolshark::local::LPooled;
17use smallvec::{smallvec, SmallVec};
18use std::{
19 cmp::{Eq, PartialEq},
20 collections::hash_map::Entry,
21 fmt::{self, Debug},
22 iter,
23};
24use triomphe::Arc;
25
26mod fntyp;
27mod tval;
28mod tvar;
29
30pub use fntyp::{FnArgType, FnType};
31pub use tval::TVal;
32use tvar::would_cycle_inner;
33pub use tvar::TVar;
34
35#[derive(Debug, Clone, Copy)]
36#[bitflags]
37#[repr(u8)]
38pub enum ContainsFlags {
39 AliasTVars,
40 InitTVars,
41}
42
43struct AndAc(bool);
44
45impl FromIterator<bool> for AndAc {
46 fn from_iter<T: IntoIterator<Item = bool>>(iter: T) -> Self {
47 AndAc(iter.into_iter().all(|b| b))
48 }
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
52pub enum Type {
53 Bottom,
54 Any,
55 Primitive(BitFlags<Typ>),
56 Ref { scope: ModPath, name: ModPath, params: Arc<[Type]> },
57 Fn(Arc<FnType>),
58 Set(Arc<[Type]>),
59 TVar(TVar),
60 Error(Arc<Type>),
61 Array(Arc<Type>),
62 ByRef(Arc<Type>),
63 Tuple(Arc<[Type]>),
64 Struct(Arc<[(ArcStr, Type)]>),
65 Variant(ArcStr, Arc<[Type]>),
66 Map { key: Arc<Type>, value: Arc<Type> },
67}
68
69impl Default for Type {
70 fn default() -> Self {
71 Self::Bottom
72 }
73}
74
75impl Type {
76 pub fn empty_tvar() -> Self {
77 Type::TVar(TVar::default())
78 }
79
80 fn iter_prims(&self) -> impl Iterator<Item = Self> {
81 match self {
82 Self::Primitive(p) => {
83 Either::Left(p.iter().map(|t| Type::Primitive(t.into())))
84 }
85 t => Either::Right(iter::once(t.clone())),
86 }
87 }
88
89 pub fn is_defined(&self) -> bool {
90 match self {
91 Self::Bottom
92 | Self::Any
93 | Self::Primitive(_)
94 | Self::Fn(_)
95 | Self::Set(_)
96 | Self::Error(_)
97 | Self::Array(_)
98 | Self::ByRef(_)
99 | Self::Tuple(_)
100 | Self::Struct(_)
101 | Self::Variant(_, _)
102 | Self::Ref { .. }
103 | Self::Map { .. } => true,
104 Self::TVar(tv) => tv.read().typ.read().is_some(),
105 }
106 }
107
108 pub fn lookup_ref<'a, R: Rt, E: UserEvent>(
109 &'a self,
110 env: &'a Env<R, E>,
111 ) -> Result<&'a Type> {
112 match self {
113 Self::Ref { scope, name, params } => {
114 let def = env
115 .lookup_typedef(scope, name)
116 .ok_or_else(|| anyhow!("undefined type {name} in {scope}"))?;
117 if def.params.len() != params.len() {
118 bail!("{} expects {} type parameters", name, def.params.len());
119 }
120 def.typ.unbind_tvars();
121 for ((tv, ct), arg) in def.params.iter().zip(params.iter()) {
122 if let Some(ct) = ct {
123 ct.check_contains(env, arg)?;
124 }
125 if !tv.would_cycle(arg) {
126 *tv.read().typ.write() = Some(arg.clone());
127 }
128 }
129 Ok(&def.typ)
130 }
131 t => Ok(t),
132 }
133 }
134
135 pub fn check_contains<R: Rt, E: UserEvent>(
136 &self,
137 env: &Env<R, E>,
138 t: &Self,
139 ) -> Result<()> {
140 if self.contains(env, t)? {
141 Ok(())
142 } else {
143 format_with_flags(PrintFlag::DerefTVars | PrintFlag::ReplacePrims, || {
144 bail!("type mismatch {self} does not contain {t}")
145 })
146 }
147 }
148
149 fn contains_int<R: Rt, E: UserEvent>(
150 &self,
151 flags: BitFlags<ContainsFlags>,
152 env: &Env<R, E>,
153 hist: &mut FxHashMap<(usize, usize), bool>,
154 t: &Self,
155 ) -> Result<bool> {
156 if (self as *const Type) == (t as *const Type) {
157 return Ok(true);
158 }
159 match (self, t) {
160 (
161 Self::Ref { scope: s0, name: n0, params: p0 },
162 Self::Ref { scope: s1, name: n1, params: p1 },
163 ) if s0 == s1 && n0 == n1 => Ok(p0.len() == p1.len()
164 && p0
165 .iter()
166 .zip(p1.iter())
167 .map(|(t0, t1)| t0.contains_int(flags, env, hist, t1))
168 .collect::<Result<AndAc>>()?
169 .0),
170 (t0 @ Self::Ref { .. }, t1) | (t0, t1 @ Self::Ref { .. }) => {
171 let t0 = t0.lookup_ref(env)?;
172 let t1 = t1.lookup_ref(env)?;
173 let t0_addr = (t0 as *const Type).addr();
174 let t1_addr = (t1 as *const Type).addr();
175 match hist.get(&(t0_addr, t1_addr)) {
176 Some(r) => Ok(*r),
177 None => {
178 hist.insert((t0_addr, t1_addr), true);
179 match t0.contains_int(flags, env, hist, t1) {
180 Ok(r) => {
181 hist.insert((t0_addr, t1_addr), r);
182 Ok(r)
183 }
184 Err(e) => {
185 hist.remove(&(t0_addr, t1_addr));
186 Err(e)
187 }
188 }
189 }
190 }
191 }
192 (Self::TVar(t0), Self::Bottom) => {
193 if let Some(_) = &*t0.read().typ.read() {
194 return Ok(true);
195 }
196 if flags.contains(ContainsFlags::InitTVars) {
197 *t0.read().typ.write() = Some(Self::Bottom);
198 }
199 Ok(true)
200 }
201 (Self::TVar(t0), Self::Any) => {
202 if let Some(t0) = &*t0.read().typ.read() {
203 return t0.contains_int(flags, env, hist, t);
204 }
205 if flags.contains(ContainsFlags::InitTVars) {
206 *t0.read().typ.write() = Some(Self::Any);
207 }
208 Ok(true)
209 }
210 (Self::Any, _) => Ok(true),
211 (Self::Bottom, _) | (_, Self::Bottom) => Ok(true),
212 (Self::Primitive(p0), Self::Primitive(p1)) => Ok(p0.contains(*p1)),
213 (
214 Self::Primitive(p),
215 Self::Array(_) | Self::Tuple(_) | Self::Struct(_) | Self::Variant(_, _),
216 ) => Ok(p.contains(Typ::Array)),
217 (Self::Array(t0), Self::Array(t1)) => t0.contains_int(flags, env, hist, t1),
218 (Self::Array(t0), Self::Primitive(p)) if *p == BitFlags::from(Typ::Array) => {
219 t0.contains_int(flags, env, hist, &Type::Any)
220 }
221 (Self::Map { key: k0, value: v0 }, Self::Map { key: k1, value: v1 }) => {
222 Ok(k0.contains_int(flags, env, hist, k1)?
223 && v0.contains_int(flags, env, hist, v1)?)
224 }
225 (Self::Primitive(p), Self::Map { .. }) => Ok(p.contains(Typ::Map)),
226 (Self::Map { key, value }, Self::Primitive(p))
227 if *p == BitFlags::from(Typ::Map) =>
228 {
229 Ok(key.contains_int(flags, env, hist, &Type::Any)?
230 && value.contains_int(flags, env, hist, &Type::Any)?)
231 }
232 (Self::Primitive(p0), Self::Error(_)) => Ok(p0.contains(Typ::Error)),
233 (Self::Error(e), Self::Primitive(p)) if *p == BitFlags::from(Typ::Error) => {
234 e.contains_int(flags, env, hist, &Type::Any)
235 }
236 (Self::Error(e0), Self::Error(e1)) => e0.contains_int(flags, env, hist, e1),
237 (Self::Tuple(t0), Self::Tuple(t1))
238 if t0.as_ptr().addr() == t1.as_ptr().addr() =>
239 {
240 Ok(true)
241 }
242 (Self::Tuple(t0), Self::Tuple(t1)) => Ok(t0.len() == t1.len()
243 && t0
244 .iter()
245 .zip(t1.iter())
246 .map(|(t0, t1)| t0.contains_int(flags, env, hist, t1))
247 .collect::<Result<AndAc>>()?
248 .0),
249 (Self::Struct(t0), Self::Struct(t1))
250 if t0.as_ptr().addr() == t1.as_ptr().addr() =>
251 {
252 Ok(true)
253 }
254 (Self::Struct(t0), Self::Struct(t1)) => {
255 Ok(t0.len() == t1.len() && {
256 t0.iter()
258 .zip(t1.iter())
259 .map(|((n0, t0), (n1, t1))| {
260 Ok(n0 == n1 && t0.contains_int(flags, env, hist, t1)?)
261 })
262 .collect::<Result<AndAc>>()?
263 .0
264 })
265 }
266 (Self::Variant(tg0, t0), Self::Variant(tg1, t1))
267 if tg0.as_ptr() == tg1.as_ptr()
268 && t0.as_ptr().addr() == t1.as_ptr().addr() =>
269 {
270 Ok(true)
271 }
272 (Self::Variant(tg0, t0), Self::Variant(tg1, t1)) => Ok(tg0 == tg1
273 && t0.len() == t1.len()
274 && t0
275 .iter()
276 .zip(t1.iter())
277 .map(|(t0, t1)| t0.contains_int(flags, env, hist, t1))
278 .collect::<Result<AndAc>>()?
279 .0),
280 (Self::ByRef(t0), Self::ByRef(t1)) => t0.contains_int(flags, env, hist, t1),
281 (Self::TVar(t0), Self::TVar(t1))
282 if t0.addr() == t1.addr() || t0.read().id == t1.read().id =>
283 {
284 Ok(true)
285 }
286 (tt0 @ Self::TVar(t0), tt1 @ Self::TVar(t1)) => {
287 #[derive(Debug)]
288 enum Act {
289 RightCopy,
290 RightAlias,
291 LeftAlias,
292 LeftCopy,
293 }
294 if t0.would_cycle(tt1) || t1.would_cycle(tt0) {
295 return Ok(true);
296 }
297 let act = {
298 let t0 = t0.read();
299 let t1 = t1.read();
300 let addr0 = Arc::as_ptr(&t0.typ).addr();
301 let addr1 = Arc::as_ptr(&t1.typ).addr();
302 if addr0 == addr1 {
303 return Ok(true);
304 }
305 if would_cycle_inner(addr0, tt1) || would_cycle_inner(addr1, tt0) {
306 return Ok(true);
307 }
308 let t0i = t0.typ.read();
309 let t1i = t1.typ.read();
310 match (&*t0i, &*t1i) {
311 (Some(t0), Some(t1)) => {
312 return t0.contains_int(flags, env, hist, &*t1)
313 }
314 (None, None) => {
315 if t0.frozen && t1.frozen {
316 return Ok(true);
317 }
318 if t0.frozen {
319 Act::RightAlias
320 } else {
321 Act::LeftAlias
322 }
323 }
324 (Some(_), None) => Act::RightCopy,
325 (None, Some(_)) => Act::LeftCopy,
326 }
327 };
328 match act {
329 Act::RightCopy if flags.contains(ContainsFlags::InitTVars) => {
330 t1.copy(t0)
331 }
332 Act::RightAlias if flags.contains(ContainsFlags::AliasTVars) => {
333 t1.alias(t0)
334 }
335 Act::LeftAlias if flags.contains(ContainsFlags::AliasTVars) => {
336 t0.alias(t1)
337 }
338 Act::LeftCopy if flags.contains(ContainsFlags::InitTVars) => {
339 t0.copy(t1)
340 }
341 Act::RightCopy | Act::RightAlias | Act::LeftAlias | Act::LeftCopy => {
342 ()
343 }
344 }
345 Ok(true)
346 }
347 (Self::TVar(t0), t1) if !t0.would_cycle(t1) => {
348 if let Some(t0) = &*t0.read().typ.read() {
349 return t0.contains_int(flags, env, hist, t1);
350 }
351 if flags.contains(ContainsFlags::InitTVars) {
352 *t0.read().typ.write() = Some(t1.clone());
353 }
354 Ok(true)
355 }
356 (t0, Self::TVar(t1)) if !t1.would_cycle(t0) => {
357 if let Some(t1) = &*t1.read().typ.read() {
358 return t0.contains_int(flags, env, hist, t1);
359 }
360 if flags.contains(ContainsFlags::InitTVars) {
361 *t1.read().typ.write() = Some(t0.clone());
362 }
363 Ok(true)
364 }
365 (Self::Set(s0), Self::Set(s1))
366 if s0.as_ptr().addr() == s1.as_ptr().addr() =>
367 {
368 Ok(true)
369 }
370 (t0, Self::Set(s)) => Ok(s
371 .iter()
372 .map(|t1| t0.contains_int(flags, env, hist, t1))
373 .collect::<Result<AndAc>>()?
374 .0),
375 (Self::Set(s), t) => Ok(s
376 .iter()
377 .fold(Ok::<_, anyhow::Error>(false), |acc, t0| {
378 Ok(acc? || t0.contains_int(flags, env, hist, t)?)
379 })?
380 || t.iter_prims().fold(Ok::<_, anyhow::Error>(true), |acc, t1| {
381 Ok(acc?
382 && s.iter().fold(Ok::<_, anyhow::Error>(false), |acc, t0| {
383 Ok(acc? || t0.contains_int(flags, env, hist, &t1)?)
384 })?)
385 })?),
386 (Self::Fn(f0), Self::Fn(f1)) => {
387 Ok(f0.as_ptr() == f1.as_ptr() || f0.contains_int(flags, env, hist, f1)?)
388 }
389 (_, Self::Any)
390 | (_, Self::TVar(_))
391 | (Self::TVar(_), _)
392 | (Self::Fn(_), _)
393 | (Self::ByRef(_), _)
394 | (_, Self::ByRef(_))
395 | (_, Self::Fn(_))
396 | (Self::Tuple(_), Self::Array(_))
397 | (Self::Tuple(_), Self::Primitive(_))
398 | (Self::Tuple(_), Self::Struct(_))
399 | (Self::Tuple(_), Self::Variant(_, _))
400 | (Self::Tuple(_), Self::Error(_))
401 | (Self::Tuple(_), Self::Map { .. })
402 | (Self::Array(_), Self::Primitive(_))
403 | (Self::Array(_), Self::Tuple(_))
404 | (Self::Array(_), Self::Struct(_))
405 | (Self::Array(_), Self::Variant(_, _))
406 | (Self::Array(_), Self::Error(_))
407 | (Self::Array(_), Self::Map { .. })
408 | (Self::Struct(_), Self::Array(_))
409 | (Self::Struct(_), Self::Primitive(_))
410 | (Self::Struct(_), Self::Tuple(_))
411 | (Self::Struct(_), Self::Variant(_, _))
412 | (Self::Struct(_), Self::Error(_))
413 | (Self::Struct(_), Self::Map { .. })
414 | (Self::Variant(_, _), Self::Array(_))
415 | (Self::Variant(_, _), Self::Struct(_))
416 | (Self::Variant(_, _), Self::Primitive(_))
417 | (Self::Variant(_, _), Self::Tuple(_))
418 | (Self::Variant(_, _), Self::Error(_))
419 | (Self::Variant(_, _), Self::Map { .. })
420 | (Self::Error(_), Self::Array(_))
421 | (Self::Error(_), Self::Primitive(_))
422 | (Self::Error(_), Self::Struct(_))
423 | (Self::Error(_), Self::Variant(_, _))
424 | (Self::Error(_), Self::Tuple(_))
425 | (Self::Error(_), Self::Map { .. })
426 | (Self::Map { .. }, Self::Array(_))
427 | (Self::Map { .. }, Self::Primitive(_))
428 | (Self::Map { .. }, Self::Struct(_))
429 | (Self::Map { .. }, Self::Variant(_, _))
430 | (Self::Map { .. }, Self::Tuple(_))
431 | (Self::Map { .. }, Self::Error(_)) => Ok(false),
432 }
433 }
434
435 pub fn contains<R: Rt, E: UserEvent>(
436 &self,
437 env: &Env<R, E>,
438 t: &Self,
439 ) -> Result<bool> {
440 self.contains_int(
441 ContainsFlags::AliasTVars | ContainsFlags::InitTVars,
442 env,
443 &mut LPooled::take(),
444 t,
445 )
446 }
447
448 pub fn contains_with_flags<R: Rt, E: UserEvent>(
449 &self,
450 flags: BitFlags<ContainsFlags>,
451 env: &Env<R, E>,
452 t: &Self,
453 ) -> Result<bool> {
454 self.contains_int(flags, env, &mut LPooled::take(), t)
455 }
456
457 fn could_match_int<R: Rt, E: UserEvent>(
458 &self,
459 env: &Env<R, E>,
460 hist: &mut FxHashMap<(usize, usize), bool>,
461 t: &Self,
462 ) -> Result<bool> {
463 let fl = BitFlags::empty();
464 match (self, t) {
465 (
466 Self::Ref { scope: s0, name: n0, params: p0 },
467 Self::Ref { scope: s1, name: n1, params: p1 },
468 ) if s0 == s1 && n0 == n1 => Ok(p0.len() == p1.len()
469 && p0
470 .iter()
471 .zip(p1.iter())
472 .map(|(t0, t1)| t0.could_match_int(env, hist, t1))
473 .collect::<Result<AndAc>>()?
474 .0),
475 (t0 @ Self::Ref { .. }, t1) | (t0, t1 @ Self::Ref { .. }) => {
476 let t0 = t0.lookup_ref(env)?;
477 let t1 = t1.lookup_ref(env)?;
478 let t0_addr = (t0 as *const Type).addr();
479 let t1_addr = (t1 as *const Type).addr();
480 match hist.get(&(t0_addr, t1_addr)) {
481 Some(r) => Ok(*r),
482 None => {
483 hist.insert((t0_addr, t1_addr), true);
484 match t0.could_match_int(env, hist, t1) {
485 Ok(r) => {
486 hist.insert((t0_addr, t1_addr), r);
487 Ok(r)
488 }
489 Err(e) => {
490 hist.remove(&(t0_addr, t1_addr));
491 Err(e)
492 }
493 }
494 }
495 }
496 }
497 (t0, Self::Primitive(s)) => {
498 for t1 in s.iter() {
499 if t0.contains_int(fl, env, hist, &Type::Primitive(t1.into()))? {
500 return Ok(true);
501 }
502 }
503 Ok(false)
504 }
505 (Type::Primitive(p), Type::Error(_)) => Ok(p.contains(Typ::Error)),
506 (Type::Error(t0), Type::Error(t1)) => t0.could_match_int(env, hist, t1),
507 (Type::Array(t0), Type::Array(t1)) => t0.could_match_int(env, hist, t1),
508 (Type::Primitive(p), Type::Array(_)) => Ok(p.contains(Typ::Array)),
509 (Type::Map { key: k0, value: v0 }, Type::Map { key: k1, value: v1 }) => {
510 Ok(k0.could_match_int(env, hist, k1)?
511 && v0.could_match_int(env, hist, v1)?)
512 }
513 (Type::Primitive(p), Type::Map { .. }) => Ok(p.contains(Typ::Map)),
514 (Type::Tuple(ts0), Type::Tuple(ts1)) => Ok(ts0.len() == ts1.len()
515 && ts0
516 .iter()
517 .zip(ts1.iter())
518 .map(|(t0, t1)| t0.could_match_int(env, hist, t1))
519 .collect::<Result<AndAc>>()?
520 .0),
521 (Type::Struct(ts0), Type::Struct(ts1)) => Ok(ts0.len() == ts1.len()
522 && ts0
523 .iter()
524 .zip(ts1.iter())
525 .map(|((n0, t0), (n1, t1))| {
526 Ok(n0 == n1 && t0.could_match_int(env, hist, t1)?)
527 })
528 .collect::<Result<AndAc>>()?
529 .0),
530 (Type::Variant(n0, ts0), Type::Variant(n1, ts1)) => Ok(ts0.len()
531 == ts1.len()
532 && n0 == n1
533 && ts0
534 .iter()
535 .zip(ts1.iter())
536 .map(|(t0, t1)| t0.could_match_int(env, hist, t1))
537 .collect::<Result<AndAc>>()?
538 .0),
539 (Type::ByRef(t0), Type::ByRef(t1)) => t0.could_match_int(env, hist, t1),
540 (t0, Self::Set(ts)) => {
541 for t1 in ts.iter() {
542 if t0.could_match_int(env, hist, t1)? {
543 return Ok(true);
544 }
545 }
546 Ok(false)
547 }
548 (Type::Set(ts), t1) => {
549 for t0 in ts.iter() {
550 if t0.could_match_int(env, hist, t1)? {
551 return Ok(true);
552 }
553 }
554 Ok(false)
555 }
556 (Type::TVar(t0), t1) => match &*t0.read().typ.read() {
557 Some(t0) => t0.could_match_int(env, hist, t1),
558 None => Ok(true),
559 },
560 (t0, Type::TVar(t1)) => match &*t1.read().typ.read() {
561 Some(t1) => t0.could_match_int(env, hist, t1),
562 None => Ok(true),
563 },
564 (Type::Any, _) | (_, Type::Any) | (Type::Bottom, _) | (_, Type::Bottom) => {
565 Ok(true)
566 }
567 (Type::Fn(_), _)
568 | (_, Type::Fn(_))
569 | (Type::Tuple(_), _)
570 | (_, Type::Tuple(_))
571 | (Type::Struct(_), _)
572 | (_, Type::Struct(_))
573 | (Type::Variant(_, _), _)
574 | (_, Type::Variant(_, _))
575 | (Type::ByRef(_), _)
576 | (_, Type::ByRef(_))
577 | (Type::Array(_), _)
578 | (_, Type::Array(_))
579 | (_, Type::Map { .. })
580 | (Type::Map { .. }, _) => Ok(false),
581 }
582 }
583
584 pub fn could_match<R: Rt, E: UserEvent>(
585 &self,
586 env: &Env<R, E>,
587 t: &Self,
588 ) -> Result<bool> {
589 self.could_match_int(env, &mut LPooled::take(), t)
590 }
591
592 fn union_int<R: Rt, E: UserEvent>(
593 &self,
594 env: &Env<R, E>,
595 hist: &mut FxHashMap<(usize, usize), Type>,
596 t: &Self,
597 ) -> Result<Self> {
598 match (self, t) {
599 (
600 Type::Ref { scope: s0, name: n0, params: p0 },
601 Type::Ref { scope: s1, name: n1, params: p1 },
602 ) if n0 == n1 && s0 == s1 && p0.len() == p1.len() => {
603 let mut params = p0
604 .iter()
605 .zip(p1.iter())
606 .map(|(p0, p1)| p0.union_int(env, hist, p1))
607 .collect::<Result<LPooled<Vec<_>>>>()?;
608 let params = Arc::from_iter(params.drain(..));
609 Ok(Self::Ref { scope: s0.clone(), name: n0.clone(), params })
610 }
611 (tr @ Type::Ref { .. }, t) => {
612 let t0 = tr.lookup_ref(env)?;
613 let t0_addr = (t0 as *const Type).addr();
614 let t_addr = (t as *const Type).addr();
615 match hist.get(&(t0_addr, t_addr)) {
616 Some(t) => Ok(t.clone()),
617 None => {
618 hist.insert((t0_addr, t_addr), tr.clone());
619 let r = t0.union_int(env, hist, t)?;
620 hist.insert((t0_addr, t_addr), r.clone());
621 Ok(r)
622 }
623 }
624 }
625 (t, tr @ Type::Ref { .. }) => {
626 let t1 = tr.lookup_ref(env)?;
627 let t1_addr = (t1 as *const Type).addr();
628 let t_addr = (t as *const Type).addr();
629 match hist.get(&(t_addr, t1_addr)) {
630 Some(t) => Ok(t.clone()),
631 None => {
632 hist.insert((t_addr, t1_addr), tr.clone());
633 let r = t.union_int(env, hist, t1)?;
634 hist.insert((t_addr, t1_addr), r.clone());
635 Ok(r)
636 }
637 }
638 }
639 (Type::Bottom, t) | (t, Type::Bottom) => Ok(t.clone()),
640 (Type::Any, _) | (_, Type::Any) => Ok(Type::Any),
641 (Type::Primitive(p), t) | (t, Type::Primitive(p)) if p.is_empty() => {
642 Ok(t.clone())
643 }
644 (Type::Primitive(s0), Type::Primitive(s1)) => {
645 let mut s = *s0;
646 s.insert(*s1);
647 Ok(Type::Primitive(s))
648 }
649 (
650 Type::Primitive(p),
651 Type::Array(_) | Type::Struct(_) | Type::Tuple(_) | Type::Variant(_, _),
652 )
653 | (
654 Type::Array(_) | Type::Struct(_) | Type::Tuple(_) | Type::Variant(_, _),
655 Type::Primitive(p),
656 ) if p.contains(Typ::Array) => Ok(Type::Primitive(*p)),
657 (Type::Primitive(p), Type::Array(t))
658 | (Type::Array(t), Type::Primitive(p)) => Ok(Type::Set(Arc::from_iter([
659 Type::Primitive(*p),
660 Type::Array(t.clone()),
661 ]))),
662 (t @ Type::Array(t0), u @ Type::Array(t1)) => {
663 if t0 == t1 {
664 Ok(Type::Array(t0.clone()))
665 } else {
666 Ok(Type::Set(Arc::from_iter([t.clone(), u.clone()])))
667 }
668 }
669 (Type::Primitive(p), Type::Map { .. })
670 | (Type::Map { .. }, Type::Primitive(p))
671 if p.contains(Typ::Map) =>
672 {
673 Ok(Type::Primitive(*p))
674 }
675 (Type::Primitive(p), Type::Map { key, value })
676 | (Type::Map { key, value }, Type::Primitive(p)) => {
677 Ok(Type::Set(Arc::from_iter([
678 Type::Primitive(*p),
679 Type::Map { key: key.clone(), value: value.clone() },
680 ])))
681 }
682 (
683 t @ Type::Map { key: k0, value: v0 },
684 u @ Type::Map { key: k1, value: v1 },
685 ) => {
686 if k0 == k1 && v0 == v1 {
687 Ok(Type::Map { key: k0.clone(), value: v0.clone() })
688 } else {
689 Ok(Type::Set(Arc::from_iter([t.clone(), u.clone()])))
690 }
691 }
692 (t @ Type::Map { .. }, u) | (u, t @ Type::Map { .. }) => {
693 Ok(Type::Set(Arc::from_iter([t.clone(), u.clone()])))
694 }
695 (Type::Primitive(p), Type::Error(_))
696 | (Type::Error(_), Type::Primitive(p))
697 if p.contains(Typ::Error) =>
698 {
699 Ok(Type::Primitive(*p))
700 }
701 (Type::Error(e0), Type::Error(e1)) => {
702 Ok(Type::Error(Arc::new(e0.union_int(env, hist, e1)?)))
703 }
704 (e @ Type::Error(_), t) | (t, e @ Type::Error(_)) => {
705 Ok(Type::Set(Arc::from_iter([e.clone(), t.clone()])))
706 }
707 (t @ Type::ByRef(t0), u @ Type::ByRef(t1)) => {
708 if t0 == t1 {
709 Ok(Type::ByRef(t0.clone()))
710 } else {
711 Ok(Type::Set(Arc::from_iter([u.clone(), t.clone()])))
712 }
713 }
714 (Type::Set(s0), Type::Set(s1)) => Ok(Type::Set(Arc::from_iter(
715 s0.iter().cloned().chain(s1.iter().cloned()),
716 ))),
717 (Type::Set(s), t) | (t, Type::Set(s)) => Ok(Type::Set(Arc::from_iter(
718 s.iter().cloned().chain(iter::once(t.clone())),
719 ))),
720 (u @ Type::Struct(t0), t @ Type::Struct(t1)) => {
721 if t0.len() == t1.len() && t0 == t1 {
722 Ok(u.clone())
723 } else {
724 Ok(Type::Set(Arc::from_iter([u.clone(), t.clone()])))
725 }
726 }
727 (u @ Type::Struct(_), t) | (t, u @ Type::Struct(_)) => {
728 Ok(Type::Set(Arc::from_iter([u.clone(), t.clone()])))
729 }
730 (u @ Type::Tuple(t0), t @ Type::Tuple(t1)) => {
731 if t0 == t1 {
732 Ok(u.clone())
733 } else {
734 Ok(Type::Set(Arc::from_iter([u.clone(), t.clone()])))
735 }
736 }
737 (u @ Type::Tuple(_), t) | (t, u @ Type::Tuple(_)) => {
738 Ok(Type::Set(Arc::from_iter([u.clone(), t.clone()])))
739 }
740 (u @ Type::Variant(tg0, t0), t @ Type::Variant(tg1, t1)) => {
741 if tg0 == tg1 && t0.len() == t1.len() {
742 let typs = t0
743 .iter()
744 .zip(t1.iter())
745 .map(|(t0, t1)| t0.union_int(env, hist, t1))
746 .collect::<Result<SmallVec<[_; 8]>>>()?;
747 Ok(Type::Variant(tg0.clone(), Arc::from_iter(typs.into_iter())))
748 } else {
749 Ok(Type::Set(Arc::from_iter([u.clone(), t.clone()])))
750 }
751 }
752 (u @ Type::Variant(_, _), t) | (t, u @ Type::Variant(_, _)) => {
753 Ok(Type::Set(Arc::from_iter([u.clone(), t.clone()])))
754 }
755 (Type::Fn(f0), Type::Fn(f1)) => {
756 if f0 == f1 {
757 Ok(Type::Fn(f0.clone()))
758 } else {
759 Ok(Type::Set(Arc::from_iter([
760 Type::Fn(f0.clone()),
761 Type::Fn(f1.clone()),
762 ])))
763 }
764 }
765 (f @ Type::Fn(_), t) | (t, f @ Type::Fn(_)) => {
766 Ok(Type::Set(Arc::from_iter([f.clone(), t.clone()])))
767 }
768 (t0 @ Type::TVar(_), t1 @ Type::TVar(_)) => {
769 if t0 == t1 {
770 Ok(t0.clone())
771 } else {
772 Ok(Type::Set(Arc::from_iter([t0.clone(), t1.clone()])))
773 }
774 }
775 (t0 @ Type::TVar(_), t1) | (t1, t0 @ Type::TVar(_)) => {
776 Ok(Type::Set(Arc::from_iter([t0.clone(), t1.clone()])))
777 }
778 (t @ Type::ByRef(_), u) | (u, t @ Type::ByRef(_)) => {
779 Ok(Type::Set(Arc::from_iter([t.clone(), u.clone()])))
780 }
781 }
782 }
783
784 pub fn union<R: Rt, E: UserEvent>(&self, env: &Env<R, E>, t: &Self) -> Result<Self> {
785 Ok(self.union_int(env, &mut LPooled::take(), t)?.normalize())
786 }
787
788 fn diff_int<R: Rt, E: UserEvent>(
789 &self,
790 env: &Env<R, E>,
791 hist: &mut FxHashMap<(usize, usize), Type>,
792 t: &Self,
793 ) -> Result<Self> {
794 match (self, t) {
795 (
796 Type::Ref { scope: s0, name: n0, .. },
797 Type::Ref { scope: s1, name: n1, .. },
798 ) if s0 == s1 && n0 == n1 => Ok(Type::Primitive(BitFlags::empty())),
799 (t0 @ Type::Ref { .. }, t1) | (t0, t1 @ Type::Ref { .. }) => {
800 let t0 = t0.lookup_ref(env)?;
801 let t1 = t1.lookup_ref(env)?;
802 let t0_addr = (t0 as *const Type).addr();
803 let t1_addr = (t1 as *const Type).addr();
804 match hist.get(&(t0_addr, t1_addr)) {
805 Some(r) => Ok(r.clone()),
806 None => {
807 let r = Type::Primitive(BitFlags::empty());
808 hist.insert((t0_addr, t1_addr), r);
809 match t0.diff_int(env, hist, &t1) {
810 Ok(r) => {
811 hist.insert((t0_addr, t1_addr), r.clone());
812 Ok(r)
813 }
814 Err(e) => {
815 hist.remove(&(t0_addr, t1_addr));
816 Err(e)
817 }
818 }
819 }
820 }
821 }
822 (Type::Set(s0), Type::Set(s1)) => {
823 let mut s: SmallVec<[Type; 4]> = smallvec![];
824 for i in 0..s0.len() {
825 s.push(s0[i].clone());
826 for j in 0..s1.len() {
827 s[i] = s[i].diff_int(env, hist, &s1[j])?
828 }
829 }
830 Ok(Self::flatten_set(s.into_iter()))
831 }
832 (Type::Set(s), t) => Ok(Self::flatten_set(
833 s.iter()
834 .map(|s| s.diff_int(env, hist, t))
835 .collect::<Result<SmallVec<[_; 8]>>>()?,
836 )),
837 (t, Type::Set(s)) => {
838 let mut t = t.clone();
839 for st in s.iter() {
840 t = t.diff_int(env, hist, st)?;
841 }
842 Ok(t)
843 }
844 (Type::Tuple(t0), Type::Tuple(t1)) => {
845 if t0 == t1 {
846 Ok(Type::Primitive(BitFlags::empty()))
847 } else {
848 Ok(self.clone())
849 }
850 }
851 (Type::Struct(t0), Type::Struct(t1)) => {
852 if t0.len() == t1.len() && t0 == t1 {
853 Ok(Type::Primitive(BitFlags::empty()))
854 } else {
855 Ok(self.clone())
856 }
857 }
858 (Type::Variant(tg0, t0), Type::Variant(tg1, t1)) => {
859 if tg0 == tg1 && t0.len() == t1.len() && t0 == t1 {
860 Ok(Type::Primitive(BitFlags::empty()))
861 } else {
862 Ok(self.clone())
863 }
864 }
865 (Type::Map { key: k0, value: v0 }, Type::Map { key: k1, value: v1 }) => {
866 if k0 == k1 && v0 == v1 {
867 Ok(Type::Primitive(BitFlags::empty()))
868 } else {
869 Ok(self.clone())
870 }
871 }
872 (Type::Map { .. }, Type::Primitive(p)) => {
873 if p.contains(Typ::Map) {
874 Ok(Type::Primitive(BitFlags::empty()))
875 } else {
876 Ok(self.clone())
877 }
878 }
879 (Type::Primitive(p), Type::Map { key, value }) => {
880 if **key == Type::Any && **value == Type::Any {
881 let mut p = *p;
882 p.remove(Typ::Map);
883 Ok(Type::Primitive(p))
884 } else {
885 Ok(Type::Primitive(*p))
886 }
887 }
888 (Type::Fn(f0), Type::Fn(f1)) => {
889 if f0 == f1 {
890 Ok(Type::Primitive(BitFlags::empty()))
891 } else {
892 Ok(Type::Fn(f0.clone()))
893 }
894 }
895 (Type::TVar(tv0), Type::TVar(tv1)) => {
896 if tv0.read().typ.as_ptr() == tv1.read().typ.as_ptr() {
897 return Ok(Type::Primitive(BitFlags::empty()));
898 }
899 Ok(match (&*tv0.read().typ.read(), &*tv1.read().typ.read()) {
900 (None, _) | (_, None) => Type::TVar(tv0.clone()),
901 (Some(t0), Some(t1)) => t0.diff_int(env, hist, t1)?,
902 })
903 }
904 (Type::TVar(tv), t) => Ok(match &*tv.read().typ.read() {
905 Some(tv) => tv.diff_int(env, hist, t)?,
906 None => self.clone(),
907 }),
908 (t, Type::TVar(tv)) => Ok(match &*tv.read().typ.read() {
909 Some(tv) => t.diff_int(env, hist, tv)?,
910 None => self.clone(),
911 }),
912 (Type::Array(t0), Type::Array(t1)) => {
913 if t0 == t1 {
914 Ok(Type::Primitive(BitFlags::empty()))
915 } else {
916 Ok(Type::Array(Arc::new(t0.diff_int(env, hist, t1)?)))
917 }
918 }
919 (Type::Primitive(p), Type::Array(t)) => {
920 if &**t == &Type::Any {
921 let mut s = *p;
922 s.remove(Typ::Array);
923 Ok(Type::Primitive(s))
924 } else {
925 Ok(Type::Primitive(*p))
926 }
927 }
928 (
929 Type::Array(_) | Type::Struct(_) | Type::Tuple(_) | Type::Variant(_, _),
930 Type::Primitive(p),
931 ) => {
932 if p.contains(Typ::Array) {
933 Ok(Type::Primitive(BitFlags::empty()))
934 } else {
935 Ok(self.clone())
936 }
937 }
938 (_, Type::Any) => Ok(Type::Primitive(BitFlags::empty())),
939 (Type::Any, _) => Ok(Type::Any),
940 (Type::Primitive(s0), Type::Primitive(s1)) => {
941 let mut s = *s0;
942 s.remove(*s1);
943 Ok(Type::Primitive(s))
944 }
945 (Type::Primitive(p), Type::Error(e)) => {
946 if &**e == &Type::Any {
947 let mut s = *p;
948 s.remove(Typ::Error);
949 Ok(Type::Primitive(s))
950 } else {
951 Ok(Type::Primitive(*p))
952 }
953 }
954 (Type::Error(_), Type::Primitive(p)) => {
955 if p.contains(Typ::Error) {
956 Ok(Type::Primitive(BitFlags::empty()))
957 } else {
958 Ok(self.clone())
959 }
960 }
961 (Type::Error(e0), Type::Error(e1)) => {
962 if e0 == e1 {
963 Ok(Type::Primitive(BitFlags::empty()))
964 } else {
965 Ok(Type::Error(Arc::new(e0.diff_int(env, hist, e1)?)))
966 }
967 }
968 (Type::ByRef(t0), Type::ByRef(t1)) => {
969 Ok(Type::ByRef(Arc::new(t0.diff_int(env, hist, t1)?)))
970 }
971 (Type::Fn(_), _)
972 | (_, Type::Fn(_))
973 | (Type::Array(_), _)
974 | (_, Type::Array(_))
975 | (Type::Tuple(_), _)
976 | (_, Type::Tuple(_))
977 | (Type::Struct(_), _)
978 | (_, Type::Struct(_))
979 | (Type::Variant(_, _), _)
980 | (_, Type::Variant(_, _))
981 | (Type::ByRef(_), _)
982 | (_, Type::ByRef(_))
983 | (Type::Error(_), _)
984 | (_, Type::Error(_))
985 | (Type::Primitive(_), _)
986 | (_, Type::Primitive(_))
987 | (Type::Bottom, _)
988 | (Type::Map { .. }, _) => Ok(self.clone()),
989 }
990 }
991
992 pub fn diff<R: Rt, E: UserEvent>(&self, env: &Env<R, E>, t: &Self) -> Result<Self> {
993 Ok(self.diff_int(env, &mut LPooled::take(), t)?.normalize())
994 }
995
996 pub fn any() -> Self {
997 Self::Any
998 }
999
1000 pub fn boolean() -> Self {
1001 Self::Primitive(Typ::Bool.into())
1002 }
1003
1004 pub fn number() -> Self {
1005 Self::Primitive(Typ::number())
1006 }
1007
1008 pub fn int() -> Self {
1009 Self::Primitive(Typ::integer())
1010 }
1011
1012 pub fn uint() -> Self {
1013 Self::Primitive(Typ::unsigned_integer())
1014 }
1015
1016 pub fn alias_tvars(&self, known: &mut FxHashMap<ArcStr, TVar>) {
1018 match self {
1019 Type::Bottom | Type::Any | Type::Primitive(_) => (),
1020 Type::Ref { params, .. } => {
1021 for t in params.iter() {
1022 t.alias_tvars(known);
1023 }
1024 }
1025 Type::Error(t) => t.alias_tvars(known),
1026 Type::Array(t) => t.alias_tvars(known),
1027 Type::Map { key, value } => {
1028 key.alias_tvars(known);
1029 value.alias_tvars(known);
1030 }
1031 Type::ByRef(t) => t.alias_tvars(known),
1032 Type::Tuple(ts) => {
1033 for t in ts.iter() {
1034 t.alias_tvars(known)
1035 }
1036 }
1037 Type::Struct(ts) => {
1038 for (_, t) in ts.iter() {
1039 t.alias_tvars(known)
1040 }
1041 }
1042 Type::Variant(_, ts) => {
1043 for t in ts.iter() {
1044 t.alias_tvars(known)
1045 }
1046 }
1047 Type::TVar(tv) => match known.entry(tv.name.clone()) {
1048 Entry::Occupied(e) => {
1049 let v = e.get();
1050 v.freeze();
1051 tv.alias(v);
1052 }
1053 Entry::Vacant(e) => {
1054 e.insert(tv.clone());
1055 ()
1056 }
1057 },
1058 Type::Fn(ft) => ft.alias_tvars(known),
1059 Type::Set(s) => {
1060 for typ in s.iter() {
1061 typ.alias_tvars(known)
1062 }
1063 }
1064 }
1065 }
1066
1067 pub fn collect_tvars(&self, known: &mut FxHashMap<ArcStr, TVar>) {
1068 match self {
1069 Type::Bottom | Type::Any | Type::Primitive(_) => (),
1070 Type::Ref { params, .. } => {
1071 for t in params.iter() {
1072 t.collect_tvars(known);
1073 }
1074 }
1075 Type::Error(t) => t.collect_tvars(known),
1076 Type::Array(t) => t.collect_tvars(known),
1077 Type::Map { key, value } => {
1078 key.collect_tvars(known);
1079 value.collect_tvars(known);
1080 }
1081 Type::ByRef(t) => t.collect_tvars(known),
1082 Type::Tuple(ts) => {
1083 for t in ts.iter() {
1084 t.collect_tvars(known)
1085 }
1086 }
1087 Type::Struct(ts) => {
1088 for (_, t) in ts.iter() {
1089 t.collect_tvars(known)
1090 }
1091 }
1092 Type::Variant(_, ts) => {
1093 for t in ts.iter() {
1094 t.collect_tvars(known)
1095 }
1096 }
1097 Type::TVar(tv) => match known.entry(tv.name.clone()) {
1098 Entry::Occupied(_) => (),
1099 Entry::Vacant(e) => {
1100 e.insert(tv.clone());
1101 ()
1102 }
1103 },
1104 Type::Fn(ft) => ft.collect_tvars(known),
1105 Type::Set(s) => {
1106 for typ in s.iter() {
1107 typ.collect_tvars(known)
1108 }
1109 }
1110 }
1111 }
1112
1113 pub fn check_tvars_declared(&self, declared: &FxHashSet<ArcStr>) -> Result<()> {
1114 match self {
1115 Type::Bottom | Type::Any | Type::Primitive(_) => Ok(()),
1116 Type::Ref { params, .. } => {
1117 params.iter().try_for_each(|t| t.check_tvars_declared(declared))
1118 }
1119 Type::Error(t) => t.check_tvars_declared(declared),
1120 Type::Array(t) => t.check_tvars_declared(declared),
1121 Type::Map { key, value } => {
1122 key.check_tvars_declared(declared)?;
1123 value.check_tvars_declared(declared)
1124 }
1125 Type::ByRef(t) => t.check_tvars_declared(declared),
1126 Type::Tuple(ts) => {
1127 ts.iter().try_for_each(|t| t.check_tvars_declared(declared))
1128 }
1129 Type::Struct(ts) => {
1130 ts.iter().try_for_each(|(_, t)| t.check_tvars_declared(declared))
1131 }
1132 Type::Variant(_, ts) => {
1133 ts.iter().try_for_each(|t| t.check_tvars_declared(declared))
1134 }
1135 Type::TVar(tv) => {
1136 if !declared.contains(&tv.name) {
1137 bail!("undeclared type variable '{}'", tv.name)
1138 } else {
1139 Ok(())
1140 }
1141 }
1142 Type::Set(s) => s.iter().try_for_each(|t| t.check_tvars_declared(declared)),
1143 Type::Fn(_) => Ok(()),
1144 }
1145 }
1146
1147 pub fn has_unbound(&self) -> bool {
1148 match self {
1149 Type::Bottom | Type::Any | Type::Primitive(_) => false,
1150 Type::Ref { .. } => false,
1151 Type::Error(e) => e.has_unbound(),
1152 Type::Array(t0) => t0.has_unbound(),
1153 Type::Map { key, value } => key.has_unbound() || value.has_unbound(),
1154 Type::ByRef(t0) => t0.has_unbound(),
1155 Type::Tuple(ts) => ts.iter().any(|t| t.has_unbound()),
1156 Type::Struct(ts) => ts.iter().any(|(_, t)| t.has_unbound()),
1157 Type::Variant(_, ts) => ts.iter().any(|t| t.has_unbound()),
1158 Type::TVar(tv) => tv.read().typ.read().is_some(),
1159 Type::Set(s) => s.iter().any(|t| t.has_unbound()),
1160 Type::Fn(ft) => ft.has_unbound(),
1161 }
1162 }
1163
1164 pub fn bind_as(&self, t: &Self) {
1166 match self {
1167 Type::Bottom | Type::Any | Type::Primitive(_) => (),
1168 Type::Ref { .. } => (),
1169 Type::Error(t0) => t0.bind_as(t),
1170 Type::Array(t0) => t0.bind_as(t),
1171 Type::Map { key, value } => {
1172 key.bind_as(t);
1173 value.bind_as(t);
1174 }
1175 Type::ByRef(t0) => t0.bind_as(t),
1176 Type::Tuple(ts) => {
1177 for elt in ts.iter() {
1178 elt.bind_as(t)
1179 }
1180 }
1181 Type::Struct(ts) => {
1182 for (_, elt) in ts.iter() {
1183 elt.bind_as(t)
1184 }
1185 }
1186 Type::Variant(_, ts) => {
1187 for elt in ts.iter() {
1188 elt.bind_as(t)
1189 }
1190 }
1191 Type::TVar(tv) => {
1192 let tv = tv.read();
1193 let mut tv = tv.typ.write();
1194 if tv.is_none() {
1195 *tv = Some(t.clone());
1196 }
1197 }
1198 Type::Set(s) => {
1199 for elt in s.iter() {
1200 elt.bind_as(t)
1201 }
1202 }
1203 Type::Fn(ft) => ft.bind_as(t),
1204 }
1205 }
1206
1207 pub fn reset_tvars(&self) -> Type {
1210 match self {
1211 Type::Bottom => Type::Bottom,
1212 Type::Any => Type::Any,
1213 Type::Primitive(p) => Type::Primitive(*p),
1214 Type::Ref { scope, name, params } => Type::Ref {
1215 scope: scope.clone(),
1216 name: name.clone(),
1217 params: Arc::from_iter(params.iter().map(|t| t.reset_tvars())),
1218 },
1219 Type::Error(t0) => Type::Error(Arc::new(t0.reset_tvars())),
1220 Type::Array(t0) => Type::Array(Arc::new(t0.reset_tvars())),
1221 Type::Map { key, value } => {
1222 let key = Arc::new(key.reset_tvars());
1223 let value = Arc::new(value.reset_tvars());
1224 Type::Map { key, value }
1225 }
1226 Type::ByRef(t0) => Type::ByRef(Arc::new(t0.reset_tvars())),
1227 Type::Tuple(ts) => {
1228 Type::Tuple(Arc::from_iter(ts.iter().map(|t| t.reset_tvars())))
1229 }
1230 Type::Struct(ts) => Type::Struct(Arc::from_iter(
1231 ts.iter().map(|(n, t)| (n.clone(), t.reset_tvars())),
1232 )),
1233 Type::Variant(tag, ts) => Type::Variant(
1234 tag.clone(),
1235 Arc::from_iter(ts.iter().map(|t| t.reset_tvars())),
1236 ),
1237 Type::TVar(tv) => Type::TVar(TVar::empty_named(tv.name.clone())),
1238 Type::Set(s) => Type::Set(Arc::from_iter(s.iter().map(|t| t.reset_tvars()))),
1239 Type::Fn(fntyp) => Type::Fn(Arc::new(fntyp.reset_tvars())),
1240 }
1241 }
1242
1243 pub fn replace_tvars(&self, known: &FxHashMap<ArcStr, Self>) -> Type {
1246 match self {
1247 Type::TVar(tv) => match known.get(&tv.name) {
1248 Some(t) => t.clone(),
1249 None => Type::TVar(tv.clone()),
1250 },
1251 Type::Bottom => Type::Bottom,
1252 Type::Any => Type::Any,
1253 Type::Primitive(p) => Type::Primitive(*p),
1254 Type::Ref { scope, name, params } => Type::Ref {
1255 scope: scope.clone(),
1256 name: name.clone(),
1257 params: Arc::from_iter(params.iter().map(|t| t.replace_tvars(known))),
1258 },
1259 Type::Error(t0) => Type::Error(Arc::new(t0.replace_tvars(known))),
1260 Type::Array(t0) => Type::Array(Arc::new(t0.replace_tvars(known))),
1261 Type::Map { key, value } => {
1262 let key = Arc::new(key.replace_tvars(known));
1263 let value = Arc::new(value.replace_tvars(known));
1264 Type::Map { key, value }
1265 }
1266 Type::ByRef(t0) => Type::ByRef(Arc::new(t0.replace_tvars(known))),
1267 Type::Tuple(ts) => {
1268 Type::Tuple(Arc::from_iter(ts.iter().map(|t| t.replace_tvars(known))))
1269 }
1270 Type::Struct(ts) => Type::Struct(Arc::from_iter(
1271 ts.iter().map(|(n, t)| (n.clone(), t.replace_tvars(known))),
1272 )),
1273 Type::Variant(tag, ts) => Type::Variant(
1274 tag.clone(),
1275 Arc::from_iter(ts.iter().map(|t| t.replace_tvars(known))),
1276 ),
1277 Type::Set(s) => {
1278 Type::Set(Arc::from_iter(s.iter().map(|t| t.replace_tvars(known))))
1279 }
1280 Type::Fn(fntyp) => Type::Fn(Arc::new(fntyp.replace_tvars(known))),
1281 }
1282 }
1283
1284 fn strip_error_int<R: Rt, E: UserEvent>(
1285 &self,
1286 env: &Env<R, E>,
1287 hist: &mut FxHashSet<usize>,
1288 ) -> Option<Type> {
1289 match self {
1290 Type::Error(t) => match t.strip_error_int(env, hist) {
1291 Some(t) => Some(t),
1292 None => Some((**t).clone()),
1293 },
1294 Type::TVar(tv) => {
1295 tv.read().typ.read().as_ref().and_then(|t| t.strip_error_int(env, hist))
1296 }
1297 Type::Primitive(p) => {
1298 if *p == BitFlags::from(Typ::Error) {
1299 Some(Type::Any)
1300 } else {
1301 None
1302 }
1303 }
1304 Type::Ref { .. } => {
1305 let t = self.lookup_ref(env).ok()?;
1306 let addr = t as *const Type as usize;
1307 if hist.insert(addr) {
1308 t.strip_error_int(env, hist)
1309 } else {
1310 None
1311 }
1312 }
1313 Type::Set(s) => {
1314 let r = Self::flatten_set(
1315 s.iter().filter_map(|t| t.strip_error_int(env, hist)),
1316 );
1317 match r {
1318 Type::Primitive(p) if p.is_empty() => None,
1319 t => Some(t),
1320 }
1321 }
1322 Type::Array(_)
1323 | Type::Map { .. }
1324 | Type::ByRef(_)
1325 | Type::Tuple(_)
1326 | Type::Struct(_)
1327 | Type::Variant(_, _)
1328 | Type::Fn(_)
1329 | Type::Any
1330 | Type::Bottom => None,
1331 }
1332 }
1333
1334 pub fn strip_error<R: Rt, E: UserEvent>(&self, env: &Env<R, E>) -> Option<Self> {
1337 self.strip_error_int(env, &mut LPooled::take())
1338 }
1339
1340 pub(crate) fn unbind_tvars(&self) {
1342 match self {
1343 Type::Bottom | Type::Any | Type::Primitive(_) | Type::Ref { .. } => (),
1344 Type::Error(t0) => t0.unbind_tvars(),
1345 Type::Array(t0) => t0.unbind_tvars(),
1346 Type::Map { key, value } => {
1347 key.unbind_tvars();
1348 value.unbind_tvars();
1349 }
1350 Type::ByRef(t0) => t0.unbind_tvars(),
1351 Type::Tuple(ts) | Type::Variant(_, ts) | Type::Set(ts) => {
1352 for t in ts.iter() {
1353 t.unbind_tvars()
1354 }
1355 }
1356 Type::Struct(ts) => {
1357 for (_, t) in ts.iter() {
1358 t.unbind_tvars()
1359 }
1360 }
1361 Type::TVar(tv) => tv.unbind(),
1362 Type::Fn(fntyp) => fntyp.unbind_tvars(),
1363 }
1364 }
1365
1366 fn check_cast_int<R: Rt, E: UserEvent>(
1367 &self,
1368 env: &Env<R, E>,
1369 hist: &mut FxHashSet<usize>,
1370 ) -> Result<()> {
1371 match self {
1372 Type::Primitive(_) | Type::Any => Ok(()),
1373 Type::Fn(_) => bail!("can't cast a value to a function"),
1374 Type::Bottom => bail!("can't cast a value to bottom"),
1375 Type::Set(s) => Ok(for t in s.iter() {
1376 t.check_cast_int(env, hist)?
1377 }),
1378 Type::TVar(tv) => match &*tv.read().typ.read() {
1379 Some(t) => t.check_cast_int(env, hist),
1380 None => bail!("can't cast a value to a free type variable"),
1381 },
1382 Type::Error(e) => e.check_cast_int(env, hist),
1383 Type::Array(et) => et.check_cast_int(env, hist),
1384 Type::Map { key, value } => {
1385 key.check_cast_int(env, hist)?;
1386 value.check_cast_int(env, hist)
1387 }
1388 Type::ByRef(_) => bail!("can't cast a reference"),
1389 Type::Tuple(ts) => Ok(for t in ts.iter() {
1390 t.check_cast_int(env, hist)?
1391 }),
1392 Type::Struct(ts) => Ok(for (_, t) in ts.iter() {
1393 t.check_cast_int(env, hist)?
1394 }),
1395 Type::Variant(_, ts) => Ok(for t in ts.iter() {
1396 t.check_cast_int(env, hist)?
1397 }),
1398 Type::Ref { .. } => {
1399 let t = self.lookup_ref(env)?;
1400 let t_addr = (t as *const Type).addr();
1401 if hist.contains(&t_addr) {
1402 Ok(())
1403 } else {
1404 hist.insert(t_addr);
1405 t.check_cast_int(env, hist)
1406 }
1407 }
1408 }
1409 }
1410
1411 pub fn check_cast<R: Rt, E: UserEvent>(&self, env: &Env<R, E>) -> Result<()> {
1412 self.check_cast_int(env, &mut LPooled::take())
1413 }
1414
1415 fn cast_value_int<R: Rt, E: UserEvent>(
1416 &self,
1417 env: &Env<R, E>,
1418 hist: &mut FxHashSet<(usize, usize)>,
1419 v: Value,
1420 ) -> Result<Value> {
1421 if self.is_a_int(env, hist, &v) {
1422 return Ok(v);
1423 }
1424 match self {
1425 Type::Bottom => bail!("can't cast {v} to Bottom"),
1426 Type::Fn(_) => bail!("can't cast {v} to a function"),
1427 Type::ByRef(_) => bail!("can't cast {v} to a reference"),
1428 Type::Primitive(s) => s
1429 .iter()
1430 .find_map(|t| v.clone().cast(t))
1431 .ok_or_else(|| anyhow!("can't cast {v} to {self}")),
1432 Type::Any => Ok(v),
1433 Type::Error(e) => {
1434 let v = match v {
1435 Value::Error(v) => (*v).clone(),
1436 v => v,
1437 };
1438 Ok(Value::Error(Arc::new(e.cast_value_int(env, hist, v)?)))
1439 }
1440 Type::Array(et) => match v {
1441 Value::Array(elts) => {
1442 let mut va = elts
1443 .iter()
1444 .map(|el| et.cast_value_int(env, hist, el.clone()))
1445 .collect::<Result<LPooled<Vec<Value>>>>()?;
1446 Ok(Value::Array(ValArray::from_iter_exact(va.drain(..))))
1447 }
1448 v => Ok(Value::Array([et.cast_value_int(env, hist, v)?].into())),
1449 },
1450 Type::Map { key, value } => match v {
1451 Value::Map(m) => {
1452 let mut m = m
1453 .into_iter()
1454 .map(|(k, v)| {
1455 Ok((
1456 key.cast_value_int(env, hist, k.clone())?,
1457 value.cast_value_int(env, hist, v.clone())?,
1458 ))
1459 })
1460 .collect::<Result<LPooled<Vec<(Value, Value)>>>>()?;
1461 Ok(Value::Map(Map::from_iter(m.drain(..))))
1462 }
1463 Value::Array(a) => {
1464 let mut m = a
1465 .iter()
1466 .map(|a| match a {
1467 Value::Array(a) if a.len() == 2 => Ok((
1468 key.cast_value_int(env, hist, a[0].clone())?,
1469 value.cast_value_int(env, hist, a[1].clone())?,
1470 )),
1471 _ => bail!("expected an array of pairs"),
1472 })
1473 .collect::<Result<LPooled<Vec<(Value, Value)>>>>()?;
1474 Ok(Value::Map(Map::from_iter(m.drain(..))))
1475 }
1476 _ => bail!("can't cast {v} to {self}"),
1477 },
1478 Type::Tuple(ts) => match v {
1479 Value::Array(elts) => {
1480 if elts.len() != ts.len() {
1481 bail!("tuple size mismatch {self} with {}", Value::Array(elts))
1482 }
1483 let a = ts
1484 .iter()
1485 .zip(elts.iter())
1486 .map(|(t, el)| t.cast_value_int(env, hist, el.clone()))
1487 .collect::<Result<SmallVec<[Value; 8]>>>()?;
1488 Ok(Value::Array(ValArray::from_iter_exact(a.into_iter())))
1489 }
1490 v => bail!("can't cast {v} to {self}"),
1491 },
1492 Type::Struct(ts) => match v {
1493 Value::Array(elts) => {
1494 if elts.len() != ts.len() {
1495 bail!("struct size mismatch {self} with {}", Value::Array(elts))
1496 }
1497 let is_pairs = elts.iter().all(|v| match v {
1498 Value::Array(a) if a.len() == 2 => match &a[0] {
1499 Value::String(_) => true,
1500 _ => false,
1501 },
1502 _ => false,
1503 });
1504 if !is_pairs {
1505 bail!("expected array of pairs, got {}", Value::Array(elts))
1506 }
1507 let mut elts_s: SmallVec<[&Value; 16]> = elts.iter().collect();
1508 elts_s.sort_by_key(|v| match v {
1509 Value::Array(a) => match &a[0] {
1510 Value::String(s) => s,
1511 _ => unreachable!(),
1512 },
1513 _ => unreachable!(),
1514 });
1515 let keys_ok = ts.iter().zip(elts_s.iter()).fold(
1516 Ok(true),
1517 |acc: Result<_>, ((fname, t), v)| {
1518 let kok = acc?;
1519 let (name, v) = match v {
1520 Value::Array(a) => match (&a[0], &a[1]) {
1521 (Value::String(n), v) => (n, v),
1522 _ => unreachable!(),
1523 },
1524 _ => unreachable!(),
1525 };
1526 Ok(kok
1527 && name == fname
1528 && t.contains(env, &Type::Primitive(Typ::get(v).into()))?)
1529 },
1530 )?;
1531 if keys_ok {
1532 let elts = ts
1533 .iter()
1534 .zip(elts_s.iter())
1535 .map(|((n, t), v)| match v {
1536 Value::Array(a) => {
1537 let a = [
1538 Value::String(n.clone()),
1539 t.cast_value_int(env, hist, a[1].clone())?,
1540 ];
1541 Ok(Value::Array(ValArray::from_iter_exact(
1542 a.into_iter(),
1543 )))
1544 }
1545 _ => unreachable!(),
1546 })
1547 .collect::<Result<SmallVec<[Value; 8]>>>()?;
1548 Ok(Value::Array(ValArray::from_iter_exact(elts.into_iter())))
1549 } else {
1550 drop(elts_s);
1551 bail!("struct fields mismatch {self}, {}", Value::Array(elts))
1552 }
1553 }
1554 v => bail!("can't cast {v} to {self}"),
1555 },
1556 Type::Variant(tag, ts) if ts.len() == 0 => match &v {
1557 Value::String(s) if s == tag => Ok(v),
1558 _ => bail!("variant tag mismatch expected {tag} got {v}"),
1559 },
1560 Type::Variant(tag, ts) => match &v {
1561 Value::Array(elts) => {
1562 if ts.len() + 1 == elts.len() {
1563 match &elts[0] {
1564 Value::String(s) if s == tag => (),
1565 v => bail!("variant tag mismatch expected {tag} got {v}"),
1566 }
1567 let a = iter::once(&Type::Primitive(Typ::String.into()))
1568 .chain(ts.iter())
1569 .zip(elts.iter())
1570 .map(|(t, v)| t.cast_value_int(env, hist, v.clone()))
1571 .collect::<Result<SmallVec<[Value; 8]>>>()?;
1572 Ok(Value::Array(ValArray::from_iter_exact(a.into_iter())))
1573 } else if ts.len() == elts.len() {
1574 let mut a = ts
1575 .iter()
1576 .zip(elts.iter())
1577 .map(|(t, v)| t.cast_value_int(env, hist, v.clone()))
1578 .collect::<Result<SmallVec<[Value; 8]>>>()?;
1579 a.insert(0, Value::String(tag.clone()));
1580 Ok(Value::Array(ValArray::from_iter_exact(a.into_iter())))
1581 } else {
1582 bail!("variant length mismatch")
1583 }
1584 }
1585 v => bail!("can't cast {v} to {self}"),
1586 },
1587 Type::Ref { .. } => self.lookup_ref(env)?.cast_value_int(env, hist, v),
1588 Type::Set(ts) => ts
1589 .iter()
1590 .find_map(|t| t.cast_value_int(env, hist, v.clone()).ok())
1591 .ok_or_else(|| anyhow!("can't cast {v} to {self}")),
1592 Type::TVar(tv) => match &*tv.read().typ.read() {
1593 Some(t) => t.cast_value_int(env, hist, v.clone()),
1594 None => Ok(v),
1595 },
1596 }
1597 }
1598
1599 pub fn cast_value<R: Rt, E: UserEvent>(&self, env: &Env<R, E>, v: Value) -> Value {
1600 match self.cast_value_int(env, &mut LPooled::take(), v) {
1601 Ok(v) => v,
1602 Err(e) => errf!(CAST_ERR_TAG, "{e:?}"),
1603 }
1604 }
1605
1606 fn is_a_int<R: Rt, E: UserEvent>(
1607 &self,
1608 env: &Env<R, E>,
1609 hist: &mut FxHashSet<(usize, usize)>,
1610 v: &Value,
1611 ) -> bool {
1612 match self {
1613 Type::Ref { .. } => match self.lookup_ref(env) {
1614 Err(_) => false,
1615 Ok(t) => {
1616 let t_addr = (t as *const Type).addr();
1617 let v_addr = (v as *const Value).addr();
1618 !hist.contains(&(t_addr, v_addr)) && {
1619 hist.insert((t_addr, v_addr));
1620 t.is_a_int(env, hist, v)
1621 }
1622 }
1623 },
1624 Type::Primitive(t) => t.contains(Typ::get(&v)),
1625 Type::Any => true,
1626 Type::Array(et) => match v {
1627 Value::Array(a) => a.iter().all(|v| et.is_a_int(env, hist, v)),
1628 _ => false,
1629 },
1630 Type::Map { key, value } => match v {
1631 Value::Map(m) => m.into_iter().all(|(k, v)| {
1632 key.is_a_int(env, hist, k) && value.is_a_int(env, hist, v)
1633 }),
1634 _ => false,
1635 },
1636 Type::Error(e) => match v {
1637 Value::Error(v) => e.is_a_int(env, hist, v),
1638 _ => false,
1639 },
1640 Type::ByRef(_) => matches!(v, Value::U64(_) | Value::V64(_)),
1641 Type::Tuple(ts) => match v {
1642 Value::Array(elts) => {
1643 elts.len() == ts.len()
1644 && ts
1645 .iter()
1646 .zip(elts.iter())
1647 .all(|(t, v)| t.is_a_int(env, hist, v))
1648 }
1649 _ => false,
1650 },
1651 Type::Struct(ts) => match v {
1652 Value::Array(elts) => {
1653 elts.len() == ts.len()
1654 && ts.iter().zip(elts.iter()).all(|((n, t), v)| match v {
1655 Value::Array(a) if a.len() == 2 => match &a[..] {
1656 [Value::String(key), v] => {
1657 n == key && t.is_a_int(env, hist, v)
1658 }
1659 _ => false,
1660 },
1661 _ => false,
1662 })
1663 }
1664 _ => false,
1665 },
1666 Type::Variant(tag, ts) if ts.len() == 0 => match &v {
1667 Value::String(s) => s == tag,
1668 _ => false,
1669 },
1670 Type::Variant(tag, ts) => match &v {
1671 Value::Array(elts) => {
1672 ts.len() + 1 == elts.len()
1673 && match &elts[0] {
1674 Value::String(s) => s == tag,
1675 _ => false,
1676 }
1677 && ts
1678 .iter()
1679 .zip(elts[1..].iter())
1680 .all(|(t, v)| t.is_a_int(env, hist, v))
1681 }
1682 _ => false,
1683 },
1684 Type::TVar(tv) => match &*tv.read().typ.read() {
1685 None => true,
1686 Some(t) => t.is_a_int(env, hist, v),
1687 },
1688 Type::Fn(_) => match v {
1689 Value::U64(_) => true,
1690 _ => false,
1691 },
1692 Type::Bottom => true,
1693 Type::Set(ts) => ts.iter().any(|t| t.is_a_int(env, hist, v)),
1694 }
1695 }
1696
1697 pub fn is_a<R: Rt, E: UserEvent>(&self, env: &Env<R, E>, v: &Value) -> bool {
1699 self.is_a_int(env, &mut LPooled::take(), v)
1700 }
1701
1702 pub fn is_bot(&self) -> bool {
1703 match self {
1704 Type::Bottom => true,
1705 Type::Any
1706 | Type::TVar(_)
1707 | Type::Primitive(_)
1708 | Type::Ref { .. }
1709 | Type::Fn(_)
1710 | Type::Error(_)
1711 | Type::Array(_)
1712 | Type::ByRef(_)
1713 | Type::Tuple(_)
1714 | Type::Struct(_)
1715 | Type::Variant(_, _)
1716 | Type::Set(_)
1717 | Type::Map { .. } => false,
1718 }
1719 }
1720
1721 pub fn with_deref<R, F: FnOnce(Option<&Self>) -> R>(&self, f: F) -> R {
1722 match self {
1723 Self::Bottom
1724 | Self::Any
1725 | Self::Primitive(_)
1726 | Self::Fn(_)
1727 | Self::Set(_)
1728 | Self::Error(_)
1729 | Self::Array(_)
1730 | Self::ByRef(_)
1731 | Self::Tuple(_)
1732 | Self::Struct(_)
1733 | Self::Variant(_, _)
1734 | Self::Ref { .. }
1735 | Self::Map { .. } => f(Some(self)),
1736 Self::TVar(tv) => match tv.read().typ.read().as_ref() {
1737 Some(t) => t.with_deref(f),
1738 None => f(None),
1739 },
1740 }
1741 }
1742
1743 pub(crate) fn flatten_set(set: impl IntoIterator<Item = Self>) -> Self {
1744 let init: Box<dyn Iterator<Item = Self>> = Box::new(set.into_iter());
1745 let mut iters: LPooled<Vec<Box<dyn Iterator<Item = Self>>>> =
1746 LPooled::from_iter([init]);
1747 let mut acc: LPooled<Vec<Self>> = LPooled::take();
1748 loop {
1749 match iters.last_mut() {
1750 None => break,
1751 Some(iter) => match iter.next() {
1752 None => {
1753 iters.pop();
1754 }
1755 Some(Type::Set(s)) => {
1756 let v: SmallVec<[Self; 16]> =
1757 s.iter().map(|t| t.clone()).collect();
1758 iters.push(Box::new(v.into_iter()))
1759 }
1760 Some(Type::Any) => return Type::Any,
1761 Some(t) => {
1762 acc.push(t);
1763 let mut i = 0;
1764 let mut j = 0;
1765 while i < acc.len() {
1766 while j < acc.len() {
1767 if j == i {
1768 j += 1;
1769 continue;
1770 }
1771 match acc[i].merge(&acc[j]) {
1772 None => j += 1,
1773 Some(t) => {
1774 acc[i] = t;
1775 acc.remove(j);
1776 i = 0;
1777 j = 0;
1778 }
1779 }
1780 }
1781 i += 1;
1782 j = 0;
1783 }
1784 }
1785 },
1786 }
1787 }
1788 acc.sort();
1789 match &**acc {
1790 [] => Type::Primitive(BitFlags::empty()),
1791 [t] => t.clone(),
1792 _ => Type::Set(Arc::from_iter(acc.drain(..))),
1793 }
1794 }
1795
1796 pub(crate) fn normalize(&self) -> Self {
1797 match self {
1798 Type::Bottom | Type::Any | Type::Primitive(_) => self.clone(),
1799 Type::Ref { scope, name, params } => {
1800 let params = Arc::from_iter(params.iter().map(|t| t.normalize()));
1801 Type::Ref { scope: scope.clone(), name: name.clone(), params }
1802 }
1803 Type::TVar(tv) => Type::TVar(tv.normalize()),
1804 Type::Set(s) => Self::flatten_set(s.iter().map(|t| t.normalize())),
1805 Type::Error(t) => Type::Error(Arc::new(t.normalize())),
1806 Type::Array(t) => Type::Array(Arc::new(t.normalize())),
1807 Type::Map { key, value } => {
1808 let key = Arc::new(key.normalize());
1809 let value = Arc::new(value.normalize());
1810 Type::Map { key, value }
1811 }
1812 Type::ByRef(t) => Type::ByRef(Arc::new(t.normalize())),
1813 Type::Tuple(t) => {
1814 Type::Tuple(Arc::from_iter(t.iter().map(|t| t.normalize())))
1815 }
1816 Type::Struct(t) => Type::Struct(Arc::from_iter(
1817 t.iter().map(|(n, t)| (n.clone(), t.normalize())),
1818 )),
1819 Type::Variant(tag, t) => Type::Variant(
1820 tag.clone(),
1821 Arc::from_iter(t.iter().map(|t| t.normalize())),
1822 ),
1823 Type::Fn(ft) => Type::Fn(Arc::new(ft.normalize())),
1824 }
1825 }
1826
1827 fn merge(&self, t: &Self) -> Option<Self> {
1828 macro_rules! flatten {
1829 ($t:expr) => {
1830 match $t {
1831 Type::Set(et) => Self::flatten_set(et.iter().cloned()),
1832 t => t.clone(),
1833 }
1834 };
1835 }
1836 match (self, t) {
1837 (
1838 Type::Ref { scope: s0, name: r0, params: a0 },
1839 Type::Ref { scope: s1, name: r1, params: a1 },
1840 ) => {
1841 if s0 == s1 && r0 == r1 && a0 == a1 {
1842 Some(Type::Ref {
1843 scope: s0.clone(),
1844 name: r0.clone(),
1845 params: a0.clone(),
1846 })
1847 } else {
1848 None
1849 }
1850 }
1851 (Type::Ref { .. }, _) | (_, Type::Ref { .. }) => None,
1852 (Type::Bottom, t) | (t, Type::Bottom) => Some(t.clone()),
1853 (Type::Any, _) | (_, Type::Any) => Some(Type::Any),
1854 (Type::Primitive(s0), Type::Primitive(s1)) => {
1855 Some(Type::Primitive(*s0 | *s1))
1856 }
1857 (Type::Primitive(p), t) | (t, Type::Primitive(p)) if p.is_empty() => {
1858 Some(t.clone())
1859 }
1860 (Type::Fn(f0), Type::Fn(f1)) => {
1861 if f0 == f1 {
1862 Some(Type::Fn(f0.clone()))
1863 } else {
1864 None
1865 }
1866 }
1867 (Type::Array(t0), Type::Array(t1)) => {
1868 if flatten!(&**t0) == flatten!(&**t1) {
1869 Some(Type::Array(t0.clone()))
1870 } else {
1871 None
1872 }
1873 }
1874 (Type::Primitive(p), Type::Array(_))
1875 | (Type::Array(_), Type::Primitive(p)) => {
1876 if p.contains(Typ::Array) {
1877 Some(Type::Primitive(*p))
1878 } else {
1879 None
1880 }
1881 }
1882 (Type::Map { key: k0, value: v0 }, Type::Map { key: k1, value: v1 }) => {
1883 if flatten!(&**k0) == flatten!(&**k1)
1884 && flatten!(&**v0) == flatten!(&**v1)
1885 {
1886 Some(Type::Map { key: k0.clone(), value: v0.clone() })
1887 } else {
1888 None
1889 }
1890 }
1891 (Type::Error(t0), Type::Error(t1)) => {
1892 if flatten!(&**t0) == flatten!(&**t1) {
1893 Some(Type::Error(t0.clone()))
1894 } else {
1895 None
1896 }
1897 }
1898 (Type::ByRef(t0), Type::ByRef(t1)) => {
1899 t0.merge(t1).map(|t| Type::ByRef(Arc::new(t)))
1900 }
1901 (Type::Set(s0), Type::Set(s1)) => {
1902 Some(Self::flatten_set(s0.iter().cloned().chain(s1.iter().cloned())))
1903 }
1904 (Type::Set(s), Type::Primitive(p)) | (Type::Primitive(p), Type::Set(s))
1905 if p.is_empty() =>
1906 {
1907 Some(Type::Set(s.clone()))
1908 }
1909 (Type::Set(s), t) | (t, Type::Set(s)) => {
1910 Some(Self::flatten_set(s.iter().cloned().chain(iter::once(t.clone()))))
1911 }
1912 (Type::Tuple(t0), Type::Tuple(t1)) => {
1913 if t0.len() == t1.len() {
1914 let t = t0
1915 .iter()
1916 .zip(t1.iter())
1917 .map(|(t0, t1)| t0.merge(t1))
1918 .collect::<Option<SmallVec<[Type; 8]>>>()?;
1919 Some(Type::Tuple(Arc::from_iter(t)))
1920 } else {
1921 None
1922 }
1923 }
1924 (Type::Variant(tag0, t0), Type::Variant(tag1, t1)) => {
1925 if tag0 == tag1 && t0.len() == t1.len() {
1926 let t = t0
1927 .iter()
1928 .zip(t1.iter())
1929 .map(|(t0, t1)| t0.merge(t1))
1930 .collect::<Option<SmallVec<[Type; 8]>>>()?;
1931 Some(Type::Variant(tag0.clone(), Arc::from_iter(t)))
1932 } else {
1933 None
1934 }
1935 }
1936 (Type::Struct(t0), Type::Struct(t1)) => {
1937 if t0.len() == t1.len() {
1938 let t = t0
1939 .iter()
1940 .zip(t1.iter())
1941 .map(|((n0, t0), (n1, t1))| {
1942 if n0 != n1 {
1943 None
1944 } else {
1945 t0.merge(t1).map(|t| (n0.clone(), t))
1946 }
1947 })
1948 .collect::<Option<SmallVec<[(ArcStr, Type); 8]>>>()?;
1949 Some(Type::Struct(Arc::from_iter(t)))
1950 } else {
1951 None
1952 }
1953 }
1954 (Type::TVar(tv0), Type::TVar(tv1)) if tv0.name == tv1.name && tv0 == tv1 => {
1955 Some(Type::TVar(tv0.clone()))
1956 }
1957 (Type::TVar(tv), t) => {
1958 tv.read().typ.read().as_ref().and_then(|tv| tv.merge(t))
1959 }
1960 (t, Type::TVar(tv)) => {
1961 tv.read().typ.read().as_ref().and_then(|tv| t.merge(tv))
1962 }
1963 (Type::ByRef(_), _)
1964 | (_, Type::ByRef(_))
1965 | (Type::Array(_), _)
1966 | (_, Type::Array(_))
1967 | (_, Type::Map { .. })
1968 | (Type::Map { .. }, _)
1969 | (Type::Tuple(_), _)
1970 | (_, Type::Tuple(_))
1971 | (Type::Struct(_), _)
1972 | (_, Type::Struct(_))
1973 | (Type::Variant(_, _), _)
1974 | (_, Type::Variant(_, _))
1975 | (_, Type::Fn(_))
1976 | (Type::Fn(_), _)
1977 | (Type::Error(_), _)
1978 | (_, Type::Error(_)) => None,
1979 }
1980 }
1981
1982 pub fn scope_refs(&self, scope: &ModPath) -> Type {
1983 match self {
1984 Type::Bottom => Type::Bottom,
1985 Type::Any => Type::Any,
1986 Type::Primitive(s) => Type::Primitive(*s),
1987 Type::Error(t0) => Type::Error(Arc::new(t0.scope_refs(scope))),
1988 Type::Array(t0) => Type::Array(Arc::new(t0.scope_refs(scope))),
1989 Type::Map { key, value } => {
1990 let key = Arc::new(key.scope_refs(scope));
1991 let value = Arc::new(value.scope_refs(scope));
1992 Type::Map { key, value }
1993 }
1994 Type::ByRef(t) => Type::ByRef(Arc::new(t.scope_refs(scope))),
1995 Type::Tuple(ts) => {
1996 let i = ts.iter().map(|t| t.scope_refs(scope));
1997 Type::Tuple(Arc::from_iter(i))
1998 }
1999 Type::Variant(tag, ts) => {
2000 let i = ts.iter().map(|t| t.scope_refs(scope));
2001 Type::Variant(tag.clone(), Arc::from_iter(i))
2002 }
2003 Type::Struct(ts) => {
2004 let i = ts.iter().map(|(n, t)| (n.clone(), t.scope_refs(scope)));
2005 Type::Struct(Arc::from_iter(i))
2006 }
2007 Type::TVar(tv) => match tv.read().typ.read().as_ref() {
2008 None => Type::TVar(TVar::empty_named(tv.name.clone())),
2009 Some(typ) => {
2010 let typ = typ.scope_refs(scope);
2011 Type::TVar(TVar::named(tv.name.clone(), typ))
2012 }
2013 },
2014 Type::Ref { scope: _, name, params } => {
2015 let params = Arc::from_iter(params.iter().map(|t| t.scope_refs(scope)));
2016 Type::Ref { scope: scope.clone(), name: name.clone(), params }
2017 }
2018 Type::Set(ts) => {
2019 Type::Set(Arc::from_iter(ts.iter().map(|t| t.scope_refs(scope))))
2020 }
2021 Type::Fn(f) => Type::Fn(Arc::new(f.scope_refs(scope))),
2022 }
2023 }
2024}
2025
2026impl fmt::Display for Type {
2027 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2028 match self {
2029 Self::Bottom => write!(f, "_"),
2030 Self::Any => write!(f, "Any"),
2031 Self::Ref { scope: _, name, params } => {
2032 write!(f, "{name}")?;
2033 if !params.is_empty() {
2034 write!(f, "<")?;
2035 for (i, t) in params.iter().enumerate() {
2036 write!(f, "{t}")?;
2037 if i < params.len() - 1 {
2038 write!(f, ", ")?;
2039 }
2040 }
2041 write!(f, ">")?;
2042 }
2043 Ok(())
2044 }
2045 Self::TVar(tv) => write!(f, "{tv}"),
2046 Self::Fn(t) => write!(f, "{t}"),
2047 Self::Error(t) => write!(f, "Error<{t}>"),
2048 Self::Array(t) => write!(f, "Array<{t}>"),
2049 Self::Map { key, value } => write!(f, "Map<{key}, {value}>"),
2050 Self::ByRef(t) => write!(f, "&{t}"),
2051 Self::Tuple(ts) => {
2052 write!(f, "(")?;
2053 for (i, t) in ts.iter().enumerate() {
2054 write!(f, "{t}")?;
2055 if i < ts.len() - 1 {
2056 write!(f, ", ")?;
2057 }
2058 }
2059 write!(f, ")")
2060 }
2061 Self::Variant(tag, ts) if ts.len() == 0 => {
2062 write!(f, "`{tag}")
2063 }
2064 Self::Variant(tag, ts) => {
2065 write!(f, "`{tag}(")?;
2066 for (i, t) in ts.iter().enumerate() {
2067 write!(f, "{t}")?;
2068 if i < ts.len() - 1 {
2069 write!(f, ", ")?
2070 }
2071 }
2072 write!(f, ")")
2073 }
2074 Self::Struct(ts) => {
2075 write!(f, "{{")?;
2076 for (i, (n, t)) in ts.iter().enumerate() {
2077 write!(f, "{n}: {t}")?;
2078 if i < ts.len() - 1 {
2079 write!(f, ", ")?
2080 }
2081 }
2082 write!(f, "}}")
2083 }
2084 Self::Set(s) => {
2085 write!(f, "[")?;
2086 for (i, t) in s.iter().enumerate() {
2087 write!(f, "{t}")?;
2088 if i < s.len() - 1 {
2089 write!(f, ", ")?;
2090 }
2091 }
2092 write!(f, "]")
2093 }
2094 Self::Primitive(s) => {
2095 let replace = PRINT_FLAGS.get().contains(PrintFlag::ReplacePrims);
2096 if replace && *s == Typ::number() {
2097 write!(f, "Number")
2098 } else if replace && *s == Typ::float() {
2099 write!(f, "Float")
2100 } else if replace && *s == Typ::real() {
2101 write!(f, "Real")
2102 } else if replace && *s == Typ::integer() {
2103 write!(f, "Int")
2104 } else if replace && *s == Typ::unsigned_integer() {
2105 write!(f, "Uint")
2106 } else if replace && *s == Typ::signed_integer() {
2107 write!(f, "Sint")
2108 } else if s.len() == 0 {
2109 write!(f, "[]")
2110 } else if s.len() == 1 {
2111 write!(f, "{}", s.iter().next().unwrap())
2112 } else {
2113 let mut s = *s;
2114 macro_rules! builtin {
2115 ($set:expr, $name:literal) => {
2116 if replace && s.contains($set) {
2117 s.remove($set);
2118 write!(f, $name)?;
2119 if !s.is_empty() {
2120 write!(f, ", ")?
2121 }
2122 }
2123 };
2124 }
2125 write!(f, "[")?;
2126 builtin!(Typ::number(), "Number");
2127 builtin!(Typ::real(), "Real");
2128 builtin!(Typ::float(), "Float");
2129 builtin!(Typ::integer(), "Int");
2130 builtin!(Typ::unsigned_integer(), "Uint");
2131 builtin!(Typ::signed_integer(), "Sint");
2132 for (i, t) in s.iter().enumerate() {
2133 write!(f, "{t}")?;
2134 if i < s.len() - 1 {
2135 write!(f, ", ")?;
2136 }
2137 }
2138 write!(f, "]")
2139 }
2140 }
2141 }
2142 }
2143}