Readable error messages

This commit is contained in:
Shunsuke Shibayama 2022-09-14 21:46:12 +09:00
parent 6593bf9e2e
commit 615d7937d9
4 changed files with 58 additions and 3 deletions

View file

@ -593,11 +593,13 @@ impl Context {
}
}
}
let proj = mono_proj(*lhs, rhs);
Err(EvalError::no_candidate_error(
line!() as usize,
&mono_proj(*lhs, rhs),
&proj,
t_loc,
self.caused_by(),
self.get_no_candidate_hint(&proj),
))
}
Type::Ref(l) => Ok(ref_(self.eval_t_params(*l, level, t_loc)?)),

View file

@ -1,10 +1,31 @@
use erg_common::astr::AtomicStr;
use erg_common::enum_unwrap;
use erg_type::typaram::TyParam;
use erg_type::Type;
use crate::context::Context;
#[derive(PartialEq, Eq)]
enum Sequence {
Forward,
Backward,
}
impl Context {
fn readable_type(&self, typ: &Type) -> Type {
match typ {
Type::FreeVar(fv) if fv.constraint_is_sandwiched() => {
let (sub, sup) = fv.get_bound_types().unwrap();
if sup == Type::Obj {
return sub;
}
Type::FreeVar(fv.clone())
}
other => other.clone(),
}
}
pub(crate) fn get_type_mismatch_hint(
&self,
expected: &Type,
@ -25,4 +46,35 @@ impl Context {
_ => None,
}
}
pub(crate) fn get_no_candidate_hint(&self, proj: &Type) -> Option<AtomicStr> {
match proj {
Type::MonoProj { lhs, rhs: _ } => {
if let Type::FreeVar(fv) = lhs.as_ref() {
let (sub, sup) = fv.get_bound_types()?;
// TODO: automating
let (verb, preposition, sequence) = match &sup.name()[..] {
"Add" => Some(("add", "and", Sequence::Forward)),
"Sub" => Some(("subtract", "from", Sequence::Backward)),
"Mul" => Some(("multiply", "and", Sequence::Forward)),
"Div" => Some(("divide", "by", Sequence::Forward)),
_ => None,
}?;
let sup = enum_unwrap!(sup.typarams().remove(0), TyParam::Type);
let sup = self.readable_type(&sup);
let (l, r) = if sequence == Sequence::Forward {
(sub, sup)
} else {
(sup, sub)
};
Some(AtomicStr::from(format!(
"cannot {verb} {l} {preposition} {r}"
)))
} else {
None
}
}
_ => None,
}
}
}

View file

@ -1594,7 +1594,7 @@ impl Context {
op_t,
set! {
static_instance("R", Type),
subtypeof(l, poly("Mul", params))
subtypeof(l, poly("Div", params))
},
);
self.register_builtin_impl("__div__", op_t, Const, Private);

View file

@ -1145,6 +1145,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
proj: &Type,
loc: Location,
caused_by: AtomicStr,
hint: Option<AtomicStr>,
) -> Self {
Self::new(
ErrorCore::new(
@ -1157,7 +1158,7 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
"traditional_chinese" => format!("{proj}沒有候選項"),
"english" => format!("no candidate for {proj}"),
),
None,
hint,
),
caused_by,
)