From ddd5254db49c3455c018afce1d854d920c417ee6 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 12 Oct 2024 05:34:18 -0300 Subject: [PATCH] checker: fix missing checker for option map indexing (fix #22490) (#22495) --- vlib/v/checker/checker.v | 9 +++++++++ vlib/v/checker/tests/option_map_err.out | 6 ++++++ vlib/v/checker/tests/option_map_err.vv | 23 +++++++++++++++++++++++ 3 files changed, 38 insertions(+) create mode 100644 vlib/v/checker/tests/option_map_err.out create mode 100644 vlib/v/checker/tests/option_map_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index e8575b46d..62be8f886 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1278,6 +1278,15 @@ fn (mut c Checker) check_expr_option_or_result_call(expr ast.Expr, ret_type ast. c.check_or_expr(expr.or_expr, ret_type, ret_type.set_flag(.result), expr) } + } else if expr.left is ast.SelectorExpr && expr.left_type.has_option_or_result() { + with_modifier_kind := if expr.left_type.has_flag(.option) { + 'an Option' + } else { + 'a Result' + } + with_modifier := if expr.left_type.has_flag(.option) { '?' } else { '!' } + c.error('field `${expr.left.field_name}` is ${with_modifier_kind}, so it should have either an `or {}` block, or `${with_modifier}` at the end', + expr.left.pos) } } ast.CastExpr { diff --git a/vlib/v/checker/tests/option_map_err.out b/vlib/v/checker/tests/option_map_err.out new file mode 100644 index 000000000..cc6bd6622 --- /dev/null +++ b/vlib/v/checker/tests/option_map_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/option_map_err.vv:22:13: error: field `opmap` is an Option, so it should have either an `or {}` block, or `?` at the end + 20 | } + 21 | } + 22 | assert op2.opmap['1'] == 1.0 + | ~~~~~ + 23 | } diff --git a/vlib/v/checker/tests/option_map_err.vv b/vlib/v/checker/tests/option_map_err.vv new file mode 100644 index 000000000..abbfcd4fa --- /dev/null +++ b/vlib/v/checker/tests/option_map_err.vv @@ -0,0 +1,23 @@ +struct OptionalMap { + opmap ?map[string]f64 +} + +fn main() { + op := OptionalMap{ + opmap: { + '1': 0.0 + } + } + assert op.opmap or { + { + '1': 0.0 + } + }['1'] == 0.0 + + op2 := OptionalMap{ + opmap: { + '1': 1.0 + } + } + assert op2.opmap['1'] == 1.0 +} -- 2.39.5