mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: implement infering generic struct types (#17717)
This commit is contained in:
parent
977cd0d8df
commit
968b519be5
@ -297,11 +297,8 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0
|
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0
|
||||||
&& !node.is_short_syntax {
|
&& !node.is_short_syntax && c.table.cur_concrete_types.len != 0 {
|
||||||
if c.table.cur_concrete_types.len == 0 {
|
if node.generic_types.len == 0 {
|
||||||
c.error('generic struct init must specify type parameter, e.g. Foo[int]',
|
|
||||||
node.pos)
|
|
||||||
} else if node.generic_types.len == 0 {
|
|
||||||
c.error('generic struct init must specify type parameter, e.g. Foo[T]',
|
c.error('generic struct init must specify type parameter, e.g. Foo[T]',
|
||||||
node.pos)
|
node.pos)
|
||||||
} else if node.generic_types.len > 0
|
} else if node.generic_types.len > 0
|
||||||
@ -691,8 +688,8 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if struct_sym.info is ast.Struct {
|
if struct_sym.info is ast.Struct {
|
||||||
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0 {
|
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0
|
||||||
if node.is_short_syntax {
|
&& c.table.cur_concrete_types.len == 0 {
|
||||||
concrete_types := c.infer_struct_generic_types(node.typ, node)
|
concrete_types := c.infer_struct_generic_types(node.typ, node)
|
||||||
if concrete_types.len > 0 {
|
if concrete_types.len > 0 {
|
||||||
generic_names := struct_sym.info.generic_types.map(c.table.sym(it).name)
|
generic_names := struct_sym.info.generic_types.map(c.table.sym(it).name)
|
||||||
@ -700,7 +697,6 @@ fn (mut c Checker) struct_init(mut node ast.StructInit, is_field_zero_struct_ini
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return node.typ
|
return node.typ
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,12 +3,6 @@ vlib/v/checker/tests/generic_interface_err.vv:10:1: warning: unused variable: `i
|
|||||||
9 | s := Struct{7}
|
9 | s := Struct{7}
|
||||||
10 | i := Interface(s)
|
10 | i := Interface(s)
|
||||||
| ^
|
| ^
|
||||||
vlib/v/checker/tests/generic_interface_err.vv:9:6: error: generic struct init must specify type parameter, e.g. Foo[int]
|
|
||||||
7 | }
|
|
||||||
8 |
|
|
||||||
9 | s := Struct{7}
|
|
||||||
| ~~~~~~~~~
|
|
||||||
10 | i := Interface(s)
|
|
||||||
vlib/v/checker/tests/generic_interface_err.vv:10:6: error: can not find method `method` on `Struct`, needed for interface: `Interface`
|
vlib/v/checker/tests/generic_interface_err.vv:10:6: error: can not find method `method` on `Struct`, needed for interface: `Interface`
|
||||||
8 |
|
8 |
|
||||||
9 | s := Struct{7}
|
9 | s := Struct{7}
|
||||||
|
@ -1,15 +1,8 @@
|
|||||||
vlib/v/checker/tests/generics_struct_init_err.vv:58:8: error: generic struct init must specify type parameter, e.g. Foo[int]
|
vlib/v/checker/tests/generics_struct_init_err.vv:67:23: error: could not infer generic type `T` in call to `call`
|
||||||
56 | ret = holder_call_12(neg, 3)
|
|
||||||
57 | assert ret == -3
|
|
||||||
58 | ret = FnHolder1{neg}.call(4)
|
|
||||||
| ~~~~~~~~~~~~~~
|
|
||||||
59 | assert ret == -4
|
|
||||||
60 |
|
|
||||||
vlib/v/checker/tests/generics_struct_init_err.vv:67:8: error: generic struct init must specify type parameter, e.g. Foo[int]
|
|
||||||
65 | ret = holder_call_22(neg, 5)
|
65 | ret = holder_call_22(neg, 5)
|
||||||
66 | assert ret == -5
|
66 | assert ret == -5
|
||||||
67 | ret = FnHolder2{neg}.call(6)
|
67 | ret = FnHolder2{neg}.call(6)
|
||||||
| ~~~~~~~~~~~~~~
|
| ~~~~~~~
|
||||||
68 | assert ret == -6
|
68 | assert ret == -6
|
||||||
69 | }
|
69 | }
|
||||||
vlib/v/checker/tests/generics_struct_init_err.vv:22:7: error: generic struct init must specify type parameter, e.g. Foo[T]
|
vlib/v/checker/tests/generics_struct_init_err.vv:22:7: error: generic struct init must specify type parameter, e.g. Foo[T]
|
||||||
|
@ -3,12 +3,6 @@ vlib/v/checker/tests/interface_generic_err.vv:8:1: warning: unused variable: `wh
|
|||||||
7 | what := What{}
|
7 | what := What{}
|
||||||
8 | why := Why(what)
|
8 | why := Why(what)
|
||||||
| ~~~
|
| ~~~
|
||||||
vlib/v/checker/tests/interface_generic_err.vv:7:9: error: generic struct init must specify type parameter, e.g. Foo[int]
|
|
||||||
5 |
|
|
||||||
6 | // no segfault without generic
|
|
||||||
7 | what := What{}
|
|
||||||
| ~~~~~~
|
|
||||||
8 | why := Why(what)
|
|
||||||
vlib/v/checker/tests/interface_generic_err.vv:8:8: error: could not infer generic type `T` in interface `Why`
|
vlib/v/checker/tests/interface_generic_err.vv:8:8: error: could not infer generic type `T` in interface `Why`
|
||||||
6 | // no segfault without generic
|
6 | // no segfault without generic
|
||||||
7 | what := What{}
|
7 | what := What{}
|
||||||
|
36
vlib/v/tests/generics_struct_types_infer_test.v
Normal file
36
vlib/v/tests/generics_struct_types_infer_test.v
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
struct Foo[T, U] {
|
||||||
|
a T
|
||||||
|
b U
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_generic_struct_types_infer() {
|
||||||
|
st11 := Foo{'two', 2}
|
||||||
|
println(st11.a)
|
||||||
|
println(st11.b)
|
||||||
|
assert st11.a == 'two'
|
||||||
|
assert st11.b == 2
|
||||||
|
|
||||||
|
st12 := Foo{
|
||||||
|
a: 'two'
|
||||||
|
b: 2
|
||||||
|
}
|
||||||
|
println(st12.a)
|
||||||
|
println(st12.b)
|
||||||
|
assert st12.a == 'two'
|
||||||
|
assert st12.b == 2
|
||||||
|
|
||||||
|
st21 := Foo{1, 'one'}
|
||||||
|
println(st21.a)
|
||||||
|
println(st21.b)
|
||||||
|
assert st21.a == 1
|
||||||
|
assert st21.b == 'one'
|
||||||
|
|
||||||
|
st22 := Foo{
|
||||||
|
a: 1
|
||||||
|
b: 'one'
|
||||||
|
}
|
||||||
|
println(st22.a)
|
||||||
|
println(st22.b)
|
||||||
|
assert st22.a == 1
|
||||||
|
assert st22.b == 'one'
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user