1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: fix error assigning generic function variable with generic struct return (#18472)

This commit is contained in:
Turiiya 2023-06-18 21:22:22 +02:00 committed by GitHub
parent 017cc6738b
commit 0454f43fa3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 24 additions and 0 deletions

View File

@ -507,6 +507,16 @@ fn (mut c Checker) assign_stmt(mut node ast.AssignStmt) {
c.error('cannot copy map: call `move` or `clone` method (or use a reference)', c.error('cannot copy map: call `move` or `clone` method (or use a reference)',
right.pos()) right.pos())
} }
if left_sym.kind == .function && right_sym.info is ast.FnType {
return_sym := c.table.sym(right_sym.info.func.return_type)
if return_sym.kind == .placeholder {
c.error('unkown return type: cannot assign `${right}` as a function variable',
right.pos())
} else if (!right_sym.info.is_anon && return_sym.kind == .any)
|| (return_sym.info is ast.Struct && (return_sym.info as ast.Struct).is_generic) {
c.error('cannot assign `${right}` as a generic function variable', right.pos())
}
}
if left_type.is_any_kind_of_pointer() && !left.is_auto_deref_var() { if left_type.is_any_kind_of_pointer() && !left.is_auto_deref_var() {
if !c.inside_unsafe && node.op !in [.assign, .decl_assign] { if !c.inside_unsafe && node.op !in [.assign, .decl_assign] {
// ptr op= // ptr op=

View File

@ -5,6 +5,13 @@ vlib/v/checker/tests/generic_fn_infinite_loop_limit_err.vv:6:2: warning: unused
| ~~~ | ~~~
7 | // ff1 := f1[int] <-- is a valid usage with generic return types that are not generic structs 7 | // ff1 := f1[int] <-- is a valid usage with generic return types that are not generic structs
8 | } 8 | }
vlib/v/checker/tests/generic_fn_infinite_loop_limit_err.vv:6:9: error: cannot assign `f1` as a generic function variable
4 |
5 | fn main() {
6 | ff1 := f1 // <-- missing e.g. `[int]`
| ~~
7 | // ff1 := f1[int] <-- is a valid usage with generic return types that are not generic structs
8 | }
vlib/v/checker/tests/generic_fn_infinite_loop_limit_err.vv:1:1: error: generic function visited more than 10000 times vlib/v/checker/tests/generic_fn_infinite_loop_limit_err.vv:1:1: error: generic function visited more than 10000 times
1 | fn f1[T](x T, i int) T { 1 | fn f1[T](x T, i int) T {
| ~~~~~~~~~~~~~~~~~~~~~~ | ~~~~~~~~~~~~~~~~~~~~~~

View File

@ -5,3 +5,10 @@ Did you mean `[2]fn (u32) UnknownThing`?
| ~~~~~~~~~~~~ | ~~~~~~~~~~~~
3 | } 3 | }
4 | 4 |
vlib/v/checker/tests/unknown_array_fn_type_in_struct_field.vv:6:18: error: unkown return type: cannot assign `virt.fns[0]` as a function variable
4 |
5 | fn (virt Virt) caller() {
6 | func := virt.fns[0]
| ~~~
7 | func(5)
8 | }