fix: sub unification bug

This commit is contained in:
Shunsuke Shibayama 2024-02-16 17:50:57 +09:00
parent fae18d3c15
commit 5f652f3dd5
2 changed files with 14 additions and 2 deletions

View file

@ -177,6 +177,14 @@ impl<'c> Substituter<'c> {
stps.swap(0, 1);
}
} else if qt.qual_name() != st.qual_name() || qtps.len() != stps.len() {
// e.g. qt: Iterable(T), st: Vec(<: Iterable(Int))
/*if let Some(st_sups) = ctx.get_nominal_super_type_ctxs(st) {
for sup in st_sups {
if sup.typ.qual_name() == qt.qual_name() {
return Self::substitute_typarams(ctx, qt, &sup.typ);
}
}
}*/
if let Some(inner) = st.ref_inner().or_else(|| st.ref_mut_inner()) {
return Self::substitute_typarams(ctx, qt, &inner);
} else if let Some(sub) = st.get_sub() {

View file

@ -1544,7 +1544,9 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
Ok(())
}
// TODO: Current implementation is inefficient because coercion is performed twice with `subtype_of` in `sub_unify`
/// e.g. `maybe_sub: Vec, maybe_sup: Iterable T (Vec <: Iterable Int, T <: Int)`
///
/// TODO: Current implementation is inefficient because coercion is performed twice with `subtype_of` in `sub_unify`
fn nominal_sub_unify(
&self,
maybe_sub: &Type,
@ -1573,7 +1575,9 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
compatibles.push(&sub_ctx.typ);
}
for sup_ty in sups {
if self.ctx.subtype_of(sup_ty, maybe_sup) {
if sup_ty.qual_name() == maybe_sup.qual_name()
&& self.ctx.subtype_of(sup_ty, maybe_sup)
{
if !compatibles.is_empty() {
let mut idx = compatibles.len();
for (i, comp) in compatibles.iter().enumerate() {