diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 9c18815cdc..51ab091479 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -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 diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index 84a2686200..c495c43f66 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -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()) { - g.write('&') + 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 { diff --git a/vlib/v/tests/options/option_unwrapped_arg_generic_opt_test.v b/vlib/v/tests/options/option_unwrapped_arg_generic_opt_test.v new file mode 100644 index 0000000000..6821344787 --- /dev/null +++ b/vlib/v/tests/options/option_unwrapped_arg_generic_opt_test.v @@ -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`') } +}