From 33167960ed3dcbee36958f6339fc62e7a0009f93 Mon Sep 17 00:00:00 2001 From: yuyi Date: Wed, 16 Mar 2022 15:31:38 +0800 Subject: [PATCH] checker: check the sumtype mismatch returned by match expr (#13751) --- vlib/v/checker/match.v | 5 ++++- .../match_return_sumtype_mismatch_err.out | 7 +++++++ .../match_return_sumtype_mismatch_err.vv | 19 +++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 vlib/v/checker/tests/match_return_sumtype_mismatch_err.out create mode 100644 vlib/v/checker/tests/match_return_sumtype_mismatch_err.vv diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index 81e9ef937f..5dc1d6e349 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -85,7 +85,10 @@ pub fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { && !c.check_types(expr_type, ret_type) { ret_sym := c.table.sym(ret_type) is_noreturn := is_noreturn_callexpr(stmt.expr) - if !(node.is_expr && ret_sym.kind == .sum_type) && !is_noreturn { + if !(node.is_expr && ret_sym.kind == .sum_type + && (ret_type.has_flag(.generic) + || c.table.is_sumtype_or_in_variant(ret_type, expr_type))) + && !is_noreturn { c.error('return type mismatch, it should be `$ret_sym.name`', stmt.expr.pos()) } diff --git a/vlib/v/checker/tests/match_return_sumtype_mismatch_err.out b/vlib/v/checker/tests/match_return_sumtype_mismatch_err.out new file mode 100644 index 0000000000..25086c8629 --- /dev/null +++ b/vlib/v/checker/tests/match_return_sumtype_mismatch_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/match_return_sumtype_mismatch_err.vv:15:11: error: return type mismatch, it should be `Myt` + 13 | return match b { + 14 | true { St('TRUE') } + 15 | false { `F` } + | ~~~ + 16 | } + 17 | } diff --git a/vlib/v/checker/tests/match_return_sumtype_mismatch_err.vv b/vlib/v/checker/tests/match_return_sumtype_mismatch_err.vv new file mode 100644 index 0000000000..3f5a1a1d47 --- /dev/null +++ b/vlib/v/checker/tests/match_return_sumtype_mismatch_err.vv @@ -0,0 +1,19 @@ +type St = string +type Ru = rune +type Myt = Ru | St + +fn myt_t1(b bool) Myt { + match b { + true { return St('TRUE') } + false { return Ru(`F`) } + } +} + +fn myt_t2(b bool) Myt { + return match b { + true { St('TRUE') } + false { `F` } + } +} + +fn main() {}