mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: fix option ptr assignment (#18394)
This commit is contained in:
parent
c4a20f0992
commit
af8df871d1
@ -1883,19 +1883,32 @@ fn (mut g Gen) expr_with_tmp_var(expr ast.Expr, expr_typ ast.Type, ret_typ ast.T
|
|||||||
g.gen_option_error(ret_typ, expr)
|
g.gen_option_error(ret_typ, expr)
|
||||||
g.writeln(';')
|
g.writeln(';')
|
||||||
} else {
|
} else {
|
||||||
|
mut is_ptr_to_ptr_assign := false
|
||||||
g.writeln('${g.typ(ret_typ)} ${tmp_var};')
|
g.writeln('${g.typ(ret_typ)} ${tmp_var};')
|
||||||
if ret_typ.has_flag(.option) {
|
if ret_typ.has_flag(.option) {
|
||||||
if expr_typ.has_flag(.option) && expr in [ast.StructInit, ast.ArrayInit, ast.MapInit] {
|
if expr_typ.has_flag(.option) && expr in [ast.StructInit, ast.ArrayInit, ast.MapInit] {
|
||||||
g.write('_option_none(&(${styp}[]) { ')
|
g.write('_option_none(&(${styp}[]) { ')
|
||||||
} else {
|
} else {
|
||||||
g.write('_option_ok(&(${styp}[]) { ')
|
is_ptr_to_ptr_assign = (expr is ast.SelectorExpr
|
||||||
|
|| (expr is ast.Ident && !(expr as ast.Ident).is_auto_heap()))
|
||||||
|
&& ret_typ.is_ptr() && expr_typ.is_ptr() && expr_typ.has_flag(.option)
|
||||||
|
// option ptr assignment simplification
|
||||||
|
if is_ptr_to_ptr_assign {
|
||||||
|
g.write('${tmp_var} = ')
|
||||||
|
} else {
|
||||||
|
g.write('_option_ok(&(${styp}[]) { ')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
g.write('_result_ok(&(${styp}[]) { ')
|
g.write('_result_ok(&(${styp}[]) { ')
|
||||||
}
|
}
|
||||||
g.expr_with_cast(expr, expr_typ, ret_typ)
|
g.expr_with_cast(expr, expr_typ, ret_typ)
|
||||||
if ret_typ.has_flag(.option) {
|
if ret_typ.has_flag(.option) {
|
||||||
g.writeln(' }, (${c.option_name}*)(&${tmp_var}), sizeof(${styp}));')
|
if is_ptr_to_ptr_assign {
|
||||||
|
g.writeln(';')
|
||||||
|
} else {
|
||||||
|
g.writeln(' }, (${c.option_name}*)(&${tmp_var}), sizeof(${styp}));')
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
g.writeln(' }, (${c.result_name}*)(&${tmp_var}), sizeof(${styp}));')
|
g.writeln(' }, (${c.result_name}*)(&${tmp_var}), sizeof(${styp}));')
|
||||||
}
|
}
|
||||||
|
20
vlib/v/tests/option_ptr_generic_test.v
Normal file
20
vlib/v/tests/option_ptr_generic_test.v
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
[heap]
|
||||||
|
struct Node[T] {
|
||||||
|
mut:
|
||||||
|
value T
|
||||||
|
next ?&Node[T]
|
||||||
|
}
|
||||||
|
|
||||||
|
fn print_t(node ?&Node[int]) ?&Node[int] {
|
||||||
|
println(node)
|
||||||
|
assert node == none
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
n := Node[int]{
|
||||||
|
value: 5
|
||||||
|
}
|
||||||
|
t := print_t(n.next)
|
||||||
|
assert t == none
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user