checker: check argument type error of the generics fn declaration (#12539)
parent
bf7074cad4
commit
fbe2b5cb58
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 | }
|
|
@ -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() {
|
||||
}
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue