cgen: fix codegen for option unwrapped var passed to generic option type (fix #23972) (#24096)

This commit is contained in:
Felipe Pena 2025-04-02 03:13:20 -03:00 committed by GitHub
parent 44d3d59dd5
commit a298fb8aba
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 35 additions and 2 deletions

View file

@ -2614,7 +2614,7 @@ fn (mut g Gen) keep_alive_call_postgen(node ast.CallExpr, tmp_cnt_save int) {
@[inline]
fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang ast.Language, is_smartcast bool) {
arg_typ := if arg.ct_expr {
mut arg_typ := if arg.ct_expr {
g.unwrap_generic(g.type_resolver.get_type(arg.expr))
} else {
g.unwrap_generic(arg.typ)
@ -2754,6 +2754,13 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as
if (arg_sym.info is ast.Alias || exp_sym.info is ast.Alias) && expected_type != arg_typ {
g.expr_opt_with_alias(arg.expr, arg_typ, expected_type)
} else {
if arg.expr is ast.Ident {
if arg.expr.obj is ast.Var {
if arg.expr.obj.smartcasts.len > 0 {
arg_typ = arg.expr.obj.smartcasts.last()
}
}
}
g.expr_with_opt(arg.expr, arg_typ, expected_type)
}
return

View file

@ -1030,14 +1030,23 @@ fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) {
elem_sym := g.table.final_sym(array_info.elem_type)
elem_is_array_var := elem_sym.kind in [.array, .array_fixed] && node.right is ast.Ident
g.write('array_push${noscan}((array*)')
mut needs_addr := false
if !left.typ.is_ptr()
|| (node.left_type.has_flag(.shared_f) && !node.left_type.deref().is_ptr()) {
if node.left is ast.CallExpr {
g.write('ADDR(${g.styp(node.left_type)}, ')
needs_addr = true
} else {
g.write('&')
}
}
g.expr(node.left)
if node.left_type.has_flag(.shared_f) {
g.write('->val')
}
if needs_addr {
g.write(')')
}
if elem_sym.kind == .function {
g.write(', _MOV((voidptr[]){ ')
} else if elem_is_array_var {

View file

@ -0,0 +1,17 @@
fn test_main() {
mut arr := ?[]int(none)
if arr == none {
arr = []int{}
} else {
ret := unwrap(arr)
assert ret == arr
}
assert arr?.len == 0
}
fn t(a ?int) {}
@[inline]
pub fn unwrap[T](t ?T) T {
return t or { panic('unexpected `none`') }
}