mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: check generic struct declaration (#15106)
This commit is contained in:
parent
368cccb059
commit
eed496d0bc
@ -24,6 +24,18 @@ pub fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
|
|||||||
struct_sym.info.is_heap = true
|
struct_sym.info.is_heap = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Ensure each generic type of the embed was declared in the struct's definition
|
||||||
|
if node.generic_types.len > 0 && embed.typ.has_flag(.generic) {
|
||||||
|
embed_generic_names := c.table.generic_type_names(embed.typ)
|
||||||
|
node_generic_names := node.generic_types.map(c.table.type_to_str(it))
|
||||||
|
for name in embed_generic_names {
|
||||||
|
if name !in node_generic_names {
|
||||||
|
struct_generic_names := node_generic_names.join(', ')
|
||||||
|
c.error('generic type name `$name` is not mentioned in struct `$node.name<$struct_generic_names>`',
|
||||||
|
embed.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if struct_sym.info.is_minify {
|
if struct_sym.info.is_minify {
|
||||||
node.fields.sort_with_compare(minify_sort_fn)
|
node.fields.sort_with_compare(minify_sort_fn)
|
||||||
@ -122,6 +134,18 @@ pub fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Ensure each generic type of the field was declared in the struct's definition
|
||||||
|
if node.generic_types.len > 0 && field.typ.has_flag(.generic) {
|
||||||
|
field_generic_names := c.table.generic_type_names(field.typ)
|
||||||
|
node_generic_names := node.generic_types.map(c.table.type_to_str(it))
|
||||||
|
for name in field_generic_names {
|
||||||
|
if name !in node_generic_names {
|
||||||
|
struct_generic_names := node_generic_names.join(', ')
|
||||||
|
c.error('generic type name `$name` is not mentioned in struct `$node.name<$struct_generic_names>`',
|
||||||
|
field.type_pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if node.generic_types.len == 0 && has_generic_types {
|
if node.generic_types.len == 0 && has_generic_types {
|
||||||
c.error('generic struct declaration must specify the generic type names, e.g. Foo<T>',
|
c.error('generic struct declaration must specify the generic type names, e.g. Foo<T>',
|
||||||
|
14
vlib/v/checker/tests/generics_struct_decl_no_mention_err.out
Normal file
14
vlib/v/checker/tests/generics_struct_decl_no_mention_err.out
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
vlib/v/checker/tests/generics_struct_decl_no_mention_err.vv:4:2: error: generic type name `T` is not mentioned in struct `Foo<U>`
|
||||||
|
2 |
|
||||||
|
3 | struct Foo<U> {
|
||||||
|
4 | Bar<T>
|
||||||
|
| ~~~~~~
|
||||||
|
5 | foo U
|
||||||
|
6 | bar P
|
||||||
|
vlib/v/checker/tests/generics_struct_decl_no_mention_err.vv:6:6: error: generic type name `P` is not mentioned in struct `Foo<U>`
|
||||||
|
4 | Bar<T>
|
||||||
|
5 | foo U
|
||||||
|
6 | bar P
|
||||||
|
| ^
|
||||||
|
7 | }
|
||||||
|
8 |
|
10
vlib/v/checker/tests/generics_struct_decl_no_mention_err.vv
Normal file
10
vlib/v/checker/tests/generics_struct_decl_no_mention_err.vv
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
fn main() {}
|
||||||
|
|
||||||
|
struct Foo<U> {
|
||||||
|
Bar<T>
|
||||||
|
foo U
|
||||||
|
bar P
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Bar<T> {
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user