checker: check argument type error of the generics fn declaration (#12539)

pull/12550/head
yuyi 2021-11-23 04:39:20 +08:00 committed by GitHub
parent bf7074cad4
commit fbe2b5cb58
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 46 additions and 10 deletions

View File

@ -8258,6 +8258,25 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
mut v := node.scope.find_var(param.name) or { continue }
v.is_auto_heap = true
}
if info.generic_types.len > 0 && !param.typ.has_flag(.generic)
&& info.concrete_types.len == 0 {
c.error('generic struct in fn declaration must specify the generic type names, e.g. Foo<T>',
param.type_pos)
}
} else if arg_typ_sym.kind == .interface_ {
info := arg_typ_sym.info as ast.Interface
if info.generic_types.len > 0 && !param.typ.has_flag(.generic)
&& info.concrete_types.len == 0 {
c.error('generic interface in fn declaration must specify the generic type names, e.g. Foo<T>',
param.type_pos)
}
} else if arg_typ_sym.kind == .sum_type {
info := arg_typ_sym.info as ast.SumType
if info.generic_types.len > 0 && !param.typ.has_flag(.generic)
&& info.concrete_types.len == 0 {
c.error('generic sumtype in fn declaration must specify the generic type names, e.g. Foo<T>',
param.type_pos)
}
}
}
if c.pref.translated && node.is_variadic && node.params.len == 1 && param.typ.is_ptr() {
@ -8366,15 +8385,6 @@ 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<T>', node.method_type_pos)
}
}
}
node.source_file = c.file
}

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/generics_fn_arg_type_err.vv:14:23: error: generic interface in fn declaration must specify the generic type names, e.g. Foo<T>
12 | }
13 |
14 | fn do_list_thing(list List) { // <--- Error here
| ~~~~
15 | // ...
16 | }

View File

@ -0,0 +1,19 @@
interface List<T> {
mut:
add(e T) bool
}
struct LinkedList<T> {
// ...
}
fn (mut list LinkedList<T>) add(e T) {
// ...
}
fn do_list_thing(list List) { // <--- Error here
// ...
}
fn main() {
}

View File

@ -1,4 +1,4 @@
vlib/v/checker/tests/generics_method_receiver_type_err.vv:6:11: error: receiver must specify the generic type names, e.g. Foo<T>
vlib/v/checker/tests/generics_method_receiver_type_err.vv:6:11: error: generic struct in fn declaration must specify the generic type names, e.g. Foo<T>
4 | }
5 |
6 | pub fn (x Node) str() string {