1
0
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:
shove 2022-11-03 18:18:30 +08:00 committed by GitHub
parent 14f90b1196
commit 5c7ceb16dd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 66 additions and 13 deletions

View File

@ -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)
}
}
}

View File

@ -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 | }

View File

@ -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 | }

View File

@ -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
}

View File

@ -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 | }

View File

@ -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> {

View File

@ -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> {