From c31e93052b3d3390d53340590e78b24e786a4efb Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Thu, 25 May 2023 18:03:43 +0900 Subject: [PATCH] fix: infinite recursion bugs --- crates/erg_compiler/context/eval.rs | 4 ++- crates/erg_compiler/context/inquire.rs | 35 +++++++++++++++----------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/crates/erg_compiler/context/eval.rs b/crates/erg_compiler/context/eval.rs index 4a793f4a4..0a5c3099c 100644 --- a/crates/erg_compiler/context/eval.rs +++ b/crates/erg_compiler/context/eval.rs @@ -1337,6 +1337,8 @@ impl Context { } TyParam::FreeVar(fv) if fv.is_linked() => self.convert_tp_into_type(fv.crack().clone()), TyParam::Type(t) => Ok(t.as_ref().clone()), + TyParam::Mono(name) => Ok(Type::Mono(name)), + // TyParam::Erased(_t) => Ok(Type::Obj), TyParam::Value(v) => self.convert_value_into_type(v).map_err(TyParam::Value), // TODO: Dict, Set other => Err(other), @@ -1672,7 +1674,7 @@ impl Context { line!() as usize, ().loc(), self.caused_by(), - &tp.qual_name().unwrap_or("_".into()), + &tp.to_string(), ) })?; if qt.is_generalized() { diff --git a/crates/erg_compiler/context/inquire.rs b/crates/erg_compiler/context/inquire.rs index df1e18576..7a71f0aa6 100644 --- a/crates/erg_compiler/context/inquire.rs +++ b/crates/erg_compiler/context/inquire.rs @@ -4,14 +4,15 @@ use std::path::{Path, PathBuf}; use erg_common::config::Input; use erg_common::consts::{ERG_MODE, PYTHON_MODE}; -use erg_common::dict; use erg_common::error::{ErrorCore, Location, SubMessage}; use erg_common::levenshtein; use erg_common::set::Set; use erg_common::traits::{Locational, NoTypeDisplay, Stream}; use erg_common::triple::Triple; use erg_common::Str; -use erg_common::{fmt_option, fmt_slice, log, option_enum_unwrap, set, switch_lang}; +use erg_common::{ + dict, fmt_option, fmt_slice, get_hash, log, option_enum_unwrap, set, switch_lang, +}; use erg_parser::ast::{self, Identifier, VarName}; use erg_parser::token::Token; @@ -1024,20 +1025,23 @@ impl Context { let coerced = self .coerce(obj.t(), &()) .map_err(|mut errs| errs.remove(0))?; - if &coerced == obj.ref_t() { - Err(TyCheckError::no_attr_error( - self.cfg.input.clone(), - line!() as usize, - attr_name.loc(), - namespace.name.to_string(), - obj.ref_t(), - attr_name.inspect(), - self.get_similar_attr(obj.ref_t(), attr_name.inspect()), - )) - } else { + if &coerced != obj.ref_t() { + let hash = get_hash(obj.ref_t()); obj.ref_t().coerce(); - self.search_method_info(obj, attr_name, pos_args, kw_args, input, namespace) + if get_hash(obj.ref_t()) != hash { + return self + .search_method_info(obj, attr_name, pos_args, kw_args, input, namespace); + } } + Err(TyCheckError::no_attr_error( + self.cfg.input.clone(), + line!() as usize, + attr_name.loc(), + namespace.name.to_string(), + obj.ref_t(), + attr_name.inspect(), + self.get_similar_attr(obj.ref_t(), attr_name.inspect()), + )) } fn validate_visibility( @@ -1263,12 +1267,13 @@ impl Context { return Err(self.not_callable_error(obj, attr_name, instance, None)); } if sub != Never { + let hash = get_hash(instance); instance.coerce(); if instance.is_quantified_subr() { let instance = self.instantiate(instance.clone(), obj)?; self.substitute_call(obj, attr_name, &instance, pos_args, kw_args)?; return Ok(SubstituteResult::Coerced(instance)); - } else { + } else if get_hash(instance) != hash { return self .substitute_call(obj, attr_name, instance, pos_args, kw_args); }