From 1aad481c29b202b3752226af9ce005edc0d8f263 Mon Sep 17 00:00:00 2001 From: shove Date: Tue, 26 Dec 2023 13:03:50 +0800 Subject: [PATCH] checker: fix mismatch checking when a function returns sumtype as an argument (fix #19325) (#20264) --- vlib/v/checker/check_types.v | 6 ++++++ .../checker/tests/fn_call_arg_fn_mismatch_err.out | 6 ++++++ .../checker/tests/fn_call_arg_fn_mismatch_err.vv | 15 +++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 vlib/v/checker/tests/fn_call_arg_fn_mismatch_err.out create mode 100644 vlib/v/checker/tests/fn_call_arg_fn_mismatch_err.vv diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index f59fa83205eaee..d612ff37bd9e2e 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -436,6 +436,12 @@ fn (mut c Checker) check_matching_function_symbols(got_type_sym &ast.TypeSymbol, if !c.check_basic(got_fn.return_type, exp_fn.return_type) { return false } + // The check for sumtype in c.check_basic() in the previous step is only for its variant to be subsumed + // So we need to do a second, more rigorous check of the return value being sumtype. + if c.table.final_sym(exp_fn.return_type).kind == .sum_type + && got_fn.return_type.idx() != exp_fn.return_type.idx() { + return false + } for i, got_arg in got_fn.params { exp_arg := exp_fn.params[i] exp_arg_typ := c.unwrap_generic(exp_arg.typ) diff --git a/vlib/v/checker/tests/fn_call_arg_fn_mismatch_err.out b/vlib/v/checker/tests/fn_call_arg_fn_mismatch_err.out new file mode 100644 index 00000000000000..06465789b8e1eb --- /dev/null +++ b/vlib/v/checker/tests/fn_call_arg_fn_mismatch_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/fn_call_arg_fn_mismatch_err.vv:14:8: error: cannot use `fn () string` as `fn () Response` in argument 1 to `event` + 12 | + 13 | fn main() { + 14 | event(foo) + | ~~~ + 15 | } diff --git a/vlib/v/checker/tests/fn_call_arg_fn_mismatch_err.vv b/vlib/v/checker/tests/fn_call_arg_fn_mismatch_err.vv new file mode 100644 index 00000000000000..dcb70a661f33c5 --- /dev/null +++ b/vlib/v/checker/tests/fn_call_arg_fn_mismatch_err.vv @@ -0,0 +1,15 @@ +// for issue 19325 +type Response = int | string + +fn foo() string { + return 'hello' +} + +fn event(cb fn () Response) { + resp := cb() + assert resp is string +} + +fn main() { + event(foo) +}