diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 858ea6e16c..2122d1dd84 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2914,9 +2914,13 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp ast.Ty is_cast_fixed_array_init := expr is ast.CastExpr && (expr.expr is ast.ArrayInit && expr.expr.is_fixed) + is_primitive_to_interface := fname.contains('_to_Interface_') && expr is ast.Ident + && g.table.sym(got).kind in [.i8, .i16, .i32, .int, .i64, .isize, .u8, .u16, .u32, .u64, .usize, .f32, .f64, .bool, .rune] + if !is_cast_fixed_array_init && (is_comptime_variant || !expr.is_lvalue() || (expr is ast.Ident && (expr.obj.is_simple_define_const() - || (expr.obj is ast.Var && expr.obj.is_index_var)))) { + || (expr.obj is ast.Var && expr.obj.is_index_var))) + || is_primitive_to_interface) { // Note: the `_to_sumtype_` family of functions do call memdup internally, making // another duplicate with the HEAP macro is redundant, so use ADDR instead: if expr.is_as_cast() { diff --git a/vlib/v/tests/interfaces/interface_mut_value_update_test.v b/vlib/v/tests/interfaces/interface_mut_value_update_test.v new file mode 100644 index 0000000000..b3d5019962 --- /dev/null +++ b/vlib/v/tests/interfaces/interface_mut_value_update_test.v @@ -0,0 +1,34 @@ +interface Value {} + +struct Foo { +mut: + value int +} + +fn test_main() { + mut i := 0 + mut integers := []Value{} + integers << i + i = 1 + integers << i + i = 2 + integers << i + assert integers == [0, 1, 2] + + mut f := Foo{ + value: 0 + } + mut foos := []Foo{} + foos << f + f.value = 1 + foos << f + f.value = 2 + foos << f + assert foos == [Foo{ + value: 0 + }, Foo{ + value: 1 + }, Foo{ + value: 2 + }] +}