1use std::cmp::Ordering;
2use std::fmt;
3use std::ops::{Add, Div, Mul, Neg, Range, RangeInclusive, Sub};
4
5use erg_common::consts::DEBUG_MODE;
6use erg_common::dict::Dict;
7use erg_common::set::Set;
8use erg_common::traits::{LimitedDisplay, StructuralEq};
9use erg_common::{dict, ref_addr_eq, set, Str};
10
11use erg_parser::ast::ConstLambda;
12use erg_parser::token::TokenKind;
13
14use crate::context::eval::UndoableLinkedList;
15
16use super::constructors::int_interval;
17use super::free::{
18 CanbeFree, Constraint, FreeKind, FreeTyParam, FreeTyVar, HasLevel, Level, GENERIC_LEVEL,
19};
20use super::value::ValueObj;
21use super::{Field, ParamTy, ReplaceTable, SharedFrees};
22use super::{Type, CONTAINER_OMIT_THRESHOLD};
23
24#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
25#[repr(u8)]
26pub enum OpKind {
27 Add,
28 Sub,
29 Mul,
30 Div,
31 FloorDiv,
32 Pow,
33 Mod,
34 Pos,
35 Neg,
36 Invert,
37 Gt,
38 Lt,
39 Ge,
40 Le,
41 Eq,
42 Ne,
43 As,
44 And,
45 Or,
46 Not,
47 BitAnd,
48 BitOr,
49 BitXor,
50 Shl,
51 Shr,
52 ClosedRange,
53 LeftOpenRange,
54 RightOpenRange,
55 OpenRange,
56}
57
58impl fmt::Display for OpKind {
59 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
60 match self {
61 Self::Add => write!(f, "+"),
62 Self::Sub => write!(f, "-"),
63 Self::Mul => write!(f, "*"),
64 Self::Div => write!(f, "/"),
65 Self::FloorDiv => write!(f, "//"),
66 Self::Pow => write!(f, "**"),
67 Self::Mod => write!(f, "%"),
68 Self::Pos => write!(f, "+"),
69 Self::Neg => write!(f, "-"),
70 Self::Invert => write!(f, "~"),
71 Self::Gt => write!(f, ">"),
72 Self::Lt => write!(f, "<"),
73 Self::Ge => write!(f, ">="),
74 Self::Le => write!(f, "<="),
75 Self::Eq => write!(f, "=="),
76 Self::Ne => write!(f, "!="),
77 Self::As => write!(f, "as"),
78 Self::And => write!(f, "and"),
79 Self::Or => write!(f, "or"),
80 Self::Not => write!(f, "not"),
81 Self::BitAnd => write!(f, "&&"),
82 Self::BitOr => write!(f, "||"),
83 Self::BitXor => write!(f, "^^"),
84 Self::Shl => write!(f, "<<"),
85 Self::Shr => write!(f, ">>"),
86 Self::ClosedRange => write!(f, ".."),
87 Self::LeftOpenRange => write!(f, "<.."),
88 Self::RightOpenRange => write!(f, "..<"),
89 Self::OpenRange => write!(f, "<..<"),
90 }
91 }
92}
93
94impl TryFrom<TokenKind> for OpKind {
95 type Error = ();
96 fn try_from(tk: TokenKind) -> Result<Self, Self::Error> {
97 match tk {
98 TokenKind::Plus => Ok(Self::Add),
99 TokenKind::Minus => Ok(Self::Sub),
100 TokenKind::Star => Ok(Self::Mul),
101 TokenKind::Slash => Ok(Self::Div),
102 TokenKind::FloorDiv => Ok(Self::FloorDiv),
103 TokenKind::Pow => Ok(Self::Pow),
104 TokenKind::Mod => Ok(Self::Mod),
105 TokenKind::PreBitNot => Ok(Self::Invert),
106 TokenKind::Gre => Ok(Self::Gt),
107 TokenKind::Less => Ok(Self::Lt),
108 TokenKind::GreEq => Ok(Self::Ge),
109 TokenKind::LessEq => Ok(Self::Le),
110 TokenKind::DblEq => Ok(Self::Eq),
111 TokenKind::NotEq => Ok(Self::Ne),
112 TokenKind::As => Ok(Self::As),
113 TokenKind::AndOp => Ok(Self::And),
114 TokenKind::OrOp => Ok(Self::Or),
115 TokenKind::BitAnd => Ok(Self::BitAnd),
116 TokenKind::BitOr => Ok(Self::BitOr),
117 TokenKind::BitXor => Ok(Self::BitXor),
118 TokenKind::Shl => Ok(Self::Shl),
119 TokenKind::Shr => Ok(Self::Shr),
120 TokenKind::Closed => Ok(Self::ClosedRange),
121 TokenKind::LeftOpen => Ok(Self::LeftOpenRange),
122 TokenKind::RightOpen => Ok(Self::RightOpenRange),
123 TokenKind::Open => Ok(Self::OpenRange),
124 _ => Err(()),
125 }
126 }
127}
128
129impl OpKind {
130 pub fn is_comparison(&self) -> bool {
131 matches!(
132 self,
133 Self::Gt | Self::Lt | Self::Ge | Self::Le | Self::Eq | Self::Ne
134 )
135 }
136}
137
138#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
139pub enum IntervalOp {
140 Closed,
142 LeftOpen,
144 RightOpen,
146 Open,
148}
149
150impl IntervalOp {
151 pub const fn is_closed(&self) -> bool {
152 matches!(self, Self::Closed)
153 }
154 pub const fn is_left_open(&self) -> bool {
155 matches!(self, Self::LeftOpen | Self::Open)
156 }
157 pub const fn is_right_open(&self) -> bool {
158 matches!(self, Self::RightOpen | Self::Open)
159 }
160 pub const fn is_open(&self) -> bool {
161 matches!(self, Self::Open)
162 }
163}
164
165impl fmt::Display for IntervalOp {
166 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
167 match self {
168 Self::Closed => write!(f, ".."),
169 Self::LeftOpen => write!(f, "<.."),
170 Self::RightOpen => write!(f, "..<"),
171 Self::Open => write!(f, "<..<"),
172 }
173 }
174}
175
176#[derive(Debug, Clone, PartialEq, Eq, Hash)]
177pub struct TyParamLambda {
178 pub const_: ConstLambda,
179 pub nd_params: Vec<ParamTy>,
180 pub var_params: Option<ParamTy>,
181 pub d_params: Vec<ParamTy>,
182 pub kw_var_params: Option<ParamTy>,
183 pub body: Vec<TyParam>,
184}
185
186impl fmt::Display for TyParamLambda {
187 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
188 write!(f, "{}", self.const_)
189 }
190}
191
192impl HasLevel for TyParamLambda {
193 fn level(&self) -> Option<usize> {
194 self.body.iter().filter_map(|tp| tp.level()).min()
195 }
196 fn set_level(&self, lev: Level) {
197 for tp in self.body.iter() {
198 tp.set_level(lev);
199 }
200 }
201}
202
203impl StructuralEq for TyParamLambda {
204 fn structural_eq(&self, other: &Self) -> bool {
205 self.body.len() == other.body.len()
206 && self
207 .body
208 .iter()
209 .zip(other.body.iter())
210 .all(|(a, b)| a.structural_eq(b))
211 }
212}
213
214impl TyParamLambda {
215 pub const fn new(
216 lambda: ConstLambda,
217 nd_params: Vec<ParamTy>,
218 var_params: Option<ParamTy>,
219 d_params: Vec<ParamTy>,
220 kw_var_params: Option<ParamTy>,
221 body: Vec<TyParam>,
222 ) -> Self {
223 Self {
224 const_: lambda,
225 nd_params,
226 var_params,
227 d_params,
228 kw_var_params,
229 body,
230 }
231 }
232}
233
234#[derive(Debug, Clone, Hash)]
251pub enum TyParam {
252 Value(ValueObj),
253 Type(Box<Type>),
254 List(Vec<TyParam>),
255 UnsizedList(Box<TyParam>),
256 Tuple(Vec<TyParam>),
257 Set(Set<TyParam>),
258 Dict(Dict<TyParam, TyParam>),
259 Record(Dict<Field, TyParam>),
260 DataClass {
261 name: Str,
262 fields: Dict<Field, TyParam>,
263 },
264 Lambda(TyParamLambda),
265 Mono(Str),
266 Proj {
267 obj: Box<TyParam>,
268 attr: Str,
269 },
270 ProjCall {
271 obj: Box<TyParam>,
272 attr: Str,
273 args: Vec<TyParam>,
274 },
275 App {
276 name: Str,
277 args: Vec<TyParam>,
278 },
279 UnaryOp {
280 op: OpKind,
281 val: Box<TyParam>,
282 },
283 BinOp {
284 op: OpKind,
285 lhs: Box<TyParam>,
286 rhs: Box<TyParam>,
287 },
288 Erased(Box<Type>),
289 FreeVar(FreeTyParam),
290 Failure,
291}
292
293impl PartialEq for TyParam {
294 fn eq(&self, other: &Self) -> bool {
295 match (self, other) {
296 (Self::Value(l), Self::Value(r)) => l == r,
297 (Self::Type(l), Self::Type(r)) => l == r,
298 (Self::List(l), Self::List(r)) => l == r,
299 (Self::UnsizedList(l), Self::UnsizedList(r)) => l == r,
300 (Self::Tuple(l), Self::Tuple(r)) => l == r,
301 (Self::Dict(l), Self::Dict(r)) => l.linear_eq(r),
302 (Self::Record(l), Self::Record(r)) => l == r,
303 (
304 Self::DataClass {
305 name: ln,
306 fields: lfs,
307 },
308 Self::DataClass {
309 name: rn,
310 fields: rfs,
311 },
312 ) => ln == rn && lfs == rfs,
313 (Self::Set(l), Self::Set(r)) => l.linear_eq(r),
314 (Self::Lambda(l), Self::Lambda(r)) => l == r,
315 (Self::Mono(l), Self::Mono(r)) => l == r,
316 (
317 Self::Proj { obj, attr },
318 Self::Proj {
319 obj: r_obj,
320 attr: r_attr,
321 },
322 ) => obj == r_obj && attr == r_attr,
323 (
324 Self::ProjCall { obj, attr, args },
325 Self::ProjCall {
326 obj: r_obj,
327 attr: r_attr,
328 args: r_args,
329 },
330 ) => obj == r_obj && attr == r_attr && args == r_args,
331 (
332 Self::App {
333 name: ln,
334 args: lps,
335 },
336 Self::App {
337 name: rn,
338 args: rps,
339 },
340 ) => ln == rn && lps == rps,
341 (
342 Self::UnaryOp { op, val },
343 Self::UnaryOp {
344 op: r_op,
345 val: r_val,
346 },
347 ) => op == r_op && val == r_val,
348 (
349 Self::BinOp { op, lhs, rhs },
350 Self::BinOp {
351 op: r_op,
352 lhs: r_lhs,
353 rhs: r_rhs,
354 },
355 ) => op == r_op && lhs == r_lhs && rhs == r_rhs,
356 (Self::Erased(l), Self::Erased(r)) => l == r,
357 (Self::FreeVar(l), Self::FreeVar(r)) => l == r,
358 (Self::FreeVar(fv), other) => match &*fv.borrow() {
359 FreeKind::Linked(t) => t == other,
360 _ => false,
361 },
362 (self_, Self::FreeVar(fv)) => match &*fv.borrow() {
363 FreeKind::Linked(t) => t == self_,
364 _ => false,
365 },
366 (Self::Failure, Self::Failure) => true,
367 (Self::Type(l), Self::Value(ValueObj::Type(r))) => l.as_ref() == r.typ(),
368 (Self::Value(ValueObj::Type(l)), Self::Type(r)) => l.typ() == r.as_ref(),
369 _ => false,
370 }
371 }
372}
373
374impl Eq for TyParam {}
375
376impl fmt::Display for TyParam {
377 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378 self.limited_fmt(f, <Self as LimitedDisplay>::DEFAULT_LIMIT)
379 }
380}
381
382impl LimitedDisplay for TyParam {
383 fn limited_fmt<W: std::fmt::Write>(&self, f: &mut W, limit: isize) -> fmt::Result {
384 if limit == 0 {
385 return write!(f, "...");
386 }
387 match self {
388 Self::Value(v) => v.limited_fmt(f, limit),
389 Self::Failure => write!(f, "<Failure>"),
390 Self::Type(t) => t.limited_fmt(f, limit),
391 Self::FreeVar(fv) => fv.limited_fmt(f, limit),
392 Self::UnaryOp { op, val } => {
393 write!(f, "{op}")?;
394 val.limited_fmt(f, limit - 1)
395 }
396 Self::BinOp { op, lhs, rhs } => {
397 lhs.limited_fmt(f, limit - 1)?;
398 write!(f, " {op} ")?;
399 rhs.limited_fmt(f, limit - 1)
400 }
401 Self::App { name, args } => {
402 if limit.is_negative() && self.namespace().is_empty() {
403 write!(f, "global::")?;
404 }
405 write!(f, "{name}")?;
406 write!(f, "(")?;
407 for (i, arg) in args.iter().enumerate() {
408 if i > 0 {
409 write!(f, ", ")?;
410 }
411 arg.limited_fmt(f, limit - 1)?;
412 }
413 write!(f, ")")?;
414 Ok(())
415 }
416 Self::Erased(t) => {
417 write!(f, "_: ")?;
418 t.limited_fmt(f, limit - 1)
419 }
420 Self::Mono(name) => {
421 if limit.is_negative() && self.namespace().is_empty() {
422 write!(f, "global::")?;
423 }
424 write!(f, "{name}")
425 }
426 Self::Proj { obj, attr } => {
427 obj.limited_fmt(f, limit - 1)?;
428 write!(f, ".")?;
429 write!(f, "{attr}")
430 }
431 Self::ProjCall { obj, attr, args } => {
432 write!(f, "(")?;
433 obj.limited_fmt(f, limit - 1)?;
434 write!(f, ").")?;
435 write!(f, "{attr}")?;
436 write!(f, "(")?;
437 for (i, arg) in args.iter().enumerate() {
438 if i > 0 {
439 write!(f, ", ")?;
440 }
441 arg.limited_fmt(f, limit - 1)?;
442 }
443 write!(f, ")")?;
444 Ok(())
445 }
446 Self::List(lis) => {
447 write!(f, "[")?;
448 for (i, t) in lis.iter().enumerate() {
449 if i > 0 {
450 write!(f, ", ")?;
451 }
452 if limit.is_positive() && i >= CONTAINER_OMIT_THRESHOLD {
453 write!(f, "...")?;
454 break;
455 }
456 t.limited_fmt(f, limit - 1)?;
457 }
458 write!(f, "]")
459 }
460 Self::UnsizedList(elem) => {
461 write!(f, "[")?;
462 elem.limited_fmt(f, limit - 1)?;
463 write!(f, "; _]")
464 }
465 Self::Set(st) => {
466 write!(f, "{{")?;
467 for (i, t) in st.iter().enumerate() {
468 if i > 0 {
469 write!(f, ", ")?;
470 }
471 if limit.is_positive() && i >= CONTAINER_OMIT_THRESHOLD {
472 write!(f, "...")?;
473 break;
474 }
475 t.limited_fmt(f, limit - 1)?;
476 }
477 write!(f, "}}")
478 }
479 Self::Dict(dict) => {
480 write!(f, "{{")?;
481 for (i, (k, v)) in dict.iter().enumerate() {
482 if i > 0 {
483 write!(f, ", ")?;
484 }
485 if limit.is_positive() && i >= CONTAINER_OMIT_THRESHOLD {
486 write!(f, "...")?;
487 break;
488 }
489 k.limited_fmt(f, limit - 1)?;
490 write!(f, ": ")?;
491 v.limited_fmt(f, limit - 1)?;
492 }
493 write!(f, "}}")
494 }
495 Self::Record(rec) => {
496 write!(f, "{{")?;
497 for (i, (field, v)) in rec.iter().enumerate() {
498 if i > 0 {
499 write!(f, "; ")?;
500 }
501 if limit.is_positive() && i >= CONTAINER_OMIT_THRESHOLD {
502 write!(f, "...")?;
503 break;
504 }
505 write!(f, "{field} = ")?;
506 v.limited_fmt(f, limit - 1)?;
507 }
508 if rec.is_empty() {
509 write!(f, "=")?;
510 }
511 write!(f, "}}")
512 }
513 Self::DataClass { name, fields } => {
514 write!(f, "{name} {{")?;
515 for (i, (field, v)) in fields.iter().enumerate() {
516 if i > 0 {
517 write!(f, "; ")?;
518 }
519 if limit.is_positive() && i >= CONTAINER_OMIT_THRESHOLD {
520 write!(f, "...")?;
521 break;
522 }
523 write!(f, "{field} = ")?;
524 v.limited_fmt(f, limit - 1)?;
525 }
526 write!(f, "}}")?;
527 Ok(())
528 }
529 Self::Lambda(lambda) => write!(f, "{lambda}"),
530 Self::Tuple(tuple) => {
531 write!(f, "(")?;
532 for (i, t) in tuple.iter().enumerate() {
533 if i > 0 {
534 write!(f, ", ")?;
535 }
536 if limit.is_positive() && i >= CONTAINER_OMIT_THRESHOLD {
537 write!(f, "...")?;
538 break;
539 }
540 t.limited_fmt(f, limit - 1)?;
541 }
542 write!(f, ")")
543 }
544 }
545 }
546}
547
548impl CanbeFree for TyParam {
549 fn unbound_name(&self) -> Option<Str> {
550 match self {
551 TyParam::FreeVar(fv) => fv.unbound_name(),
552 TyParam::Type(t) => t.unbound_name(),
553 TyParam::Value(ValueObj::Type(ty)) => ty.typ().unbound_name(),
554 _ => None,
555 }
556 }
557
558 fn unbound_id(&self) -> Option<usize> {
559 match self {
560 TyParam::FreeVar(fv) => fv.unbound_id(),
561 TyParam::Type(t) => t.unbound_id(),
562 TyParam::Value(ValueObj::Type(ty)) => ty.typ().unbound_id(),
563 _ => None,
564 }
565 }
566
567 fn constraint(&self) -> Option<Constraint> {
568 match self {
569 TyParam::FreeVar(fv) => fv.constraint(),
570 TyParam::Type(t) => t.constraint(),
571 TyParam::Value(ValueObj::Type(ty)) => ty.typ().constraint(),
572 _ => None,
573 }
574 }
575
576 fn destructive_update_constraint(&self, new_constraint: Constraint, in_instantiation: bool) {
577 match self {
578 Self::FreeVar(fv) => {
579 fv.update_constraint(new_constraint, in_instantiation);
580 }
581 Self::Type(t) => {
582 t.destructive_update_constraint(new_constraint, in_instantiation);
583 }
584 Self::Value(ValueObj::Type(ty)) => {
585 ty.typ()
586 .destructive_update_constraint(new_constraint, in_instantiation);
587 }
588 _ => {}
589 }
590 }
591}
592
593impl Default for TyParam {
594 #[inline]
595 fn default() -> Self {
596 Self::Failure
597 }
598}
599
600impl Add for TyParam {
601 type Output = Self;
602 fn add(self, rhs: Self) -> Self::Output {
603 Self::bin(OpKind::Add, self, rhs)
604 }
605}
606
607impl Sub for TyParam {
608 type Output = Self;
609 fn sub(self, rhs: Self) -> Self::Output {
610 Self::bin(OpKind::Sub, self, rhs)
611 }
612}
613
614impl Mul for TyParam {
615 type Output = Self;
616 fn mul(self, rhs: Self) -> Self::Output {
617 Self::bin(OpKind::Mul, self, rhs)
618 }
619}
620
621impl Div for TyParam {
622 type Output = Self;
623 fn div(self, rhs: Self) -> Self::Output {
624 Self::bin(OpKind::Div, self, rhs)
625 }
626}
627
628impl Neg for TyParam {
629 type Output = Self;
630 fn neg(self) -> Self::Output {
631 Self::unary(OpKind::Neg, self)
632 }
633}
634
635impl From<Range<TyParam>> for TyParam {
636 fn from(r: Range<TyParam>) -> Self {
637 Self::t(int_interval(IntervalOp::RightOpen, r.start, r.end))
638 }
639}
640
641impl From<Range<&TyParam>> for TyParam {
642 fn from(r: Range<&TyParam>) -> Self {
643 Self::t(int_interval(
644 IntervalOp::RightOpen,
645 r.start.clone(),
646 r.end.clone(),
647 ))
648 }
649}
650
651impl From<RangeInclusive<TyParam>> for TyParam {
652 fn from(r: RangeInclusive<TyParam>) -> Self {
653 let (start, end) = r.into_inner();
654 Self::t(int_interval(IntervalOp::Closed, start, end))
655 }
656}
657
658impl From<RangeInclusive<&TyParam>> for TyParam {
659 fn from(r: RangeInclusive<&TyParam>) -> Self {
660 let (start, end) = r.into_inner();
661 Self::t(int_interval(IntervalOp::Closed, start.clone(), end.clone()))
662 }
663}
664
665impl<V: Into<ValueObj>> From<V> for TyParam {
666 fn from(v: V) -> Self {
667 Self::Value(v.into())
668 }
669}
670
671impl From<Dict<Type, Type>> for TyParam {
672 fn from(v: Dict<Type, Type>) -> Self {
673 Self::Dict(
674 v.into_iter()
675 .map(|(k, v)| (TyParam::t(k), TyParam::t(v)))
676 .collect(),
677 )
678 }
679}
680
681impl<'t> TryFrom<&'t TyParam> for &'t FreeTyParam {
682 type Error = ();
683 fn try_from(t: &'t TyParam) -> Result<&'t FreeTyParam, ()> {
684 match t {
685 TyParam::FreeVar(fv) => Ok(fv),
686 _ => Err(()),
687 }
688 }
689}
690
691impl<'t> TryFrom<&'t TyParam> for &'t FreeTyVar {
692 type Error = ();
693 fn try_from(t: &'t TyParam) -> Result<&'t FreeTyVar, ()> {
694 match t {
695 TyParam::Type(ty) => <&FreeTyVar>::try_from(ty.as_ref()),
696 TyParam::Value(ValueObj::Type(ty)) => <&FreeTyVar>::try_from(ty.typ()),
697 _ => Err(()),
698 }
699 }
700}
701
702impl TryFrom<TyParam> for Dict<TyParam, TyParam> {
703 type Error = ();
704 fn try_from(tp: TyParam) -> Result<Self, ()> {
705 match tp {
706 TyParam::FreeVar(fv) if fv.is_linked() => Dict::try_from(fv.crack().clone()),
707 TyParam::Dict(tps) => Ok(tps),
708 TyParam::Value(ValueObj::Dict(dict)) => Ok(dict
709 .into_iter()
710 .map(|(k, v)| (TyParam::value(k), TyParam::value(v)))
711 .collect()),
712 _ => Err(()),
713 }
714 }
715}
716
717impl TryFrom<TyParam> for Vec<TyParam> {
718 type Error = ();
719 fn try_from(tp: TyParam) -> Result<Self, ()> {
720 match tp {
721 TyParam::FreeVar(fv) if fv.is_linked() => Vec::try_from(fv.crack().clone()),
722 TyParam::List(tps) => Ok(tps),
723 TyParam::Value(ValueObj::List(list)) => {
724 Ok(list.iter().cloned().map(TyParam::value).collect::<Vec<_>>())
725 }
726 _ => Err(()),
727 }
728 }
729}
730
731impl<'a> TryFrom<&'a TyParam> for &'a Type {
732 type Error = ();
733 fn try_from(tp: &'a TyParam) -> Result<&'a Type, ()> {
734 match tp {
735 TyParam::FreeVar(fv) if fv.is_linked() => {
736 <&'a Type>::try_from(fv.forced_as_ref().linked().unwrap())
737 }
738 TyParam::Type(t) => Ok(t.as_ref()),
739 TyParam::Value(v) => <&Type>::try_from(v),
740 _ => Err(()),
742 }
743 }
744}
745
746impl TryFrom<&TyParam> for usize {
747 type Error = ();
748 fn try_from(tp: &TyParam) -> Result<Self, ()> {
749 match tp {
750 TyParam::FreeVar(fv) if fv.is_linked() => usize::try_from(&*fv.crack()),
751 TyParam::Value(v) => usize::try_from(v),
752 _ => Err(()),
753 }
754 }
755}
756
757impl HasLevel for TyParam {
758 fn level(&self) -> Option<Level> {
759 match self {
760 Self::Type(t) => t.level(),
761 Self::FreeVar(fv) => fv.level(),
762 Self::List(tps) | Self::Tuple(tps) => tps.iter().filter_map(|tp| tp.level()).min(),
763 Self::UnsizedList(tp) => tp.level(),
764 Self::Dict(tps) => tps
765 .iter()
766 .map(|(k, v)| {
767 k.level()
768 .unwrap_or(GENERIC_LEVEL)
769 .min(v.level().unwrap_or(GENERIC_LEVEL))
770 })
771 .min(),
772 Self::Record(rec) | Self::DataClass { fields: rec, .. } => rec
773 .iter()
774 .map(|(_, v)| v.level().unwrap_or(GENERIC_LEVEL))
775 .min(),
776 Self::Lambda(lambda) => lambda.level(),
777 Self::Set(tps) => tps.iter().filter_map(|tp| tp.level()).min(),
778 Self::Proj { obj, .. } => obj.level(),
779 Self::ProjCall { obj, args, .. } => obj.level().and_then(|l| {
780 args.iter()
781 .filter_map(|tp| tp.level())
782 .min()
783 .map(|r| l.min(r))
784 }),
785 Self::App { args, .. } => args.iter().filter_map(|tp| tp.level()).min(),
786 Self::UnaryOp { val, .. } => val.level(),
787 Self::BinOp { lhs, rhs, .. } => lhs.level().and_then(|l| rhs.level().map(|r| l.min(r))),
788 Self::Value(val) => val.level(),
789 Self::Erased(ty) => ty.level(),
790 Self::Mono(_) | Self::Failure => None,
791 }
792 }
793
794 fn set_level(&self, level: Level) {
795 match self {
796 Self::Type(t) => t.set_level(level),
797 Self::FreeVar(fv) => fv.set_level(level),
798 Self::Dict(tps) => {
799 for (k, v) in tps.iter() {
800 k.set_level(level);
801 v.set_level(level);
802 }
803 }
804 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
805 for (_, v) in rec.iter() {
806 v.set_level(level);
807 }
808 }
809 Self::List(tps) => {
810 for tp in tps {
811 tp.set_level(level);
812 }
813 }
814 Self::UnsizedList(tp) => tp.set_level(level),
815 Self::Tuple(tps) => {
816 for tp in tps {
817 tp.set_level(level);
818 }
819 }
820 Self::Set(tps) => {
821 for tp in tps.iter() {
822 tp.set_level(level);
823 }
824 }
825 Self::Lambda(lambda) => lambda.set_level(level),
826 Self::UnaryOp { val, .. } => val.set_level(level),
827 Self::BinOp { lhs, rhs, .. } => {
828 lhs.set_level(level);
829 rhs.set_level(level);
830 }
831 Self::App { args, .. } => {
832 for arg in args.iter() {
833 arg.set_level(level);
834 }
835 }
836 Self::Proj { obj, .. } => {
837 obj.set_level(level);
838 }
839 Self::ProjCall { obj, args, .. } => {
840 obj.set_level(level);
841 for arg in args.iter() {
842 arg.set_level(level);
843 }
844 }
845 Self::Value(val) => val.set_level(level),
846 Self::Erased(ty) => ty.set_level(level),
847 Self::Mono(_) | Self::Failure => {}
848 }
849 }
850}
851
852impl StructuralEq for TyParam {
853 fn structural_eq(&self, other: &Self) -> bool {
854 match (self, other) {
855 (Self::Type(l), Self::Type(r)) => l.structural_eq(r),
856 (Self::List(l), Self::List(r)) => l.iter().zip(r).all(|(l, r)| l.structural_eq(r)),
857 (Self::UnsizedList(l), Self::UnsizedList(r)) => l.structural_eq(r),
858 (Self::Tuple(l), Self::Tuple(r)) => l.iter().zip(r).all(|(l, r)| l.structural_eq(r)),
859 (Self::Dict(l), Self::Dict(r)) => {
860 if l.len() != r.len() {
861 return false;
862 }
863 for (key, val) in l.iter() {
864 if let Some(r_val) = r.get_by(key, |l, r| l.structural_eq(r)) {
865 if !val.structural_eq(r_val) {
866 return false;
867 }
868 } else {
869 return false;
870 }
871 }
872 true
873 }
874 (Self::Record(l), Self::Record(r)) => {
875 if l.len() != r.len() {
876 return false;
877 }
878 for (l_field, l_val) in l.iter() {
879 if let Some((r_field, r_val)) = r.get_key_value(l_field) {
880 if l_field.vis != r_field.vis || !l_val.structural_eq(r_val) {
881 return false;
882 }
883 } else {
884 return false;
885 }
886 }
887 true
888 }
889 (
890 Self::DataClass { name, fields },
891 Self::DataClass {
892 name: r_name,
893 fields: r_fields,
894 },
895 ) => {
896 if name != r_name || fields.len() != r_fields.len() {
897 return false;
898 }
899 for (l_field, l_val) in fields.iter() {
900 if let Some((r_field, r_val)) = r_fields.get_key_value(l_field) {
901 if l_field.vis != r_field.vis || !l_val.structural_eq(r_val) {
902 return false;
903 }
904 } else {
905 return false;
906 }
907 }
908 true
909 }
910 (Self::Set(l), Self::Set(r)) => {
911 if l.len() != r.len() {
912 return false;
913 }
914 for l_val in l.iter() {
915 if r.get_by(l_val, |l, r| l.structural_eq(r)).is_none() {
916 return false;
917 }
918 }
919 true
920 }
921 (Self::Lambda(l), Self::Lambda(r)) => l.structural_eq(r),
922 (
923 Self::Proj { obj, attr },
924 Self::Proj {
925 obj: r_obj,
926 attr: r_attr,
927 },
928 ) => obj.structural_eq(r_obj) && attr == r_attr,
929 (
930 Self::ProjCall { obj, attr, args },
931 Self::ProjCall {
932 obj: r_obj,
933 attr: r_attr,
934 args: r_args,
935 },
936 ) => {
937 obj.structural_eq(r_obj)
938 && attr == r_attr
939 && args.iter().zip(r_args).all(|(l, r)| l.structural_eq(r))
940 }
941 (
942 Self::App {
943 name: ln,
944 args: lps,
945 },
946 Self::App {
947 name: rn,
948 args: rps,
949 },
950 ) => ln == rn && lps.iter().zip(rps).all(|(l, r)| l.structural_eq(r)),
951 (
952 Self::UnaryOp { op, val },
953 Self::UnaryOp {
954 op: r_op,
955 val: r_val,
956 },
957 ) => op == r_op && val.structural_eq(r_val),
958 (
959 Self::BinOp { op, lhs, rhs },
960 Self::BinOp {
961 op: r_op,
962 lhs: r_lhs,
963 rhs: r_rhs,
964 },
965 ) => op == r_op && lhs.structural_eq(r_lhs) && rhs.structural_eq(r_rhs),
966 (Self::Erased(l), Self::Erased(r)) => l.structural_eq(r),
967 (Self::FreeVar(fv), other) | (other, Self::FreeVar(fv)) if fv.is_linked() => {
968 fv.crack().structural_eq(other)
969 }
970 (Self::FreeVar(l), Self::FreeVar(r)) => l.structural_eq(r),
971 (Self::Type(l), Self::Value(ValueObj::Type(r))) => l.structural_eq(r.typ()),
972 (Self::Value(ValueObj::Type(l)), Self::Type(r)) => l.typ().structural_eq(r),
973 _ => self == other,
974 }
975 }
976}
977
978impl TyParam {
979 pub fn t(t: Type) -> Self {
980 Self::Type(Box::new(t))
981 }
982
983 pub fn mono<S: Into<Str>>(name: S) -> Self {
984 Self::Mono(name.into())
985 }
986
987 pub fn mono_q<S: Into<Str>>(name: S, constr: Constraint) -> Self {
988 Self::named_free_var(name.into(), crate::ty::free::GENERIC_LEVEL, constr)
989 }
990
991 pub fn proj<S: Into<Str>>(self, attr: S) -> Self {
992 Self::Proj {
993 obj: Box::new(self),
994 attr: attr.into(),
995 }
996 }
997
998 pub fn proj_call(self, attr: Str, args: Vec<TyParam>) -> Self {
999 Self::ProjCall {
1000 obj: Box::new(self),
1001 attr,
1002 args,
1003 }
1004 }
1005
1006 pub fn range(start: Self, end: Self) -> Self {
1007 Self::DataClass {
1008 name: "Range".into(),
1009 fields: dict! {
1010 Field::private("start".into()) => start,
1011 Field::private("end".into()) => end,
1012 Field::private("step".into()) => ValueObj::None.into(),
1013 },
1014 }
1015 }
1016
1017 pub fn free_instance(level: usize, t: Type) -> Self {
1018 let constraint = Constraint::new_type_of(t);
1019 Self::FreeVar(FreeTyParam::new_unbound(level, constraint))
1020 }
1021
1022 pub fn free_var(level: usize, constr: Constraint) -> Self {
1023 Self::FreeVar(FreeTyParam::new_unbound(level, constr))
1024 }
1025
1026 pub fn named_free_var(name: Str, level: usize, constr: Constraint) -> Self {
1027 Self::FreeVar(FreeTyParam::new_named_unbound(name, level, constr))
1028 }
1029
1030 #[inline]
1032 pub fn value<V: Into<ValueObj>>(v: V) -> Self {
1033 Self::Value(v.into())
1034 }
1035
1036 #[inline]
1037 pub fn unary(op: OpKind, val: TyParam) -> Self {
1038 Self::UnaryOp {
1039 op,
1040 val: Box::new(val),
1041 }
1042 }
1043
1044 #[inline]
1045 pub fn bin(op: OpKind, lhs: TyParam, rhs: TyParam) -> Self {
1046 Self::BinOp {
1047 op,
1048 lhs: Box::new(lhs),
1049 rhs: Box::new(rhs),
1050 }
1051 }
1052
1053 pub fn app(name: Str, args: Vec<TyParam>) -> Self {
1054 Self::App { name, args }
1055 }
1056
1057 #[inline]
1058 pub fn erased(t: Type) -> Self {
1059 Self::Erased(Box::new(t))
1060 }
1061
1062 pub fn unsized_list(elem: TyParam) -> Self {
1063 Self::UnsizedList(Box::new(elem))
1064 }
1065
1066 pub fn succ(self) -> Self {
1068 Self::app("succ".into(), vec![self])
1069 }
1070
1071 pub fn pred(self) -> Self {
1073 Self::app("pred".into(), vec![self])
1074 }
1075
1076 pub fn qual_name(&self) -> Option<Str> {
1077 match self {
1078 Self::Type(t) => Some(t.qual_name()),
1079 Self::FreeVar(fv) if fv.is_linked() => fv.crack().qual_name(),
1080 Self::FreeVar(fv) if fv.is_generalized() => fv.unbound_name(),
1081 Self::Mono(name) => Some(name.clone()),
1082 Self::Value(val) => val.qual_name(),
1083 Self::App { name, .. } => Some(name.clone()),
1084 _ => None,
1085 }
1086 }
1087
1088 pub fn local_name(&self) -> Option<Str> {
1089 match self {
1090 Self::FreeVar(fv) if fv.is_linked() => fv.crack().local_name(),
1091 Self::Mono(name) | Self::App { name, .. } => {
1092 let namespaces = name.split_with(&[".", "::"]);
1093 Some(Str::rc(namespaces.last().unwrap()))
1094 }
1095 _ => self.qual_name(),
1096 }
1097 }
1098
1099 pub fn tvar_name(&self) -> Option<Str> {
1100 match self {
1101 Self::Type(t) => t.tvar_name(),
1102 Self::FreeVar(fv) if fv.is_linked() => fv.crack().tvar_name(),
1103 Self::FreeVar(fv) => fv.unbound_name(),
1104 Self::Value(ValueObj::Type(t)) => t.typ().tvar_name(),
1105 _ => None,
1106 }
1107 }
1108
1109 pub fn cheap_cmp(&self, r: &TyParam) -> Option<TyParamOrdering> {
1111 match (self, r) {
1112 (Self::Type(l), Self::Type(r)) =>
1113 if l == r { Some(TyParamOrdering::Equal) } else { Some(TyParamOrdering::NotEqual) },
1114 (Self::Value(l), Self::Value(r)) =>
1115 l.try_cmp(r).map(Into::into),
1116 (Self::FreeVar(fv), p) if fv.is_linked() =>
1117 fv.crack().cheap_cmp(p),
1118 (p, Self::FreeVar(fv)) if fv.is_linked() =>
1119 p.cheap_cmp(&fv.crack()),
1120 (Self::FreeVar{ .. } | Self::Erased(_), Self::FreeVar{ .. } | Self::Erased(_))
1121 => Some(Any),
1122 (Self::App{ name, args }, Self::App{ name: rname, args: rargs }) =>
1123 if name == rname
1124 && args.len() == rargs.len()
1125 && args.iter().zip(rargs.iter()).all(|(l, r)| l.cheap_cmp(r) == Some(Equal)) {
1126 Some(TyParamOrdering::Equal)
1127 } else {
1128 Some(TyParamOrdering::NotEqual)
1129 },
1130 (l, r @ (Self::Erased(_) | Self::Mono{ .. } | Self::FreeVar{ .. })) =>
1131 r.cheap_cmp(l).map(|ord| ord.reverse()),
1132 _ => None,
1133 }
1134 }
1135
1136 pub fn coerce(&self, list: Option<&UndoableLinkedList>) {
1138 if let Some(list) = list {
1139 self.undoable_coerce(list);
1140 } else {
1141 self.destructive_coerce();
1142 }
1143 }
1144
1145 pub fn undoable_coerce(&self, list: &UndoableLinkedList) {
1146 match self {
1147 TyParam::FreeVar(fv) if fv.is_linked() => {
1148 fv.crack().undoable_coerce(list);
1149 }
1150 TyParam::FreeVar(fv) if fv.is_unbound_and_typed() => {
1151 let typ = fv.get_type().unwrap();
1152 typ.undoable_coerce(list);
1153 }
1154 TyParam::Type(t) => t.undoable_coerce(list),
1155 TyParam::Value(ValueObj::Type(t)) => t.typ().undoable_coerce(list),
1156 _ => {}
1158 }
1159 }
1160
1161 pub fn destructive_coerce(&self) {
1162 match self {
1163 TyParam::FreeVar(fv) if fv.is_linked() => {
1164 fv.crack().destructive_coerce();
1165 }
1166 TyParam::Type(t) => t.destructive_coerce(),
1167 TyParam::Value(ValueObj::Type(t)) => t.typ().destructive_coerce(),
1168 _ => {}
1169 }
1170 }
1171
1172 pub fn qvars(&self) -> Set<(Str, Constraint)> {
1173 match self {
1174 Self::FreeVar(fv) if fv.is_linked() => fv.forced_as_ref().linked().unwrap().qvars(),
1175 Self::FreeVar(fv) if !fv.constraint_is_uninited() => {
1176 let base = set! {(fv.unbound_name().unwrap(), fv.constraint().unwrap())};
1177 if let Some(ty) = fv.get_type() {
1178 base.concat(ty.qvars())
1179 } else {
1180 base
1181 }
1182 }
1183 Self::FreeVar(_) => set! {},
1184 Self::Type(t) => t.qvars(),
1185 Self::Proj { obj, .. } => obj.qvars(),
1186 Self::ProjCall { obj, args, .. } => args
1187 .iter()
1188 .fold(obj.qvars(), |acc, arg| acc.concat(arg.qvars())),
1189 Self::List(ts) | Self::Tuple(ts) => {
1190 ts.iter().fold(set! {}, |acc, t| acc.concat(t.qvars()))
1191 }
1192 Self::UnsizedList(elem) => elem.qvars(),
1193 Self::Set(ts) => ts.iter().fold(set! {}, |acc, t| acc.concat(t.qvars())),
1194 Self::Dict(ts) => ts.iter().fold(set! {}, |acc, (k, v)| {
1195 acc.concat(k.qvars().concat(v.qvars()))
1196 }),
1197 Self::Record(rec) | Self::DataClass { fields: rec, .. } => rec
1198 .iter()
1199 .fold(set! {}, |acc, (_, v)| acc.concat(v.qvars())),
1200 Self::Lambda(lambda) => lambda
1201 .body
1202 .iter()
1203 .fold(set! {}, |acc, t| acc.concat(t.qvars())),
1204 Self::UnaryOp { val, .. } => val.qvars(),
1205 Self::BinOp { lhs, rhs, .. } => lhs.qvars().concat(rhs.qvars()),
1206 Self::App { args, .. } => args.iter().fold(set! {}, |acc, p| acc.concat(p.qvars())),
1207 Self::Erased(t) => t.qvars(),
1208 Self::Value(val) => val.qvars(),
1209 Self::Mono(_) | Self::Failure => set! {},
1210 }
1211 }
1212
1213 pub fn has_qvar(&self) -> bool {
1214 match self {
1215 Self::FreeVar(fv) if fv.is_unbound() && fv.is_generalized() => true,
1216 Self::FreeVar(fv) if fv.is_linked() => fv.crack().has_qvar(),
1217 Self::FreeVar(_) => false,
1218 Self::Type(t) => t.has_qvar(),
1219 Self::Proj { obj, .. } => obj.has_qvar(),
1220 Self::ProjCall { obj, args, .. } => obj.has_qvar() || args.iter().any(|t| t.has_qvar()),
1221 Self::List(tps) | Self::Tuple(tps) => tps.iter().any(|tp| tp.has_qvar()),
1222 Self::UnsizedList(elem) => elem.has_qvar(),
1223 Self::Set(tps) => tps.iter().any(|tp| tp.has_qvar()),
1224 Self::Dict(tps) => tps.iter().any(|(k, v)| k.has_qvar() || v.has_qvar()),
1225 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
1226 rec.iter().any(|(_, tp)| tp.has_qvar())
1227 }
1228 Self::Lambda(lambda) => lambda.body.iter().any(|tp| tp.has_qvar()),
1229 Self::UnaryOp { val, .. } => val.has_qvar(),
1230 Self::BinOp { lhs, rhs, .. } => lhs.has_qvar() || rhs.has_qvar(),
1231 Self::App { args, .. } => args.iter().any(|p| p.has_qvar()),
1232 Self::Erased(t) => t.has_qvar(),
1233 Self::Value(val) => val.has_qvar(),
1234 Self::Mono(_) | Self::Failure => false,
1235 }
1236 }
1237
1238 pub fn contains_tvar(&self, target: &FreeTyVar) -> bool {
1239 match self {
1240 Self::FreeVar(fv) if fv.is_linked() => fv.crack().contains_tvar(target),
1241 Self::FreeVar(fv) => fv.get_type().is_some_and(|t| t.contains_tvar(target)),
1242 Self::Type(t) => t.contains_tvar(target),
1243 Self::Erased(t) => t.contains_tvar(target),
1244 Self::Proj { obj, .. } => obj.contains_tvar(target),
1245 Self::ProjCall { obj, args, .. } => {
1246 obj.contains_tvar(target) || args.iter().any(|t| t.contains_tvar(target))
1247 }
1248 Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_tvar(target)),
1249 Self::UnsizedList(elem) => elem.contains_tvar(target),
1250 Self::Set(ts) => ts.iter().any(|t| t.contains_tvar(target)),
1251 Self::Dict(ts) => ts
1252 .iter()
1253 .any(|(k, v)| k.contains_tvar(target) || v.contains_tvar(target)),
1254 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
1255 rec.iter().any(|(_, tp)| tp.contains_tvar(target))
1256 }
1257 Self::Lambda(lambda) => lambda.body.iter().any(|tp| tp.contains_tvar(target)),
1258 Self::UnaryOp { val, .. } => val.contains_tvar(target),
1259 Self::BinOp { lhs, rhs, .. } => lhs.contains_tvar(target) || rhs.contains_tvar(target),
1260 Self::App { args, .. } => args.iter().any(|p| p.contains_tvar(target)),
1261 Self::Value(val) => val.contains_tvar(target),
1262 Self::Mono(_) | Self::Failure => false,
1263 }
1264 }
1265
1266 pub fn contains_type(&self, target: &Type) -> bool {
1267 match self {
1268 Self::FreeVar(fv) if fv.is_linked() => fv.crack().contains_type(target),
1269 Self::FreeVar(fv) => fv.get_type().is_some_and(|t| t.contains_type(target)),
1270 Self::Type(t) => t.contains_type(target),
1271 Self::Erased(t) => t.contains_type(target),
1272 Self::Proj { obj, .. } => obj.contains_type(target),
1273 Self::ProjCall { obj, args, .. } => {
1274 obj.contains_type(target) || args.iter().any(|t| t.contains_type(target))
1275 }
1276 Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_type(target)),
1277 Self::UnsizedList(elem) => elem.contains_type(target),
1278 Self::Set(ts) => ts.iter().any(|t| t.contains_type(target)),
1279 Self::Dict(ts) => ts
1280 .iter()
1281 .any(|(k, v)| k.contains_type(target) || v.contains_type(target)),
1282 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
1283 rec.iter().any(|(_, tp)| tp.contains_type(target))
1284 }
1285 Self::Lambda(lambda) => lambda.body.iter().any(|tp| tp.contains_type(target)),
1286 Self::UnaryOp { val, .. } => val.contains_type(target),
1287 Self::BinOp { lhs, rhs, .. } => lhs.contains_type(target) || rhs.contains_type(target),
1288 Self::App { args, .. } => args.iter().any(|p| p.contains_type(target)),
1289 Self::Value(val) => val.contains_type(target),
1290 Self::Mono(_) | Self::Failure => false,
1291 }
1292 }
1293
1294 pub fn has_type_satisfies(&self, f: impl Fn(&Type) -> bool + Copy) -> bool {
1295 match self {
1296 Self::FreeVar(fv) if fv.is_linked() => fv.crack().has_type_satisfies(f),
1297 Self::FreeVar(fv) => fv.get_type().is_some_and(|t| f(&t)),
1298 Self::Type(t) => f(t),
1299 Self::Erased(t) => f(t),
1300 Self::Proj { obj, .. } => obj.has_type_satisfies(f),
1301 Self::ProjCall { obj, args, .. } => {
1302 obj.has_type_satisfies(f) || args.iter().any(|tp| tp.has_type_satisfies(f))
1303 }
1304 Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|tp| tp.has_type_satisfies(f)),
1305 Self::UnsizedList(elem) => elem.has_type_satisfies(f),
1306 Self::Set(ts) => ts.iter().any(|tp| tp.has_type_satisfies(f)),
1307 Self::Dict(ts) => ts
1308 .iter()
1309 .any(|(k, v)| k.has_type_satisfies(f) || v.has_type_satisfies(f)),
1310 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
1311 rec.values().any(|tp| tp.has_type_satisfies(f))
1312 }
1313 Self::Lambda(lambda) => lambda.body.iter().any(|tp| tp.has_type_satisfies(f)),
1314 Self::UnaryOp { val, .. } => val.has_type_satisfies(f),
1315 Self::BinOp { lhs, rhs, .. } => lhs.has_type_satisfies(f) || rhs.has_type_satisfies(f),
1316 Self::App { args, .. } => args.iter().any(|p| p.has_type_satisfies(f)),
1317 Self::Value(val) => val.has_type_satisfies(f),
1318 Self::Mono(_) | Self::Failure => false,
1319 }
1320 }
1321
1322 pub fn contains_tp(&self, target: &TyParam) -> bool {
1323 if self == target {
1324 return true;
1325 }
1326 match self {
1327 Self::FreeVar(fv) if fv.is_linked() => fv.crack().contains_tp(target),
1328 Self::FreeVar(fv) => fv.get_type().is_some_and(|t| t.contains_tp(target)),
1329 Self::Type(t) => t.contains_tp(target),
1330 Self::Erased(t) => t.contains_tp(target),
1331 Self::Proj { obj, .. } => obj.contains_tp(target),
1332 Self::ProjCall { obj, args, .. } => {
1333 obj.contains_tp(target) || args.iter().any(|t| t.contains_tp(target))
1334 }
1335 Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_tp(target)),
1336 Self::UnsizedList(elem) => elem.contains_tp(target),
1337 Self::Set(ts) => ts.iter().any(|t| t.contains_tp(target)),
1338 Self::Dict(ts) => ts
1339 .iter()
1340 .any(|(k, v)| k.contains_tp(target) || v.contains_tp(target)),
1341 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
1342 rec.iter().any(|(_, tp)| tp.contains_tp(target))
1343 }
1344 Self::Lambda(lambda) => lambda.body.iter().any(|tp| tp.contains_tp(target)),
1345 Self::UnaryOp { val, .. } => val.contains_tp(target),
1346 Self::BinOp { lhs, rhs, .. } => lhs.contains_tp(target) || rhs.contains_tp(target),
1347 Self::App { args, .. } => args.iter().any(|p| p.contains_tp(target)),
1348 Self::Value(val) => val.contains_tp(target),
1349 Self::Mono(_) | Self::Failure => false,
1350 }
1351 }
1352
1353 pub fn contains_value(&self, target: &ValueObj) -> bool {
1354 match self {
1355 Self::FreeVar(fv) if fv.is_linked() => fv.crack().contains_value(target),
1356 Self::FreeVar(fv) => fv.get_type().is_some_and(|t| t.contains_value(target)),
1357 Self::Type(t) => t.contains_value(target),
1358 Self::Erased(t) => t.contains_value(target),
1359 Self::Proj { obj, .. } => obj.contains_value(target),
1360 Self::ProjCall { obj, args, .. } => {
1361 obj.contains_value(target) || args.iter().any(|t| t.contains_value(target))
1362 }
1363 Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_value(target)),
1364 Self::UnsizedList(elem) => elem.contains_value(target),
1365 Self::Set(ts) => ts.iter().any(|t| t.contains_value(target)),
1366 Self::Dict(ts) => ts
1367 .iter()
1368 .any(|(k, v)| k.contains_value(target) || v.contains_value(target)),
1369 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
1370 rec.iter().any(|(_, tp)| tp.contains_value(target))
1371 }
1372 Self::Lambda(lambda) => lambda.body.iter().any(|tp| tp.contains_value(target)),
1373 Self::UnaryOp { val, .. } => val.contains_value(target),
1374 Self::BinOp { lhs, rhs, .. } => {
1375 lhs.contains_value(target) || rhs.contains_value(target)
1376 }
1377 Self::App { args, .. } => args.iter().any(|p| p.contains_value(target)),
1378 Self::Value(val) => val.contains(target),
1379 Self::Mono(_) | Self::Failure => false,
1380 }
1381 }
1382
1383 pub fn contains_failure(&self) -> bool {
1384 self.contains_tp(&TyParam::Failure)
1385 || self.contains_type(&Type::Failure)
1386 || self.contains_value(&ValueObj::Failure)
1387 }
1388
1389 pub fn is_recursive(&self) -> bool {
1390 match self {
1391 Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_recursive(),
1392 Self::FreeVar(fv) => fv.get_type().is_some_and(|t| t.contains_tp(self)),
1393 Self::Proj { obj, .. } => obj.contains_tp(self),
1394 Self::ProjCall { obj, args, .. } => {
1395 obj.contains_tp(self) || args.iter().any(|t| t.contains_tp(self))
1396 }
1397 Self::BinOp { lhs, rhs, .. } => lhs.contains_tp(self) || rhs.contains_tp(self),
1398 Self::UnaryOp { val, .. } => val.contains_tp(self),
1399 Self::App { args, .. } => args.iter().any(|t| t.contains_tp(self)),
1400 Self::Lambda(lambda) => lambda.body.iter().any(|t| t.contains_tp(self)),
1401 Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.contains_tp(self)),
1402 Self::UnsizedList(elem) => elem.contains_tp(self),
1403 Self::Set(ts) => ts.iter().any(|t| t.contains_tp(self)),
1404 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
1405 rec.iter().any(|(_, t)| t.contains_tp(self))
1406 }
1407 Self::Dict(ts) => ts
1408 .iter()
1409 .any(|(k, v)| k.contains_tp(self) || v.contains_tp(self)),
1410 Self::Type(t) => t.contains_tp(self),
1411 Self::Value(val) => val.contains_tp(self),
1412 Self::Erased(t) => t.contains_tp(self),
1413 Self::Mono(_) | Self::Failure => false,
1414 }
1415 }
1416
1417 pub fn is_unbound_var(&self) -> bool {
1418 match self {
1419 Self::FreeVar(fv) => fv.is_unbound() || fv.crack().is_unbound_var(),
1420 Self::Type(t) => t.is_unbound_var(),
1421 Self::Value(ValueObj::Type(t)) => t.typ().is_unbound_var(),
1422 _ => false,
1423 }
1424 }
1425
1426 pub fn has_unbound_var(&self) -> bool {
1427 match self {
1428 Self::FreeVar(fv) => fv.has_unbound_var(),
1429 Self::Type(t) => t.has_unbound_var(),
1430 Self::Proj { obj, .. } => obj.has_unbound_var(),
1431 Self::ProjCall { obj, args, .. } => {
1432 obj.has_unbound_var() || args.iter().any(|t| t.has_unbound_var())
1433 }
1434 Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.has_unbound_var()),
1435 Self::UnsizedList(elem) => elem.has_unbound_var(),
1436 Self::Set(ts) => ts.iter().any(|t| t.has_unbound_var()),
1437 Self::Dict(kv) => kv
1438 .iter()
1439 .any(|(k, v)| k.has_unbound_var() || v.has_unbound_var()),
1440 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
1441 rec.iter().any(|(_, v)| v.has_unbound_var())
1442 }
1443 Self::Lambda(lambda) => lambda.body.iter().any(|t| t.has_unbound_var()),
1444 Self::UnaryOp { val, .. } => val.has_unbound_var(),
1445 Self::BinOp { lhs, rhs, .. } => lhs.has_unbound_var() || rhs.has_unbound_var(),
1446 Self::App { args, .. } => args.iter().any(|p| p.has_unbound_var()),
1447 Self::Erased(t) => t.has_unbound_var(),
1448 Self::Value(val) => val.has_unbound_var(),
1449 Self::Mono(_) | Self::Failure => false,
1450 }
1451 }
1452
1453 pub fn has_no_unbound_var(&self) -> bool {
1454 !self.has_unbound_var()
1455 }
1456
1457 pub fn has_undoable_linked_var(&self) -> bool {
1458 match self {
1459 Self::FreeVar(fv) => fv.is_undoable_linked(),
1460 Self::Type(t) => t.has_undoable_linked_var(),
1461 Self::Proj { obj, .. } => obj.has_undoable_linked_var(),
1462 Self::ProjCall { obj, args, .. } => {
1463 obj.has_undoable_linked_var() || args.iter().any(|t| t.has_undoable_linked_var())
1464 }
1465 Self::List(ts) | Self::Tuple(ts) => ts.iter().any(|t| t.has_undoable_linked_var()),
1466 Self::UnsizedList(elem) => elem.has_undoable_linked_var(),
1467 Self::Set(ts) => ts.iter().any(|t| t.has_undoable_linked_var()),
1468 Self::Dict(kv) => kv
1469 .iter()
1470 .any(|(k, v)| k.has_undoable_linked_var() || v.has_undoable_linked_var()),
1471 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
1472 rec.iter().any(|(_, v)| v.has_undoable_linked_var())
1473 }
1474 Self::Lambda(lambda) => lambda.body.iter().any(|t| t.has_undoable_linked_var()),
1475 Self::UnaryOp { val, .. } => val.has_undoable_linked_var(),
1476 Self::BinOp { lhs, rhs, .. } => {
1477 lhs.has_undoable_linked_var() || rhs.has_undoable_linked_var()
1478 }
1479 Self::App { args, .. } => args.iter().any(|p| p.has_undoable_linked_var()),
1480 Self::Erased(t) => t.has_undoable_linked_var(),
1481 Self::Value(val) => val.has_undoable_linked_var(),
1482 Self::Mono(_) | Self::Failure => false,
1483 }
1484 }
1485
1486 pub fn union_size(&self) -> usize {
1487 match self {
1488 Self::FreeVar(fv) if fv.is_linked() => fv.crack().union_size(),
1489 Self::Type(t) => t.union_size(),
1490 Self::Proj { obj, .. } => obj.union_size(),
1491 Self::ProjCall { obj, args, .. } => obj
1492 .union_size()
1493 .max(args.iter().map(|t| t.union_size()).max().unwrap_or(1)),
1494 Self::List(ts) | Self::Tuple(ts) => {
1495 ts.iter().map(|t| t.union_size()).max().unwrap_or(1)
1496 }
1497 Self::UnsizedList(elem) => elem.union_size(),
1498 Self::Set(ts) => ts.iter().map(|t| t.union_size()).max().unwrap_or(1),
1499 Self::Dict(kv) => kv
1500 .iter()
1501 .map(|(k, v)| k.union_size().max(v.union_size()))
1502 .max()
1503 .unwrap_or(1),
1504 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
1505 rec.iter().map(|(_, v)| v.union_size()).max().unwrap_or(1)
1506 }
1507 Self::Lambda(lambda) => lambda
1508 .body
1509 .iter()
1510 .map(|t| t.union_size())
1511 .max()
1512 .unwrap_or(1),
1513 Self::UnaryOp { val, .. } => val.union_size(),
1514 Self::BinOp { lhs, rhs, .. } => lhs.union_size().max(rhs.union_size()),
1515 Self::App { args, .. } => args.iter().map(|p| p.union_size()).max().unwrap_or(1),
1516 Self::Erased(t) => t.union_size(),
1517 Self::Value(ValueObj::Type(t)) => t.typ().union_size(),
1518 _ => 1,
1519 }
1520 }
1521
1522 pub fn has_upper_bound(&self) -> bool {
1523 match self {
1524 Self::Erased(_) => false,
1527 Self::FreeVar(fv) => !fv.is_unbound(), _ => true,
1529 }
1530 }
1531
1532 pub fn has_lower_bound(&self) -> bool {
1533 match self {
1534 Self::Erased(_) => false,
1535 Self::FreeVar(fv) => !fv.is_unbound(),
1536 _ => true,
1537 }
1538 }
1539
1540 pub fn is_erased(&self) -> bool {
1541 match self {
1542 Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_erased(),
1543 Self::Erased(_) => true,
1544 _ => false,
1545 }
1546 }
1547
1548 pub fn is_type(&self) -> bool {
1549 match self {
1550 Self::Type(_) => true,
1551 Self::FreeVar(fv) if fv.is_linked() => fv.crack().is_type(),
1552 Self::Value(ValueObj::Type(_)) => true,
1553 _ => false,
1554 }
1555 }
1556
1557 pub fn as_type(&self) -> Option<&Type> {
1558 <&Type>::try_from(self).ok()
1559 }
1560
1561 pub fn substitute(self, var: &str, to: &TyParam) -> TyParam {
1562 if self.qual_name().is_some_and(|n| n == var) {
1563 return to.clone();
1564 }
1565 self.map(&mut |tp| tp.substitute(var, to), &SharedFrees::new())
1566 }
1567
1568 pub fn replace(self, target: &TyParam, to: &TyParam) -> TyParam {
1569 let table = ReplaceTable::make_tp(target, to);
1570 table.replace_tp(self)
1571 }
1572
1573 pub(crate) fn _replace(self, target: &TyParam, to: &TyParam, tvs: &SharedFrees) -> TyParam {
1574 if &self == target {
1575 return to.clone();
1576 }
1577 match self {
1578 TyParam::Type(t) => TyParam::t(t._replace_tp(target, to, tvs)),
1579 TyParam::Value(val) => TyParam::value(val.replace_tp(target, to, tvs)),
1580 self_ => self_.map(&mut |tp| tp._replace(target, to, tvs), tvs),
1581 }
1582 }
1583
1584 pub fn replace_t(self, target: &Type, to: &Type, tvs: &SharedFrees) -> TyParam {
1585 match self {
1586 Self::FreeVar(fv) if fv.is_linked() => fv.unwrap_linked().replace_t(target, to, tvs),
1587 Self::FreeVar(fv) if fv.get_type().is_some() => {
1588 let id = fv.unbound_id().unwrap();
1589 if let Some(tp) = tvs.get_tp(id) {
1590 return tp;
1591 }
1592 let typ = fv.get_type().unwrap();
1593 let new_typ = typ.clone()._replace(target, to, tvs);
1594 if new_typ != typ {
1595 let fv_clone = fv.deep_clone();
1596 fv_clone.update_type(new_typ);
1597 tvs.insert_tp(id, Self::FreeVar(fv_clone.clone()));
1598 Self::FreeVar(fv_clone)
1599 } else {
1600 Self::FreeVar(fv)
1601 }
1602 }
1603 Self::Type(t) => Self::t(t._replace(target, to, tvs)),
1604 Self::Erased(t) => Self::erased(t._replace(target, to, tvs)),
1605 Self::Value(val) => Self::Value(val.replace_t(target, to, tvs)),
1606 _ => self.map(&mut |tp| tp.replace_t(target, to, tvs), &SharedFrees::new()),
1607 }
1608 }
1609
1610 pub fn eliminate_t(self, target: &Type) -> Self {
1611 self.replace_t(target, &Type::Never, &SharedFrees::new())
1612 }
1613
1614 pub fn normalize(self) -> TyParam {
1616 match self {
1617 TyParam::Value(ValueObj::Type(obj)) => TyParam::t(obj.typ().clone().normalize()),
1618 TyParam::Type(t) => TyParam::t(t.normalize()),
1619 other => other,
1620 }
1621 }
1622
1623 fn addr_eq(&self, other: &TyParam) -> bool {
1624 match (self, other) {
1625 (Self::FreeVar(slf), _) if slf.is_linked() => slf.crack().addr_eq(other),
1626 (_, Self::FreeVar(otr)) if otr.is_linked() => otr.crack().addr_eq(self),
1627 (Self::FreeVar(slf), Self::FreeVar(otr)) => slf.addr_eq(otr),
1628 (Self::Type(slf), Self::Type(otr)) => slf.addr_eq(otr),
1629 (Self::Value(ValueObj::Type(slf)), Self::Value(ValueObj::Type(otr))) => {
1630 slf.typ().addr_eq(otr.typ())
1631 }
1632 (Self::Type(slf), Self::Value(ValueObj::Type(otr))) => slf.addr_eq(otr.typ()),
1633 (Self::Value(ValueObj::Type(slf)), Self::Type(otr)) => slf.typ().addr_eq(otr),
1634 _ => ref_addr_eq!(self, other),
1635 }
1636 }
1637
1638 pub(crate) fn destructive_link(&self, to: &TyParam) {
1640 if self.addr_eq(to) {
1641 return;
1642 }
1643 if self.level() == Some(GENERIC_LEVEL) {
1644 if DEBUG_MODE {
1645 panic!("{self} is fixed");
1646 }
1647 return;
1648 }
1649 match self {
1650 Self::FreeVar(fv) => {
1651 if to.contains_tp(self) {
1652 let to = to.clone().eliminate_recursion(self);
1653 if !self.addr_eq(&to) {
1654 fv.link(&to);
1655 }
1656 } else {
1657 fv.link(to);
1658 }
1659 }
1660 Self::Type(t) => {
1661 if let Ok(to) = <&Type>::try_from(to) {
1662 t.destructive_link(to);
1663 } else if DEBUG_MODE {
1664 panic!("{to} is not a type");
1665 }
1666 }
1667 Self::Value(ValueObj::Type(t)) => {
1668 if let Ok(to) = <&Type>::try_from(to) {
1669 t.typ().destructive_link(to);
1670 } else if DEBUG_MODE {
1671 panic!("{to} is not a type");
1672 }
1673 }
1674 _ => {
1675 if DEBUG_MODE {
1676 panic!("{self} is not a free variable")
1677 }
1678 }
1679 }
1680 }
1681
1682 pub(crate) fn undoable_link(&self, to: &TyParam, list: &UndoableLinkedList) {
1684 list.push_tp(self);
1685 if self.addr_eq(to) {
1686 self.inc_undo_count();
1687 return;
1688 }
1689 match self {
1690 Self::FreeVar(fv) => {
1691 if to.contains_tp(self) {
1692 let to = to.clone().eliminate_recursion(self);
1693 if self.addr_eq(&to) {
1694 self.inc_undo_count();
1695 } else {
1696 fv.undoable_link(&to);
1697 }
1698 } else {
1699 fv.undoable_link(to);
1700 }
1701 }
1702 Self::Type(t) => {
1703 if let Ok(to) = <&Type>::try_from(to) {
1704 t.undoable_link(to, list);
1705 } else if DEBUG_MODE {
1706 panic!("{to} is not a type");
1707 }
1708 }
1709 Self::Value(ValueObj::Type(t)) => {
1710 if let Ok(to) = <&Type>::try_from(to) {
1711 t.typ().undoable_link(to, list);
1712 } else if DEBUG_MODE {
1713 panic!("{to} is not a type");
1714 }
1715 }
1716 _ => {
1717 if DEBUG_MODE {
1718 panic!("{self} is not a free variable")
1719 }
1720 }
1721 }
1722 }
1723
1724 pub(crate) fn link(&self, to: &TyParam, list: Option<&UndoableLinkedList>) {
1725 if let Some(list) = list {
1726 self.undoable_link(to, list);
1727 } else {
1728 self.destructive_link(to);
1729 }
1730 }
1731
1732 pub(crate) fn undo(&self) {
1733 match self {
1734 Self::FreeVar(fv) if fv.is_undoable_linked() => fv.undo(),
1735 Self::Type(t) => t.undo(),
1736 Self::Value(ValueObj::Type(t)) => t.typ().undo(),
1737 _ => {}
1743 }
1744 }
1745
1746 pub(crate) fn undoable_update_constraint(
1747 &self,
1748 new_constraint: Constraint,
1749 list: &UndoableLinkedList,
1750 ) {
1751 let Some(level) = self.level() else {
1752 if DEBUG_MODE {
1753 todo!();
1754 }
1755 return;
1756 };
1757 let new = if let Some(name) = self.unbound_name() {
1758 Self::named_free_var(name, level, new_constraint)
1759 } else {
1760 Self::free_var(level, new_constraint)
1761 };
1762 self.undoable_link(&new, list);
1763 }
1764
1765 pub(crate) fn update_constraint(
1766 &self,
1767 new_constraint: Constraint,
1768 list: Option<&UndoableLinkedList>,
1769 in_instantiation: bool,
1770 ) {
1771 if let Some(list) = list {
1772 self.undoable_update_constraint(new_constraint, list);
1773 } else {
1774 self.destructive_update_constraint(new_constraint, in_instantiation);
1775 }
1776 }
1777
1778 fn inc_undo_count(&self) {
1779 match self {
1780 Self::FreeVar(fv) => fv.inc_undo_count(),
1781 _ => panic!("{self} is not a free variable"),
1782 }
1783 }
1784
1785 pub fn typarams(&self) -> Vec<TyParam> {
1786 match self {
1787 Self::FreeVar(fv) if fv.is_linked() => fv.crack().typarams(),
1788 Self::Type(t) => t.typarams(),
1789 Self::Value(val) => val.typarams(),
1790 Self::App { args, .. } => args.clone(),
1791 _ => vec![],
1792 }
1793 }
1794
1795 pub fn contained_ts(&self) -> Set<Type> {
1796 match self {
1797 Self::FreeVar(fv) if fv.is_linked() => fv.crack().contained_ts(),
1798 Self::Type(t) => t.contained_ts(),
1799 Self::Value(val) => val.contained_ts(),
1800 Self::App { args, .. } => args
1801 .iter()
1802 .fold(set! {}, |acc, p| acc.concat(p.contained_ts())),
1803 _ => set! {},
1804 }
1805 }
1806
1807 pub fn dereference(&mut self) {
1808 match self {
1809 Self::FreeVar(fv) if fv.is_linked() => {
1810 let new = fv.crack().clone();
1811 *self = new;
1812 self.dereference();
1813 }
1814 Self::FreeVar(fv) if fv.is_generalized() => {
1815 fv.update_init();
1816 }
1817 Self::FreeVar(_) => {}
1818 Self::Type(t) => t.dereference(),
1819 Self::Value(val) => val.dereference(),
1820 Self::App { args, .. } => {
1821 for arg in args {
1822 arg.dereference();
1823 }
1824 }
1825 Self::Proj { obj, .. } => obj.dereference(),
1826 Self::ProjCall { obj, args, .. } => {
1827 obj.dereference();
1828 for arg in args {
1829 arg.dereference();
1830 }
1831 }
1832 Self::List(ts) | Self::Tuple(ts) => {
1833 for t in ts {
1834 t.dereference();
1835 }
1836 }
1837 Self::UnsizedList(elem) => elem.dereference(),
1838 Self::Set(ts) => {
1839 let ts_ = std::mem::take(ts);
1840 *ts = ts_
1841 .into_iter()
1842 .map(|mut t| {
1843 t.dereference();
1844 t
1845 })
1846 .collect();
1847 }
1848 Self::Dict(ts) => {
1849 let ts_ = std::mem::take(ts);
1850 *ts = ts_
1851 .into_iter()
1852 .map(|(mut k, mut v)| {
1853 k.dereference();
1854 v.dereference();
1855 (k, v)
1856 })
1857 .collect();
1858 }
1859 Self::Record(rec) | Self::DataClass { fields: rec, .. } => {
1860 for (_, t) in rec.iter_mut() {
1861 t.dereference();
1862 }
1863 }
1864 Self::Lambda(lambda) => {
1865 for t in &mut lambda.body {
1866 t.dereference();
1867 }
1868 }
1869 Self::UnaryOp { val, .. } => val.dereference(),
1870 Self::BinOp { lhs, rhs, .. } => {
1871 lhs.dereference();
1872 rhs.dereference();
1873 }
1874 Self::Erased(t) => t.dereference(),
1875 Self::Mono(_) | Self::Failure => {}
1876 }
1877 }
1878
1879 pub fn namespace(&self) -> Str {
1880 match self {
1881 Self::FreeVar(fv) if fv.is_linked() => fv.crack().namespace(),
1882 Self::Mono(name) | Self::App { name, .. } => {
1883 let namespaces = name.split_with(&[".", "::"]);
1884 if namespaces.len() > 1 {
1885 Str::rc(
1886 name.trim_end_matches(namespaces.last().unwrap())
1887 .trim_end_matches('.')
1888 .trim_end_matches("::"),
1889 )
1890 } else {
1891 Str::ever("")
1892 }
1893 }
1894 _ => Str::ever(""),
1895 }
1896 }
1897
1898 pub fn variables(&self) -> Set<Str> {
1899 match self {
1900 Self::FreeVar(fv) if fv.is_linked() => fv.crack().variables(),
1901 Self::FreeVar(fv) if fv.get_type().is_some() => fv.get_type().unwrap().variables(),
1902 Self::FreeVar(_) => set! {},
1903 Self::Mono(name) => set! { name.clone() },
1904 Self::App { name, args } => {
1905 let mut set = set! { name.clone() };
1906 for arg in args {
1907 set.merge(arg.variables());
1908 }
1909 set
1910 }
1911 Self::List(tps) | Self::Tuple(tps) => {
1912 tps.iter().fold(set! {}, |acc, t| acc.concat(t.variables()))
1913 }
1914 Self::Set(tps) => tps.iter().fold(set! {}, |acc, t| acc.concat(t.variables())),
1915 Self::Record(rec) | Self::DataClass { fields: rec, .. } => rec
1916 .iter()
1917 .fold(set! {}, |acc, (_, v)| acc.concat(v.variables())),
1918 Self::Dict(tps) => tps.iter().fold(set! {}, |acc, (k, v)| {
1919 acc.concat(k.variables().concat(v.variables()))
1920 }),
1921 Self::UnsizedList(elem) => elem.variables(),
1922 Self::BinOp { lhs, rhs, .. } => lhs.variables().concat(rhs.variables()),
1923 Self::UnaryOp { val, .. } => val.variables(),
1924 Self::Lambda(lambda) => lambda
1925 .body
1926 .iter()
1927 .fold(set! {}, |acc, t| acc.concat(t.variables())),
1928 Self::Proj { obj, .. } => obj.variables(),
1929 Self::ProjCall { obj, args, .. } => {
1930 let mut set = obj.variables();
1931 for arg in args {
1932 set.merge(arg.variables());
1933 }
1934 set
1935 }
1936 Self::Type(t) | Self::Erased(t) => t.variables(),
1937 Self::Value(val) => val.variables(),
1938 Self::Failure => set! {},
1939 }
1940 }
1941
1942 pub fn map(self, f: &mut impl FnMut(TyParam) -> TyParam, tvs: &SharedFrees) -> TyParam {
1944 match self {
1945 TyParam::FreeVar(fv) if fv.is_linked() => f(fv.unwrap_linked()),
1946 TyParam::FreeVar(fv) if fv.get_type().is_some() => {
1947 if let Some(id) = fv.unbound_id() {
1948 if let Some(tp) = tvs.get_tp(id) {
1949 return tp;
1950 }
1951 }
1952 let typ = fv.get_type().unwrap();
1953 let new_typ = typ.clone().map_tp(f, tvs);
1954 if typ != new_typ {
1955 let fv_clone = fv.deep_clone();
1956 fv_clone.update_type(new_typ);
1957 if let Some(id) = fv_clone.unbound_id() {
1958 tvs.insert_tp(id, TyParam::FreeVar(fv_clone.clone()));
1959 }
1960 TyParam::FreeVar(fv_clone)
1961 } else {
1962 TyParam::FreeVar(fv)
1963 }
1964 }
1965 TyParam::FreeVar(_) => self,
1966 TyParam::App { name, args } => {
1967 let new_args = args.into_iter().map(f).collect::<Vec<_>>();
1968 TyParam::app(name, new_args)
1969 }
1970 TyParam::BinOp { op, lhs, rhs } => {
1971 let new_lhs = f(*lhs);
1972 let new_rhs = f(*rhs);
1973 TyParam::bin(op, new_lhs, new_rhs)
1974 }
1975 TyParam::UnaryOp { op, val } => TyParam::unary(op, f(*val)),
1976 TyParam::UnsizedList(elem) => TyParam::unsized_list(f(*elem)),
1977 TyParam::List(tps) => TyParam::List(tps.into_iter().map(f).collect()),
1978 TyParam::Tuple(tps) => TyParam::Tuple(tps.into_iter().map(f).collect()),
1979 TyParam::Set(tps) => TyParam::Set(tps.into_iter().map(f).collect()),
1980 TyParam::Dict(tps) => {
1981 let new_tps = tps.into_iter().map(|(k, v)| (f(k), f(v))).collect();
1982 TyParam::Dict(new_tps)
1983 }
1984 TyParam::Record(rec) => {
1985 let new_rec = rec.into_iter().map(|(k, v)| (k, f(v))).collect();
1986 TyParam::Record(new_rec)
1987 }
1988 TyParam::DataClass { name, fields } => {
1989 let new_fields = fields.into_iter().map(|(k, v)| (k, f(v))).collect();
1990 TyParam::DataClass {
1991 name,
1992 fields: new_fields,
1993 }
1994 }
1995 TyParam::Lambda(lambda) => {
1996 let new_body = lambda.body.into_iter().map(f).collect();
1997 TyParam::Lambda(TyParamLambda {
1998 body: new_body,
1999 ..lambda
2000 })
2001 }
2002 TyParam::Proj { obj, attr } => TyParam::Proj {
2003 obj: Box::new(f(*obj)),
2004 attr,
2005 },
2006 TyParam::ProjCall { obj, attr, args } => TyParam::ProjCall {
2007 obj: Box::new(f(*obj)),
2008 attr,
2009 args: args.into_iter().map(f).collect::<Vec<_>>(),
2010 },
2011 TyParam::Value(val) => TyParam::Value(val.map_tp(f, tvs)),
2012 TyParam::Type(t) => TyParam::t(t.map_tp(f, tvs)),
2013 TyParam::Erased(t) => TyParam::erased(t.map_tp(f, tvs)),
2014 TyParam::Mono(_) | TyParam::Failure => self,
2015 }
2016 }
2017
2018 pub fn map_t(self, f: &mut impl FnMut(Type) -> Type, tvs: &SharedFrees) -> TyParam {
2019 match self {
2020 TyParam::FreeVar(fv) if fv.is_linked() => fv.unwrap_linked().map_t(f, tvs),
2021 TyParam::FreeVar(fv) if fv.get_type().is_some() => {
2022 if let Some(id) = fv.unbound_id() {
2023 if let Some(tp) = tvs.get_tp(id) {
2024 return tp;
2025 }
2026 }
2027 let typ = fv.get_type().unwrap();
2028 let new_typ = f(typ.clone());
2029 if typ != new_typ {
2030 let fv_clone = fv.deep_clone();
2031 fv_clone.update_type(new_typ);
2032 if let Some(id) = fv_clone.unbound_id() {
2033 tvs.insert_tp(id, TyParam::FreeVar(fv_clone.clone()));
2034 }
2035 TyParam::FreeVar(fv_clone)
2036 } else {
2037 TyParam::FreeVar(fv)
2038 }
2039 }
2040 TyParam::FreeVar(_) => self,
2041 TyParam::App { name, args } => {
2042 let new_args = args
2043 .into_iter()
2044 .map(|tp| tp.map_t(f, tvs))
2045 .collect::<Vec<_>>();
2046 TyParam::app(name, new_args)
2047 }
2048 TyParam::BinOp { op, lhs, rhs } => {
2049 TyParam::bin(op, lhs.map_t(f, tvs), rhs.map_t(f, tvs))
2050 }
2051 TyParam::UnaryOp { op, val } => TyParam::unary(op, val.map_t(f, tvs)),
2052 TyParam::UnsizedList(elem) => TyParam::unsized_list(elem.map_t(f, tvs)),
2053 TyParam::List(tps) => {
2054 TyParam::List(tps.into_iter().map(|tp| tp.map_t(f, tvs)).collect())
2055 }
2056 TyParam::Tuple(tps) => {
2057 TyParam::Tuple(tps.into_iter().map(|tp| tp.map_t(f, tvs)).collect())
2058 }
2059 TyParam::Set(tps) => TyParam::Set(tps.into_iter().map(|tp| tp.map_t(f, tvs)).collect()),
2060 TyParam::Dict(tps) => {
2061 let new_tps = tps
2062 .into_iter()
2063 .map(|(k, v)| (k.map_t(f, tvs), v.map_t(f, tvs)))
2064 .collect();
2065 TyParam::Dict(new_tps)
2066 }
2067 TyParam::Record(rec) => {
2068 let new_rec = rec.into_iter().map(|(k, v)| (k, v.map_t(f, tvs))).collect();
2069 TyParam::Record(new_rec)
2070 }
2071 TyParam::DataClass { name, fields } => {
2072 let new_fields = fields
2073 .into_iter()
2074 .map(|(k, v)| (k, v.map_t(f, tvs)))
2075 .collect();
2076 TyParam::DataClass {
2077 name,
2078 fields: new_fields,
2079 }
2080 }
2081 TyParam::Lambda(lambda) => {
2082 let new_body = lambda.body.into_iter().map(|tp| tp.map_t(f, tvs)).collect();
2083 TyParam::Lambda(TyParamLambda {
2084 body: new_body,
2085 ..lambda
2086 })
2087 }
2088 TyParam::Proj { obj, attr } => TyParam::Proj {
2089 obj: Box::new(obj.map_t(f, tvs)),
2090 attr,
2091 },
2092 TyParam::ProjCall { obj, attr, args } => {
2093 let new_args = args
2094 .into_iter()
2095 .map(|tp| tp.map_t(f, tvs))
2096 .collect::<Vec<_>>();
2097 TyParam::ProjCall {
2098 obj: Box::new(obj.map_t(f, tvs)),
2099 attr,
2100 args: new_args,
2101 }
2102 }
2103 TyParam::Value(val) => TyParam::Value(val.map_t(f)),
2104 TyParam::Type(t) => TyParam::t(f(*t)),
2105 TyParam::Erased(t) => TyParam::erased(f(*t)),
2106 TyParam::Mono(_) | TyParam::Failure => self,
2107 }
2108 }
2109
2110 pub fn is_free_var(&self) -> bool {
2111 match self {
2112 Self::FreeVar(_) => true,
2113 Self::Type(t) => t.is_free_var(),
2114 Self::Value(ValueObj::Type(t)) => t.typ().is_free_var(),
2115 _ => false,
2116 }
2117 }
2118
2119 pub fn eliminate_recursion(self, target: &TyParam) -> Self {
2120 if self.is_free_var() && self.addr_eq(target) {
2121 return Self::Failure;
2122 }
2123 self.map(
2124 &mut |tp| tp.eliminate_recursion(target),
2125 &SharedFrees::new(),
2126 )
2127 }
2128
2129 pub fn as_free(&self) -> Option<&FreeTyParam> {
2130 <&FreeTyParam>::try_from(self).ok()
2131 }
2132
2133 pub fn is_none(&self) -> bool {
2134 match self {
2135 Self::Value(val) => val.is_none(),
2136 _ => false,
2137 }
2138 }
2139
2140 pub fn is_failure(&self) -> bool {
2141 match self {
2142 Self::Failure => true,
2143 Self::Value(val) => val.is_failure(),
2144 Self::Type(t) => t.is_failure(),
2145 _ => false,
2146 }
2147 }
2148
2149 pub const fn is_str_value(&self) -> bool {
2150 match self {
2151 Self::Value(val) => val.is_str(),
2152 _ => false,
2153 }
2154 }
2155
2156 pub const fn is_nat_value(&self) -> bool {
2157 match self {
2158 Self::Value(val) => val.is_nat(),
2159 _ => false,
2160 }
2161 }
2162
2163 pub const fn is_int_value(&self) -> bool {
2164 match self {
2165 Self::Value(val) => val.is_int(),
2166 _ => false,
2167 }
2168 }
2169
2170 pub const fn is_float_value(&self) -> bool {
2171 match self {
2172 Self::Value(val) => val.is_float(),
2173 _ => false,
2174 }
2175 }
2176
2177 pub const fn is_bool_value(&self) -> bool {
2178 match self {
2179 Self::Value(val) => val.is_bool(),
2180 _ => false,
2181 }
2182 }
2183}
2184
2185#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
2186#[repr(u8)]
2187pub enum TyParamOrdering {
2188 Less,
2189 Equal,
2190 Greater,
2191 LessEqual, NotEqual, GreaterEqual, Any,
2195 NoRelation,
2196}
2197
2198use TyParamOrdering::*;
2199
2200impl From<Ordering> for TyParamOrdering {
2201 fn from(o: Ordering) -> Self {
2202 match o {
2203 Ordering::Less => Less,
2204 Ordering::Equal => Equal,
2205 Ordering::Greater => Greater,
2206 }
2207 }
2208}
2209
2210impl TryFrom<TyParamOrdering> for Ordering {
2211 type Error = ();
2212 fn try_from(o: TyParamOrdering) -> Result<Self, Self::Error> {
2213 match o {
2214 Less => Ok(Ordering::Less),
2215 Equal => Ok(Ordering::Equal),
2216 Greater => Ok(Ordering::Greater),
2217 _ => Err(()),
2218 }
2219 }
2220}
2221
2222impl TyParamOrdering {
2223 pub const fn canbe_eq(self) -> bool {
2224 matches!(self, LessEqual | GreaterEqual | Equal | Any)
2225 }
2226 pub const fn canbe_lt(self) -> bool {
2227 matches!(self, Less | LessEqual | NotEqual | Any)
2228 }
2229 pub const fn canbe_gt(self) -> bool {
2230 matches!(self, Greater | GreaterEqual | NotEqual | Any)
2231 }
2232 pub const fn canbe_le(self) -> bool {
2233 matches!(self, Less | LessEqual | Equal | Any)
2234 }
2235 pub const fn canbe_ge(self) -> bool {
2236 matches!(self, Greater | GreaterEqual | Equal | Any)
2237 }
2238 pub const fn canbe_ne(self) -> bool {
2239 matches!(self, NotEqual | Any)
2240 }
2241 pub const fn is_lt(&self) -> bool {
2242 matches!(self, Less | LessEqual | Any)
2243 }
2244 pub const fn is_le(&self) -> bool {
2245 matches!(self, Less | Equal | LessEqual | Any)
2246 }
2247 pub const fn is_gt(&self) -> bool {
2248 matches!(self, Greater | GreaterEqual | Any)
2249 }
2250 pub const fn is_ge(&self) -> bool {
2251 matches!(self, Greater | Equal | GreaterEqual | Any)
2252 }
2253 pub const fn is_eq(&self) -> bool {
2254 matches!(self, Equal | Any)
2255 }
2256 pub const fn is_ne(&self) -> bool {
2257 matches!(self, Less | Greater | NotEqual | Any)
2258 }
2259 pub const fn reverse(&self) -> Self {
2260 match self {
2261 Less => Greater,
2262 Greater => Less,
2263 LessEqual => GreaterEqual,
2264 GreaterEqual => LessEqual,
2265 Equal => NotEqual,
2266 NotEqual => Equal,
2267 Any | NoRelation => Any,
2268 }
2269 }
2270}