From c52ae3b98665965a95aa7c64bac2f3b09d4e52ae Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 15 Jan 2024 18:32:34 +0800 Subject: [PATCH] parser: check non-generic interface defining generic method --- .../tests/generic_interface_method_decl_err.out | 2 +- .../tests/generic_interface_method_decl_err.vv | 2 +- vlib/v/parser/struct.v | 9 +++++++-- vlib/v/parser/tests/generic_interface_decl_err.out | 7 +++++++ vlib/v/parser/tests/generic_interface_decl_err.vv | 13 +++++++++++++ 5 files changed, 29 insertions(+), 4 deletions(-) create mode 100644 vlib/v/parser/tests/generic_interface_decl_err.out create mode 100644 vlib/v/parser/tests/generic_interface_decl_err.vv diff --git a/vlib/v/checker/tests/generic_interface_method_decl_err.out b/vlib/v/checker/tests/generic_interface_method_decl_err.out index 2a0b194312a4b8..4648e3b25a5051 100644 --- a/vlib/v/checker/tests/generic_interface_method_decl_err.out +++ b/vlib/v/checker/tests/generic_interface_method_decl_err.out @@ -1,5 +1,5 @@ vlib/v/checker/tests/generic_interface_method_decl_err.vv:2:8: error: no need to add generic type names in generic interface's method - 1 | interface Expr { + 1 | interface Expr { 2 | accept(v Visitor) R | ^ 3 | } diff --git a/vlib/v/checker/tests/generic_interface_method_decl_err.vv b/vlib/v/checker/tests/generic_interface_method_decl_err.vv index 59e30df07f9b7d..3da9361b7f5bc1 100644 --- a/vlib/v/checker/tests/generic_interface_method_decl_err.vv +++ b/vlib/v/checker/tests/generic_interface_method_decl_err.vv @@ -1,4 +1,4 @@ -interface Expr { +interface Expr { accept(v Visitor) R } diff --git a/vlib/v/parser/struct.v b/vlib/v/parser/struct.v index a72aac92e619ae..9a6ccf9dac7825 100644 --- a/vlib/v/parser/struct.v +++ b/vlib/v/parser/struct.v @@ -632,8 +632,13 @@ fn (mut p Parser) interface_decl() ast.InterfaceDecl { mut_pos = fields.len } if p.peek_tok.kind in [.lt, .lsbr] && p.peek_tok.is_next_to(p.tok) { - p.error_with_pos("no need to add generic type names in generic interface's method", - p.peek_tok.pos()) + if generic_types.len == 0 { + p.error_with_pos('non-generic interface `${interface_name}` cannot define a generic method', + p.peek_tok.pos()) + } else { + p.error_with_pos("no need to add generic type names in generic interface's method", + p.peek_tok.pos()) + } return ast.InterfaceDecl{} } mut comments := p.eat_comments() diff --git a/vlib/v/parser/tests/generic_interface_decl_err.out b/vlib/v/parser/tests/generic_interface_decl_err.out new file mode 100644 index 00000000000000..88576f9396610b --- /dev/null +++ b/vlib/v/parser/tests/generic_interface_decl_err.out @@ -0,0 +1,7 @@ +vlib/v/parser/tests/generic_interface_decl_err.vv:4:6: error: non-generic interface `Abc` cannot define a generic method + 2 | + 3 | interface Abc { + 4 | test[T]() + | ^ + 5 | } + 6 | diff --git a/vlib/v/parser/tests/generic_interface_decl_err.vv b/vlib/v/parser/tests/generic_interface_decl_err.vv new file mode 100644 index 00000000000000..f5ae589c8bee43 --- /dev/null +++ b/vlib/v/parser/tests/generic_interface_decl_err.vv @@ -0,0 +1,13 @@ +module main + +interface Abc { + test[T]() +} + +struct Xyz {} + +fn (xyz Xyz) test[T]() {} + +fn main() { + _ := Abc(Xyz{}) +}