From 1ced1e910829e51ee04befe3a4f6c9b2bb541616 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 27 Oct 2024 15:31:01 -0300 Subject: [PATCH] checker: fix return type checks, when returning struct values, implementing IError in non-result fn (fix #22659) (fix #22658) (#22660) --- vlib/v/checker/return.v | 2 +- .../tests/mut_receiver_wrong_return_type.out | 26 ------------------- .../v/checker/tests/wrong_return_type_err.out | 14 ++++++++++ vlib/v/checker/tests/wrong_return_type_err.vv | 25 ++++++++++++++++++ ... printing_result_or_expr_with_map_val.out} | 0 ...> printing_result_or_expr_with_map_val.vv} | 2 +- 6 files changed, 41 insertions(+), 28 deletions(-) create mode 100644 vlib/v/checker/tests/wrong_return_type_err.out create mode 100644 vlib/v/checker/tests/wrong_return_type_err.vv rename vlib/v/slow_tests/inout/{printing_option_or_expr_with_map_val.out => printing_result_or_expr_with_map_val.out} (100%) rename vlib/v/slow_tests/inout/{printing_option_or_expr_with_map_val.vv => printing_result_or_expr_with_map_val.vv} (93%) diff --git a/vlib/v/checker/return.v b/vlib/v/checker/return.v index 2d5aead3077ccb..6dd9a47c2277f6 100644 --- a/vlib/v/checker/return.v +++ b/vlib/v/checker/return.v @@ -243,7 +243,7 @@ fn (mut c Checker) return_stmt(mut node ast.Return) { } } // `fn foo() !int { return Err{} }` - if got_type_sym.kind == .struct + if expected_fn_return_type_has_result && got_type_sym.kind == .struct && c.type_implements(got_type, ast.error_type, node.pos) { node.exprs[expr_idxs[i]] = ast.CastExpr{ expr: node.exprs[expr_idxs[i]] diff --git a/vlib/v/checker/tests/mut_receiver_wrong_return_type.out b/vlib/v/checker/tests/mut_receiver_wrong_return_type.out index 07f9827ca56b86..50c8b65764be70 100644 --- a/vlib/v/checker/tests/mut_receiver_wrong_return_type.out +++ b/vlib/v/checker/tests/mut_receiver_wrong_return_type.out @@ -1,17 +1,3 @@ -vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:4:2: error: `&Test` doesn't implement method `msg` of interface `IError` - 2 | - 3 | fn (mut test Test) test() ?int { - 4 | return test - | ~~~~~~~~~~~ - 5 | } - 6 | -vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:4:2: error: `&Test` doesn't implement method `code` of interface `IError` - 2 | - 3 | fn (mut test Test) test() ?int { - 4 | return test - | ~~~~~~~~~~~ - 5 | } - 6 | 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 { @@ -19,18 +5,6 @@ vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:4:9: error: cannot use `T | ~~~~ 5 | } 6 | -vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:8:2: error: `&Test` doesn't implement method `msg` of interface `IError` - 6 | - 7 | fn (mut test Test) test2() int { - 8 | return test - | ~~~~~~~~~~~ - 9 | } -vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:8:2: error: `&Test` doesn't implement method `code` of interface `IError` - 6 | - 7 | fn (mut test Test) test2() int { - 8 | return test - | ~~~~~~~~~~~ - 9 | } vlib/v/checker/tests/mut_receiver_wrong_return_type.vv:8:9: error: cannot use `Test` as type `int` in return argument 6 | 7 | fn (mut test Test) test2() int { diff --git a/vlib/v/checker/tests/wrong_return_type_err.out b/vlib/v/checker/tests/wrong_return_type_err.out new file mode 100644 index 00000000000000..5619aa821a6470 --- /dev/null +++ b/vlib/v/checker/tests/wrong_return_type_err.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/wrong_return_type_err.vv:9:10: error: cannot use `Error` as type `int` in return argument + 7 | fn double_positive(num int) int { + 8 | if num <= 0 { + 9 | return Error{} + | ~~~~~~~ + 10 | } + 11 | return num * 2 +vlib/v/checker/tests/wrong_return_type_err.vv:16:10: error: cannot use `Error` as type `Val` in return argument + 14 | fn new_val(num int) Val { + 15 | if num <= 0 { + 16 | return Error{} + | ~~~~~~~ + 17 | } + 18 | return Val{ diff --git a/vlib/v/checker/tests/wrong_return_type_err.vv b/vlib/v/checker/tests/wrong_return_type_err.vv new file mode 100644 index 00000000000000..c7b9c842b533e5 --- /dev/null +++ b/vlib/v/checker/tests/wrong_return_type_err.vv @@ -0,0 +1,25 @@ +module main + +struct Val { + val int +} + +fn double_positive(num int) int { + if num <= 0 { + return Error{} + } + return num * 2 +} + +fn new_val(num int) Val { + if num <= 0 { + return Error{} + } + return Val{ + val: num + } +} + +fn main() { + println(new_val(2)) +} diff --git a/vlib/v/slow_tests/inout/printing_option_or_expr_with_map_val.out b/vlib/v/slow_tests/inout/printing_result_or_expr_with_map_val.out similarity index 100% rename from vlib/v/slow_tests/inout/printing_option_or_expr_with_map_val.out rename to vlib/v/slow_tests/inout/printing_result_or_expr_with_map_val.out diff --git a/vlib/v/slow_tests/inout/printing_option_or_expr_with_map_val.vv b/vlib/v/slow_tests/inout/printing_result_or_expr_with_map_val.vv similarity index 93% rename from vlib/v/slow_tests/inout/printing_option_or_expr_with_map_val.vv rename to vlib/v/slow_tests/inout/printing_result_or_expr_with_map_val.vv index b149d1427bba3c..cd226dfd23fa44 100644 --- a/vlib/v/slow_tests/inout/printing_option_or_expr_with_map_val.vv +++ b/vlib/v/slow_tests/inout/printing_result_or_expr_with_map_val.vv @@ -13,7 +13,7 @@ fn (my MyError) code() int { type MapString = map[string]string | int -fn f() ?MapString { +fn f() !MapString { return MyError{ msg: 'String Error' }