mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 10:49:54 +00:00
chore: set recursion call limit to sub_unify
This commit is contained in:
parent
dc7565cb26
commit
bb0f4d20fc
2 changed files with 40 additions and 0 deletions
|
@ -2,6 +2,7 @@
|
|||
use std::iter::repeat;
|
||||
use std::mem;
|
||||
use std::option::Option;
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use erg_common::consts::DEBUG_MODE;
|
||||
use erg_common::fresh::FRESH_GEN;
|
||||
|
@ -33,6 +34,7 @@ pub struct Unifier<'c, 'l, 'u, L: Locational> {
|
|||
loc: &'l L,
|
||||
undoable: Option<&'u UndoableLinkedList>,
|
||||
change_generalized: bool,
|
||||
recursion_limit: AtomicUsize,
|
||||
param_name: Option<Str>,
|
||||
}
|
||||
|
||||
|
@ -49,6 +51,7 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
|
|||
loc,
|
||||
undoable,
|
||||
change_generalized,
|
||||
recursion_limit: AtomicUsize::new(128),
|
||||
param_name,
|
||||
}
|
||||
}
|
||||
|
@ -945,6 +948,18 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
|
|||
/// ```
|
||||
fn sub_unify(&self, maybe_sub: &Type, maybe_sup: &Type) -> TyCheckResult<()> {
|
||||
log!(info "trying {}sub_unify:\nmaybe_sub: {maybe_sub}\nmaybe_sup: {maybe_sup}", self.undoable.map_or("", |_| "undoable_"));
|
||||
self.recursion_limit.fetch_sub(1, Ordering::SeqCst);
|
||||
if self.recursion_limit.load(Ordering::SeqCst) == 0 {
|
||||
log!(err "recursion limit exceeded: {maybe_sub} / {maybe_sup}");
|
||||
return Err(TyCheckError::recursion_limit(
|
||||
self.ctx.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
self.loc.loc(),
|
||||
fn_name!(),
|
||||
line!(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
// In this case, there is no new information to be gained
|
||||
// この場合、特に新しく得られる情報はない
|
||||
if maybe_sub == &Type::Never || maybe_sup == &Type::Obj || maybe_sup.addr_eq(maybe_sub) {
|
||||
|
|
|
@ -53,6 +53,31 @@ impl TyCheckError {
|
|||
)
|
||||
}
|
||||
|
||||
pub fn recursion_limit(
|
||||
input: Input,
|
||||
errno: usize,
|
||||
loc: Location,
|
||||
fn_name: &str,
|
||||
line: u32,
|
||||
) -> Self {
|
||||
Self::new(
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::only_loc(loc)],
|
||||
switch_lang!(
|
||||
"japanese" => format!("コンパイラ内部の再帰呼び出し回数が上限に達しました。これはErg compilerのバグです、開発者に報告して下さい ({URL})\n\n{fn_name}:{line}より発生"),
|
||||
"simplified_chinese" => format!("编译器内部的递归调用次数已达到上限。这是Erg编译器的错误,请报告给{URL}\n\n原因来自: {fn_name}:{line}"),
|
||||
"traditional_chinese" => format!("編譯器內部的遞歸調用次數已達到上限。這是Erg編譯器的錯誤,請報告給{URL}\n\n原因來自: {fn_name}:{line}"),
|
||||
"english" => format!("the number of recursive calls in the compiler has reached the limit. This is a bug of the Erg compiler, please report it to {URL}\n\ncaused from: {fn_name}:{line}"),
|
||||
),
|
||||
errno,
|
||||
CompilerSystemError,
|
||||
loc,
|
||||
),
|
||||
input,
|
||||
"".to_string(),
|
||||
)
|
||||
}
|
||||
|
||||
pub fn no_type_spec_error(
|
||||
input: Input,
|
||||
errno: usize,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue