mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: check generic interface declaration (#15108)
This commit is contained in:
parent
706a922e0c
commit
5462d4aebf
@ -40,6 +40,18 @@ pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
|||||||
embed.pos)
|
embed.pos)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
// Ensure each generic type of the embed was declared in the interface'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 {
|
||||||
|
interface_generic_names := node_generic_names.join(', ')
|
||||||
|
c.error('generic type name `$name` is not mentioned in interface `$node.name<$interface_generic_names>`',
|
||||||
|
embed.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
isym_info := isym.info as ast.Interface
|
isym_info := isym.info as ast.Interface
|
||||||
for f in isym_info.fields {
|
for f in isym_info.fields {
|
||||||
if !efnames_ds_info[f.name] {
|
if !efnames_ds_info[f.name] {
|
||||||
@ -115,6 +127,18 @@ pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
|||||||
}
|
}
|
||||||
if method.return_type.has_flag(.generic) {
|
if method.return_type.has_flag(.generic) {
|
||||||
has_generic_types = true
|
has_generic_types = true
|
||||||
|
// Ensure each generic type of the method was declared in the interface's definition
|
||||||
|
if node.generic_types.len > 0 {
|
||||||
|
method_generic_names := c.table.generic_type_names(method.return_type)
|
||||||
|
node_generic_names := node.generic_types.map(c.table.type_to_str(it))
|
||||||
|
for name in method_generic_names {
|
||||||
|
if name !in node_generic_names {
|
||||||
|
interface_generic_names := node_generic_names.join(', ')
|
||||||
|
c.error('generic type name `$name` is not mentioned in interface `$node.name<$interface_generic_names>`',
|
||||||
|
method.return_type_pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for j, param in method.params {
|
for j, param in method.params {
|
||||||
if j == 0 && is_js {
|
if j == 0 && is_js {
|
||||||
@ -128,6 +152,18 @@ pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
|||||||
c.error('invalid use of reserved type `$param.name` as a parameter name',
|
c.error('invalid use of reserved type `$param.name` as a parameter name',
|
||||||
param.pos)
|
param.pos)
|
||||||
}
|
}
|
||||||
|
// Ensure each generic type of the method was declared in the interface's definition
|
||||||
|
if node.generic_types.len > 0 && param.typ.has_flag(.generic) {
|
||||||
|
method_generic_names := c.table.generic_type_names(param.typ)
|
||||||
|
node_generic_names := node.generic_types.map(c.table.type_to_str(it))
|
||||||
|
for name in method_generic_names {
|
||||||
|
if name !in node_generic_names {
|
||||||
|
interface_generic_names := node_generic_names.join(', ')
|
||||||
|
c.error('generic type name `$name` is not mentioned in interface `$node.name<$interface_generic_names>`',
|
||||||
|
param.type_pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if is_js {
|
if is_js {
|
||||||
ptyp := c.table.sym(param.typ)
|
ptyp := c.table.sym(param.typ)
|
||||||
if !ptyp.is_js_compatible() && !(j == method.params.len - 1
|
if !ptyp.is_js_compatible() && !(j == method.params.len - 1
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
vlib/v/checker/tests/generics_interface_decl_no_mention_err.vv:4:2: error: generic type name `T` is not mentioned in interface `Foo<U>`
|
||||||
|
2 |
|
||||||
|
3 | interface Foo<U> {
|
||||||
|
4 | Bar<T>
|
||||||
|
| ~~~
|
||||||
|
5 | foo(u U, p P)
|
||||||
|
6 | bar(u U) []P
|
||||||
|
vlib/v/checker/tests/generics_interface_decl_no_mention_err.vv:5:13: error: generic type name `P` is not mentioned in interface `Foo<U>`
|
||||||
|
3 | interface Foo<U> {
|
||||||
|
4 | Bar<T>
|
||||||
|
5 | foo(u U, p P)
|
||||||
|
| ^
|
||||||
|
6 | bar(u U) []P
|
||||||
|
7 | }
|
||||||
|
vlib/v/checker/tests/generics_interface_decl_no_mention_err.vv:6:11: error: generic type name `P` is not mentioned in interface `Foo<U>`
|
||||||
|
4 | Bar<T>
|
||||||
|
5 | foo(u U, p P)
|
||||||
|
6 | bar(u U) []P
|
||||||
|
| ~~~
|
||||||
|
7 | }
|
||||||
|
8 |
|
@ -0,0 +1,10 @@
|
|||||||
|
fn main() {}
|
||||||
|
|
||||||
|
interface Foo<U> {
|
||||||
|
Bar<T>
|
||||||
|
foo(u U, p P)
|
||||||
|
bar(u U) []P
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Bar<T> {
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user