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 ret_type := ast.void_type
|
||||||
mut nbranches_with_return := 0
|
mut nbranches_with_return := 0
|
||||||
mut nbranches_without_return := 0
|
mut nbranches_without_return := 0
|
||||||
|
mut must_be_option := false
|
||||||
for mut branch in node.branches {
|
for mut branch in node.branches {
|
||||||
if node.is_expr {
|
if node.is_expr {
|
||||||
c.stmts_ending_with_expression(mut branch.stmts, c.expected_or_type)
|
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)
|
c.expr(mut stmt.expr)
|
||||||
})
|
})
|
||||||
unwrapped_expected_type := c.unwrap_generic(node.expected_type)
|
unwrapped_expected_type := c.unwrap_generic(node.expected_type)
|
||||||
|
must_be_option = must_be_option || expr_type == ast.none_type
|
||||||
stmt.typ = expr_type
|
stmt.typ = expr_type
|
||||||
if first_iteration {
|
if first_iteration {
|
||||||
if unwrapped_expected_type.has_option_or_result()
|
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) {
|
if stmt.typ != ast.error_type && !is_noreturn_callexpr(stmt.expr) {
|
||||||
ret_sym := c.table.sym(ret_type)
|
ret_sym := c.table.sym(ret_type)
|
||||||
stmt_sym := c.table.sym(stmt.typ)
|
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`',
|
c.error('invalid match expression, must supply at least one value other than `none`',
|
||||||
node.pos)
|
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)
|
cond_var := c.get_base_name(&node.cond)
|
||||||
if cond_var != '' {
|
if cond_var != '' {
|
||||||
mut cond_is_auto_heap := false
|
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) {
|
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
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
c.error('return type mismatch, it should be `${ret_sym.name}`, but it is instead `${c.table.type_to_str(expr_type)}`',
|
if expr_type != ast.none_type && ret_type != ast.none_type {
|
||||||
last_stmt.pos)
|
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
|
} else if expr_type == ast.void_type && ret_type.idx() == ast.void_type_idx
|
||||||
&& ret_type.has_option_or_result() {
|
&& 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