fix: subtyping bug

This commit is contained in:
Shunsuke Shibayama 2023-06-10 11:16:30 +09:00
parent 57e5a50e1b
commit 0840d9bf60
11 changed files with 120 additions and 81 deletions

View file

@ -1645,6 +1645,9 @@ impl Context {
let qtps = qt.typarams();
let stps = st.typarams();
if qt.qual_name() != st.qual_name() || qtps.len() != stps.len() {
if let Some(sub) = st.get_sub() {
return self.substitute_typarams(qt, &sub);
}
log!(err "{qt} / {st}");
log!(err "[{}] [{}]", erg_common::fmt_vec(&qtps), erg_common::fmt_vec(&stps));
return Ok(()); // TODO: e.g. Sub(Int) / Eq and Sub(?T)
@ -1673,7 +1676,7 @@ impl Context {
match qtp {
TyParam::FreeVar(ref fv) if fv.is_generalized() => {
if !stp.is_unbound_var() || !stp.is_generalized() {
fv.undoable_link(&stp);
qtp.undoable_link(&stp);
}
if let Err(errs) = self.sub_unify_tp(&stp, &qtp, None, &(), false) {
log!(err "{errs}");
@ -1696,16 +1699,16 @@ impl Context {
&tp.to_string(),
)
})?;
if qt.is_generalized() {
if let Ok(qt) = <&FreeTyVar>::try_from(&qt) {
if !st.is_unbound_var() || !st.is_generalized() {
qt.undoable_link(&st);
}
}
if qt.is_generalized() && qt.is_free_var() && (!st.is_unbound_var() || !st.is_generalized())
{
qt.undoable_link(&st);
}
if !st.is_unbound_var() || !st.is_generalized() {
self.substitute_typarams(&qt, &st)?;
}
if st.has_no_unbound_var() && qt.has_no_unbound_var() {
return Ok(());
}
if let Err(errs) = self.sub_unify(&st, &qt, &(), None) {
log!(err "{errs}");
}
@ -1716,7 +1719,7 @@ impl Context {
match qtp {
TyParam::FreeVar(ref fv) if fv.is_undoable_linked() => {
if !stp.is_unbound_var() || !stp.is_generalized() {
fv.undoable_link(&stp);
qtp.undoable_link(&stp);
}
if let Err(errs) = self.sub_unify_tp(&stp, &qtp, None, &(), false) {
log!(err "{errs}");
@ -1739,12 +1742,8 @@ impl Context {
&tp.to_string(),
)
})?;
if qt.has_undoable_linked_var() {
if let Ok(qt) = <&FreeTyVar>::try_from(&qt) {
if !st.is_unbound_var() || !st.is_generalized() {
qt.undoable_link(&st);
}
}
if qt.has_undoable_linked_var() && (!st.is_unbound_var() || !st.is_generalized()) {
qt.undoable_link(&st);
}
if !st.is_unbound_var() || !st.is_generalized() {
self.overwrite_typarams(&qt, &st)?;