Skip to content

Commit

Permalink
cgen: fix casting primitive type to alias, where option alias is expe…
Browse files Browse the repository at this point in the history
…cted (fix #23859) (#23860)
  • Loading branch information
felipensp authored Mar 5, 2025
1 parent a74f317 commit 7faf1bf
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 3 deletions.
14 changes: 11 additions & 3 deletions vlib/v/gen/c/assign.v
Original file line number Diff line number Diff line change
Expand Up @@ -66,18 +66,26 @@ fn (mut g Gen) expr_opt_with_alias(expr ast.Expr, expr_typ ast.Type, ret_typ ast
g.writeln('${ret_styp} ${ret_var} = {.state=2, .err=_const_none__, .data={EMPTY_STRUCT_INITIALIZATION}};')

if expr !is ast.None {
g.write('_option_clone((${option_name}*)')
has_addr := expr !in [ast.Ident, ast.SelectorExpr]
is_option_expr := expr_typ.has_flag(.option)
if is_option_expr {
g.write('_option_clone((${option_name}*)')
} else {
g.write('_option_ok(&(${styp}[]){ ')
}
has_addr := is_option_expr && expr !in [ast.Ident, ast.SelectorExpr]
if has_addr {
expr_styp := g.styp(expr_typ).replace('*', '_ptr')
g.write('ADDR(${expr_styp}, ')
} else {
} else if is_option_expr {
g.write('&')
}
g.expr(expr)
if has_addr {
g.write(')')
}
if !is_option_expr {
g.write(' }')
}
g.writeln(', (${option_name}*)&${ret_var}, sizeof(${styp}));')
}
g.write(line)
Expand Down
35 changes: 35 additions & 0 deletions vlib/v/tests/options/option_cast_primitive_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
module main

type Float = f32

struct Note {
mut:
seen string
}

fn (mut n Note) bad_call(value ?Float) {
if val := value {
n.seen += ', ${val}'
}
}

fn (mut n Note) good_call(value ?f32) {
if val := value {
n.seen += ', ${val}'
}
}

fn test_main() {
mut good := Note{}
mut bad := Note{}
mut c := 0
for {
good.good_call(f32(c))
bad.bad_call(Float(c))
c += 1
if c >= 5 {
break
}
}
assert '${good.seen}' == '${bad.seen}'
}

0 comments on commit 7faf1bf

Please sign in to comment.