From ddc003380c8edaea116dbe92a1814a8d98681426 Mon Sep 17 00:00:00 2001 From: yuyi Date: Tue, 4 May 2021 00:48:54 +0800 Subject: [PATCH] checker: check generics fn that return generic struct (#9979) --- vlib/v/checker/checker.v | 9 +++++++++ .../generics_fn_return_generic_struct_err.out | 7 +++++++ .../generics_fn_return_generic_struct_err.vv | 18 ++++++++++++++++++ 3 files changed, 34 insertions(+) create mode 100644 vlib/v/checker/tests/generics_fn_return_generic_struct_err.out create mode 100644 vlib/v/checker/tests/generics_fn_return_generic_struct_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 02d52d7078..e0d0ba0555 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -6808,6 +6808,15 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { c.error('only functions that do NOT return values can have `[if $ct_name]` tags', node.pos) } + if node.generic_names.len > 0 { + gs := c.table.get_type_symbol(node.return_type) + if gs.info is ast.Struct { + if gs.info.is_generic && !node.return_type.has_flag(.generic) { + c.error('return generic struct in fn declaration must specify the generic type names, e.g. Foo', + node.return_type_pos) + } + } + } } if node.is_method { mut sym := c.table.get_type_symbol(node.receiver.typ) diff --git a/vlib/v/checker/tests/generics_fn_return_generic_struct_err.out b/vlib/v/checker/tests/generics_fn_return_generic_struct_err.out new file mode 100644 index 0000000000..12a579c300 --- /dev/null +++ b/vlib/v/checker/tests/generics_fn_return_generic_struct_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/generics_fn_return_generic_struct_err.vv:13:32: error: return generic struct in fn declaration must specify the generic type names, e.g. Foo + 11 | } + 12 | + 13 | pub fn new_channel_struct() GenericChannelStruct { + | ~~~~~~~~~~~~~~~~~~~~ + 14 | d := GenericChannelStruct{ + 15 | ch: chan T{} diff --git a/vlib/v/checker/tests/generics_fn_return_generic_struct_err.vv b/vlib/v/checker/tests/generics_fn_return_generic_struct_err.vv new file mode 100644 index 0000000000..0f9a5d5f91 --- /dev/null +++ b/vlib/v/checker/tests/generics_fn_return_generic_struct_err.vv @@ -0,0 +1,18 @@ +struct GenericChannelStruct { + ch chan T +} + +struct Simple { + msg string +} + +fn main() { + new_channel_struct() +} + +pub fn new_channel_struct() GenericChannelStruct { + d := GenericChannelStruct{ + ch: chan T{} + } + return d +}