fix: Structural types instantiation/generalization

This commit is contained in:
Shunsuke Shibayama 2023-02-23 02:35:05 +09:00
parent c9dda183ab
commit 2c3a27ed4b
8 changed files with 134 additions and 37 deletions

View file

@ -64,6 +64,11 @@ impl Context {
})
.collect(),
),
TyParam::Record(rec) => TyParam::Record(
rec.into_iter()
.map(|(field, tp)| (field, self.generalize_tp(tp, variance, uninit)))
.collect(),
),
TyParam::FreeVar(_) => free,
TyParam::Proj { obj, attr } => {
let obj = self.generalize_tp(*obj, variance, uninit);
@ -185,6 +190,13 @@ impl Context {
return_t,
)
}
Record(rec) => {
let fields = rec
.into_iter()
.map(|(name, t)| (name, self.generalize_t_inner(t, variance, uninit)))
.collect();
Type::Record(fields)
}
Callable { .. } => todo!(),
Ref(t) => ref_(self.generalize_t_inner(*t, variance, uninit)),
RefMut { before, after } => {
@ -235,6 +247,9 @@ impl Context {
or(l, r)
}
Not(l) => not(self.generalize_t_inner(*l, variance, uninit)),
Structural(t) => self
.generalize_t_inner(*t, variance, uninit)
.structuralize(),
// REVIEW: その他何でもそのまま通していいのか?
other => other,
}
@ -367,6 +382,13 @@ impl Context {
}
Ok(TyParam::Set(new_set))
}
TyParam::Record(rec) => {
let mut new_rec = dict! {};
for (field, tp) in rec.into_iter() {
new_rec.insert(field, self.deref_tp(tp, variance, qnames, loc)?);
}
Ok(TyParam::Record(new_rec))
}
TyParam::Proj { obj, attr } => {
let obj = self.deref_tp(*obj, variance, qnames, loc)?;
Ok(TyParam::Proj {
@ -686,6 +708,10 @@ impl Context {
}
self.eval_proj_call(lhs, attr_name, new_args, self.level, loc)
}
Type::Structural(t) => {
let t = self.deref_tyvar(*t, variance, qnames, loc)?;
Ok(t.structuralize())
}
t => Ok(t),
}
}