From 4007c6cf89256dfe3c18a428cd5e67505bff1935 Mon Sep 17 00:00:00 2001 From: yuyi Date: Tue, 28 Mar 2023 20:00:08 +0800 Subject: [PATCH] checker: check generic struct infering error (#17802) --- vlib/v/checker/check_types.v | 3 +++ vlib/v/checker/tests/generic_interface_err.out | 6 ++++++ vlib/v/checker/tests/generics_struct_infer_err.out | 7 +++++++ vlib/v/checker/tests/generics_struct_infer_err.vv | 11 +++++++++++ vlib/v/checker/tests/generics_struct_init_err.out | 4 ++-- vlib/v/checker/tests/interface_generic_err.out | 6 ++++++ 6 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 vlib/v/checker/tests/generics_struct_infer_err.out create mode 100644 vlib/v/checker/tests/generics_struct_infer_err.vv diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 2f12d5aaf5..da0f9d5aaf 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -793,6 +793,9 @@ fn (mut c Checker) infer_struct_generic_types(typ ast.Type, node ast.StructInit) } } } + c.error('could not infer generic type `${gt_name}` in generic struct `${sym.name}[${generic_names.join(', ')}]`', + node.pos) + return concrete_types } } return concrete_types diff --git a/vlib/v/checker/tests/generic_interface_err.out b/vlib/v/checker/tests/generic_interface_err.out index 5c197aefe0..007bc890f7 100644 --- a/vlib/v/checker/tests/generic_interface_err.out +++ b/vlib/v/checker/tests/generic_interface_err.out @@ -3,6 +3,12 @@ vlib/v/checker/tests/generic_interface_err.vv:10:1: warning: unused variable: `i 9 | s := Struct{7} 10 | i := Interface(s) | ^ +vlib/v/checker/tests/generic_interface_err.vv:9:6: error: could not infer generic type `T` in generic struct `Struct[T]` + 7 | } + 8 | + 9 | s := Struct{7} + | ~~~~~~~~~ + 10 | i := Interface(s) vlib/v/checker/tests/generic_interface_err.vv:10:6: error: can not find method `method` on `Struct`, needed for interface: `Interface` 8 | 9 | s := Struct{7} diff --git a/vlib/v/checker/tests/generics_struct_infer_err.out b/vlib/v/checker/tests/generics_struct_infer_err.out new file mode 100644 index 0000000000..d7fda8c1fd --- /dev/null +++ b/vlib/v/checker/tests/generics_struct_infer_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/generics_struct_infer_err.vv:7:10: error: could not infer generic type `U` in generic struct `Foo[T, U]` + 5 | + 6 | fn main() { + 7 | st11 := Foo{ + | ~~~~ + 8 | a: 'two' + 9 | } diff --git a/vlib/v/checker/tests/generics_struct_infer_err.vv b/vlib/v/checker/tests/generics_struct_infer_err.vv new file mode 100644 index 0000000000..800bbe3861 --- /dev/null +++ b/vlib/v/checker/tests/generics_struct_infer_err.vv @@ -0,0 +1,11 @@ +struct Foo[T, U] { + a T + b U +} + +fn main() { + st11 := Foo{ + a: 'two' + } + println(st11) +} diff --git a/vlib/v/checker/tests/generics_struct_init_err.out b/vlib/v/checker/tests/generics_struct_init_err.out index b29871d11e..32e1c26f4f 100644 --- a/vlib/v/checker/tests/generics_struct_init_err.out +++ b/vlib/v/checker/tests/generics_struct_init_err.out @@ -1,8 +1,8 @@ -vlib/v/checker/tests/generics_struct_init_err.vv:67:23: error: could not infer generic type `T` in call to `call` +vlib/v/checker/tests/generics_struct_init_err.vv:67:8: error: could not infer generic type `T` in generic struct `FnHolder2[T]` 65 | ret = holder_call_22(neg, 5) 66 | assert ret == -5 67 | ret = FnHolder2{neg}.call(6) - | ~~~~~~~ + | ~~~~~~~~~~~~~~ 68 | assert ret == -6 69 | } vlib/v/checker/tests/generics_struct_init_err.vv:22:7: error: generic struct init must specify type parameter, e.g. Foo[T] diff --git a/vlib/v/checker/tests/interface_generic_err.out b/vlib/v/checker/tests/interface_generic_err.out index 709993e1a8..bf888de203 100644 --- a/vlib/v/checker/tests/interface_generic_err.out +++ b/vlib/v/checker/tests/interface_generic_err.out @@ -3,6 +3,12 @@ vlib/v/checker/tests/interface_generic_err.vv:8:1: warning: unused variable: `wh 7 | what := What{} 8 | why := Why(what) | ~~~ +vlib/v/checker/tests/interface_generic_err.vv:7:9: error: could not infer generic type `T` in generic struct `What[T]` + 5 | + 6 | // no segfault without generic + 7 | what := What{} + | ~~~~~~ + 8 | why := Why(what) vlib/v/checker/tests/interface_generic_err.vv:8:8: error: could not infer generic type `T` in interface `Why` 6 | // no segfault without generic 7 | what := What{}