This commit is contained in:
Felipe Pena 2025-09-09 19:16:46 -03:00
parent bae7684276
commit d661e4b9f4
6 changed files with 41 additions and 2 deletions

View file

@ -1613,6 +1613,7 @@ fn (t Tree) call_expr(node ast.CallExpr) &Node {
obj.add_terse('is_ctor_new', t.bool_node(node.is_ctor_new)) obj.add_terse('is_ctor_new', t.bool_node(node.is_ctor_new))
obj.add_terse('is_return_used', t.bool_node(node.is_return_used)) obj.add_terse('is_return_used', t.bool_node(node.is_return_used))
obj.add_terse('is_static_method', t.bool_node(node.is_static_method)) obj.add_terse('is_static_method', t.bool_node(node.is_static_method))
obj.add_terse('is_variadic', t.bool_node(node.is_variadic))
obj.add('should_be_skipped', t.bool_node(node.should_be_skipped)) obj.add('should_be_skipped', t.bool_node(node.should_be_skipped))
obj.add_terse('free_receiver', t.bool_node(node.free_receiver)) obj.add_terse('free_receiver', t.bool_node(node.free_receiver))
obj.add('scope', t.number_node(int(node.scope))) obj.add('scope', t.number_node(int(node.scope)))

View file

@ -830,6 +830,7 @@ pub mut:
is_ctor_new bool // if JS ctor calls requires `new` before call, marked as `[use_new]` in V is_ctor_new bool // if JS ctor calls requires `new` before call, marked as `[use_new]` in V
is_file_translated bool // true, when the file it resides in is `@[translated]` is_file_translated bool // true, when the file it resides in is `@[translated]`
is_static_method bool // it is a static method call is_static_method bool // it is a static method call
is_variadic bool
args []CallArg args []CallArg
expected_arg_types []Type expected_arg_types []Type
comptime_ret_val bool comptime_ret_val bool

View file

@ -2906,6 +2906,7 @@ fn (mut c Checker) check_expected_arg_count(mut node ast.CallExpr, f &ast.Fn) !
min_required_params-- min_required_params--
} }
if f.is_variadic { if f.is_variadic {
node.is_variadic = f.is_variadic
min_required_params-- min_required_params--
c.markused_array_method(!c.is_builtin_mod, '') c.markused_array_method(!c.is_builtin_mod, '')
} else { } else {

View file

@ -2369,8 +2369,7 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
} }
} }
// only v variadic, C variadic args will be appended like normal args // only v variadic, C variadic args will be appended like normal args
is_variadic := expected_types.len > 0 && expected_types.last().has_flag(.variadic) is_variadic := node.language == .v && node.is_variadic
&& node.language == .v
mut already_decomposed := false mut already_decomposed := false
for i, arg in args { for i, arg in args {
if is_variadic && i == expected_types.len - 1 { if is_variadic && i == expected_types.len - 1 {
@ -2539,6 +2538,14 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
false) false)
} else { } else {
noscan := g.check_noscan(arr_info.elem_type) noscan := g.check_noscan(arr_info.elem_type)
is_option := arr_info.elem_type.has_flag(.option)
tmp_var := if is_option { g.new_tmp_var() } else { '' }
base_type := g.base_type(varg_type)
tmp := if is_option { g.go_before_last_stmt() } else { '' }
if is_option {
g.writeln('${g.styp(varg_type)} ${tmp_var};')
g.write('_option_ok((${base_type}[]) {')
}
g.write('new_array_from_c_array${noscan}(${variadic_count}, ${variadic_count}, sizeof(${elem_type}), _MOV((${elem_type}[${variadic_count}]){') g.write('new_array_from_c_array${noscan}(${variadic_count}, ${variadic_count}, sizeof(${elem_type}), _MOV((${elem_type}[${variadic_count}]){')
for j in arg_nr .. args.len { for j in arg_nr .. args.len {
g.ref_or_deref_arg(args[j], arr_info.elem_type, node.language, g.ref_or_deref_arg(args[j], arr_info.elem_type, node.language,
@ -2548,6 +2555,11 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
} }
} }
g.write('}))') g.write('}))')
if is_option {
g.writeln(' }, (${option_name}*)&${tmp_var}, sizeof(${base_type}));')
g.write(tmp)
g.write(tmp_var)
}
} }
} }
} else { } else {

View file

@ -944,6 +944,9 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) {
for arg in node.args { for arg in node.args {
w.expr(arg.expr) w.expr(arg.expr)
} }
if node.is_variadic && node.expected_arg_types.last().has_flag(.option) {
w.used_option++
}
for concrete_type in node.concrete_types { for concrete_type in node.concrete_types {
w.mark_by_type(concrete_type) w.mark_by_type(concrete_type)
} }

View file

@ -0,0 +1,21 @@
struct Empty {
}
type Elem = int | Empty
fn new_elems(elems ...??int) []Elem {
mut out := []Elem{}
for elem in elems {
if elem == none {
out << Empty{}
} else {
out << elem
}
}
return out
}
fn test_main() {
elems := new_elems(0, none, 2)
assert '${elems}' == '[Elem(0), Elem(Empty{}), Elem(2)]'
}