mirror of
https://github.com/vlang/v.git
synced 2025-09-13 01:16:02 -04:00
cgen: fix return with option on orexpr (#20728)
This commit is contained in:
parent
a374d25420
commit
e6570ddcf9
@ -6624,19 +6624,30 @@ fn (mut g Gen) gen_or_block_stmts(cvar_name string, cast_typ string, stmts []ast
|
||||
is_array_fixed = expr_stmt.expr is ast.ArrayInit
|
||||
&& g.table.final_sym(return_type).kind == .array_fixed
|
||||
if !is_array_fixed {
|
||||
g.write('*(${cast_typ}*) ${cvar_name}.data = ')
|
||||
if g.inside_return && !g.inside_struct_init
|
||||
&& expr_stmt.expr is ast.CallExpr
|
||||
&& return_type.has_option_or_result() {
|
||||
g.write('${cvar_name} = ')
|
||||
} else {
|
||||
g.write('*(${cast_typ}*) ${cvar_name}.data = ')
|
||||
}
|
||||
}
|
||||
} else {
|
||||
g.write('${cvar_name} = ')
|
||||
}
|
||||
|
||||
if is_array_fixed {
|
||||
g.write('memcpy(${cvar_name}.data, (${cast_typ})')
|
||||
}
|
||||
old_inside_opt_data := g.inside_opt_data
|
||||
g.inside_opt_data = true
|
||||
g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type.clear_option_and_result())
|
||||
g.inside_opt_data = old_inside_opt_data
|
||||
// return expr or { fn_returns_option() }
|
||||
if is_option && g.inside_return && expr_stmt.expr is ast.CallExpr
|
||||
&& return_type.has_option_or_result() {
|
||||
g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type)
|
||||
} else {
|
||||
old_inside_opt_data := g.inside_opt_data
|
||||
g.inside_opt_data = true
|
||||
g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type.clear_option_and_result())
|
||||
g.inside_opt_data = old_inside_opt_data
|
||||
}
|
||||
if is_array_fixed {
|
||||
g.write(', sizeof(${cast_typ}))')
|
||||
}
|
||||
|
20
vlib/v/tests/option_call_on_orexpr_test.v
Normal file
20
vlib/v/tests/option_call_on_orexpr_test.v
Normal file
@ -0,0 +1,20 @@
|
||||
fn find_startswith_string(a []string, search string) ?string {
|
||||
for s in a {
|
||||
if s.starts_with(search) {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return none
|
||||
}
|
||||
|
||||
fn find_any_startswith_string(a []string, b []string, search string) ?string {
|
||||
// cannot convert 'struct _option_string' to 'struct string'
|
||||
// V wants the or {} block to return a string, but find_startswith_string returns ?string
|
||||
return find_startswith_string(a, search) or { find_startswith_string(b, search) }
|
||||
}
|
||||
|
||||
fn test_main() {
|
||||
deadbeef := find_any_startswith_string(['foobar', 'barfoo'], ['deadbeef', 'beefdead'],
|
||||
'dead')
|
||||
assert deadbeef or { panic('unreachable') } == 'deadbeef'
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user