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 }
|
mut v := node.scope.find_var(param.name) or { continue }
|
||||||
v.is_auto_heap = true
|
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() {
|
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)
|
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
|
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 | }
|
4 | }
|
||||||
5 |
|
5 |
|
||||||
6 | pub fn (x Node) str() string {
|
6 | pub fn (x Node) str() string {
|
||||||
|
|
Loading…
Reference in New Issue