mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
This commit is contained in:
parent
f7e062c91a
commit
95f00937bb
2 changed files with 32 additions and 4 deletions
|
@ -41,6 +41,7 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
|
|||
mut ret_type := ast.void_type
|
||||
mut nbranches_with_return := 0
|
||||
mut nbranches_without_return := 0
|
||||
mut must_be_option := false
|
||||
for mut branch in node.branches {
|
||||
if node.is_expr {
|
||||
c.stmts_ending_with_expression(mut branch.stmts, c.expected_or_type)
|
||||
|
@ -77,6 +78,7 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
|
|||
c.expr(mut stmt.expr)
|
||||
})
|
||||
unwrapped_expected_type := c.unwrap_generic(node.expected_type)
|
||||
must_be_option = must_be_option || expr_type == ast.none_type
|
||||
stmt.typ = expr_type
|
||||
if first_iteration {
|
||||
if unwrapped_expected_type.has_option_or_result()
|
||||
|
@ -127,6 +129,9 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
|
|||
}
|
||||
}
|
||||
}
|
||||
if must_be_option && ret_type == ast.none_type && expr_type != ret_type {
|
||||
ret_type = expr_type.set_flag(.option)
|
||||
}
|
||||
if stmt.typ != ast.error_type && !is_noreturn_callexpr(stmt.expr) {
|
||||
ret_sym := c.table.sym(ret_type)
|
||||
stmt_sym := c.table.sym(stmt.typ)
|
||||
|
@ -249,7 +254,7 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
|
|||
c.error('invalid match expression, must supply at least one value other than `none`',
|
||||
node.pos)
|
||||
}
|
||||
node.return_type = ret_type
|
||||
node.return_type = if must_be_option { ret_type.set_flag(.option) } else { ret_type }
|
||||
cond_var := c.get_base_name(&node.cond)
|
||||
if cond_var != '' {
|
||||
mut cond_is_auto_heap := false
|
||||
|
@ -268,7 +273,7 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type {
|
|||
}
|
||||
}
|
||||
}
|
||||
return ret_type
|
||||
return node.return_type
|
||||
}
|
||||
|
||||
fn (mut c Checker) check_match_branch_last_stmt(last_stmt ast.ExprStmt, ret_type ast.Type, expr_type ast.Type) {
|
||||
|
@ -285,8 +290,10 @@ fn (mut c Checker) check_match_branch_last_stmt(last_stmt ast.ExprStmt, ret_type
|
|||
return
|
||||
}
|
||||
}
|
||||
c.error('return type mismatch, it should be `${ret_sym.name}`, but it is instead `${c.table.type_to_str(expr_type)}`',
|
||||
last_stmt.pos)
|
||||
if expr_type != ast.none_type && ret_type != ast.none_type {
|
||||
c.error('return type mismatch, it should be `${ret_sym.name}`, but it is instead `${c.table.type_to_str(expr_type)}`',
|
||||
last_stmt.pos)
|
||||
}
|
||||
}
|
||||
} else if expr_type == ast.void_type && ret_type.idx() == ast.void_type_idx
|
||||
&& ret_type.has_option_or_result() {
|
||||
|
|
21
vlib/v/tests/options/option_match_none_test.v
Normal file
21
vlib/v/tests/options/option_match_none_test.v
Normal file
|
@ -0,0 +1,21 @@
|
|||
fn test_main() {
|
||||
a := match 1 {
|
||||
0 { none }
|
||||
else { 1 }
|
||||
}
|
||||
assert '${a}' == 'Option(1)'
|
||||
|
||||
b := match 2 {
|
||||
0 { none }
|
||||
2 { none }
|
||||
else { 1 }
|
||||
}
|
||||
assert '${b}' == 'Option(none)'
|
||||
|
||||
c := match 2 {
|
||||
0 { 1 }
|
||||
2 { 2 }
|
||||
else { none }
|
||||
}
|
||||
assert '${c}' == 'Option(2)'
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue