diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 9ac1c44fcb..6f05ab376e 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -221,13 +221,13 @@ fn (mut p Parser) fn_decl() ast.FnDecl { language = rec.language } mut name := '' + name_pos := p.tok.position() if p.tok.kind == .name { - pos := p.tok.position() // TODO high order fn name = if language == .js { p.check_js_name() } else { p.check_name() } if language == .v && !p.pref.translated && util.contains_capital(name) && !p.builtin_mod { p.error_with_pos('function names cannot contain uppercase letters, use snake_case instead', - pos) + name_pos) return ast.FnDecl{ scope: 0 } @@ -243,7 +243,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { } } if is_duplicate { - p.error_with_pos('duplicate method `$name`', pos) + p.error_with_pos('duplicate method `$name`', name_pos) return ast.FnDecl{ scope: 0 } @@ -251,7 +251,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl { } // cannot redefine buildin function if !is_method && !p.builtin_mod && name in builtin_functions { - p.error_with_pos('cannot redefine builtin function `$name`', pos) + p.error_with_pos('cannot redefine builtin function `$name`', name_pos) return ast.FnDecl{ scope: 0 } @@ -267,14 +267,19 @@ fn (mut p Parser) fn_decl() ast.FnDecl { p.error_with_pos('cannot overload `!=`, `>`, `<=` and `>=` as they are auto generated from `==` and`<`', p.tok.position()) } else { - pos := p.tok.position() - p.error_with_pos('expecting method name', pos) + p.error_with_pos('expecting method name', p.tok.position()) return ast.FnDecl{ scope: 0 } } // generic_names := p.parse_generic_names() + // check generic receiver method has no generic names + if is_method && rec.typ.has_flag(.generic) && generic_names.len == 0 + && p.table.get_type_symbol(rec.typ).kind != .any { + p.error_with_pos('generic receiver method `$name` should add generic names, e.g. $name', + name_pos) + } // Args args2, are_args_type_only, is_variadic := p.fn_args() params << args2 diff --git a/vlib/v/parser/tests/generic_multiple_receiver_method_has_no_generic_names_err.out b/vlib/v/parser/tests/generic_multiple_receiver_method_has_no_generic_names_err.out new file mode 100644 index 0000000000..146771c8da --- /dev/null +++ b/vlib/v/parser/tests/generic_multiple_receiver_method_has_no_generic_names_err.out @@ -0,0 +1,7 @@ +vlib/v/parser/tests/generic_multiple_receiver_method_has_no_generic_names_err.vv:6:20: error: generic receiver method `poll` should add generic names, e.g. poll + 4 | } + 5 | + 6 | fn (q Queue) poll() A { + | ~~~~ + 7 | return q.buffer[0] + 8 | } diff --git a/vlib/v/parser/tests/generic_multiple_receiver_method_has_no_generic_names_err.vv b/vlib/v/parser/tests/generic_multiple_receiver_method_has_no_generic_names_err.vv new file mode 100644 index 0000000000..29c0ef8edf --- /dev/null +++ b/vlib/v/parser/tests/generic_multiple_receiver_method_has_no_generic_names_err.vv @@ -0,0 +1,13 @@ +struct Queue{ + buffer []A + size B +} + +fn (q Queue) poll() A { + return q.buffer[0] +} + +fn main() { + q := Queue{} + println(q) +} diff --git a/vlib/v/parser/tests/generic_receiver_method_has_no_generic_names_err.out b/vlib/v/parser/tests/generic_receiver_method_has_no_generic_names_err.out new file mode 100644 index 0000000000..3682d147f5 --- /dev/null +++ b/vlib/v/parser/tests/generic_receiver_method_has_no_generic_names_err.out @@ -0,0 +1,7 @@ +vlib/v/parser/tests/generic_receiver_method_has_no_generic_names_err.vv:5:17: error: generic receiver method `poll` should add generic names, e.g. poll + 3 | } + 4 | + 5 | fn (q Queue) poll() T { + | ~~~~ + 6 | return q.buffer[0] + 7 | } diff --git a/vlib/v/parser/tests/generic_receiver_method_has_no_generic_names_err.vv b/vlib/v/parser/tests/generic_receiver_method_has_no_generic_names_err.vv new file mode 100644 index 0000000000..cb2eeb20f2 --- /dev/null +++ b/vlib/v/parser/tests/generic_receiver_method_has_no_generic_names_err.vv @@ -0,0 +1,12 @@ +struct Queue{ + buffer []T +} + +fn (q Queue) poll() T { + return q.buffer[0] +} + +fn main() { + q := Queue{} + println(q) +}