erg_compiler/context/
test.rs1use erg_common::traits::StructuralEq;
3use erg_common::Str;
4
5use crate::ty::constructors::{func1, mono, mono_q, poly, refinement, ty_tp};
6use crate::ty::free::Constraint;
7use crate::ty::typaram::TyParam;
8use crate::ty::{Predicate, Type};
9use Type::*;
10
11use crate::context::Context;
12
13impl Context {
14 pub fn assert_var_type(&self, varname: &str, ty: &Type) -> Result<(), ()> {
15 let Some((_, vi)) = self.get_var_info(varname) else {
16 panic!("variable not found: {varname}");
17 };
18 println!("{varname}: {}", vi.t);
19 if vi.t.structural_eq(ty) {
20 Ok(())
21 } else {
22 println!("{varname} is not the type of {ty}");
23 Err(())
24 }
25 }
26
27 pub fn assert_attr_type(&self, receiver_t: &Type, attr: &str, ty: &Type) -> Result<(), ()> {
28 let Some(ctx) = self.get_nominal_type_ctx(receiver_t) else {
29 panic!("type not found: {receiver_t}");
30 };
31 let Some((_, vi)) = ctx.get_method_kv(attr) else {
32 panic!("attribute not found: {attr}");
33 };
34 println!("{attr}: {}", vi.t);
35 if vi.t.structural_eq(ty) {
36 Ok(())
37 } else {
38 println!("{attr} is not the type of {ty}");
39 Err(())
40 }
41 }
42
43 pub fn test_refinement_subtyping(&self) -> Result<(), ()> {
44 let lhs = Nat;
46 let var = Str::ever("I");
47 let rhs = refinement(
48 var.clone(),
49 Type::Int,
50 Predicate::eq(var, TyParam::value(1)),
51 );
52 if self.supertype_of(&lhs, &rhs) {
53 Ok(())
54 } else {
55 Err(())
56 }
57 }
58
59 pub fn test_quant_subtyping(&self) -> Result<(), ()> {
60 let t = crate::ty::constructors::type_q("T");
61 let quant = func1(t.clone(), t).quantify();
62 let subr = func1(Obj, Never);
63 assert!(!self.subtype_of(&quant, &subr));
64 assert!(self.subtype_of(&subr, &quant));
65 Ok(())
66 }
67
68 pub fn test_resolve_trait_inner1(&self) -> Result<(), ()> {
69 let name = Str::ever("Add");
70 let params = vec![TyParam::t(Nat)];
71 let maybe_trait = poly(name, params);
72 let mut min = Type::Obj;
73 for pair in self.get_trait_impls(&maybe_trait) {
74 if self.supertype_of(&pair.sup_trait, &maybe_trait) {
75 min = self.min(&min, &pair.sub_type).unwrap_or(&min).clone();
76 }
77 }
78 if min == Nat {
79 Ok(())
80 } else {
81 Err(())
82 }
83 }
84
85 pub fn test_instantiation_and_generalization(&self) -> Result<(), ()> {
86 use crate::ty::free::HasLevel;
87 let t = mono_q("T", Constraint::new_subtype_of(mono("Eq")));
88 let unbound = func1(t.clone(), t);
89 let quantified = unbound.clone().quantify();
90 println!("quantified : {quantified}");
91 let inst = self.instantiate_def_type(&unbound).map_err(|_| ())?;
92 println!("inst: {inst}");
93 inst.lift();
94 let quantified_again = self.generalize_t(inst);
95 println!("quantified_again: {quantified_again}");
96 assert!(quantified.structural_eq(&quantified_again));
97 Ok(())
98 }
99
100 pub fn test_patch(&self) -> Result<(), ()> {
101 use crate::ty::constructors::or;
102 assert!(self.subtype_of(&Int, &mono("Eq")));
103 assert!(self.subtype_of(&or(Int, NoneType), &mono("Eq")));
104 assert!(!self.subtype_of(&or(Int, Float), &mono("Eq")));
105 assert!(self.subtype_of(&Int, &poly("Sub", vec![ty_tp(Int)])));
106 assert!(self.subtype_of(&Nat, &poly("Sub", vec![ty_tp(Nat)])));
107 Ok(())
108 }
109
110 pub fn test_intersection(&self) -> Result<(), ()> {
111 assert!(self.subtype_of(&Code, &(Int | Str | Code | NoneType)));
112 assert!(self.subtype_of(&(Int | Str), &(Int | Str | Code | NoneType)));
113 Ok(())
114 }
115}