fix: structural type check

This commit is contained in:
Shunsuke Shibayama 2024-08-09 13:38:04 +09:00
parent f337aefdda
commit 0875c7e5c9
3 changed files with 59 additions and 3 deletions

View file

@ -869,6 +869,22 @@ impl Context {
Type::NamedTuple(fields) => fields.iter().cloned().collect(),
Type::Refinement(refine) => self.fields(&refine.t),
Type::Structural(t) => self.fields(t),
Type::Or(l, r) => {
let l_fields = self.fields(l);
let r_fields = self.fields(r);
let l_field_names = l_fields.keys().collect::<Set<_>>();
let r_field_names = r_fields.keys().collect::<Set<_>>();
let field_names = l_field_names.intersection(&r_field_names);
let mut fields = Dict::new();
for (name, l_t, r_t) in field_names
.iter()
.map(|&name| (name, &l_fields[name], &r_fields[name]))
{
let union = self.union(l_t, r_t);
fields.insert(name.clone(), union);
}
fields
}
other => {
let Some(ctx) = self.get_nominal_type_ctx(other) else {
return Dict::new();

View file

@ -2038,6 +2038,14 @@ impl Context {
Immutable,
Visibility::BUILTIN_PUBLIC,
);
let mut generic_set_sized = Self::builtin_methods(Some(mono(SIZED)), 2);
generic_set_sized.register_builtin_erg_impl(
FUNDAMENTAL_LEN,
fn0_met(mono(GENERIC_SET), Nat),
Const,
Visibility::BUILTIN_PUBLIC,
);
generic_set.register_trait_methods(mono(GENERIC_SET), generic_set_sized);
/* Set */
let mut set_ =
Self::builtin_poly_class(SET, vec![PS::t_nd(TY_T), PS::named_nd(TY_N, Nat)], 10);
@ -2128,6 +2136,14 @@ impl Context {
Visibility::BUILTIN_PUBLIC,
);
generic_dict.register_trait_methods(g_dict_t.clone(), generic_dict_eq);
let mut generic_dict_sized = Self::builtin_methods(Some(mono(SIZED)), 2);
generic_dict_sized.register_builtin_erg_impl(
FUNDAMENTAL_LEN,
fn0_met(g_dict_t.clone(), Nat).quantify(),
Const,
Visibility::BUILTIN_PUBLIC,
);
generic_dict.register_trait_methods(g_dict_t.clone(), generic_dict_sized);
let D = mono_q_tp(TY_D, instanceof(mono(GENERIC_DICT)));
// .get: _: T -> T or None
let dict_get_t = fn1_met(g_dict_t.clone(), T.clone(), or(T.clone(), NoneType)).quantify();
@ -2334,9 +2350,14 @@ impl Context {
Immutable,
Visibility::BUILTIN_PUBLIC,
);
bytes
.register_trait(self, poly(SEQUENCE, vec![ty_tp(Int)]))
.unwrap();
let mut bytes_seq = Self::builtin_methods(Some(poly(SEQUENCE, vec![ty_tp(Int)])), 2);
bytes_seq.register_builtin_erg_impl(
FUNDAMENTAL_LEN,
fn0_met(mono(BYTES), Nat),
Const,
Visibility::BUILTIN_PUBLIC,
);
bytes.register_trait_methods(Str, bytes_seq);
let mut bytes_eq = Self::builtin_methods(Some(mono(EQ)), 2);
bytes_eq.register_builtin_erg_impl(
OP_EQ,
@ -2375,6 +2396,14 @@ impl Context {
);
generic_tuple.register_trait_methods(mono(GENERIC_TUPLE), tuple_hash);
generic_tuple.register_trait(self, mono(EQ_HASH)).unwrap();
let mut generic_tuple_sized = Self::builtin_methods(Some(mono(SIZED)), 2);
generic_tuple_sized.register_builtin_erg_impl(
FUNDAMENTAL_LEN,
fn0_met(mono(GENERIC_TUPLE), Nat),
Const,
Visibility::BUILTIN_PUBLIC,
);
generic_tuple.register_trait_methods(mono(GENERIC_TUPLE), generic_tuple_sized);
/* HomogenousTuple */
let mut homo_tuple = Self::builtin_poly_class(HOMOGENOUS_TUPLE, vec![PS::t_nd(TY_T)], 1);
homo_tuple.register_superclass(mono(GENERIC_TUPLE), &generic_tuple);

View file

@ -18,3 +18,14 @@ assert w == 1
gt|T, U| x: Structural({.__gt__ = (self: T, other: U) -> Bool}), y: U = x.__gt__ y
assert gt(2, True)
length|T| x: Structural { .__len__ = (self: T) -> Nat } = x.__len__()
assert length("aaa") == 3
assert length(bytes("aaa", "utf-8")) == 3
assert length([1, 2]) == 2
assert length({"a": 1}) == 1
assert length({1, 2, 3}) == 3
assert length((1, 2, 3)) == 3
s as Str or Bytes = "a"
assert length(s) == 1