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

@ -9,7 +9,7 @@ use erg_common::{fmt_vec, log};
use crate::ty::constructors::*;
use crate::ty::free::{CanbeFree, Constraint, Free, HasLevel};
use crate::ty::typaram::TyParam;
use crate::ty::typaram::{TyParam, TyParamLambda};
use crate::ty::value::ValueObj;
use crate::ty::{HasType, Predicate, SubrType, Type};
@ -69,6 +69,33 @@ impl Context {
.map(|(field, tp)| (field, self.generalize_tp(tp, variance, uninit)))
.collect(),
),
TyParam::Lambda(lambda) => {
let nd_params = lambda
.nd_params
.into_iter()
.map(|pt| pt.map_type(|t| self.generalize_t_inner(t, variance, uninit)))
.collect::<Vec<_>>();
let var_params = lambda
.var_params
.map(|pt| pt.map_type(|t| self.generalize_t_inner(t, variance, uninit)));
let d_params = lambda
.d_params
.into_iter()
.map(|pt| pt.map_type(|t| self.generalize_t_inner(t, variance, uninit)))
.collect::<Vec<_>>();
let body = lambda
.body
.into_iter()
.map(|tp| self.generalize_tp(tp, variance, uninit))
.collect();
TyParam::Lambda(TyParamLambda::new(
lambda.const_,
nd_params,
var_params,
d_params,
body,
))
}
TyParam::FreeVar(_) => free,
TyParam::Proj { obj, attr } => {
let obj = self.generalize_tp(*obj, variance, uninit);
@ -389,6 +416,34 @@ impl Context {
}
Ok(TyParam::Record(new_rec))
}
TyParam::Lambda(lambda) => {
let nd_params = lambda
.nd_params
.into_iter()
.map(|pt| pt.try_map_type(|t| self.deref_tyvar(t, variance, qnames, loc)))
.collect::<TyCheckResult<_>>()?;
let var_params = lambda
.var_params
.map(|pt| pt.try_map_type(|t| self.deref_tyvar(t, variance, qnames, loc)))
.transpose()?;
let d_params = lambda
.d_params
.into_iter()
.map(|pt| pt.try_map_type(|t| self.deref_tyvar(t, variance, qnames, loc)))
.collect::<TyCheckResult<_>>()?;
let body = lambda
.body
.into_iter()
.map(|tp| self.deref_tp(tp, variance, qnames, loc))
.collect::<TyCheckResult<Vec<_>>>()?;
Ok(TyParam::Lambda(TyParamLambda::new(
lambda.const_,
nd_params,
var_params,
d_params,
body,
)))
}
TyParam::Proj { obj, attr } => {
let obj = self.deref_tp(*obj, variance, qnames, loc)?;
Ok(TyParam::Proj {