mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: check generic interface declaration (#15047)
This commit is contained in:
parent
28fd17654e
commit
7594157deb
@ -11,6 +11,7 @@ pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
||||
mut decl_sym := c.table.sym(node.typ)
|
||||
is_js := node.language == .js
|
||||
if mut decl_sym.info is ast.Interface {
|
||||
mut has_generic_types := false
|
||||
if node.embeds.len > 0 {
|
||||
all_embeds := c.expand_iface_embeds(node, 0, node.embeds)
|
||||
// eprintln('> node.name: $node.name | node.embeds.len: $node.embeds.len | all_embeds: $all_embeds.len')
|
||||
@ -31,6 +32,9 @@ pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
||||
}
|
||||
for embed in all_embeds {
|
||||
isym := c.table.sym(embed.typ)
|
||||
if embed.typ.has_flag(.generic) {
|
||||
has_generic_types = true
|
||||
}
|
||||
if isym.kind != .interface_ {
|
||||
c.error('interface `$node.name` tries to embed `$isym.name`, but `$isym.name` is not an interface, but `$isym.kind`',
|
||||
embed.pos)
|
||||
@ -109,10 +113,16 @@ pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
||||
c.error('method $method.name returns non JS type', method.pos)
|
||||
}
|
||||
}
|
||||
if method.return_type.has_flag(.generic) {
|
||||
has_generic_types = true
|
||||
}
|
||||
for j, param in method.params {
|
||||
if j == 0 && is_js {
|
||||
continue // no need to check first param
|
||||
}
|
||||
if param.typ.has_flag(.generic) {
|
||||
has_generic_types = true
|
||||
}
|
||||
c.ensure_type_exists(param.typ, param.pos) or { return }
|
||||
if param.name in reserved_type_names {
|
||||
c.error('invalid use of reserved type `$param.name` as a parameter name',
|
||||
@ -145,6 +155,9 @@ pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
||||
c.check_valid_snake_case(field.name, 'field name', field.pos)
|
||||
}
|
||||
c.ensure_type_exists(field.typ, field.pos) or { return }
|
||||
if field.typ.has_flag(.generic) {
|
||||
has_generic_types = true
|
||||
}
|
||||
if is_js {
|
||||
tsym := c.table.sym(field.typ)
|
||||
if !tsym.is_js_compatible() {
|
||||
@ -161,6 +174,10 @@ pub fn (mut c Checker) interface_decl(mut node ast.InterfaceDecl) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if node.generic_types.len == 0 && has_generic_types {
|
||||
c.error('generic interface declaration must specify the generic type names, e.g. Foo<T>',
|
||||
node.pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,5 @@
|
||||
vlib/v/checker/tests/generics_interface_declaration_err.vv:1:1: error: generic interface declaration must specify the generic type names, e.g. Foo<T>
|
||||
1 | interface Expr {
|
||||
| ~~~~~~~~~~~~~~~~
|
||||
2 | accept(v Visitor<R>) R
|
||||
3 | }
|
@ -0,0 +1,9 @@
|
||||
interface Expr {
|
||||
accept(v Visitor<R>) R
|
||||
}
|
||||
|
||||
interface Visitor<R> {
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
Loading…
Reference in New Issue
Block a user