checker: check the arity and the kinds of the type parameters in generic struct inits (#13429)
parent
7f29418c63
commit
a21f4563b3
|
@ -138,6 +138,20 @@ pub fn (mut c Checker) struct_init(mut node ast.StructInit) ast.Type {
|
|||
} else 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
|
||||
&& node.generic_types.len != struct_sym.info.generic_types.len {
|
||||
c.error('generic struct init expects $struct_sym.info.generic_types.len generic parameter, but got $node.generic_types.len',
|
||||
node.pos)
|
||||
} else if node.generic_types.len > 0 {
|
||||
for gtyp in node.generic_types {
|
||||
gtyp_name := c.table.sym(gtyp).name
|
||||
if gtyp_name !in c.table.cur_fn.generic_names {
|
||||
cur_generic_names := '(' + c.table.cur_fn.generic_names.join(',') + ')'
|
||||
c.error('generic struct init type parameter `$gtyp_name` must be within the parameters `$cur_generic_names` of the current generic function',
|
||||
node.pos)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if node.generic_types.len > 0 && struct_sym.info.generic_types != node.generic_types {
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
vlib/v/checker/tests/generics_struct_init_type_parameter_count_err.vv:6:9: error: generic struct init expects 1 generic parameter, but got 2
|
||||
4 |
|
||||
5 | pub fn send<A, B>(res A, b B) string {
|
||||
6 | msg := Response<A, B>{
|
||||
| ~~~~~~~~~~~~~~~
|
||||
7 | result: res
|
||||
8 | }
|
|
@ -0,0 +1,16 @@
|
|||
struct Response<U> {
|
||||
result U
|
||||
}
|
||||
|
||||
pub fn send<A, B>(res A, b B) string {
|
||||
msg := Response<A, B>{
|
||||
result: res
|
||||
}
|
||||
println(b)
|
||||
return '$msg'
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mut ret := send(123, 22.2)
|
||||
println(ret)
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
vlib/v/checker/tests/generics_struct_init_type_parameter_err.vv:6:9: error: generic struct init type parameter `U` must be within the parameters `(A,B)` of the current generic function
|
||||
4 |
|
||||
5 | pub fn send<A, B>(res A, b B) string {
|
||||
6 | msg := Response<U>{
|
||||
| ~~~~~~~~~~~~
|
||||
7 | result: res
|
||||
8 | }
|
||||
vlib/v/checker/tests/generics_struct_init_type_parameter_err.vv:7:3: error: cannot assign to field `result`: expected `U`, not `int`
|
||||
5 | pub fn send<A, B>(res A, b B) string {
|
||||
6 | msg := Response<U>{
|
||||
7 | result: res
|
||||
| ~~~~~~~~~~~
|
||||
8 | }
|
||||
9 | println(b)
|
|
@ -0,0 +1,16 @@
|
|||
struct Response<U> {
|
||||
result U
|
||||
}
|
||||
|
||||
pub fn send<A, B>(res A, b B) string {
|
||||
msg := Response<U>{
|
||||
result: res
|
||||
}
|
||||
println(b)
|
||||
return '$msg'
|
||||
}
|
||||
|
||||
fn main() {
|
||||
mut ret := send(123, 22.2)
|
||||
println(ret)
|
||||
}
|
Loading…
Reference in New Issue