1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: check error of casting to interface (fix #17522) (#17531)

This commit is contained in:
yuyi 2023-03-08 04:49:53 +08:00 committed by GitHub
parent b85f71d00f
commit b6c4e88462
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 3 deletions

View File

@ -913,8 +913,8 @@ fn (mut c Checker) type_implements(typ ast.Type, interface_type ast.Type, pos to
// TODO: remove once deprecation period for `IError` methods has ended
if inter_sym.idx == ast.error_type_idx
&& (imethod.name == 'msg' || imethod.name == 'code') {
// c.note("`$styp` doesn't implement method `$imethod.name` of interface `$inter_sym.name`. The usage of fields is being deprecated in favor of methods.",
// pos)
c.note("`${styp}` doesn't implement method `${imethod.name}` of interface `${inter_sym.name}`. The usage of fields is being deprecated in favor of methods.",
pos)
return false
}
// <<
@ -2828,6 +2828,11 @@ fn (mut c Checker) cast_expr(mut node ast.CastExpr) ast.Type {
final_to_sym = c.table.final_sym(to_type)
}
}
} else {
ft := c.table.type_to_str(from_type)
tt := c.table.type_to_str(to_type)
c.error('`${ft}` does not implement interface `${tt}`, cannot cast `${ft}` to interface `${tt}`',
node.pos)
}
} else if to_type == ast.bool_type && from_type != ast.bool_type && !c.inside_unsafe
&& !c.pref.translated && !c.file.is_translated {

View File

@ -0,0 +1,12 @@
vlib/v/checker/tests/cast_to_interface_err.vv:20:9: notice: `CustomError` doesn't implement method `msg` of interface `IError`. The usage of fields is being deprecated in favor of methods.
18 |
19 | fn my_error() IError {
20 | return IError(CustomError{})
| ~~~~~~~~~~~~~~~~~~~~~
21 | }
vlib/v/checker/tests/cast_to_interface_err.vv:20:9: error: `CustomError` does not implement interface `IError`, cannot cast `CustomError` to interface `IError`
18 |
19 | fn my_error() IError {
20 | return IError(CustomError{})
| ~~~~~~~~~~~~~~~~~~~~~
21 | }

View File

@ -0,0 +1,21 @@
fn main() {
dump(foo()!)
}
fn foo() !int {
// do something
if true {
return 1
}
return my_error()
}
struct CustomError {
pub:
msg string
code int
}
fn my_error() IError {
return IError(CustomError{})
}

View File

@ -1,3 +1,17 @@
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:8:14: notice: `int` doesn't implement method `msg` of interface `IError`. The usage of fields is being deprecated in favor of methods.
6 | if _ := f() {
7 | } else {
8 | _ = err is int
| ~~~
9 | }
10 |
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:12:14: notice: `int` doesn't implement method `msg` of interface `IError`. The usage of fields is being deprecated in favor of methods.
10 |
11 | _ = f() or {
12 | _ = err is int
| ~~~
13 | 0
14 | }
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 {
@ -6,7 +20,7 @@ vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:8:14: error:
9 | }
10 |
vlib/v/checker/tests/infix_is_notis_interface_unimplemented_err.vv:12:14: error: `int` doesn't implement interface `IError`
10 |
10 |
11 | _ = f() or {
12 | _ = err is int
| ~~~

View File

@ -1,3 +1,16 @@
vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:4:2: notice: `&Test` doesn't implement method `msg` of interface `IError`. The usage of fields is being deprecated in favor of methods.
2 |
3 | fn (mut test Test) test() ?int {
4 | return test
| ~~~~~~~~~~~
5 | }
6 |
vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:8:2: notice: `&Test` doesn't implement method `msg` of interface `IError`. The usage of fields is being deprecated in favor of methods.
6 |
7 | fn (mut test Test) test2() int {
8 | return test
| ~~~~~~~~~~~
9 | }
vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:4:9: error: cannot use `Test` as type `?int` in return argument
2 |
3 | fn (mut test Test) test() ?int {