mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
fix
This commit is contained in:
parent
bae7684276
commit
d661e4b9f4
6 changed files with 41 additions and 2 deletions
|
@ -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_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_variadic', t.bool_node(node.is_variadic))
|
||||
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('scope', t.number_node(int(node.scope)))
|
||||
|
|
|
@ -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_file_translated bool // true, when the file it resides in is `@[translated]`
|
||||
is_static_method bool // it is a static method call
|
||||
is_variadic bool
|
||||
args []CallArg
|
||||
expected_arg_types []Type
|
||||
comptime_ret_val bool
|
||||
|
|
|
@ -2906,6 +2906,7 @@ fn (mut c Checker) check_expected_arg_count(mut node ast.CallExpr, f &ast.Fn) !
|
|||
min_required_params--
|
||||
}
|
||||
if f.is_variadic {
|
||||
node.is_variadic = f.is_variadic
|
||||
min_required_params--
|
||||
c.markused_array_method(!c.is_builtin_mod, '')
|
||||
} else {
|
||||
|
|
|
@ -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
|
||||
is_variadic := expected_types.len > 0 && expected_types.last().has_flag(.variadic)
|
||||
&& node.language == .v
|
||||
is_variadic := node.language == .v && node.is_variadic
|
||||
mut already_decomposed := false
|
||||
for i, arg in args {
|
||||
if is_variadic && i == expected_types.len - 1 {
|
||||
|
@ -2539,6 +2538,14 @@ fn (mut g Gen) call_args(node ast.CallExpr) {
|
|||
false)
|
||||
} else {
|
||||
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}]){')
|
||||
for j in arg_nr .. args.len {
|
||||
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('}))')
|
||||
if is_option {
|
||||
g.writeln(' }, (${option_name}*)&${tmp_var}, sizeof(${base_type}));')
|
||||
g.write(tmp)
|
||||
g.write(tmp_var)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -944,6 +944,9 @@ pub fn (mut w Walker) call_expr(mut node ast.CallExpr) {
|
|||
for arg in node.args {
|
||||
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 {
|
||||
w.mark_by_type(concrete_type)
|
||||
}
|
||||
|
|
21
vlib/v/tests/options/option_fn_variadic_test.v
Normal file
21
vlib/v/tests/options/option_fn_variadic_test.v
Normal 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)]'
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue