mirror of
https://github.com/vlang/v.git
synced 2025-09-13 09:25:45 -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
|
is_array_fixed = expr_stmt.expr is ast.ArrayInit
|
||||||
&& g.table.final_sym(return_type).kind == .array_fixed
|
&& g.table.final_sym(return_type).kind == .array_fixed
|
||||||
if !is_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 {
|
} else {
|
||||||
g.write('${cvar_name} = ')
|
g.write('${cvar_name} = ')
|
||||||
}
|
}
|
||||||
|
|
||||||
if is_array_fixed {
|
if is_array_fixed {
|
||||||
g.write('memcpy(${cvar_name}.data, (${cast_typ})')
|
g.write('memcpy(${cvar_name}.data, (${cast_typ})')
|
||||||
}
|
}
|
||||||
old_inside_opt_data := g.inside_opt_data
|
// return expr or { fn_returns_option() }
|
||||||
g.inside_opt_data = true
|
if is_option && g.inside_return && expr_stmt.expr is ast.CallExpr
|
||||||
g.expr_with_cast(expr_stmt.expr, expr_stmt.typ, return_type.clear_option_and_result())
|
&& return_type.has_option_or_result() {
|
||||||
g.inside_opt_data = old_inside_opt_data
|
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 {
|
if is_array_fixed {
|
||||||
g.write(', sizeof(${cast_typ}))')
|
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