Skip to content

Commit 74ae887

Browse files
authored
cgen: fix mutable sumtype (fix #25108) (#25111)
1 parent 5a87e8c commit 74ae887

File tree

4 files changed

+47
-50
lines changed

4 files changed

+47
-50
lines changed

vlib/v/gen/c/cgen.v

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2805,9 +2805,10 @@ fn (mut g Gen) write_sumtype_casting_fn(fun SumtypeCastingFn) {
28052805
} else {
28062806
// g.definitions.writeln('${g.static_modifier} inline ${exp_cname} ${fun.fn_name}(${got_cname}* x);')
28072807
// sb.writeln('${g.static_modifier} inline ${exp_cname} ${fun.fn_name}(${got_cname}* x) {')
2808-
g.definitions.writeln('${exp_cname} ${fun.fn_name}(${got_cname}* x);')
2809-
sb.writeln('${exp_cname} ${fun.fn_name}(${got_cname}* x) {')
2810-
sb.writeln('\t${got_cname}* ptr = memdup(x, sizeof(${got_cname}));')
2808+
g.definitions.writeln('${exp_cname} ${fun.fn_name}(${got_cname}* x, bool is_mut);')
2809+
sb.writeln('${exp_cname} ${fun.fn_name}(${got_cname}* x, bool is_mut) {')
2810+
sb.writeln('\t${got_cname}* ptr = x;')
2811+
sb.writeln('\tif (!is_mut) { ptr = memdup(x, sizeof(${got_cname})); }')
28112812
}
28122813
for embed_hierarchy in g.table.get_embeds(got_sym) {
28132814
// last embed in the hierarchy
@@ -2853,19 +2854,14 @@ fn (mut g Gen) write_sumtype_casting_fn(fun SumtypeCastingFn) {
28532854
fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp ast.Type, got ast.Type, exp_styp string,
28542855
got_is_ptr bool, got_is_fn bool, got_styp string) {
28552856
mut rparen_n := 1
2856-
mut mutable_idx := 0
2857+
mut mutable_is_mut_arg_pos := 0
28572858

28582859
is_not_ptr_and_fn := !got_is_ptr && !got_is_fn
28592860
is_sumtype_cast := !got_is_fn && fname.contains('_to_sumtype_')
28602861
is_comptime_variant := is_not_ptr_and_fn && expr is ast.Ident
28612862
&& g.comptime.is_comptime_variant_var(expr)
28622863
if exp.is_ptr() {
2863-
if $d('mutable_sumtype', false) && is_sumtype_cast && g.expected_arg_mut
2864-
&& expr is ast.Ident {
2865-
g.write('&(${exp_styp.trim_right('*')}){._${got_styp.trim_right('*')}=')
2866-
rparen_n = 0
2867-
mutable_idx = got.idx()
2868-
} else if (expr is ast.UnsafeExpr && expr.expr is ast.Nil) || got == ast.nil_type {
2864+
if (expr is ast.UnsafeExpr && expr.expr is ast.Nil) || got == ast.nil_type {
28692865
g.write('(void*)0')
28702866
return
28712867
} else {
@@ -2875,6 +2871,7 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp ast.Ty
28752871
} else {
28762872
g.write('${fname}(')
28772873
}
2874+
mutable_is_mut_arg_pos = rparen_n
28782875
if is_not_ptr_and_fn {
28792876
is_cast_fixed_array_init := expr is ast.CastExpr
28802877
&& (expr.expr is ast.ArrayInit && expr.expr.is_fixed)
@@ -2915,10 +2912,14 @@ fn (mut g Gen) call_cfn_for_casting_expr(fname string, expr ast.Expr, exp ast.Ty
29152912
g.expr(expr)
29162913
g.left_is_opt = old_left_is_opt
29172914
}
2918-
if mutable_idx != 0 {
2919-
g.write(', ._typ=${mutable_idx}}')
2915+
if is_sumtype_cast {
2916+
// the `_to_sumtype_` family of functions last `is_mut` param
2917+
g.write(')'.repeat(rparen_n - mutable_is_mut_arg_pos))
2918+
g.write(', ${exp.is_ptr()}')
2919+
g.write(')'.repeat(mutable_is_mut_arg_pos))
2920+
} else {
2921+
g.write(')'.repeat(rparen_n))
29202922
}
2921-
g.write(')'.repeat(rparen_n))
29222923
}
29232924

29242925
// use instead of expr() when you need a var to use as reference
@@ -3100,7 +3101,7 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ
31003101
g.expr(expr)
31013102
g.writeln(';')
31023103
g.write2(stmt_str, ' ')
3103-
g.write('${fname}(&${tmp_var})')
3104+
g.write('${fname}(&${tmp_var}, ${unwrapped_expected_type.is_ptr()})')
31043105
return
31053106
} else {
31063107
g.call_cfn_for_casting_expr(fname, expr, expected_type, got_type,
@@ -3505,7 +3506,7 @@ fn (mut g Gen) gen_clone_assignment(var_type ast.Type, val ast.Expr, typ ast.Typ
35053506
g.write('}, sizeof(${shared_styp}))')
35063507
}
35073508
if is_sumtype {
3508-
g.write('))')
3509+
g.write('), false)')
35093510
}
35103511
} else if right_sym.kind == .string {
35113512
// `str1 = str2` => `str1 = str2.clone()`

vlib/v/gen/c/json.v

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -381,8 +381,8 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
381381
if fv_sym.kind == .struct && !is_option && field_op != '->' {
382382
dec.writeln('\tif (root->type == cJSON_NULL) { ')
383383
dec.writeln('\t\tstruct ${first_variant_name} empty = {0};')
384-
dec.writeln('res = ${variant_typ}_to_sumtype_${ret_styp}(&empty); } \n else ')
385-
// dec.writeln('res = ${variant_typ}_to_sumtype_${sym.cname}(&empty); } \n else ')
384+
dec.writeln('res = ${variant_typ}_to_sumtype_${ret_styp}(&empty, false); } \n else ')
385+
// dec.writeln('res = ${variant_typ}_to_sumtype_${sym.cname}(&empty, false); } \n else ')
386386
}
387387
//
388388
dec.writeln('if (cJSON_IsObject(root) || (cJSON_IsArray(root) && cJSON_IsObject(root->child))) {')
@@ -409,7 +409,7 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
409409

410410
// Helpers for decoding
411411
g.get_sumtype_casting_fn(variant, typ)
412-
g.definitions.writeln('static inline ${sym.cname} ${variant_typ}_to_sumtype_${sym.cname}(${variant_typ}* x);')
412+
g.definitions.writeln('static inline ${sym.cname} ${variant_typ}_to_sumtype_${sym.cname}(${variant_typ}* x, bool is_mut);')
413413

414414
// ENCODING
415415
enc.writeln('\tif (${var_data}${field_op}_typ == ${int(variant.idx())}) {')
@@ -485,9 +485,9 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
485485
dec.writeln('\t\t${variant_typ} value = *(${variant_typ}*)(${tmp}.data);')
486486
}
487487
if is_option {
488-
dec.writeln('\t\t\t_option_ok(&(${sym.cname}[]){ ${variant_typ}_to_sumtype_${sym.cname}(&value) }, (${option_name}*)&res, sizeof(${sym.cname}));')
488+
dec.writeln('\t\t\t_option_ok(&(${sym.cname}[]){ ${variant_typ}_to_sumtype_${sym.cname}(&value, false) }, (${option_name}*)&res, sizeof(${sym.cname}));')
489489
} else {
490-
dec.writeln('\t\tres = ${variant_typ}_to_sumtype_${ret_styp}(&value);')
490+
dec.writeln('\t\tres = ${variant_typ}_to_sumtype_${ret_styp}(&value, false);')
491491
}
492492
dec.writeln('\t}')
493493
} $else {
@@ -498,10 +498,10 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
498498
if utyp.has_flag(.option) {
499499
dec.writeln('\t\t\t\t${prefix}res.state = 0;')
500500
tmp_time_var := g.new_tmp_var()
501-
dec.writeln('\t\t\t\t${g.base_type(utyp)} ${tmp_time_var} = ${variant_typ}_to_sumtype_${sym.cname}(&${tmp});')
501+
dec.writeln('\t\t\t\t${g.base_type(utyp)} ${tmp_time_var} = ${variant_typ}_to_sumtype_${sym.cname}(&${tmp}, false);')
502502
dec.writeln('\t\t\t\tvmemcpy(&${prefix}res.data, ${tmp_time_var}._time__Time, sizeof(${variant_typ}));')
503503
} else {
504-
dec.writeln('\t\t\t\t${prefix}res = ${variant_typ}_to_sumtype_${sym.cname}(&${tmp});')
504+
dec.writeln('\t\t\t\t${prefix}res = ${variant_typ}_to_sumtype_${sym.cname}(&${tmp}, false);')
505505
}
506506
dec.writeln('\t\t\t}')
507507
} else if !is_js_prim(variant_typ) && variant_sym.kind != .enum {
@@ -512,9 +512,9 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
512512
dec.writeln('\t\t\t\t\treturn (${result_name}_${ret_styp}){ .is_error = true, .err = ${tmp}.err, .data = {0} };')
513513
dec.writeln('\t\t\t\t}')
514514
if is_option {
515-
dec.writeln('\t\t\t\t_option_ok(&(${sym.cname}[]){ ${variant_typ}_to_sumtype_${sym.cname}((${variant_typ}*)${tmp}.data) }, (${option_name}*)&res, sizeof(${sym.cname}));')
515+
dec.writeln('\t\t\t\t_option_ok(&(${sym.cname}[]){ ${variant_typ}_to_sumtype_${sym.cname}((${variant_typ}*)${tmp}.data, false) }, (${option_name}*)&res, sizeof(${sym.cname}));')
516516
} else {
517-
dec.writeln('\t\t\t\t${prefix}res = ${variant_typ}_to_sumtype_${sym.cname}((${variant_typ}*)${tmp}.data);')
517+
dec.writeln('\t\t\t\t${prefix}res = ${variant_typ}_to_sumtype_${sym.cname}((${variant_typ}*)${tmp}.data, false);')
518518
}
519519
dec.writeln('\t\t\t}')
520520
}
@@ -536,7 +536,7 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
536536
var_t := 'bool'
537537
dec.writeln('\t\tif (cJSON_IsBool(root)) {')
538538
dec.writeln('\t\t\t${var_t} value = ${js_dec_name(var_t)}(root);')
539-
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}(&value);')
539+
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}(&value, false);')
540540
dec.writeln('\t\t}')
541541
}
542542

@@ -552,9 +552,9 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
552552
dec.writeln('\t\tif (cJSON_IsNumber(root)) {')
553553
dec.writeln('\t\t\t${var_t} value = ${js_dec_name('u64')}(root);')
554554
if utyp.has_flag(.option) {
555-
dec.writeln('\t\t\t_option_ok(&(${sym.cname}[]){ ${var_t}_to_sumtype_${sym.cname}(&value) }, (${option_name}*)&${prefix}res, sizeof(${sym.cname}));')
555+
dec.writeln('\t\t\t_option_ok(&(${sym.cname}[]){ ${var_t}_to_sumtype_${sym.cname}(&value, false) }, (${option_name}*)&${prefix}res, sizeof(${sym.cname}));')
556556
} else {
557-
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}(&value);')
557+
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}(&value, false);')
558558
}
559559
dec.writeln('\t\t}')
560560
}
@@ -568,9 +568,9 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
568568
dec.writeln('\t\tif (cJSON_IsString(root)) {')
569569
dec.writeln('\t\t\t${var_t} value = ${js_dec_name(var_t)}(root);')
570570
if utyp.has_flag(.option) {
571-
dec.writeln('\t\t\t_option_ok(&(${sym.cname}[]){ ${var_t}_to_sumtype_${sym.cname}(&value) }, (${option_name}*)&${prefix}res, sizeof(${sym.cname}));')
571+
dec.writeln('\t\t\t_option_ok(&(${sym.cname}[]){ ${var_t}_to_sumtype_${sym.cname}(&value, false) }, (${option_name}*)&${prefix}res, sizeof(${sym.cname}));')
572572
} else {
573-
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}(&value);')
573+
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}(&value, false);')
574574
}
575575
dec.writeln('\t\t}')
576576
}
@@ -592,9 +592,9 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
592592
dec.writeln('\t\t\t\treturn (${result_name}_${ret_styp}){ .is_error = true, .err = ${tmp}.err, .data = {0} };')
593593
dec.writeln('\t\t\t}')
594594
if utyp.has_flag(.option) {
595-
dec.writeln('\t\t\t_option_ok(&(${sym.cname}[]){ ${var_t}_to_sumtype_${sym.cname}((${var_t}*)${tmp}.data) }, (${option_name}*)&${prefix}res, sizeof(${sym.cname}));')
595+
dec.writeln('\t\t\t_option_ok(&(${sym.cname}[]){ ${var_t}_to_sumtype_${sym.cname}((${var_t}*)${tmp}.data, false) }, (${option_name}*)&${prefix}res, sizeof(${sym.cname}));')
596596
} else {
597-
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}((${var_t}*)${tmp}.data);')
597+
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}((${var_t}*)${tmp}.data, false);')
598598
}
599599
dec.writeln('\t\t}')
600600
}
@@ -611,9 +611,9 @@ fn (mut g Gen) gen_sumtype_enc_dec(utyp ast.Type, sym ast.TypeSymbol, mut enc st
611611
dec.writeln('\t\tif (cJSON_IsNumber(root)) {')
612612
dec.writeln('\t\t\t${var_t} value = ${js_dec_name(var_t)}(root);')
613613
if utyp.has_flag(.option) {
614-
dec.writeln('\t\t\t_option_ok(&(${sym.cname}[]){ ${var_t}_to_sumtype_${sym.cname}(&value) }, (${option_name}*)&${prefix}res, sizeof(${sym.cname}));')
614+
dec.writeln('\t\t\t_option_ok(&(${sym.cname}[]){ ${var_t}_to_sumtype_${sym.cname}(&value, false) }, (${option_name}*)&${prefix}res, sizeof(${sym.cname}));')
615615
} else {
616-
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}(&value);')
616+
dec.writeln('\t\t\t${prefix}res = ${var_t}_to_sumtype_${sym.cname}(&value, false);')
617617
}
618618
dec.writeln('\t\t}')
619619
}

vlib/v/tests/sumtypes/sumtype_arg_mutable_test.v

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,12 @@ fn test_main() {
2828
mut s := String{
2929
s: 'string'
3030
}
31-
if $d('mutable_sumtype', false) {
32-
assert i.i == 333
33-
assert s.s == 'string'
34-
init(mut i)
35-
init(mut s)
36-
assert i.i == 0
37-
assert s.s == ''
38-
init_int(mut i)
39-
assert i.i == 0
40-
}
31+
assert i.i == 333
32+
assert s.s == 'string'
33+
init(mut i)
34+
init(mut s)
35+
assert i.i == 0
36+
assert s.s == ''
37+
init_int(mut i)
38+
assert i.i == 0
4139
}

vlib/v/tests/sumtypes/sumtype_mutable_test.v

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,11 @@ fn test_main() {
1414
mut my_struct := &MyStructA{
1515
test: false
1616
}
17-
if $d('mutable_sumtype', false) {
18-
assert my_struct.test == false
19-
my_struct.test = true
20-
assert my_struct.test == true
21-
but_why(mut my_struct)
22-
assert my_struct.test == false
23-
}
17+
assert my_struct.test == false
18+
my_struct.test = true
19+
assert my_struct.test == true
20+
but_why(mut my_struct)
21+
assert my_struct.test == false
2422
}
2523

2624
fn but_why(mut passed MySumType) {

0 commit comments

Comments
 (0)