diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 2cb9a5a849..fcaf5b408a 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -1025,7 +1025,11 @@ pub fn (t &Table) fn_signature(func &Fn, opts FnSignatureOpts) string { sb.write_string('$param.name ') } styp := t.type_to_str(typ) - sb.write_string('$styp') + if i == func.params.len - 1 && func.is_variadic { + sb.write_string('...$styp') + } else { + sb.write_string('$styp') + } } sb.write_string(')') if func.return_type != ast.void_type { diff --git a/vlib/v/checker/tests/fn_args.out b/vlib/v/checker/tests/fn_args.out index c5e82d8ce0..2df630ba13 100644 --- a/vlib/v/checker/tests/fn_args.out +++ b/vlib/v/checker/tests/fn_args.out @@ -1,28 +1,35 @@ -vlib/v/checker/tests/fn_args.vv:7:6: error: cannot use `&int` as `byte` in argument 1 to `uu8` - 5 | fn basic() { - 6 | v := 4 - 7 | uu8(&v) +vlib/v/checker/tests/fn_args.vv:9:6: error: cannot use `&int` as `byte` in argument 1 to `uu8` + 7 | fn basic() { + 8 | v := 4 + 9 | uu8(&v) | ~~ - 8 | arr([5]!) - 9 | fun(fn(i &int){}) -vlib/v/checker/tests/fn_args.vv:8:6: error: cannot use `[1]int` as `[]int` in argument 1 to `arr` - 6 | v := 4 - 7 | uu8(&v) - 8 | arr([5]!) + 10 | arr([5]!) + 11 | fun(fn (i &int) {}) +vlib/v/checker/tests/fn_args.vv:10:6: error: cannot use `[1]int` as `[]int` in argument 1 to `arr` + 8 | v := 4 + 9 | uu8(&v) + 10 | arr([5]!) | ~~~~ - 9 | fun(fn(i &int){}) - 10 | } -vlib/v/checker/tests/fn_args.vv:9:6: error: cannot use `fn (&int)` as `fn (int)` in argument 1 to `fun` - 7 | uu8(&v) - 8 | arr([5]!) - 9 | fun(fn(i &int){}) - | ~~~~~~~~~~~~ - 10 | } - 11 | + 11 | fun(fn (i &int) {}) + 12 | fun(fn (ii ...int) {}) +vlib/v/checker/tests/fn_args.vv:11:6: error: cannot use `fn (&int)` as `fn (int)` in argument 1 to `fun` + 9 | uu8(&v) + 10 | arr([5]!) + 11 | fun(fn (i &int) {}) + | ~~~~~~~~~~~~~~ + 12 | fun(fn (ii ...int) {}) + 13 | } Details: ``'s expected fn argument: `` is NOT a pointer, but the passed fn argument: `i` is a pointer -vlib/v/checker/tests/fn_args.vv:18:4: error: cannot use `int` as `&S1` in argument 1 to `f` - 16 | fn ptr() { - 17 | v := 4 - 18 | f(v) +vlib/v/checker/tests/fn_args.vv:12:6: error: cannot use `fn (...int)` as `fn (int)` in argument 1 to `fun` + 10 | arr([5]!) + 11 | fun(fn (i &int) {}) + 12 | fun(fn (ii ...int) {}) + | ~~~~~~~~~~~~~~~~~ + 13 | } + 14 | +vlib/v/checker/tests/fn_args.vv:22:4: error: cannot use `int` as `&S1` in argument 1 to `f` + 20 | fn ptr() { + 21 | v := 4 + 22 | f(v) | ^ - 19 | } + 23 | } diff --git a/vlib/v/checker/tests/fn_args.vv b/vlib/v/checker/tests/fn_args.vv index 7ba79a97df..5cfdff5992 100644 --- a/vlib/v/checker/tests/fn_args.vv +++ b/vlib/v/checker/tests/fn_args.vv @@ -1,16 +1,20 @@ fn uu8(a byte) {} + fn arr(a []int) {} -fn fun(a fn(int)) {} + +fn fun(a fn (int)) {} fn basic() { v := 4 uu8(&v) arr([5]!) - fun(fn(i &int){}) + fun(fn (i &int) {}) + fun(fn (ii ...int) {}) } struct S1 { } + fn f(p &S1) {} fn ptr() { diff --git a/vlib/v/checker/tests/struct_field_type_err.out b/vlib/v/checker/tests/struct_field_type_err.out new file mode 100644 index 0000000000..6c8e6df75e --- /dev/null +++ b/vlib/v/checker/tests/struct_field_type_err.out @@ -0,0 +1,43 @@ +vlib/v/checker/tests/struct_field_type_err.vv:12:3: error: cannot assign to field `n`: expected `int`, not `bool` + 10 | fn main() { + 11 | mut data := Data{ + 12 | n: true + | ~~~~~~~ + 13 | b: 0 + 14 | f1: fn (v ...voidptr) {} +vlib/v/checker/tests/struct_field_type_err.vv:13:3: error: cannot assign to field `b`: expected `bool`, not `int literal` + 11 | mut data := Data{ + 12 | n: true + 13 | b: 0 + | ~~~~ + 14 | f1: fn (v ...voidptr) {} + 15 | f2: fn (v voidptr) {} +vlib/v/checker/tests/struct_field_type_err.vv:14:3: error: cannot assign to field `f1`: expected `fn (voidptr)`, not `fn (...voidptr)` + 12 | n: true + 13 | b: 0 + 14 | f1: fn (v ...voidptr) {} + | ~~~~~~~~~~~~~~~~~~~~~~~~ + 15 | f2: fn (v voidptr) {} + 16 | data: true +Details: ``'s expected fn argument: `` is a pointer, but the passed fn argument: `v` is NOT a pointer +vlib/v/checker/tests/struct_field_type_err.vv:15:3: error: cannot assign to field `f2`: expected `fn (...voidptr)`, not `fn (voidptr)` + 13 | b: 0 + 14 | f1: fn (v ...voidptr) {} + 15 | f2: fn (v voidptr) {} + | ~~~~~~~~~~~~~~~~~~~~~ + 16 | data: true + 17 | } +Details: ``'s expected fn argument: `` is NOT a pointer, but the passed fn argument: `v` is a pointer +vlib/v/checker/tests/struct_field_type_err.vv:16:3: error: cannot assign to field `data`: expected `&Data`, not `bool` + 14 | f1: fn (v ...voidptr) {} + 15 | f2: fn (v voidptr) {} + 16 | data: true + | ~~~~~~~~~~ + 17 | } + 18 | +vlib/v/checker/tests/struct_field_type_err.vv:19:11: error: cannot assign to `data.n`: expected `int`, not `bool` + 17 | } + 18 | + 19 | data.n = true + | ~~~~ + 20 | } diff --git a/vlib/v/checker/tests/struct_field_type_err.vv b/vlib/v/checker/tests/struct_field_type_err.vv new file mode 100644 index 0000000000..44850c2817 --- /dev/null +++ b/vlib/v/checker/tests/struct_field_type_err.vv @@ -0,0 +1,20 @@ +struct Data { +mut: + n int + b bool + f1 fn (voidptr) + f2 fn (...voidptr) + data &Data +} + +fn main() { + mut data := Data{ + n: true + b: 0 + f1: fn (v ...voidptr) {} + f2: fn (v voidptr) {} + data: true + } + + data.n = true +}