From 0615f2e2368f5e1412237601d002c4dba535e59b Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 7 Jun 2021 17:11:29 +0800 Subject: [PATCH] checker: check generic method receivers with no type parameter (#10374) --- vlib/v/checker/checker.v | 9 +++++++++ .../tests/generics_method_receiver_type_err.out | 7 +++++++ .../tests/generics_method_receiver_type_err.vv | 16 ++++++++++++++++ 3 files changed, 32 insertions(+) create mode 100644 vlib/v/checker/tests/generics_method_receiver_type_err.out create mode 100644 vlib/v/checker/tests/generics_method_receiver_type_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 347641b55b..04831c357e 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -7252,6 +7252,15 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { c.error('missing return at end of function `$node.name`', node.pos) } } + if node.is_method { + sym := c.table.get_type_symbol(node.receiver.typ) + if sym.kind == .struct_ { + info := sym.info as ast.Struct + if info.is_generic && c.table.cur_fn.generic_names.len == 0 { + c.error('receiver must specify the generic type names, e.g. Foo', node.method_type_pos) + } + } + } c.returns = false node.source_file = c.file } diff --git a/vlib/v/checker/tests/generics_method_receiver_type_err.out b/vlib/v/checker/tests/generics_method_receiver_type_err.out new file mode 100644 index 0000000000..1a8b84de53 --- /dev/null +++ b/vlib/v/checker/tests/generics_method_receiver_type_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/generics_method_receiver_type_err.vv:6:11: error: receiver must specify the generic type names, e.g. Foo + 4 | } + 5 | + 6 | pub fn (x Node) str() string { + | ~~~~ + 7 | return 'Value is : ${u16(x.val)}\nName is : $x.name' + 8 | } diff --git a/vlib/v/checker/tests/generics_method_receiver_type_err.vv b/vlib/v/checker/tests/generics_method_receiver_type_err.vv new file mode 100644 index 0000000000..8a6763cc1c --- /dev/null +++ b/vlib/v/checker/tests/generics_method_receiver_type_err.vv @@ -0,0 +1,16 @@ +struct Node { + val T + name string +} + +pub fn (x Node) str() string { + return 'Value is : ${u16(x.val)}\nName is : $x.name' +} + +fn main() { + xx := Node{ + val: u16(11) + name: 'man' + } + println(xx.str()) +}