mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
cgen: pass sum type values automatically by reference too, when functions require that (#17476)
This commit is contained in:
parent
904f984367
commit
5e2ff246c8
@ -2289,6 +2289,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) {
|
||||
arg_typ := g.unwrap_generic(arg.typ)
|
||||
arg_sym := g.table.sym(arg_typ)
|
||||
exp_is_ptr := expected_type.is_ptr() || expected_type.idx() in ast.pointer_type_idxs
|
||||
arg_is_ptr := arg_typ.is_ptr() || arg_typ.idx() in ast.pointer_type_idxs
|
||||
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
|
||||
g.write('&/*mut*/')
|
||||
} else if exp_is_ptr && !arg_is_ptr {
|
||||
if arg.is_mut {
|
||||
arg_sym := g.table.sym(arg_typ)
|
||||
if exp_sym.kind == .array {
|
||||
if (arg.expr is ast.Ident && (arg.expr as ast.Ident).kind == .variable)
|
||||
|| 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
|
||||
g.write('ADDR(${g.typ(atype)}/*qq*/, ')
|
||||
}
|
||||
}
|
||||
} else if arg_sym.kind == .sum_type && exp_sym.kind == .sum_type {
|
||||
// Automatically passing sum types by reference if the argument expects it,
|
||||
// not only the argument is mutable.
|
||||
if arg.expr is ast.SelectorExpr {
|
||||
g.write('&/*sum*/')
|
||||
g.expr(arg.expr)
|
||||
return
|
||||
} else if arg.expr is ast.CastExpr {
|
||||
g.write('ADDR(${g.typ(expected_deref_type)}/*sum*/, ')
|
||||
g.expr_with_cast(arg.expr, arg_typ, expected_type)
|
||||
g.write(')')
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if arg_typ.has_flag(.shared_f) && !expected_type.has_flag(.shared_f) {
|
||||
|
20
vlib/v/gen/c/testdata/sumtype_pass_by_reference.out
vendored
Normal file
20
vlib/v/gen/c/testdata/sumtype_pass_by_reference.out
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
&Expr(ParExpr{
|
||||
expr: Expr(InfixExpr{
|
||||
left: unknown sum type value
|
||||
right: unknown sum type value
|
||||
})
|
||||
})
|
||||
&Expr(ParExpr{
|
||||
expr: Expr(InfixExpr{
|
||||
left: unknown sum type value
|
||||
right: unknown sum type value
|
||||
})
|
||||
})
|
||||
&Expr(InfixExpr{
|
||||
left: unknown sum type value
|
||||
right: unknown sum type value
|
||||
})
|
||||
&Expr(InfixExpr{
|
||||
left: unknown sum type value
|
||||
right: unknown sum type value
|
||||
})
|
27
vlib/v/gen/c/testdata/sumtype_pass_by_reference.vv
vendored
Normal file
27
vlib/v/gen/c/testdata/sumtype_pass_by_reference.vv
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
module main
|
||||
|
||||
struct ParExpr {
|
||||
expr Expr
|
||||
}
|
||||
|
||||
struct InfixExpr {
|
||||
left Expr
|
||||
right Expr
|
||||
}
|
||||
|
||||
type Expr = InfixExpr | ParExpr
|
||||
|
||||
fn print_expr(expr &Expr) {
|
||||
println(expr)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
par := ParExpr{
|
||||
expr: InfixExpr{}
|
||||
}
|
||||
|
||||
print_expr(par)
|
||||
print_expr(Expr(par))
|
||||
print_expr(par.expr)
|
||||
print_expr(&par.expr)
|
||||
}
|
Loading…
Reference in New Issue
Block a user