Skip to content

Commit

Permalink
checker: fix return map index with or_block (#20544)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 committed Jan 15, 2024
1 parent df8f8ae commit 46abcd9
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 1 deletion.
17 changes: 16 additions & 1 deletion vlib/v/checker/checker.v
Expand Up @@ -80,6 +80,7 @@ pub mut:
inside_lambda bool // true inside `|...| ...`
inside_ref_lit bool // true inside `a := &something`
inside_defer bool // true inside `defer {}` blocks
inside_return bool // true inside `return ...` blocks
inside_fn_arg bool // `a`, `b` in `a.f(b)`
inside_ct_attr bool // true inside `[if expr]`
inside_x_is_type bool // true inside the Type expression of `if x is Type {`
Expand Down Expand Up @@ -1208,7 +1209,21 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast.
}
ast.IndexExpr {
if expr.or_expr.kind != .absent {
c.check_or_expr(expr.or_expr, ret_type, ret_type.set_flag(.result), expr)
mut return_none_or_error := false
if expr.or_expr.stmts.len > 0 {
last_stmt := expr.or_expr.stmts.last()
if last_stmt is ast.ExprStmt {
if c.inside_return && last_stmt.typ in [ast.none_type, ast.error_type] {
return_none_or_error = true
}
}
}
if return_none_or_error {
c.check_expr_option_or_result_call(expr.or_expr, c.table.cur_fn.return_type)
} else {
c.check_or_expr(expr.or_expr, ret_type, ret_type.set_flag(.result),
expr)
}
}
}
ast.CastExpr {
Expand Down
5 changes: 5 additions & 0 deletions vlib/v/checker/return.v
Expand Up @@ -25,6 +25,11 @@ fn (mut c Checker) return_stmt(mut node ast.Return) {
if c.table.cur_fn == unsafe { nil } {
return
}
prev_inside_return := c.inside_return
c.inside_return = true
defer {
c.inside_return = prev_inside_return
}
c.expected_type = c.table.cur_fn.return_type
mut expected_type := c.unwrap_generic(c.expected_type)
if expected_type != 0 && c.table.sym(expected_type).kind == .alias {
Expand Down
24 changes: 24 additions & 0 deletions vlib/v/tests/return_map_index_with_or_block_test.v
@@ -0,0 +1,24 @@
fn get_value1(m map[string]int, key string) ?int {
return m[key] or { none }
}

fn get_value2(m map[string]int, key string) !int {
return m[key] or { error('not found') }
}

fn test_return_map_index_with_or_block() {
m := {
'aaa': 111
}
if ret1 := get_value1(m, 'aaa') {
assert ret1 == 111
} else {
assert false
}

if ret2 := get_value2(m, 'aaa') {
assert ret2 == 111
} else {
assert false
}
}

0 comments on commit 46abcd9

Please sign in to comment.