parent
3175525b5e
commit
ae22967d1d
|
@ -6752,6 +6752,24 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||||
c.file.generic_fns << node
|
c.file.generic_fns << node
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
// Check generics fn/method without generic type parameters
|
||||||
|
mut need_generic_names := false
|
||||||
|
if node.generic_names.len == 0 {
|
||||||
|
if node.return_type.has_flag(.generic) {
|
||||||
|
need_generic_names = true
|
||||||
|
} else {
|
||||||
|
for param in node.params {
|
||||||
|
if param.typ.has_flag(.generic) {
|
||||||
|
need_generic_names = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if need_generic_names {
|
||||||
|
c.error('generic function declaration must specify generic type names, e.g. foo<T>',
|
||||||
|
node.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
if node.language == .v && !c.is_builtin_mod {
|
if node.language == .v && !c.is_builtin_mod {
|
||||||
c.check_valid_snake_case(node.name, 'function name', node.pos)
|
c.check_valid_snake_case(node.name, 'function name', node.pos)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
vlib/v/checker/tests/generic_fn_decl_without_generic_names_err.vv:26:1: error: generic function declaration must specify generic type names, e.g. foo<T>
|
||||||
|
24 | }
|
||||||
|
25 |
|
||||||
|
26 | fn g_worker(g Generic<T>) {
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
27 | t := <-g.ch
|
||||||
|
28 | handle(t)
|
||||||
|
vlib/v/checker/tests/generic_fn_decl_without_generic_names_err.vv:32:1: error: generic function declaration must specify generic type names, e.g. foo<T>
|
||||||
|
30 | }
|
||||||
|
31 |
|
||||||
|
32 | fn handle(t T) {
|
||||||
|
| ~~~~~~~~~~~~~~
|
||||||
|
33 | println("hi")
|
||||||
|
34 | }
|
|
@ -0,0 +1,34 @@
|
||||||
|
struct Generic<T> {
|
||||||
|
ch chan T
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Concrete {
|
||||||
|
msg string
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
g := create_generic_t<Concrete>()
|
||||||
|
g.ch <- Concrete{
|
||||||
|
msg: 'hello'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_generic_t<T>() Generic<T> {
|
||||||
|
g := Generic{
|
||||||
|
ch: chan T{}
|
||||||
|
}
|
||||||
|
|
||||||
|
go g_worker(g)
|
||||||
|
|
||||||
|
return g
|
||||||
|
}
|
||||||
|
|
||||||
|
fn g_worker(g Generic<T>) {
|
||||||
|
t := <-g.ch
|
||||||
|
handle(t)
|
||||||
|
// println("${t.msg}")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle(t T) {
|
||||||
|
println("hi")
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
vlib/v/checker/tests/receiver_unknown_type_single_letter.vv:1:5: error: unknown type `A`
|
vlib/v/checker/tests/receiver_unknown_type_single_letter.vv:1:1: error: unknown type `Abc`
|
||||||
1 | fn (p A) foo() {}
|
1 | fn (p Abc) foo() {}
|
||||||
| ~~~
|
| ~~~~~~~~~~~~~~~~
|
||||||
2 |
|
2 |
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
fn (p A) foo() {}
|
fn (p Abc) foo() {}
|
||||||
|
|
||||||
|
|
|
@ -336,6 +336,7 @@ fn (mut p Parser) fn_decl() ast.FnDecl {
|
||||||
short_fn_name := name
|
short_fn_name := name
|
||||||
is_main := short_fn_name == 'main' && p.mod == 'main'
|
is_main := short_fn_name == 'main' && p.mod == 'main'
|
||||||
is_test := short_fn_name.starts_with('test_') || short_fn_name.starts_with('testsuite_')
|
is_test := short_fn_name.starts_with('test_') || short_fn_name.starts_with('testsuite_')
|
||||||
|
|
||||||
// Register
|
// Register
|
||||||
if is_method {
|
if is_method {
|
||||||
mut type_sym := p.table.get_type_symbol(rec.typ)
|
mut type_sym := p.table.get_type_symbol(rec.typ)
|
||||||
|
|
Loading…
Reference in New Issue