fix: improve match error messages

This commit is contained in:
Shunsuke Shibayama 2023-03-17 00:13:43 +09:00
parent a7ff798c6d
commit 3ff0eb8f65
2 changed files with 16 additions and 4 deletions

View file

@ -304,6 +304,7 @@ impl Context {
let match_target_expr_t = pos_args[0].expr.ref_t(); let match_target_expr_t = pos_args[0].expr.ref_t();
// Never or T => T // Never or T => T
let mut union_pat_t = Type::Never; let mut union_pat_t = Type::Never;
let mut arm_ts = vec![];
for (i, pos_arg) in pos_args.iter().skip(1).enumerate() { for (i, pos_arg) in pos_args.iter().skip(1).enumerate() {
let lambda = erg_common::enum_unwrap!(&pos_arg.expr, hir::Expr::Lambda); // already checked let lambda = erg_common::enum_unwrap!(&pos_arg.expr, hir::Expr::Lambda); // already checked
if !lambda.params.defaults.is_empty() { if !lambda.params.defaults.is_empty() {
@ -334,6 +335,7 @@ impl Context {
ParamKind::NonDefault, ParamKind::NonDefault,
)?; )?;
union_pat_t = self.union(&union_pat_t, &rhs); union_pat_t = self.union(&union_pat_t, &rhs);
arm_ts.push(rhs);
} }
// NG: expr_t: Nat, union_pat_t: {1, 2} // NG: expr_t: Nat, union_pat_t: {1, 2}
// OK: expr_t: Int, union_pat_t: {1} or 'T // OK: expr_t: Int, union_pat_t: {1} or 'T
@ -347,6 +349,8 @@ impl Context {
pos_args[0].loc(), pos_args[0].loc(),
self.caused_by(), self.caused_by(),
match_target_expr_t, match_target_expr_t,
&union_pat_t,
arm_ts,
))); )));
} }
let branch_ts = pos_args let branch_ts = pos_args

View file

@ -409,15 +409,23 @@ impl TyCheckError {
loc: Location, loc: Location,
caused_by: String, caused_by: String,
expr_t: &Type, expr_t: &Type,
union_pat_t: &Type,
arm_ts: Vec<Type>,
) -> Self { ) -> Self {
let arms = arm_ts
.into_iter()
.enumerate()
.fold("".to_string(), |acc, (i, t)| {
acc + &format!("{} arm type: {t}\n", ordinal_num(i + 1))
});
Self::new( Self::new(
ErrorCore::new( ErrorCore::new(
vec![SubMessage::only_loc(loc)], vec![SubMessage::only_loc(loc)],
switch_lang!( switch_lang!(
"japanese" => format!("{expr_t}型の全パターンを網羅していません"), "japanese" => format!("{expr_t}型の全パターンを網羅していません\nunion type: {union_pat_t}\n{arms}"),
"simplified_chinese" => format!("并非所有{expr_t}类型的模式都被涵盖"), "simplified_chinese" => format!("并非所有{expr_t}类型的模式都被涵盖\nunion type: {union_pat_t}\n{arms}"),
"traditional_chinese" => format!("並非所有{expr_t}類型的模式都被涵蓋"), "traditional_chinese" => format!("並非所有{expr_t}類型的模式都被涵蓋\nunion type: {union_pat_t}\n{arms}"),
"english" => format!("not all patterns of type {expr_t} are covered"), "english" => format!("not all patterns of type {expr_t} are covered\nunion type: {union_pat_t}\n{arms}"),
), ),
errno, errno,
TypeError, TypeError,