Add hint.rs in context

This commit is contained in:
Shunsuke Shibayama 2022-09-02 01:20:35 +09:00
parent 0844fb2f7a
commit 3550a0e4b5
7 changed files with 17 additions and 6 deletions

View file

@ -7,12 +7,15 @@ use crate::context::Context;
impl Context {
pub(crate) fn get_type_mismatch_hint(&self, expected: &Type, found: &Type) -> Option<Str> {
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,

View file

@ -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 {

View file

@ -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;

View file

@ -393,6 +393,7 @@ impl Context {
"import::name",
&Str,
mod_name.ref_t(),
self.get_type_mismatch_hint(&Str, mod_name.ref_t()),
));
}
}

View file

@ -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) {

View file

@ -513,6 +513,7 @@ impl TyCheckError {
name: &str,
expect: &Type,
found: &Type,
hint: Option<Str>,
) -> 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,
)

View file

@ -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))
}