checker/gen: allow vargs to be forwarded. fix/enable variadic test
parent
b288ecb795
commit
c1e8612624
|
@ -18,7 +18,6 @@ const (
|
|||
'vlib/regex/regex_test.v',
|
||||
'vlib/v/tests/enum_bitfield_test.v',
|
||||
'vlib/v/tests/fixed_array_test.v',
|
||||
'vlib/v/tests/fn_variadic_test.v',
|
||||
'vlib/v/tests/num_lit_call_method_test.v',
|
||||
'vlib/v/tests/option_test.v',
|
||||
'vlib/v/tests/pointers_test.v',
|
||||
|
|
|
@ -492,7 +492,11 @@ pub fn (c mut Checker) call_method(call_expr mut ast.CallExpr) table.Type {
|
|||
} else {
|
||||
method.args[i + 1].typ
|
||||
}
|
||||
call_expr.args[i].typ = c.expr(arg.expr)
|
||||
arg_typ := c.expr(arg.expr)
|
||||
call_expr.args[i].typ = arg_typ
|
||||
if method.is_variadic && table.type_is(arg_typ, .variadic) && call_expr.args.len-1 > i {
|
||||
c.error('when forwarding a varg variable, it must be the final argument', call_expr.pos)
|
||||
}
|
||||
}
|
||||
// TODO: typ optimize.. this node can get processed more than once
|
||||
if call_expr.expected_arg_types.len == 0 {
|
||||
|
@ -616,6 +620,9 @@ pub fn (c mut Checker) call_fn(call_expr mut ast.CallExpr) table.Type {
|
|||
call_expr.args[i].typ = typ
|
||||
typ_sym := c.table.get_type_symbol(typ)
|
||||
arg_typ_sym := c.table.get_type_symbol(arg.typ)
|
||||
if f.is_variadic && table.type_is(typ, .variadic) && call_expr.args.len-1 > i {
|
||||
c.error('when forwarding a varg variable, it must be the final argument', call_expr.pos)
|
||||
}
|
||||
if !c.table.check(typ, arg.typ) {
|
||||
// str method, allow type with str method if fn arg is string
|
||||
if arg_typ_sym.kind == .string && typ_sym.has_method('str') {
|
||||
|
|
|
@ -384,9 +384,11 @@ fn (g mut Gen) fn_call(node ast.CallExpr) {
|
|||
fn (g mut Gen) call_args(args []ast.CallArg, expected_types []table.Type) {
|
||||
is_variadic := expected_types.len > 0 && table.type_is(expected_types[expected_types.len -
|
||||
1], .variadic)
|
||||
is_forwarding_varg := args.len > 0 && table.type_is(args[args.len-1].typ, .variadic)
|
||||
gen_vargs := is_variadic && !is_forwarding_varg
|
||||
mut arg_no := 0
|
||||
for arg in args {
|
||||
if is_variadic && arg_no == expected_types.len - 1 {
|
||||
if gen_vargs && arg_no == expected_types.len - 1 {
|
||||
break
|
||||
}
|
||||
// some c fn definitions dont have args (cfns.v) or are not updated in checker
|
||||
|
@ -396,12 +398,12 @@ fn (g mut Gen) call_args(args []ast.CallArg, expected_types []table.Type) {
|
|||
} else {
|
||||
g.expr(arg.expr)
|
||||
}
|
||||
if arg_no < args.len - 1 || is_variadic {
|
||||
if arg_no < args.len - 1 || gen_vargs {
|
||||
g.write(', ')
|
||||
}
|
||||
arg_no++
|
||||
}
|
||||
if is_variadic {
|
||||
if is_variadic && !is_forwarding_varg {
|
||||
varg_type := expected_types[expected_types.len - 1]
|
||||
struct_name := 'varg_' + g.typ(varg_type).replace('*', '_ptr')
|
||||
variadic_count := args.len - arg_no
|
||||
|
|
Loading…
Reference in New Issue