diff --git a/crates/erg_compiler/context/initialize/classes.rs b/crates/erg_compiler/context/initialize/classes.rs index 4b6f49af7..b08c00309 100644 --- a/crates/erg_compiler/context/initialize/classes.rs +++ b/crates/erg_compiler/context/initialize/classes.rs @@ -896,6 +896,9 @@ impl Context { str_.register_py_builtin(OP_GE, fn1_met(Str, Str, Bool), Some(OP_GE), 0); str_.register_py_builtin(OP_LT, fn1_met(Str, Str, Bool), Some(OP_LT), 0); str_.register_py_builtin(OP_LE, fn1_met(Str, Str, Bool), Some(OP_LE), 0); + if PYTHON_MODE { + str_.register_py_builtin(OP_MOD, fn1_met(Str, Obj, Str), Some(OP_MOD), 0); + } str_.register_trait(self, mono(ORD)).unwrap(); str_.register_trait(self, mono(PATH_LIKE)).unwrap(); let t_s_replace = fn_met( diff --git a/crates/erg_compiler/context/inquire.rs b/crates/erg_compiler/context/inquire.rs index 5f4b57665..bf9268d6e 100644 --- a/crates/erg_compiler/context/inquire.rs +++ b/crates/erg_compiler/context/inquire.rs @@ -1442,9 +1442,9 @@ impl Context { let coerced = self .coerce(obj.t(), &()) .map_err(|mut errs| errs.remove(0))?; - if &coerced != obj.ref_t() { + if &coerced != obj.ref_t() && obj.ref_t().as_free().is_some() { let hash = get_hash(obj.ref_t()); - obj.ref_t().destructive_link(&coerced); + obj.ref_t().destructive_link(&coerced); // obj.ref_t().coerce(None); if get_hash(obj.ref_t()) != hash { return self .search_method_info(obj, attr_name, pos_args, kw_args, input, namespace); @@ -1587,9 +1587,10 @@ impl Context { let coerced = self .coerce(obj.t(), &()) .map_err(|mut errs| errs.remove(0))?; - if &coerced != obj.ref_t() { + // REVIEW: if obj.ref_t() is not a free-var but contains free-vars + if &coerced != obj.ref_t() && obj.ref_t().as_free().is_some() { let hash = get_hash(obj.ref_t()); - obj.ref_t().destructive_link(&coerced); + obj.ref_t().destructive_link(&coerced); // obj.ref_t().coerce(None); if get_hash(obj.ref_t()) != hash { return self.search_method_info_without_args(obj, attr_name, input, namespace); } diff --git a/crates/erg_compiler/lower.rs b/crates/erg_compiler/lower.rs index 5d1ca603e..c4af5727f 100644 --- a/crates/erg_compiler/lower.rs +++ b/crates/erg_compiler/lower.rs @@ -33,7 +33,7 @@ use crate::artifact::{BuildRunnable, Buildable, CompleteArtifact, IncompleteArti use crate::build_package::CheckStatus; use crate::module::SharedCompilerResource; use crate::ty::constructors::{ - free_var, func, guard, list_t, mono, poly, proc, refinement, set_t, singleton, ty_tp, + free_var, from_str, func, guard, list_t, mono, poly, proc, refinement, set_t, singleton, ty_tp, unsized_list_t, v_enum, }; use crate::ty::free::Constraint; @@ -3074,7 +3074,7 @@ impl GenericASTLowerer { line!() as usize, method_name.inspect(), method_name.loc(), - &mono(&sup.name), // TODO: get super type + &from_str(&sup.name), // TODO: get super type self.module.context.caused_by(), )); } diff --git a/crates/erg_compiler/ty/constructors.rs b/crates/erg_compiler/ty/constructors.rs index 8043d291e..8554992c5 100644 --- a/crates/erg_compiler/ty/constructors.rs +++ b/crates/erg_compiler/ty/constructors.rs @@ -518,6 +518,34 @@ pub fn mono>(name: S) -> Type { Type::Mono(name) } +pub fn from_str(name: impl Into) -> Type { + let name = name.into(); + match &name[..] { + "Obj" => Type::Obj, + "Int" => Type::Int, + "Nat" => Type::Nat, + "Ratio" => Type::Ratio, + "Float" => Type::Float, + "Complex" => Type::Complex, + "Bool" => Type::Bool, + "Str" => Type::Str, + "NoneType" => Type::NoneType, + "Code" => Type::Code, + "Frame" => Type::Frame, + "Error" => Type::Error, + "Inf" => Type::Inf, + "NegInf" => Type::NegInf, + "Type" => Type::Type, + "ClassType" => Type::ClassType, + "TraitType" => Type::TraitType, + "Patch" => Type::Patch, + "NotImplementedType" => Type::NotImplementedType, + "Ellipsis" => Type::Ellipsis, + "Never" => Type::Never, + _ => Type::Mono(name), + } +} + #[inline] pub fn poly>(name: S, params: Vec) -> Type { Type::Poly { diff --git a/crates/erg_compiler/ty/mod.rs b/crates/erg_compiler/ty/mod.rs index 6bcfd1639..bd13ed821 100644 --- a/crates/erg_compiler/ty/mod.rs +++ b/crates/erg_compiler/ty/mod.rs @@ -886,6 +886,25 @@ impl SubrType { } self } + + pub fn destructive_coerce(&self) { + for nd in self.non_default_params.iter() { + nd.typ().destructive_coerce(); + } + if let Some(var) = self.var_params.as_ref() { + var.typ().destructive_coerce(); + } + for d in self.default_params.iter() { + d.typ().destructive_coerce(); + if let Some(default) = d.default_typ() { + default.destructive_coerce(); + } + } + if let Some(kw_var) = self.kw_var_params.as_ref() { + kw_var.typ().destructive_coerce(); + } + self.return_t.destructive_coerce(); + } } #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -3307,6 +3326,8 @@ impl Type { } } } + Type::Subr(subr) => subr.destructive_coerce(), + // TODO: _ => {} } }