mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 12:14:43 +00:00
fix: record type subtyping
This commit is contained in:
parent
95595ef67c
commit
6ce41ef8bd
5 changed files with 19 additions and 3 deletions
|
@ -527,6 +527,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
(Bool, Guard { .. }) => true,
|
(Bool, Guard { .. }) => true,
|
||||||
(Mono(n), NamedTuple(_)) => &n[..] == "GenericNamedTuple" || &n[..] == "GenericTuple",
|
(Mono(n), NamedTuple(_)) => &n[..] == "GenericNamedTuple" || &n[..] == "GenericTuple",
|
||||||
|
(Mono(n), Record(_)) => &n[..] == "Record",
|
||||||
(Type, Subr(subr)) => self.supertype_of(&Type, &subr.return_t),
|
(Type, Subr(subr)) => self.supertype_of(&Type, &subr.return_t),
|
||||||
(Type, Poly { name, params }) if &name[..] == "Array" || &name[..] == "Set" => {
|
(Type, Poly { name, params }) if &name[..] == "Array" || &name[..] == "Set" => {
|
||||||
let elem_t = self.convert_tp_into_type(params[0].clone()).unwrap();
|
let elem_t = self.convert_tp_into_type(params[0].clone()).unwrap();
|
||||||
|
|
|
@ -1695,6 +1695,14 @@ impl Context {
|
||||||
/* record */
|
/* record */
|
||||||
let mut record = Self::builtin_mono_class(RECORD, 2);
|
let mut record = Self::builtin_mono_class(RECORD, 2);
|
||||||
record.register_superclass(Obj, &obj);
|
record.register_superclass(Obj, &obj);
|
||||||
|
let mut record_eq = Self::builtin_methods(Some(mono(EQ)), 2);
|
||||||
|
record_eq.register_builtin_erg_impl(
|
||||||
|
OP_EQ,
|
||||||
|
fn1_met(mono(RECORD), mono(RECORD), Bool),
|
||||||
|
Const,
|
||||||
|
Visibility::BUILTIN_PUBLIC,
|
||||||
|
);
|
||||||
|
record.register_trait(mono(RECORD), record_eq);
|
||||||
/* GenericNamedTuple */
|
/* GenericNamedTuple */
|
||||||
let mut generic_named_tuple = Self::builtin_mono_class(GENERIC_NAMED_TUPLE, 2);
|
let mut generic_named_tuple = Self::builtin_mono_class(GENERIC_NAMED_TUPLE, 2);
|
||||||
generic_named_tuple.register_superclass(mono(GENERIC_TUPLE), &generic_tuple);
|
generic_named_tuple.register_superclass(mono(GENERIC_TUPLE), &generic_tuple);
|
||||||
|
|
|
@ -550,15 +550,14 @@ impl Context {
|
||||||
return Ok(t);
|
return Ok(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let Some(decl_t) = opt_decl_t {
|
|
||||||
return Ok(decl_t.typ().clone());
|
|
||||||
}
|
|
||||||
if let Some((typ, _)) = self.get_type(ident.inspect()) {
|
if let Some((typ, _)) = self.get_type(ident.inspect()) {
|
||||||
Ok(typ.clone())
|
Ok(typ.clone())
|
||||||
} else if not_found_is_qvar {
|
} else if not_found_is_qvar {
|
||||||
let tyvar = named_free_var(Str::rc(other), self.level, Constraint::Uninited);
|
let tyvar = named_free_var(Str::rc(other), self.level, Constraint::Uninited);
|
||||||
tmp_tv_cache.push_or_init_tyvar(&ident.name, &tyvar, self);
|
tmp_tv_cache.push_or_init_tyvar(&ident.name, &tyvar, self);
|
||||||
Ok(tyvar)
|
Ok(tyvar)
|
||||||
|
} else if let Some(decl_t) = opt_decl_t {
|
||||||
|
Ok(decl_t.typ().clone())
|
||||||
} else {
|
} else {
|
||||||
Err(TyCheckErrors::from(TyCheckError::no_type_error(
|
Err(TyCheckErrors::from(TyCheckError::no_type_error(
|
||||||
self.cfg.input.clone(),
|
self.cfg.input.clone(),
|
||||||
|
@ -1375,6 +1374,7 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: opt_decl_t must be disassembled for each polymorphic type
|
||||||
pub(crate) fn instantiate_typespec_full(
|
pub(crate) fn instantiate_typespec_full(
|
||||||
&self,
|
&self,
|
||||||
t_spec: &TypeSpec,
|
t_spec: &TypeSpec,
|
||||||
|
|
|
@ -19,6 +19,7 @@ from _erg_set import Set
|
||||||
from _erg_contains_operator import contains_operator
|
from _erg_contains_operator import contains_operator
|
||||||
from _erg_mutate_operator import mutate_operator
|
from _erg_mutate_operator import mutate_operator
|
||||||
|
|
||||||
|
Record = tuple
|
||||||
|
|
||||||
class Never:
|
class Never:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -7,3 +7,9 @@ higher2(f: ((g: Nat -> Nat) -> Nat)): Nat = f((x: Nat) -> x + 1)
|
||||||
f(g: Bool -> Nat): Nat = g(False)
|
f(g: Bool -> Nat): Nat = g(False)
|
||||||
|
|
||||||
print! higher2 f # OK
|
print! higher2 f # OK
|
||||||
|
|
||||||
|
str_to_int_or_rec(_: {Str: Int or Record}) = None
|
||||||
|
|
||||||
|
str_to_int_or_rec { "a": 1 }
|
||||||
|
str_to_int_or_rec { "a": {.a = 1} }
|
||||||
|
str_to_int_or_rec { "a": {.a = 1}, "b": 1 }
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue