Skip to content

Commit

Permalink
chore: set recursion call limit to sub_unify
Browse files Browse the repository at this point in the history
  • Loading branch information
mtshiba committed May 17, 2024
1 parent dc7565c commit bb0f4d2
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
15 changes: 15 additions & 0 deletions crates/erg_compiler/context/unify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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>,
}

Expand All @@ -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,
}
}
Expand Down Expand Up @@ -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) {
Expand Down
25 changes: 25 additions & 0 deletions crates/erg_compiler/error/tycheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit bb0f4d2

Please sign in to comment.