1use std::convert::TryInto;
2
3use erg_common::consts::PYTHON_MODE;
4use erg_common::dict;
5use erg_common::fresh::FRESH_GEN;
6
7use crate::ty::*;
8
9#[macro_export]
10macro_rules! fn_t {
11 ($input: expr => $ret: expr) => {
12 Type::Subr($crate::ty::SubrType::new(
13 $crate::ty::SubrKind::Func,
14 vec![$crate::ty::ParamTy::Pos($input)],
15 None,
16 vec![],
17 None,
18 $ret,
19 ))
20 };
21}
22
23#[inline]
24pub fn pos(ty: Type) -> ParamTy {
25 ParamTy::Pos(ty)
26}
27
28#[inline]
29pub fn kw(name: &'static str, ty: Type) -> ParamTy {
30 ParamTy::kw(Str::ever(name), ty)
31}
32
33#[inline]
34pub const fn kw_default(name: &'static str, ty: Type, default: Type) -> ParamTy {
35 ParamTy::kw_default(Str::ever(name), ty, default)
36}
37
38#[inline]
39pub const fn anon(ty: Type) -> ParamTy {
40 ParamTy::Pos(ty)
41}
42
43#[inline]
44pub fn free_var(level: usize, constraint: Constraint) -> Type {
45 Type::FreeVar(Free::new_unbound(level, constraint.to_type_constraint()))
46}
47
48#[inline]
49pub fn named_free_var(name: Str, level: usize, constraint: Constraint) -> Type {
50 Type::FreeVar(Free::new_named_unbound(
51 name,
52 level,
53 constraint.to_type_constraint(),
54 ))
55}
56
57#[inline]
58pub fn named_uninit_var(name: Str) -> Type {
59 Type::FreeVar(Free::new_named_unbound(name, 1, Constraint::Uninited))
60}
61
62pub fn list_t(elem_t: Type, len: TyParam) -> Type {
63 poly("List", vec![TyParam::t(elem_t), len])
64}
65
66pub fn list_mut(elem_t: Type, len: TyParam) -> Type {
67 poly("List!", vec![TyParam::t(elem_t), len])
68}
69
70pub fn out_list_t(elem_t: Type, len: TyParam) -> Type {
71 if PYTHON_MODE {
72 list_mut(elem_t, len)
73 } else {
74 list_t(elem_t, len)
75 }
76}
77
78pub fn unknown_len_list_t(elem_t: Type) -> Type {
79 list_t(elem_t, TyParam::erased(Type::Nat))
80}
81
82pub fn unknown_len_list_mut(elem_t: Type) -> Type {
83 list_mut(elem_t, TyParam::erased(Type::Nat))
84}
85
86pub fn out_unknown_len_list_t(elem_t: Type) -> Type {
87 if PYTHON_MODE {
88 unknown_len_list_mut(elem_t)
89 } else {
90 unknown_len_list_t(elem_t)
91 }
92}
93
94pub fn str_dict_t(value: Type) -> Type {
95 dict! { Type::Str => value }.into()
96}
97
98pub fn unsized_list_t(elem_t: Type) -> Type {
101 poly("UnsizedList", vec![TyParam::t(elem_t)])
102}
103
104pub fn tuple_t(args: Vec<Type>) -> Type {
105 poly(
106 "Tuple",
107 vec![TyParam::List(args.into_iter().map(TyParam::t).collect())],
108 )
109}
110
111pub fn homo_tuple_t(t: Type) -> Type {
112 poly("HomogenousTuple", vec![TyParam::t(t)])
113}
114
115pub fn set_t(elem_t: Type, len: TyParam) -> Type {
116 poly("Set", vec![TyParam::t(elem_t), len])
117}
118
119pub fn unknown_len_set_t(elem_t: Type) -> Type {
120 set_t(elem_t, TyParam::erased(Type::Nat))
121}
122
123pub fn set_mut(elem_t: Type, len: TyParam) -> Type {
124 poly("Set!", vec![TyParam::t(elem_t), len])
125}
126
127pub fn out_set_t(elem_t: Type, len: TyParam) -> Type {
128 if PYTHON_MODE {
129 set_mut(elem_t, len)
130 } else {
131 set_t(elem_t, len)
132 }
133}
134
135pub fn dict_t(dict: TyParam) -> Type {
136 poly("Dict", vec![dict])
137}
138
139pub fn dict_mut(dict: TyParam) -> Type {
140 poly("Dict!", vec![dict])
141}
142
143pub fn out_dict_t(dict: TyParam) -> Type {
144 if PYTHON_MODE {
145 dict_mut(dict)
146 } else {
147 dict_t(dict)
148 }
149}
150
151#[inline]
152pub fn range(t: Type) -> Type {
153 poly("Range", vec![TyParam::t(t)])
154}
155
156#[inline]
157pub fn module(path: TyParam) -> Type {
158 poly("Module", vec![path])
159}
160
161#[inline]
162pub fn py_module(path: TyParam) -> Type {
163 poly("PyModule", vec![path])
164}
165
166pub fn module_from_path<P: Into<PathBuf>>(path: P) -> Type {
167 let s = ValueObj::Str(Str::rc(&path.into().to_string_lossy()));
168 module(TyParam::Value(s))
169}
170
171pub fn try_v_enum(s: Set<ValueObj>) -> Result<Type, Set<ValueObj>> {
172 if !is_homogeneous(&s) {
173 return Err(s);
174 }
175 let name = FRESH_GEN.fresh_varname();
176 let t = inner_class(&s);
177 let preds = s
178 .into_iter()
179 .map(|o| Predicate::eq(name.clone(), TyParam::value(o)))
180 .fold(Predicate::FALSE, |acc, p| acc | p);
181 let refine = RefinementType::new(name, t, preds);
182 Ok(Type::Refinement(refine))
183}
184
185pub fn v_enum(s: Set<ValueObj>) -> Type {
186 try_v_enum(s).unwrap_or_else(|set| panic!("not homogeneous: {}", set))
187}
188
189pub fn t_enum(s: Set<Type>) -> Type {
190 try_v_enum(s.into_iter().map(ValueObj::builtin_type).collect())
191 .unwrap_or_else(|set| panic!("not homogeneous: {}", set))
192}
193
194pub fn t_singleton(t: Type) -> Type {
195 t_enum(set! {t})
196}
197
198pub fn tp_enum(ty: Type, s: Set<TyParam>) -> Type {
199 let name = FRESH_GEN.fresh_varname();
200 let preds = s
201 .into_iter()
202 .map(|tp| Predicate::eq(name.clone(), tp))
203 .fold(Predicate::FALSE, |acc, p| acc | p);
204 let refine = RefinementType::new(name, ty, preds);
205 Type::Refinement(refine)
206}
207
208pub fn singleton(ty: Type, tp: TyParam) -> Type {
209 let name = FRESH_GEN.fresh_varname();
210 let preds = Predicate::eq(name.clone(), tp);
211 let refine = RefinementType::new(name, ty, preds);
212 Type::Refinement(refine)
213}
214
215#[inline]
216pub fn int_interval<P, PErr, Q, QErr>(op: IntervalOp, l: P, r: Q) -> Type
217where
218 P: TryInto<TyParam, Error = PErr>,
219 PErr: fmt::Debug,
220 Q: TryInto<TyParam, Error = QErr>,
221 QErr: fmt::Debug,
222{
223 interval(op, Type::Int, l, r)
224}
225
226#[inline]
227pub fn closed_range<P, PErr, Q, QErr>(t: Type, l: P, r: Q) -> Type
228where
229 P: TryInto<TyParam, Error = PErr>,
230 PErr: fmt::Debug,
231 Q: TryInto<TyParam, Error = QErr>,
232 QErr: fmt::Debug,
233{
234 interval(IntervalOp::Closed, t, l, r)
235}
236
237#[inline]
238pub fn interval<P, PErr, Q, QErr>(op: IntervalOp, t: Type, l: P, r: Q) -> Type
239where
240 P: TryInto<TyParam, Error = PErr>,
241 PErr: fmt::Debug,
242 Q: TryInto<TyParam, Error = QErr>,
243 QErr: fmt::Debug,
244{
245 let l = l.try_into().unwrap_or_else(|l| todo!("{l:?}"));
246 let r = r.try_into().unwrap_or_else(|r| todo!("{r:?}"));
247 let name = FRESH_GEN.fresh_varname();
248 let pred = match op {
249 IntervalOp::LeftOpen if l == TyParam::value(NegInf) => Predicate::le(name.clone(), r),
250 IntervalOp::LeftOpen => Predicate::and(
252 Predicate::ge(name.clone(), TyParam::succ(l)),
253 Predicate::le(name.clone(), r),
254 ),
255 IntervalOp::RightOpen if r == TyParam::value(Inf) => Predicate::ge(name.clone(), l),
256 IntervalOp::RightOpen => Predicate::and(
258 Predicate::ge(name.clone(), l),
259 Predicate::le(name.clone(), TyParam::pred(r)),
260 ),
261 IntervalOp::Closed => Predicate::and(
263 Predicate::ge(name.clone(), l),
264 Predicate::le(name.clone(), r),
265 ),
266 IntervalOp::Open if l == TyParam::value(NegInf) && r == TyParam::value(Inf) => {
267 return refinement(name, t, Predicate::TRUE)
268 }
269 IntervalOp::Open => Predicate::and(
271 Predicate::ge(name.clone(), TyParam::succ(l)),
272 Predicate::le(name.clone(), TyParam::pred(r)),
273 ),
274 };
275 refinement(name, t, pred)
276}
277
278pub fn iter(t: Type) -> Type {
279 poly("Iter", vec![TyParam::t(t)])
280}
281
282pub fn ref_(t: Type) -> Type {
283 Type::Ref(Box::new(t))
284}
285
286pub fn ref_mut(before: Type, after: Option<Type>) -> Type {
287 Type::RefMut {
288 before: Box::new(before),
289 after: after.map(Box::new),
290 }
291}
292
293pub fn subr_t(
302 kind: SubrKind,
303 non_default_params: Vec<ParamTy>,
304 var_params: Option<ParamTy>,
305 default_params: Vec<ParamTy>,
306 kw_var_params: Option<ParamTy>,
307 return_t: Type,
308) -> Type {
309 Type::Subr(SubrType::new(
310 kind,
311 non_default_params,
312 var_params,
313 default_params,
314 kw_var_params,
315 return_t,
316 ))
317}
318
319pub fn func(
320 non_default_params: Vec<ParamTy>,
321 var_params: Option<ParamTy>,
322 default_params: Vec<ParamTy>,
323 kw_var_params: Option<ParamTy>,
324 return_t: Type,
325) -> Type {
326 Type::Subr(SubrType::new(
327 SubrKind::Func,
328 non_default_params,
329 var_params,
330 default_params,
331 kw_var_params,
332 return_t,
333 ))
334}
335
336pub fn no_var_func(
337 non_default_params: Vec<ParamTy>,
338 default_params: Vec<ParamTy>,
339 return_t: Type,
340) -> Type {
341 func(non_default_params, None, default_params, None, return_t)
342}
343
344pub fn func0(return_t: Type) -> Type {
345 func(vec![], None, vec![], None, return_t)
346}
347
348pub fn func1(param_t: Type, return_t: Type) -> Type {
349 func(vec![ParamTy::Pos(param_t)], None, vec![], None, return_t)
350}
351
352pub fn kind1(param: Type) -> Type {
353 func1(param, Type::Type)
354}
355
356pub fn func2(l: Type, r: Type, return_t: Type) -> Type {
357 func(
358 vec![ParamTy::Pos(l), ParamTy::Pos(r)],
359 None,
360 vec![],
361 None,
362 return_t,
363 )
364}
365
366pub fn func3(l: Type, m: Type, r: Type, return_t: Type) -> Type {
367 func(
368 vec![ParamTy::Pos(l), ParamTy::Pos(m), ParamTy::Pos(r)],
369 None,
370 vec![],
371 None,
372 return_t,
373 )
374}
375
376pub fn default_func(defaults: Vec<ParamTy>, return_t: Type) -> Type {
377 func(vec![], None, defaults, None, return_t)
378}
379
380pub fn bin_op(l: Type, r: Type, return_t: Type) -> Type {
381 nd_func(
382 vec![
383 ParamTy::kw(Str::ever("lhs"), l),
384 ParamTy::kw(Str::ever("rhs"), r),
385 ],
386 None,
387 return_t,
388 )
389}
390
391pub fn proc(
392 non_default_params: Vec<ParamTy>,
393 var_params: Option<ParamTy>,
394 default_params: Vec<ParamTy>,
395 kw_var_params: Option<ParamTy>,
396 return_t: Type,
397) -> Type {
398 Type::Subr(SubrType::new(
399 SubrKind::Proc,
400 non_default_params,
401 var_params,
402 default_params,
403 kw_var_params,
404 return_t,
405 ))
406}
407
408pub fn no_var_proc(
409 non_default_params: Vec<ParamTy>,
410 default_params: Vec<ParamTy>,
411 return_t: Type,
412) -> Type {
413 proc(non_default_params, None, default_params, None, return_t)
414}
415
416pub fn proc0(return_t: Type) -> Type {
417 proc(vec![], None, vec![], None, return_t)
418}
419
420pub fn proc1(param_t: Type, return_t: Type) -> Type {
421 proc(vec![ParamTy::Pos(param_t)], None, vec![], None, return_t)
422}
423
424pub fn proc2(l: Type, r: Type, return_t: Type) -> Type {
425 proc(
426 vec![ParamTy::Pos(l), ParamTy::Pos(r)],
427 None,
428 vec![],
429 None,
430 return_t,
431 )
432}
433
434pub fn fn_met(
435 self_t: Type,
436 mut non_default_params: Vec<ParamTy>,
437 var_params: Option<ParamTy>,
438 default_params: Vec<ParamTy>,
439 kw_var_params: Option<ParamTy>,
440 return_t: Type,
441) -> Type {
442 non_default_params.insert(0, ParamTy::kw(Str::ever("self"), self_t));
443 Type::Subr(SubrType::new(
444 SubrKind::Func,
445 non_default_params,
446 var_params,
447 default_params,
448 kw_var_params,
449 return_t,
450 ))
451}
452
453pub fn no_var_fn_met(
454 self_t: Type,
455 non_default_params: Vec<ParamTy>,
456 default_params: Vec<ParamTy>,
457 return_t: Type,
458) -> Type {
459 fn_met(
460 self_t,
461 non_default_params,
462 None,
463 default_params,
464 None,
465 return_t,
466 )
467}
468
469pub fn fn0_met(self_t: Type, return_t: Type) -> Type {
470 fn_met(self_t, vec![], None, vec![], None, return_t)
471}
472
473pub fn fn1_met(self_t: Type, input_t: Type, return_t: Type) -> Type {
474 fn_met(
475 self_t,
476 vec![ParamTy::Pos(input_t)],
477 None,
478 vec![],
479 None,
480 return_t,
481 )
482}
483
484pub fn fn1_kw_met(self_t: Type, input: ParamTy, return_t: Type) -> Type {
485 fn_met(self_t, vec![input], None, vec![], None, return_t)
486}
487
488pub fn fn2_met(self_t: Type, l: Type, r: Type, return_t: Type) -> Type {
489 fn_met(
490 self_t,
491 vec![ParamTy::Pos(l), ParamTy::Pos(r)],
492 None,
493 vec![],
494 None,
495 return_t,
496 )
497}
498
499pub fn pr_met(
500 self_t: Type,
501 non_default_params: Vec<ParamTy>,
502 var_params: Option<ParamTy>,
503 default_params: Vec<ParamTy>,
504 return_t: Type,
505) -> Type {
506 kw_var_pr_met(
507 self_t,
508 non_default_params,
509 var_params,
510 default_params,
511 None,
512 return_t,
513 )
514}
515
516pub fn pr0_met(self_t: Type, return_t: Type) -> Type {
517 pr_met(self_t, vec![], None, vec![], return_t)
518}
519
520pub fn pr1_met(self_t: Type, input_t: Type, return_t: Type) -> Type {
521 pr_met(self_t, vec![ParamTy::Pos(input_t)], None, vec![], return_t)
522}
523
524pub fn pr1_kw_met(self_t: Type, input: ParamTy, return_t: Type) -> Type {
525 pr_met(self_t, vec![input], None, vec![], return_t)
526}
527
528pub fn kw_var_pr_met(
529 self_t: Type,
530 mut non_default_params: Vec<ParamTy>,
531 var_params: Option<ParamTy>,
532 default_params: Vec<ParamTy>,
533 kw_var_params: Option<ParamTy>,
534 return_t: Type,
535) -> Type {
536 non_default_params.insert(0, ParamTy::kw(Str::ever("self"), self_t));
537 Type::Subr(SubrType::new(
538 SubrKind::Proc,
539 non_default_params,
540 var_params,
541 default_params,
542 kw_var_params,
543 return_t,
544 ))
545}
546
547#[inline]
549pub fn nd_func(params: Vec<ParamTy>, var_params: Option<ParamTy>, ret: Type) -> Type {
550 func(params, var_params, vec![], None, ret)
551}
552
553#[inline]
554pub fn nd_proc(params: Vec<ParamTy>, var_params: Option<ParamTy>, ret: Type) -> Type {
555 proc(params, var_params, vec![], None, ret)
556}
557
558#[inline]
559pub fn d_func(default_params: Vec<ParamTy>, return_t: Type) -> Type {
560 func(vec![], None, default_params, None, return_t)
561}
562
563#[inline]
564pub fn nd_proc1(pt: ParamTy, ret: Type) -> Type {
565 nd_proc(vec![pt], None, ret)
566}
567
568pub fn callable(param_ts: Vec<Type>, return_t: Type) -> Type {
569 Type::Callable {
570 param_ts,
571 return_t: Box::new(return_t),
572 }
573}
574
575#[inline]
576pub fn mono_q<S: Into<Str>>(name: S, constr: Constraint) -> Type {
577 named_free_var(name.into(), free::GENERIC_LEVEL, constr)
578}
579
580#[inline]
581pub fn type_q<S: Into<Str>>(name: S) -> Type {
582 mono_q(name, instanceof(Type::Type))
583}
584
585#[inline]
586pub fn subtype_q<S: Into<Str>>(name: S, sup: Type) -> Type {
587 mono_q(name, subtypeof(sup))
588}
589
590#[inline]
591pub fn mono<S: Into<Str>>(name: S) -> Type {
592 let name = name.into();
593 if cfg!(feature = "debug") {
594 match &name[..] {
596 "Obj" | "Int" | "Nat" | "Ratio" | "Float" | "Complex" | "Bool" | "Str" | "NoneType"
597 | "Code" | "Frame" | "Error" | "Inf" | "NegInf" | "Type" | "ClassType"
598 | "TraitType" | "Patch" | "NotImplementedType" | "Ellipsis" | "Never" => {
599 unreachable!("built-in type: {name}")
600 }
601 _ => {}
602 }
603 }
604 Type::Mono(name)
605}
606
607pub fn from_str(name: impl Into<Str>) -> Type {
608 let name = name.into();
609 match &name[..] {
610 "Obj" => Type::Obj,
611 "Int" => Type::Int,
612 "Nat" => Type::Nat,
613 "Ratio" => Type::Ratio,
614 "Float" => Type::Float,
615 "Complex" => Type::Complex,
616 "Bool" => Type::Bool,
617 "Str" => Type::Str,
618 "NoneType" => Type::NoneType,
619 "Code" => Type::Code,
620 "Frame" => Type::Frame,
621 "Error" => Type::Error,
622 "Inf" => Type::Inf,
623 "NegInf" => Type::NegInf,
624 "Type" => Type::Type,
625 "ClassType" => Type::ClassType,
626 "TraitType" => Type::TraitType,
627 "Patch" => Type::Patch,
628 "NotImplementedType" => Type::NotImplementedType,
629 "Ellipsis" => Type::Ellipsis,
630 "Never" => Type::Never,
631 _ => Type::Mono(name),
632 }
633}
634
635#[inline]
636pub fn poly<S: Into<Str>>(name: S, params: Vec<TyParam>) -> Type {
637 Type::Poly {
638 name: name.into(),
639 params,
640 }
641}
642
643pub fn type_poly<S: Into<Str>>(name: S, ts: Vec<Type>) -> Type {
644 poly(name, ts.into_iter().map(TyParam::t).collect())
645}
646
647#[inline]
648pub fn proj<S: Into<Str>>(lhs: Type, rhs: S) -> Type {
649 Type::Proj {
650 lhs: Box::new(lhs),
651 rhs: rhs.into(),
652 }
653}
654
655#[inline]
656pub fn proj_call<S: Into<Str>>(lhs: TyParam, attr_name: S, args: Vec<TyParam>) -> Type {
657 Type::ProjCall {
658 lhs: Box::new(lhs),
659 attr_name: attr_name.into(),
660 args,
661 }
662}
663
664#[inline]
673pub fn refinement(var: Str, t: Type, pred: Predicate) -> Type {
674 Type::Refinement(RefinementType::new(var, t, pred))
675}
676
677pub fn and(lhs: Type, rhs: Type) -> Type {
678 lhs & rhs
679}
680
681pub fn or(lhs: Type, rhs: Type) -> Type {
682 lhs | rhs
683}
684
685pub fn ors(tys: impl IntoIterator<Item = Type>) -> Type {
686 tys.into_iter().fold(Type::Never, or)
687}
688
689pub fn ands(tys: impl IntoIterator<Item = Type>) -> Type {
690 tys.into_iter().fold(Type::Obj, and)
691}
692
693pub fn not(ty: Type) -> Type {
694 Type::Not(Box::new(ty))
695}
696
697pub fn guard(namespace: Str, target: CastTarget, to: Type) -> Type {
698 Type::Guard(GuardType::new(namespace, target, to))
699}
700
701pub fn bounded(sub: Type, sup: Type) -> Type {
702 if sub == Type::Never {
703 sup
704 } else {
705 Type::Bounded {
706 sub: Box::new(sub),
707 sup: Box::new(sup),
708 }
709 }
710}
711
712#[inline]
713pub fn instanceof(t: Type) -> Constraint {
714 Constraint::new_type_of(t)
715}
716
717#[inline]
719pub fn subtypeof(sup: Type) -> Constraint {
720 Constraint::new_sandwiched(Type::Never, sup)
721}
722
723#[inline]
724pub fn supertypeof(sub: Type) -> Constraint {
725 Constraint::new_sandwiched(sub, Type::Obj)
726}
727
728#[inline]
729pub fn mono_q_tp<S: Into<Str>>(name: S, constr: Constraint) -> TyParam {
730 TyParam::mono_q(name, constr)
731}
732
733#[inline]
734pub fn mono_tp<S: Into<Str>>(name: S) -> TyParam {
735 TyParam::mono(name)
736}
737
738#[inline]
739pub fn ty_tp(t: Type) -> TyParam {
740 TyParam::t(t)
741}
742
743#[inline]
745pub fn value<V: Into<ValueObj>>(v: V) -> TyParam {
746 TyParam::value(v)
747}