parser: check generic receiver method decl has no generic names (fix parts of #9811) (#9819)

pull/9833/head
yuyi 2021-04-21 02:38:17 +08:00 committed by GitHub
parent 2df260acbb
commit 953057ef35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 50 additions and 6 deletions

View File

@ -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
}
}
// <T>
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<T>',
name_pos)
}
// Args
args2, are_args_type_only, is_variadic := p.fn_args()
params << args2

View File

@ -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<T>
4 | }
5 |
6 | fn (q Queue<A, B>) poll() A {
| ~~~~
7 | return q.buffer[0]
8 | }

View File

@ -0,0 +1,13 @@
struct Queue<A, B>{
buffer []A
size B
}
fn (q Queue<A, B>) poll() A {
return q.buffer[0]
}
fn main() {
q := Queue<string, int>{}
println(q)
}

View File

@ -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<T>
3 | }
4 |
5 | fn (q Queue<T>) poll() T {
| ~~~~
6 | return q.buffer[0]
7 | }

View File

@ -0,0 +1,12 @@
struct Queue<T>{
buffer []T
}
fn (q Queue<T>) poll() T {
return q.buffer[0]
}
fn main() {
q := Queue<int>{}
println(q)
}