From b01e091473a13e179d94c78131a065fd551bdb6e Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 25 Mar 2024 10:15:56 -0300 Subject: [PATCH] checker: fix option checker arg validation for ptr passing on non expected ptr (#21087) --- vlib/v/checker/check_types.v | 10 +++++++++ .../checker/tests/option_receive_ptr_err.out | 7 +++++++ .../v/checker/tests/option_receive_ptr_err.vv | 21 +++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 vlib/v/checker/tests/option_receive_ptr_err.out create mode 100644 vlib/v/checker/tests/option_receive_ptr_err.vv diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 2c3e546ca4..04c5b39c79 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -225,8 +225,18 @@ fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, lan return } } else { + if expected.has_flag(.option) { + got_is_ptr := got.is_ptr() + || (arg.expr is ast.Ident && (arg.expr as ast.Ident).is_mut()) + if (expected.is_ptr() && !got_is_ptr) || (!expected.is_ptr() && got.is_ptr()) { + got_typ_str, expected_typ_str := c.get_string_names_of(got, expected) + return error('cannot use `${got_typ_str}` as `${expected_typ_str}`') + } + } + exp_sym_idx := c.table.sym(expected).idx got_sym_idx := c.table.sym(got).idx + if expected.is_ptr() && got.is_ptr() && exp_sym_idx != got_sym_idx && exp_sym_idx in [ast.u8_type_idx, ast.byteptr_type_idx] && got_sym_idx !in [ast.u8_type_idx, ast.byteptr_type_idx] { diff --git a/vlib/v/checker/tests/option_receive_ptr_err.out b/vlib/v/checker/tests/option_receive_ptr_err.out new file mode 100644 index 0000000000..c36c9fb417 --- /dev/null +++ b/vlib/v/checker/tests/option_receive_ptr_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/option_receive_ptr_err.vv:14:23: error: cannot use `&MyStruct` as `?MyStruct` in argument 1 to `unwrap_option` + 12 | + 13 | fn wrap_unwrap_ptr(event_data &MyStruct) int { + 14 | return unwrap_option(event_data) + | ~~~~~~~~~~ + 15 | } + 16 | diff --git a/vlib/v/checker/tests/option_receive_ptr_err.vv b/vlib/v/checker/tests/option_receive_ptr_err.vv new file mode 100644 index 0000000000..1d470b3d90 --- /dev/null +++ b/vlib/v/checker/tests/option_receive_ptr_err.vv @@ -0,0 +1,21 @@ +struct MyStruct { + x int +} + +fn unwrap_option(event_data ?MyStruct) int { + if val := event_data { + return val.x + } else { + return 0 + } +} + +fn wrap_unwrap_ptr(event_data &MyStruct) int { + return unwrap_option(event_data) +} + +fn main() { + data := MyStruct { x: 0 } + result := wrap_unwrap_ptr(&data) + assert data.x == result +} \ No newline at end of file