mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
checker: fix the check of types not implemented by interfaces in infix key_is and not_is (fix #16282 #16298) (#16284)
This commit is contained in:
parent
14f90b1196
commit
5c7ceb16dd
@ -554,7 +554,12 @@ pub fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type {
|
||||
c.error('`$op` can only be used with interfaces and sum types', node.pos)
|
||||
} else if mut left_sym.info is ast.SumType {
|
||||
if typ !in left_sym.info.variants {
|
||||
c.error('`$left_sym.name` has no variant `$right_sym.name`', node.pos)
|
||||
c.error('`$left_sym.name` has no variant `$right_sym.name`', right_pos)
|
||||
}
|
||||
} else if left_sym.info is ast.Interface {
|
||||
if typ_sym.kind != .interface_ && !c.type_implements(typ, left_type, right_pos) {
|
||||
c.error("`$typ_sym.name` doesn't implement interface `$left_sym.name`",
|
||||
right_pos)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
vlib/v/checker/tests/generic_sumtype_invalid_variant.vv:5:7: error: `MultiGeneric<bool, int, string>` has no variant `u64`
|
||||
vlib/v/checker/tests/generic_sumtype_invalid_variant.vv:5:10: error: `MultiGeneric<bool, int, string>` has no variant `u64`
|
||||
3 | fn main() {
|
||||
4 | mut m := MultiGeneric<bool, int, string>(true)
|
||||
5 | if m is u64 {
|
||||
| ~~
|
||||
| ~~~
|
||||
6 | println('hi')
|
||||
7 | }
|
||||
vlib/v/checker/tests/generic_sumtype_invalid_variant.vv:8:7: error: `MultiGeneric<bool, int, string>` has no variant `X`
|
||||
vlib/v/checker/tests/generic_sumtype_invalid_variant.vv:8:10: error: `MultiGeneric<bool, int, string>` has no variant `X`
|
||||
6 | println('hi')
|
||||
7 | }
|
||||
8 | if m is X {
|
||||
| ~~
|
||||
| ^
|
||||
9 | println('hi again')
|
||||
10 | }
|
||||
|
@ -0,0 +1,20 @@
|
||||
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:8:14: error: `int` doesn't implement interface `IError`
|
||||
6 | if _ := f() {
|
||||
7 | } else {
|
||||
8 | _ = err is int
|
||||
| ~~~
|
||||
9 | }
|
||||
10 |
|
||||
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:12:14: error: `int` doesn't implement interface `IError`
|
||||
10 |
|
||||
11 | _ = f() or {
|
||||
12 | _ = err is int
|
||||
| ~~~
|
||||
13 | 0
|
||||
14 | }
|
||||
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:27:17: error: `int` doesn't implement method `some_method` of interface `IAbc`
|
||||
25 | fn type_unimplemented_interface() {
|
||||
26 | ivalue := IAbc(Struct{})
|
||||
27 | _ := ivalue is int
|
||||
| ~~~
|
||||
28 | }
|
@ -0,0 +1,28 @@
|
||||
fn f() ?int {
|
||||
return none
|
||||
}
|
||||
|
||||
fn type_unimplemented_ierror() {
|
||||
if _ := f() {
|
||||
} else {
|
||||
_ = err is int
|
||||
}
|
||||
|
||||
_ = f() or {
|
||||
_ = err is int
|
||||
0
|
||||
}
|
||||
}
|
||||
|
||||
interface IAbc {
|
||||
some_method()
|
||||
}
|
||||
|
||||
struct Struct {}
|
||||
|
||||
fn (s Struct) some_method() {}
|
||||
|
||||
fn type_unimplemented_interface() {
|
||||
ivalue := IAbc(Struct{})
|
||||
_ := ivalue is int
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
vlib/v/checker/tests/is_type_invalid.vv:14:12: error: `IoS` has no variant `u8`
|
||||
vlib/v/checker/tests/is_type_invalid.vv:14:15: error: `IoS` has no variant `u8`
|
||||
12 |
|
||||
13 | fn main() {
|
||||
14 | if IoS(1) is u8 {
|
||||
| ~~
|
||||
| ~~
|
||||
15 | println('not cool')
|
||||
16 | }
|
||||
vlib/v/checker/tests/is_type_invalid.vv:18:7: error: `Cat` doesn't implement method `speak` of interface `Animal`
|
||||
vlib/v/checker/tests/is_type_invalid.vv:18:10: error: `Cat` doesn't implement method `speak` of interface `Animal`
|
||||
16 | }
|
||||
17 | a := Animal(Dog{})
|
||||
18 | if a is Cat {
|
||||
| ~~
|
||||
| ~~~
|
||||
19 | println('not cool either')
|
||||
20 | }
|
||||
|
@ -1,12 +1,12 @@
|
||||
struct Node<T> {
|
||||
mut:
|
||||
data T
|
||||
next &Node<T> = 0
|
||||
next &Node<T> = unsafe { nil }
|
||||
}
|
||||
|
||||
struct SinglyLinkedList<T> {
|
||||
mut:
|
||||
first_node &Node<T> = 0
|
||||
first_node &Node<T> = unsafe { nil }
|
||||
}
|
||||
|
||||
fn init_singlylinkedlist<T>(nodes []Node<T>) SinglyLinkedList<T> {
|
||||
|
@ -1,12 +1,12 @@
|
||||
pub struct List<T> {
|
||||
pub mut:
|
||||
head &ListNode<T> = 0
|
||||
head &ListNode<T> = unsafe { nil }
|
||||
}
|
||||
|
||||
pub struct ListNode<T> {
|
||||
pub mut:
|
||||
value T
|
||||
next &ListNode<T> = 0
|
||||
next &ListNode<T> = unsafe { nil }
|
||||
}
|
||||
|
||||
pub fn list_new<T>() List<T> {
|
||||
|
Loading…
Reference in New Issue
Block a user