mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: make implementing an interface with another interface an error (#8398)
This commit is contained in:
parent
adb646a1d2
commit
4aee997689
@ -1870,6 +1870,11 @@ fn (mut c Checker) type_implements(typ table.Type, inter_typ table.Type, pos tok
|
||||
typ_sym := c.table.get_type_symbol(typ)
|
||||
mut inter_sym := c.table.get_type_symbol(inter_typ)
|
||||
styp := c.table.type_to_str(typ)
|
||||
same_base_type := typ.idx() == inter_typ.idx()
|
||||
if typ_sym.kind == .interface_ && inter_sym.kind == .interface_ && !same_base_type {
|
||||
c.error('cannot implement interface `$inter_sym.name` with a different interface `$styp`',
|
||||
pos)
|
||||
}
|
||||
imethods := if inter_sym.kind == .interface_ {
|
||||
(inter_sym.info as table.Interface).methods
|
||||
} else {
|
||||
@ -3566,6 +3571,8 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type {
|
||||
type_name := c.table.type_to_str(node.expr_type)
|
||||
c.error('cannot cast `$type_name` to struct', node.pos)
|
||||
}
|
||||
} else if to_type_sym.kind == .interface_ {
|
||||
c.type_implements(node.expr_type, node.typ, node.pos)
|
||||
} else if node.typ == table.bool_type {
|
||||
c.error('cannot cast to bool - use e.g. `some_int != 0` instead', node.pos)
|
||||
} else if node.expr_type == table.none_type {
|
||||
@ -3575,8 +3582,6 @@ pub fn (mut c Checker) cast_expr(mut node ast.CastExpr) table.Type {
|
||||
if (node.typ.is_ptr() || to_type_sym.kind !in [.sum_type, .interface_]) && !c.is_builtin_mod {
|
||||
type_name := c.table.type_to_str(node.typ)
|
||||
c.error('cannot cast struct to `$type_name`', node.pos)
|
||||
} else if to_type_sym.kind == .interface_ {
|
||||
c.type_implements(node.expr_type, node.typ, node.pos)
|
||||
}
|
||||
} else if node.expr_type.has_flag(.optional) || node.expr_type.has_flag(.variadic) {
|
||||
// variadic case can happen when arrays are converted into variadic
|
||||
|
@ -0,0 +1,6 @@
|
||||
vlib/v/checker/tests/interface_implementing_interface.vv:15:10: error: cannot implement interface `Thing` with a different interface `Animal`
|
||||
13 | dog := Dog{}
|
||||
14 | animal := Animal(dog)
|
||||
15 | thing := Thing(animal)
|
||||
| ~~~~~~~~~~~~~
|
||||
16 | println(thing)
|
16
vlib/v/checker/tests/interface_implementing_interface.vv
Normal file
16
vlib/v/checker/tests/interface_implementing_interface.vv
Normal file
@ -0,0 +1,16 @@
|
||||
interface Thing {
|
||||
kind string
|
||||
}
|
||||
|
||||
interface Animal {
|
||||
kind string
|
||||
}
|
||||
|
||||
struct Dog {
|
||||
kind string = 'labrador'
|
||||
}
|
||||
|
||||
dog := Dog{}
|
||||
animal := Animal(dog)
|
||||
thing := Thing(animal)
|
||||
println(thing)
|
@ -60,11 +60,4 @@ vlib/v/checker/tests/struct_type_cast_err.vv:13:10: error: cannot cast struct to
|
||||
13 | _ := int(foo)
|
||||
| ~~~~~~~~
|
||||
14 | _ = &I1(foo)
|
||||
15 | }
|
||||
vlib/v/checker/tests/struct_type_cast_err.vv:14:10: error: cannot cast struct to `&I1`
|
||||
12 | _ := i64(foo)
|
||||
13 | _ := int(foo)
|
||||
14 | _ = &I1(foo)
|
||||
| ~~~~~~~
|
||||
15 | }
|
||||
16 |
|
||||
15 | }
|
Loading…
Reference in New Issue
Block a user