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/regex/regex_test.v',
|
||||||
'vlib/v/tests/enum_bitfield_test.v',
|
'vlib/v/tests/enum_bitfield_test.v',
|
||||||
'vlib/v/tests/fixed_array_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/num_lit_call_method_test.v',
|
||||||
'vlib/v/tests/option_test.v',
|
'vlib/v/tests/option_test.v',
|
||||||
'vlib/v/tests/pointers_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 {
|
} else {
|
||||||
method.args[i + 1].typ
|
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
|
// TODO: typ optimize.. this node can get processed more than once
|
||||||
if call_expr.expected_arg_types.len == 0 {
|
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
|
call_expr.args[i].typ = typ
|
||||||
typ_sym := c.table.get_type_symbol(typ)
|
typ_sym := c.table.get_type_symbol(typ)
|
||||||
arg_typ_sym := c.table.get_type_symbol(arg.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) {
|
if !c.table.check(typ, arg.typ) {
|
||||||
// str method, allow type with str method if fn arg is string
|
// str method, allow type with str method if fn arg is string
|
||||||
if arg_typ_sym.kind == .string && typ_sym.has_method('str') {
|
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) {
|
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 -
|
is_variadic := expected_types.len > 0 && table.type_is(expected_types[expected_types.len -
|
||||||
1], .variadic)
|
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
|
mut arg_no := 0
|
||||||
for arg in args {
|
for arg in args {
|
||||||
if is_variadic && arg_no == expected_types.len - 1 {
|
if gen_vargs && arg_no == expected_types.len - 1 {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
// some c fn definitions dont have args (cfns.v) or are not updated in checker
|
// 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 {
|
} else {
|
||||||
g.expr(arg.expr)
|
g.expr(arg.expr)
|
||||||
}
|
}
|
||||||
if arg_no < args.len - 1 || is_variadic {
|
if arg_no < args.len - 1 || gen_vargs {
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
arg_no++
|
arg_no++
|
||||||
}
|
}
|
||||||
if is_variadic {
|
if is_variadic && !is_forwarding_varg {
|
||||||
varg_type := expected_types[expected_types.len - 1]
|
varg_type := expected_types[expected_types.len - 1]
|
||||||
struct_name := 'varg_' + g.typ(varg_type).replace('*', '_ptr')
|
struct_name := 'varg_' + g.typ(varg_type).replace('*', '_ptr')
|
||||||
variadic_count := args.len - arg_no
|
variadic_count := args.len - arg_no
|
||||||
|
|
Loading…
Reference in New Issue