diff --git a/compiler/erg_compiler/context/hint.rs b/compiler/erg_compiler/context/hint.rs index 3e282713..4a121cff 100644 --- a/compiler/erg_compiler/context/hint.rs +++ b/compiler/erg_compiler/context/hint.rs @@ -7,12 +7,15 @@ use crate::context::Context; impl Context { pub(crate) fn get_type_mismatch_hint(&self, expected: &Type, found: &Type) -> Option { let expected = if let Type::FreeVar(fv) = expected { - if fv.is_linked() { fv.crack().clone() } - else { + if fv.is_linked() { + fv.crack().clone() + } else { let (_sub, sup) = fv.crack_bound_types().unwrap(); sup } - } else { expected.clone() }; + } else { + expected.clone() + }; match (&expected.name()[..], &found.name()[..]) { ("Eq", "Float") => Some(Str::ever("Float has no equivalence relation defined. you should use `l - r <= Float.EPSILON` instead of `l == r`.")), _ => None, diff --git a/compiler/erg_compiler/context/inquire.rs b/compiler/erg_compiler/context/inquire.rs index b4786279..e2f28a03 100644 --- a/compiler/erg_compiler/context/inquire.rs +++ b/compiler/erg_compiler/context/inquire.rs @@ -51,6 +51,7 @@ impl Context { ident.inspect(), &spec_t, body_t, + self.get_type_mismatch_hint(&spec_t, body_t), )); } Ok(()) @@ -120,6 +121,7 @@ impl Context { "match", &class("LambdaFunc"), t, + self.get_type_mismatch_hint(&class("LambdaFunc"), t), )); } } @@ -616,6 +618,7 @@ impl Context { &name[..], param_t, arg_t, + self.get_type_mismatch_hint(param_t, arg_t), ) })?; if let Some(name) = param.name() { @@ -656,6 +659,7 @@ impl Context { &name[..], param_t, arg_t, + self.get_type_mismatch_hint(param_t, arg_t), ) }) } @@ -698,6 +702,7 @@ impl Context { &name[..], pt.typ(), arg_t, + self.get_type_mismatch_hint(pt.typ(), arg_t), ) })?; } else { diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index 8e913f4d..b845787d 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -2,6 +2,7 @@ //! `Context` is used for type inference and type checking. pub mod cache; pub mod compare; +pub mod hint; pub mod initialize; pub mod inquire; pub mod instantiate; diff --git a/compiler/erg_compiler/context/register.rs b/compiler/erg_compiler/context/register.rs index 2ff67b7d..285e62dc 100644 --- a/compiler/erg_compiler/context/register.rs +++ b/compiler/erg_compiler/context/register.rs @@ -393,6 +393,7 @@ impl Context { "import::name", &Str, mod_name.ref_t(), + self.get_type_mismatch_hint(&Str, mod_name.ref_t()), )); } } diff --git a/compiler/erg_compiler/context/tyvar.rs b/compiler/erg_compiler/context/tyvar.rs index d6b0e23b..8a86b084 100644 --- a/compiler/erg_compiler/context/tyvar.rs +++ b/compiler/erg_compiler/context/tyvar.rs @@ -1017,6 +1017,7 @@ impl Context { param_name.unwrap_or(&Str::ever("_")), maybe_sup, maybe_sub, + self.get_type_mismatch_hint(maybe_sup, maybe_sub), )); } match (maybe_sub, maybe_sup) { diff --git a/compiler/erg_compiler/error.rs b/compiler/erg_compiler/error.rs index dd61fc78..b6081d61 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -513,6 +513,7 @@ impl TyCheckError { name: &str, expect: &Type, found: &Type, + hint: Option, ) -> Self { Self::new( ErrorCore::new( @@ -525,7 +526,7 @@ impl TyCheckError { "traditional_chinese" => format!("{name}的類型不匹配:\n預期:{GREEN}{expect}{RESET}\n但找到:{RED}{found}{RESET}"), "english" => format!("the type of {name} is mismatched:\nexpected: {GREEN}{expect}{RESET}\nbut found: {RED}{found}{RESET}"), ), - None, + hint, ), caused_by, ) diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index 6e79a0b1..12ecd549 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -55,6 +55,7 @@ impl ASTLowerer { name, expect, found, + self.ctx.get_type_mismatch_hint(expect, found), ) }) } @@ -336,8 +337,6 @@ impl ASTLowerer { &hir_args.kw_args, &self.ctx.name, )?; - log!(err "{}", obj); - log!(err "{:?}", call.method_name); Ok(hir::Call::new(obj, call.method_name, hir_args, t)) }