fix: closure bug

This commit is contained in:
Shunsuke Shibayama 2023-12-28 23:31:09 +09:00
parent a128719cbd
commit b5f5876631
4 changed files with 36 additions and 21 deletions

View file

@ -607,7 +607,7 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
match res {
Ok(ty) => {
// TODO: T(:> Nat <: Int) -> T(:> Nat, <: Int) ==> Int -> Nat
// fv.link(&ty);
// Type::FreeVar(fv).destructive_link(&ty);
Ok(ty)
}
Err(errs) => {
@ -842,16 +842,8 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
.check_trait_impl(&sub_t, &super_t, self.qnames, self.loc)?;
}
let is_subtype = self.ctx.subtype_of(&sub_t, &super_t);
let sub_t = if DEBUG_MODE {
sub_t
} else {
self.deref_tyvar(sub_t)?
};
let super_t = if DEBUG_MODE {
super_t
} else {
self.deref_tyvar(super_t)?
};
let sub_t = self.deref_tyvar(sub_t)?;
let super_t = self.deref_tyvar(super_t)?;
if sub_t == super_t {
Ok(sub_t)
} else if is_subtype {
@ -1396,6 +1388,7 @@ impl Context {
Type::Or(l, r) => {
let l = self.squash_tyvar(*l);
let r = self.squash_tyvar(*r);
// REVIEW:
if l.is_unnamed_unbound_var() && r.is_unnamed_unbound_var() {
match (self.subtype_of(&l, &r), self.subtype_of(&r, &l)) {
(true, true) | (true, false) => {
@ -1409,6 +1402,13 @@ impl Context {
}
self.union(&l, &r)
}
Type::FreeVar(ref fv) if fv.constraint_is_sandwiched() => {
let (sub_t, super_t) = fv.get_subsup().unwrap();
let sub_t = self.squash_tyvar(sub_t);
let super_t = self.squash_tyvar(super_t);
typ.update_tyvar(sub_t, super_t, None, false);
typ
}
other => other,
}
}

View file

@ -1380,7 +1380,7 @@ impl Context {
&self.shared().promises
}
pub fn current_caller(&self) -> Option<ControlKind> {
pub fn current_control_flow(&self) -> Option<ControlKind> {
self.higher_order_caller
.last()
.and_then(|name| ControlKind::try_from(&name[..]).ok())
@ -1395,11 +1395,13 @@ impl Context {
None
}
pub fn current_function_ctx(&self) -> Option<&Context> {
if self.kind.is_subr() {
/// Context of the function that actually creates the scope.
/// Control flow function blocks do not create actual scopes.
pub fn current_true_function_ctx(&self) -> Option<&Context> {
if self.kind.is_subr() && self.current_control_flow().is_none() {
Some(self)
} else if let Some(outer) = self.get_outer() {
outer.current_function_ctx()
outer.current_true_function_ctx()
} else {
None
}