mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 02:39:20 +00:00
fix: recursion bugs of structural types
This commit is contained in:
parent
948a14b1af
commit
beee3b8800
5 changed files with 27 additions and 5 deletions
|
@ -7,7 +7,7 @@ use erg_common::dict::Dict;
|
|||
use erg_common::set::Set;
|
||||
use erg_common::style::colors::DEBUG_ERROR;
|
||||
use erg_common::traits::StructuralEq;
|
||||
use erg_common::{assume_unreachable, log};
|
||||
use erg_common::{assume_unreachable, log, set_recursion_limit};
|
||||
use erg_common::{Str, Triple};
|
||||
|
||||
use crate::context::eval::UndoableLinkedList;
|
||||
|
@ -355,6 +355,7 @@ impl Context {
|
|||
/// 単一化、評価等はここでは行わない、スーパータイプになる **可能性があるか** だけ判定する
|
||||
/// ので、lhsが(未連携)型変数の場合は単一化せずにtrueを返す
|
||||
pub(crate) fn structural_supertype_of(&self, lhs: &Type, rhs: &Type) -> bool {
|
||||
set_recursion_limit!(false, 128);
|
||||
match (lhs, rhs) {
|
||||
// Proc :> Func if params are compatible
|
||||
// * default params can be omitted (e.g. (Int, x := Int) -> Int <: (Int) -> Int)
|
||||
|
|
|
@ -1294,9 +1294,11 @@ impl Context {
|
|||
})
|
||||
.collect::<Vec<_>>();
|
||||
let return_t = free_var(self.level, Constraint::new_type_of(Type));
|
||||
let subr_t = fn_met(obj.t(), nd_params, None, d_params, None, return_t);
|
||||
let mut subr_t = fn_met(obj.t(), nd_params, None, d_params, None, return_t);
|
||||
if let Some(fv) = obj.ref_t().as_free() {
|
||||
if let Some((_sub, sup)) = fv.get_subsup() {
|
||||
// avoid recursion
|
||||
*subr_t.mut_self_t().unwrap() = Never;
|
||||
let vis = self
|
||||
.instantiate_vis_modifier(&attr_name.vis)
|
||||
.unwrap_or(VisibilityModifier::Public);
|
||||
|
|
|
@ -739,6 +739,9 @@ impl<T: Send + Clone> Free<T> {
|
|||
pub fn forced_as_ref(&self) -> &FreeKind<T> {
|
||||
unsafe { self.as_ptr().as_ref() }.unwrap()
|
||||
}
|
||||
pub fn forced_as_mut(&mut self) -> &mut FreeKind<T> {
|
||||
unsafe { self.as_ptr().as_mut() }.unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Free<Type> {
|
||||
|
|
|
@ -3886,6 +3886,18 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn mut_self_t(&mut self) -> Option<&mut Type> {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => {
|
||||
fv.forced_as_mut().linked_mut().and_then(|t| t.mut_self_t())
|
||||
}
|
||||
Self::Refinement(refine) => refine.t.mut_self_t(),
|
||||
Self::Subr(subr) => subr.mut_self_t(),
|
||||
Self::Quantified(quant) => quant.mut_self_t(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn non_default_params(&self) -> Option<&Vec<ParamTy>> {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => fv
|
||||
|
@ -3999,6 +4011,10 @@ impl Type {
|
|||
|
||||
pub fn mut_return_t(&mut self) -> Option<&mut Type> {
|
||||
match self {
|
||||
Self::FreeVar(fv) if fv.is_linked() => fv
|
||||
.forced_as_mut()
|
||||
.linked_mut()
|
||||
.and_then(|t| t.mut_return_t()),
|
||||
Self::Refinement(refine) => refine.t.mut_return_t(),
|
||||
Self::Subr(SubrType { return_t, .. }) | Self::Callable { return_t, .. } => {
|
||||
Some(return_t)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue