Skip to content

Commit 5e2ff24

Browse files
author
walking devel
authored
cgen: pass sum type values automatically by reference too, when functions require that (#17476)
1 parent 904f984 commit 5e2ff24

File tree

3 files changed

+61
-1
lines changed

3 files changed

+61
-1
lines changed

vlib/v/gen/c/fn.v

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2289,6 +2289,7 @@ fn (mut g Gen) keep_alive_call_postgen(node ast.CallExpr, tmp_cnt_save int) {
22892289
[inline]
22902290
fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang ast.Language) {
22912291
arg_typ := g.unwrap_generic(arg.typ)
2292+
arg_sym := g.table.sym(arg_typ)
22922293
exp_is_ptr := expected_type.is_ptr() || expected_type.idx() in ast.pointer_type_idxs
22932294
arg_is_ptr := arg_typ.is_ptr() || arg_typ.idx() in ast.pointer_type_idxs
22942295
if expected_type == 0 {
@@ -2300,7 +2301,6 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as
23002301
g.write('&/*mut*/')
23012302
} else if exp_is_ptr && !arg_is_ptr {
23022303
if arg.is_mut {
2303-
arg_sym := g.table.sym(arg_typ)
23042304
if exp_sym.kind == .array {
23052305
if (arg.expr is ast.Ident && (arg.expr as ast.Ident).kind == .variable)
23062306
|| arg.expr is ast.SelectorExpr {
@@ -2353,6 +2353,19 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type ast.Type, lang as
23532353
g.write('ADDR(${g.typ(atype)}/*qq*/, ')
23542354
}
23552355
}
2356+
} else if arg_sym.kind == .sum_type && exp_sym.kind == .sum_type {
2357+
// Automatically passing sum types by reference if the argument expects it,
2358+
// not only the argument is mutable.
2359+
if arg.expr is ast.SelectorExpr {
2360+
g.write('&/*sum*/')
2361+
g.expr(arg.expr)
2362+
return
2363+
} else if arg.expr is ast.CastExpr {
2364+
g.write('ADDR(${g.typ(expected_deref_type)}/*sum*/, ')
2365+
g.expr_with_cast(arg.expr, arg_typ, expected_type)
2366+
g.write(')')
2367+
return
2368+
}
23562369
}
23572370
}
23582371
} else if arg_typ.has_flag(.shared_f) && !expected_type.has_flag(.shared_f) {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
&Expr(ParExpr{
2+
expr: Expr(InfixExpr{
3+
left: unknown sum type value
4+
right: unknown sum type value
5+
})
6+
})
7+
&Expr(ParExpr{
8+
expr: Expr(InfixExpr{
9+
left: unknown sum type value
10+
right: unknown sum type value
11+
})
12+
})
13+
&Expr(InfixExpr{
14+
left: unknown sum type value
15+
right: unknown sum type value
16+
})
17+
&Expr(InfixExpr{
18+
left: unknown sum type value
19+
right: unknown sum type value
20+
})
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
module main
2+
3+
struct ParExpr {
4+
expr Expr
5+
}
6+
7+
struct InfixExpr {
8+
left Expr
9+
right Expr
10+
}
11+
12+
type Expr = InfixExpr | ParExpr
13+
14+
fn print_expr(expr &Expr) {
15+
println(expr)
16+
}
17+
18+
fn main() {
19+
par := ParExpr{
20+
expr: InfixExpr{}
21+
}
22+
23+
print_expr(par)
24+
print_expr(Expr(par))
25+
print_expr(par.expr)
26+
print_expr(&par.expr)
27+
}

0 commit comments

Comments
 (0)