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
|
||||
&& !node.is_short_syntax {
|
||||
if c.table.cur_concrete_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 {
|
||||
&& !node.is_short_syntax && 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[T]',
|
||||
node.pos)
|
||||
} else if node.generic_types.len > 0
|
||||
|
@ -691,13 +688,12 @@ 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.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0 {
|
||||
if node.is_short_syntax {
|
||||
concrete_types := c.infer_struct_generic_types(node.typ, node)
|
||||
if concrete_types.len > 0 {
|
||||
generic_names := struct_sym.info.generic_types.map(c.table.sym(it).name)
|
||||
node.typ = c.table.unwrap_generic_type(node.typ, generic_names, concrete_types)
|
||||
}
|
||||
if struct_sym.info.generic_types.len > 0 && struct_sym.info.concrete_types.len == 0
|
||||
&& c.table.cur_concrete_types.len == 0 {
|
||||
concrete_types := c.infer_struct_generic_types(node.typ, node)
|
||||
if concrete_types.len > 0 {
|
||||
generic_names := struct_sym.info.generic_types.map(c.table.sym(it).name)
|
||||
node.typ = c.table.unwrap_generic_type(node.typ, generic_names, concrete_types)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,12 +3,6 @@ vlib/v/checker/tests/generic_interface_err.vv:10:1: warning: unused variable: `i
|
|||
9 | s := Struct{7}
|
||||
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`
|
||||
8 |
|
||||
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]
|
||||
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]
|
||||
vlib/v/checker/tests/generics_struct_init_err.vv:67:23: error: could not infer generic type `T` in call to `call`
|
||||
65 | ret = holder_call_22(neg, 5)
|
||||
66 | assert ret == -5
|
||||
67 | ret = FnHolder2{neg}.call(6)
|
||||
| ~~~~~~~~~~~~~~
|
||||
| ~~~~~~~
|
||||
68 | assert ret == -6
|
||||
69 | }
|
||||
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{}
|
||||
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`
|
||||
6 | // no segfault without generic
|
||||
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…
Reference in New Issue
Block a user