@@ -2986,18 +2986,19 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp ast.Ty
29862986 && g.table.sym (got).kind in [.i8 , .i16 , .i32 , .int, .i64 , .isize, .u8 , .u16 , .u32 , .u64 , .usize, .f32 , .f64 , .bool, .rune]
29872987
29882988 // Check if the expression is a function argument (local variable) that needs heap allocation
2989- is_fn_arg := if expr is ast.Ident && expr.obj is ast.Var {
2990- expr.obj.is_arg
2991- } else {
2992- false
2993- }
2989+ is_fn_arg := expr.is_fn_arg ()
29942990
29952991 if ! is_cast_fixed_array_init && (is_comptime_variant || ! expr.is_lvalue ()
29962992 || (expr is ast.Ident && (expr.obj.is_simple_define_const ()
29972993 || (expr.obj is ast.Var && expr.obj.is_index_var)))
29982994 || is_primitive_to_interface || is_fn_arg) {
29992995 // Note: the `_to_sumtype_` family of functions do call memdup internally, making
3000- // another duplicate with the HEAP macro is redundant, so use ADDR instead:
2996+ // another duplicate with the HEAP macro is redundant, so use ADDR instead.
2997+ // However, this only applies when the expression is a simple Ident that we can
2998+ // easily declare a temporary variable for. For SelectorExpr and IndexExpr, we
2999+ // cannot use ADDR because it requires a temporary variable declaration.
3000+ // For sumtype casts with SelectorExpr or IndexExpr, we should not use any macro
3001+ // because the sumtype casting function already handles memory allocation.
30013002 if expr.is_as_cast () {
30023003 if ! got_is_ptr && expr is ast.SelectorExpr {
30033004 // (var as Type).field_non_ptr
@@ -3008,8 +3009,15 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp ast.Ty
30083009 defer (fn ) {
30093010 g.inside_smartcast = old_inside_smartcast
30103011 }
3012+ } else if is_sumtype_cast && is_fn_arg && expr ! is ast.Ident {
3013+ // For sumtype casts with SelectorExpr or IndexExpr, don't use any macro
3014+ // because the sumtype casting function already handles memory allocation
3015+ // and we cannot use ADDR for these expression types.
3016+ // Just take the address of the expression since the function expects a pointer.
3017+ g.write ('&(' )
3018+ rparen_n++
30113019 } else {
3012- promotion_macro_name := if is_sumtype_cast { 'ADDR' } else { 'HEAP' }
3020+ promotion_macro_name := if is_sumtype_cast && is_fn_arg { 'ADDR' } else { 'HEAP' }
30133021 g.write ('${promotion_macro_name }(${got_styp }, (' )
30143022 rparen_n + = 2
30153023 }
0 commit comments