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