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