diff --git a/crates/erg_common/shared.rs b/crates/erg_common/shared.rs index d0b4e9e2d..215271b10 100644 --- a/crates/erg_common/shared.rs +++ b/crates/erg_common/shared.rs @@ -144,6 +144,8 @@ impl Shared { #[track_caller] pub fn borrow(&self) -> RwLockReadGuard<'_, T> { self.wait_until_unlocked(); + #[cfg(any(feature = "backtrace", feature = "debug"))] + let first_catcher = self.data.try_write_for(GET_TIMEOUT).is_some(); let res = self.data.try_read_for(GET_TIMEOUT).unwrap_or_else(|| { #[cfg(any(feature = "backtrace", feature = "debug"))] { @@ -159,7 +161,7 @@ impl Shared { } }); #[cfg(any(feature = "backtrace", feature = "debug"))] - { + if first_catcher { *self.last_borrowed_at.try_write_for(GET_TIMEOUT).unwrap() = BorrowInfo::new(Some(std::panic::Location::caller())); } @@ -187,8 +189,6 @@ impl Shared { #[cfg(any(feature = "backtrace", feature = "debug"))] { let caller = std::panic::Location::caller(); - *self.last_borrowed_at.try_write_for(SET_TIMEOUT).unwrap() = - BorrowInfo::new(Some(caller)); *self .last_mut_borrowed_at .try_write_for(SET_TIMEOUT) diff --git a/crates/erg_compiler/context/compare.rs b/crates/erg_compiler/context/compare.rs index dea8f8c4d..8e3dc2908 100644 --- a/crates/erg_compiler/context/compare.rs +++ b/crates/erg_compiler/context/compare.rs @@ -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) diff --git a/crates/erg_compiler/context/inquire.rs b/crates/erg_compiler/context/inquire.rs index a36dfc7ff..70ea0c5be 100644 --- a/crates/erg_compiler/context/inquire.rs +++ b/crates/erg_compiler/context/inquire.rs @@ -1294,9 +1294,11 @@ impl Context { }) .collect::>(); 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); diff --git a/crates/erg_compiler/ty/free.rs b/crates/erg_compiler/ty/free.rs index 36edcd83f..7a68a03dc 100644 --- a/crates/erg_compiler/ty/free.rs +++ b/crates/erg_compiler/ty/free.rs @@ -739,6 +739,9 @@ impl Free { pub fn forced_as_ref(&self) -> &FreeKind { unsafe { self.as_ptr().as_ref() }.unwrap() } + pub fn forced_as_mut(&mut self) -> &mut FreeKind { + unsafe { self.as_ptr().as_mut() }.unwrap() + } } impl Free { diff --git a/crates/erg_compiler/ty/mod.rs b/crates/erg_compiler/ty/mod.rs index 5c798dd79..f11b66679 100644 --- a/crates/erg_compiler/ty/mod.rs +++ b/crates/erg_compiler/ty/mod.rs @@ -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> { 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)