mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-03 18:29:00 +00:00
fix: infinite recursion
This commit is contained in:
parent
2ac004b51e
commit
3ed863cef6
3 changed files with 31 additions and 28 deletions
|
@ -400,6 +400,26 @@ impl Context {
|
|||
}
|
||||
}
|
||||
},
|
||||
(_, Proj { .. }) => {
|
||||
if let Some(cands) = self.get_candidates(rhs) {
|
||||
for cand in cands.into_iter() {
|
||||
if self.supertype_of(lhs, &cand) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
(Proj { .. }, _) => {
|
||||
if let Some(cands) = self.get_candidates(lhs) {
|
||||
for cand in cands.into_iter() {
|
||||
if self.supertype_of(&cand, rhs) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
// true if it can be a supertype, false if it cannot (due to type constraints)
|
||||
// No type constraints are imposed here, as subsequent type decisions are made according to the possibilities
|
||||
// ?P(<: Mul ?P) :> Int
|
||||
|
@ -454,7 +474,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
},
|
||||
(Type::Record(lhs), Type::Record(rhs)) => {
|
||||
(Record(lhs), Record(rhs)) => {
|
||||
for (l_k, l_t) in lhs.iter() {
|
||||
if let Some((r_k, r_t)) = rhs.get_key_value(l_k) {
|
||||
// public <: private (private fields cannot be public)
|
||||
|
@ -678,26 +698,6 @@ impl Context {
|
|||
self.poly_supertype_of(lhs, lparams, rparams)
|
||||
}
|
||||
}
|
||||
(Proj { .. }, _) => {
|
||||
if let Some(cands) = self.get_candidates(lhs) {
|
||||
for cand in cands.into_iter() {
|
||||
if self.supertype_of(&cand, rhs) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
(_, Proj { .. }) => {
|
||||
if let Some(cands) = self.get_candidates(rhs) {
|
||||
for cand in cands.into_iter() {
|
||||
if self.supertype_of(lhs, &cand) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
(Structural(l), Structural(r)) => self.structural_supertype_of(l, r),
|
||||
// TODO: If visibility does not match, it should be reported as a cause of an error
|
||||
(Structural(l), r) => {
|
||||
|
|
|
@ -138,8 +138,8 @@ impl Generalizer {
|
|||
FreeVar(fv) if fv.is_generalized() => Type::FreeVar(fv),
|
||||
// TODO: Polymorphic generalization
|
||||
FreeVar(fv) if fv.level().unwrap() > self.level => {
|
||||
fv.generalize();
|
||||
if uninit {
|
||||
fv.generalize();
|
||||
return Type::FreeVar(fv);
|
||||
}
|
||||
if let Some((sub, sup)) = fv.get_subsup() {
|
||||
|
@ -162,13 +162,11 @@ impl Generalizer {
|
|||
self.generalize_t(sub, uninit)
|
||||
} else {
|
||||
fv.update_constraint(self.generalize_constraint(&fv), true);
|
||||
fv.generalize();
|
||||
Type::FreeVar(fv)
|
||||
}
|
||||
} else {
|
||||
// ?S(: Str) => 'S
|
||||
fv.update_constraint(self.generalize_constraint(&fv), true);
|
||||
fv.generalize();
|
||||
Type::FreeVar(fv)
|
||||
}
|
||||
}
|
||||
|
@ -515,9 +513,14 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
Type::FreeVar(fv) if fv.constraint_is_sandwiched() => {
|
||||
let (sub_t, super_t) = fv.get_subsup().unwrap();
|
||||
if self.ctx.level <= fv.level().unwrap() {
|
||||
// if fv == ?T(<: Int, :> Add(?T)), deref_tyvar(super_t) will cause infinite loop
|
||||
// so we need to force linking
|
||||
fv.forced_undoable_link(&sub_t);
|
||||
// we need to force linking to avoid infinite loop
|
||||
// e.g. fv == ?T(<: Int, :> Add(?T))
|
||||
// fv == ?T(:> ?T.Output, <: Add(Int))
|
||||
if sub_t.contains(&Type::FreeVar(fv.clone())) {
|
||||
fv.forced_undoable_link(&super_t);
|
||||
} else {
|
||||
fv.forced_undoable_link(&sub_t);
|
||||
}
|
||||
let res = self.validate_subsup(sub_t, super_t);
|
||||
fv.undo();
|
||||
match res {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue