mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: check generic fn declaration (#15104)
This commit is contained in:
parent
78242627c3
commit
58ad6f7999
@ -108,6 +108,17 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||
} else if return_sym.kind == .array_fixed {
|
||||
c.error('fixed array cannot be returned by function', node.return_type_pos)
|
||||
}
|
||||
// Ensure each generic type of the parameter was declared in the function's definition
|
||||
if node.return_type.has_flag(.generic) {
|
||||
generic_names := c.table.generic_type_names(node.return_type)
|
||||
for name in generic_names {
|
||||
if name !in node.generic_names {
|
||||
fn_generic_names := node.generic_names.join(', ')
|
||||
c.error('generic type name `$name` is not mentioned in fn `$node.name<$fn_generic_names>`',
|
||||
node.return_type_pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for mut a in node.attrs {
|
||||
if a.kind == .comptime_define {
|
||||
@ -207,6 +218,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
|
||||
}
|
||||
}
|
||||
}
|
||||
// Ensure each generic type of the parameter was declared in the function's definition
|
||||
if param.typ.has_flag(.generic) {
|
||||
generic_names := c.table.generic_type_names(param.typ)
|
||||
for name in generic_names {
|
||||
|
35
vlib/v/checker/tests/generic_fn_decl_err.out
Normal file
35
vlib/v/checker/tests/generic_fn_decl_err.out
Normal file
@ -0,0 +1,35 @@
|
||||
vlib/v/checker/tests/generic_fn_decl_err.vv:19:29: error: generic type name `P` is not mentioned in fn `create1<U>`
|
||||
17 | }
|
||||
18 |
|
||||
19 | fn (r Db) create1<U>(u U, p P) {
|
||||
| ^
|
||||
20 | println('Yo')
|
||||
21 | }
|
||||
vlib/v/checker/tests/generic_fn_decl_err.vv:23:29: error: generic type name `P` is not mentioned in fn `create2<U>`
|
||||
21 | }
|
||||
22 |
|
||||
23 | fn (r Db) create2<U>(u U, p &P) {
|
||||
| ~~
|
||||
24 | println('Yo')
|
||||
25 | }
|
||||
vlib/v/checker/tests/generic_fn_decl_err.vv:27:29: error: generic type name `P` is not mentioned in fn `create3<U>`
|
||||
25 | }
|
||||
26 |
|
||||
27 | fn (r Db) create3<U>(u U, p []P) {
|
||||
| ~~~
|
||||
28 | println('Yo')
|
||||
29 | }
|
||||
vlib/v/checker/tests/generic_fn_decl_err.vv:31:27: error: generic type name `P` is not mentioned in fn `create4<U>`
|
||||
29 | }
|
||||
30 |
|
||||
31 | fn (r Db) create4<U>(u U) P {
|
||||
| ^
|
||||
32 | return P{}
|
||||
33 | }
|
||||
vlib/v/checker/tests/generic_fn_decl_err.vv:35:27: error: generic type name `P` is not mentioned in fn `create5<U>`
|
||||
33 | }
|
||||
34 |
|
||||
35 | fn (r Db) create5<U>(u U) []P {
|
||||
| ~~~
|
||||
36 | return [P{}]
|
||||
37 | }
|
37
vlib/v/checker/tests/generic_fn_decl_err.vv
Normal file
37
vlib/v/checker/tests/generic_fn_decl_err.vv
Normal file
@ -0,0 +1,37 @@
|
||||
module main
|
||||
|
||||
struct Db {}
|
||||
struct User {}
|
||||
struct Post {}
|
||||
|
||||
fn main() {
|
||||
r := Db{}
|
||||
u := User{}
|
||||
p := Post{}
|
||||
|
||||
r.create1(u, p)
|
||||
r.create2(u, &p)
|
||||
r.create3(u, [p])
|
||||
r.create4(u)
|
||||
r.create5(u)
|
||||
}
|
||||
|
||||
fn (r Db) create1<U>(u U, p P) {
|
||||
println('Yo')
|
||||
}
|
||||
|
||||
fn (r Db) create2<U>(u U, p &P) {
|
||||
println('Yo')
|
||||
}
|
||||
|
||||
fn (r Db) create3<U>(u U, p []P) {
|
||||
println('Yo')
|
||||
}
|
||||
|
||||
fn (r Db) create4<U>(u U) P {
|
||||
return P{}
|
||||
}
|
||||
|
||||
fn (r Db) create5<U>(u U) []P {
|
||||
return [P{}]
|
||||
}
|
@ -1,7 +0,0 @@
|
||||
vlib/v/checker/tests/generic_fn_decl_err_a.vv:17:28: error: generic type name `P` is not mentioned in fn `create<U>`
|
||||
15 | }
|
||||
16 |
|
||||
17 | fn (r Db) create<U>(u U, p P) {
|
||||
| ^
|
||||
18 | println('Yo')
|
||||
19 | }
|
@ -1,19 +0,0 @@
|
||||
module main
|
||||
|
||||
struct Db {}
|
||||
|
||||
struct User {}
|
||||
|
||||
struct Post {}
|
||||
|
||||
fn main() {
|
||||
r := Db{}
|
||||
u := User{}
|
||||
p := Post{}
|
||||
|
||||
r.create(u, p)
|
||||
}
|
||||
|
||||
fn (r Db) create<U>(u U, p P) {
|
||||
println('Yo')
|
||||
}
|
Loading…
Reference in New Issue
Block a user