feat: support Structural types for methods

This commit is contained in:
Shunsuke Shibayama 2023-02-23 18:12:05 +09:00
parent 2c3a27ed4b
commit aaa6b40b24
22 changed files with 477 additions and 98 deletions

View file

@ -257,6 +257,9 @@ impl Context {
self.sub_unify_tp(lhs, lhs2, _variance, loc, allow_divergence)?;
self.sub_unify_tp(rhs, rhs2, _variance, loc, allow_divergence)
}
(TyParam::Lambda(_l), TyParam::Lambda(_r)) => {
todo!("{_l}/{_r}")
}
(l, TyParam::Erased(t)) => {
let sub_t = self.get_tp_t(l)?;
if self.subtype_of(&sub_t, t, allow_cast) {
@ -344,6 +347,9 @@ impl Context {
self.reunify_tp(lhs, lhs2, loc)?;
self.reunify_tp(rhs, rhs2, loc)
}
(TyParam::Lambda(_l), TyParam::Lambda(_r)) => {
todo!("{_l}/{_r}")
}
(l, r) if self.eq_tp(l, r, allow_cast) => Ok(()),
(l, r) => panic!("type-parameter re-unification failed:\nl: {l}\nr: {r}"),
}
@ -628,6 +634,9 @@ impl Context {
}
Ok(())
}
// e.g. T/Structural({ .method = (self: T) -> Int })
(Type::FreeVar(fv), Type::Structural(_sup)) if fv.is_unbound() => Ok(()),
(Type::Structural(_sub), Type::FreeVar(fv)) if fv.is_unbound() => Ok(()),
(_, Type::FreeVar(rfv)) if rfv.is_unbound() => {
// NOTE: cannot `borrow_mut` because of cycle reference
let rfv_ref = unsafe { rfv.as_ptr().as_mut().unwrap() };
@ -845,6 +854,7 @@ impl Context {
Ok(())
}
}
(Type::Structural(l), Type::Structural(r)) => self.sub_unify(l, r, loc, param_name),
(sub, Type::Structural(sup)) => {
let sub_fields = self.fields(sub);
for (sup_field, sup_ty) in self.fields(sup) {