fix: sub unification bug

This commit is contained in:
Shunsuke Shibayama 2024-02-16 18:31:49 +09:00
parent 5f652f3dd5
commit 67a9f88f61
3 changed files with 14 additions and 9 deletions

View file

@ -2438,7 +2438,7 @@ impl Context {
}
}
fn detach_tp(&self, tp: TyParam, tv_cache: &mut TyVarCache) -> TyParam {
pub(crate) fn detach_tp(&self, tp: TyParam, tv_cache: &mut TyVarCache) -> TyParam {
match tp {
TyParam::FreeVar(fv) if fv.is_linked() => {
let tp = fv.crack().clone();

View file

@ -167,6 +167,11 @@ impl TyVarCache {
if name.inspect() == "_" {
return Ok(());
}
if self.var_infos.get(name).is_none() {
let vi = VarInfo::type_var(Type::Type, ctx.absolutize(name.loc()), ctx.name.clone());
ctx.index().register(name.inspect().clone(), &vi);
self.var_infos.insert(name.clone(), vi);
}
if let Some(inst) = self.tyvar_instances.get(name) {
self.update_tyvar(inst, tv, ctx);
} else if let Some(inst) = self.typaram_instances.get(name) {
@ -179,9 +184,6 @@ impl TyVarCache {
}
} else {
self.tyvar_instances.insert(name.clone(), tv.clone());
let vi = VarInfo::type_var(Type::Type, ctx.absolutize(name.loc()), ctx.name.clone());
ctx.index().register(name.inspect().clone(), &vi);
self.var_infos.insert(name.clone(), vi);
}
Ok(())
}
@ -260,6 +262,12 @@ impl TyVarCache {
)
.into());
}
if self.var_infos.get(name).is_none() {
let t = ctx.get_tp_t(tp).unwrap_or(Type::Obj);
let vi = VarInfo::type_var(t, ctx.absolutize(name.loc()), ctx.name.clone());
ctx.index().register(name.inspect().clone(), &vi);
self.var_infos.insert(name.clone(), vi);
}
// FIXME:
if let Some(inst) = self.typaram_instances.get(name) {
self.update_typaram(inst, tp, ctx);
@ -270,10 +278,6 @@ impl TyVarCache {
unreachable!("{name} / {inst} / {tp}");
}
} else {
let t = ctx.get_tp_t(tp).unwrap_or(Type::Obj);
let vi = VarInfo::type_var(t, ctx.absolutize(name.loc()), ctx.name.clone());
ctx.index().register(name.inspect().clone(), &vi);
self.var_infos.insert(name.clone(), vi);
self.typaram_instances.insert(name.clone(), tp.clone());
}
Ok(())

View file

@ -1519,6 +1519,7 @@ impl Context {
if let Some(ctx) = self.get_type_ctx(ident.inspect()) {
let arg_ts = ctx.params.iter().map(|(_, vi)| &vi.t);
for ((tp, arg), arg_t) in ctx.typ.typarams().iter().zip(args.pos_args()).zip(arg_ts) {
let tp = self.detach_tp(tp.clone(), &mut tv_ctx);
if let ast::Expr::Accessor(ast::Accessor::Ident(ident)) = &arg.expr {
if self.subtype_of(arg_t, &Type::Type) {
if let Ok(tv) = self.convert_tp_into_type(tp.clone()) {
@ -1526,7 +1527,7 @@ impl Context {
continue;
}
}
let _ = tv_ctx.push_or_init_typaram(&ident.name, tp, self);
let _ = tv_ctx.push_or_init_typaram(&ident.name, &tp, self);
}
}
}