From e8108f21e08db3dc0e4e593da954e36aa64f29fb Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Mon, 16 Jan 2023 02:39:30 +0530 Subject: [PATCH] checker: check option and result handling in type-casted aliases (#16988) --- vlib/v/checker/checker.v | 2 ++ ...as_type_cast_option_result_unhandled_err.out | 13 +++++++++++++ ...ias_type_cast_option_result_unhandled_err.vv | 17 +++++++++++++++++ .../checker/tests/cast_array_to_number_err.out | 2 +- .../v/checker/tests/cast_array_to_number_err.vv | 2 +- 5 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.out create mode 100644 vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index fc9f27fcce..b83d121259 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -992,6 +992,8 @@ fn (mut c Checker) check_expr_opt_call(expr ast.Expr, ret_type ast.Type) ast.Typ if expr.or_expr.kind != .absent { c.check_or_expr(expr.or_expr, ret_type, ret_type.set_flag(.result)) } + } else if expr is ast.CastExpr { + c.check_expr_opt_call(expr.expr, ret_type) } return ret_type } diff --git a/vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.out b/vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.out new file mode 100644 index 0000000000..d0a48118e0 --- /dev/null +++ b/vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.out @@ -0,0 +1,13 @@ +vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.vv:15:12: error: ret_abc_result() returns a result, so it should have either an `or {}` block, or `!` at the end + 13 | } + 14 | + 15 | a := Alias(ret_abc_result()) + | ~~~~~~~~~~~~~~~~ + 16 | b := Alias(ret_abc_option()) + 17 | println('${a}${b}') +vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.vv:16:12: error: ret_abc_option() returns an option, so it should have either an `or {}` block, or `?` at the end + 14 | + 15 | a := Alias(ret_abc_result()) + 16 | b := Alias(ret_abc_option()) + | ~~~~~~~~~~~~~~~~ + 17 | println('${a}${b}') diff --git a/vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.vv b/vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.vv new file mode 100644 index 0000000000..0ed7e60d80 --- /dev/null +++ b/vlib/v/checker/tests/alias_type_cast_option_result_unhandled_err.vv @@ -0,0 +1,17 @@ +struct Abc { + a string +} + +type Alias = Abc + +fn ret_abc_result() !Abc { + return Abc{'a'} +} + +fn ret_abc_option() ?Abc { + return Abc{'a'} +} + +a := Alias(ret_abc_result()) +b := Alias(ret_abc_option()) +println('${a}${b}') diff --git a/vlib/v/checker/tests/cast_array_to_number_err.out b/vlib/v/checker/tests/cast_array_to_number_err.out index 3b582f504a..d667239b38 100644 --- a/vlib/v/checker/tests/cast_array_to_number_err.out +++ b/vlib/v/checker/tests/cast_array_to_number_err.out @@ -1,7 +1,7 @@ vlib/v/checker/tests/cast_array_to_number_err.vv:5:8: error: cannot cast array `[]u8` to `i16` 3 | fn main() { 4 | bytes := '010000150107120508d37445a0d7e5c5071980710c64310d9e12043000777369ff0424ab78b91a05164b00e50034003300' - 5 | yr := i16(hx.decode(bytes.substr(6,8))?) + 5 | yr := i16(hx.decode(bytes.substr(6,8))!) | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 6 | println(bytes) 7 | println('yr: $yr') diff --git a/vlib/v/checker/tests/cast_array_to_number_err.vv b/vlib/v/checker/tests/cast_array_to_number_err.vv index 167e378237..59389e2dc4 100644 --- a/vlib/v/checker/tests/cast_array_to_number_err.vv +++ b/vlib/v/checker/tests/cast_array_to_number_err.vv @@ -2,7 +2,7 @@ import encoding.hex as hx fn main() { bytes := '010000150107120508d37445a0d7e5c5071980710c64310d9e12043000777369ff0424ab78b91a05164b00e50034003300' - yr := i16(hx.decode(bytes.substr(6,8))?) + yr := i16(hx.decode(bytes.substr(6,8))!) println(bytes) println('yr: $yr') }