From d8b158be2bd86a9b8562f5a4098ced29ba484ebc Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 28 Jan 2024 22:32:39 -0300 Subject: [PATCH] checker: fix checking for option matching with non-option (#20673) --- vlib/v/checker/match.v | 8 ++++---- vlib/v/checker/tests/option_fn_err.out | 21 ++++++++++++++------- 2 files changed, 18 insertions(+), 11 deletions(-) diff --git a/vlib/v/checker/match.v b/vlib/v/checker/match.v index d74c20130c6398..57affaa8176ea0 100644 --- a/vlib/v/checker/match.v +++ b/vlib/v/checker/match.v @@ -55,6 +55,10 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { branch.branch_pos) } } + if !branch.is_else && cond_is_option && branch.exprs[0] !is ast.None { + c.error('`match` expression with Option type only checks against `none`, to match its value you must unwrap it first `var?`', + branch.pos) + } // If the last statement is an expression, return its type if branch.stmts.len > 0 { mut stmt := branch.stmts.last() @@ -63,10 +67,6 @@ fn (mut c Checker) match_expr(mut node ast.MatchExpr) ast.Type { c.expected_type = node.expected_type } expr_type := c.expr(mut stmt.expr) - if !branch.is_else && cond_is_option && branch.exprs[0] !is ast.None { - c.error('`match` expression with Option type only checks against `none`, to match its value you must unwrap it first `var?`', - branch.pos) - } stmt.typ = expr_type if first_iteration { if node.is_expr && (node.expected_type.has_flag(.option) diff --git a/vlib/v/checker/tests/option_fn_err.out b/vlib/v/checker/tests/option_fn_err.out index 8db4c6ff6b957a..568166f9bce764 100644 --- a/vlib/v/checker/tests/option_fn_err.out +++ b/vlib/v/checker/tests/option_fn_err.out @@ -3,21 +3,21 @@ vlib/v/checker/tests/option_fn_err.vv:34:16: error: cannot use `?int` as `int`, 33 | _ := bar(0) 34 | println(twice(bar(0))) | ~~~~~~ - 35 | + 35 | 36 | // anon fn vlib/v/checker/tests/option_fn_err.vv:37:16: error: cannot use `?int` as `int`, it must be unwrapped first in argument 1 to `anon` - 35 | + 35 | 36 | // anon fn 37 | fn (_ int) {}(bar(0)) | ~~~~~~ - 38 | + 38 | 39 | // assert vlib/v/checker/tests/option_fn_err.vv:40:9: error: assert can be used only with `bool` expressions, but found `bool` instead - 38 | + 38 | 39 | // assert 40 | assert bar(true) | ~~~~~~~~~ - 41 | + 41 | 42 | // struct vlib/v/checker/tests/option_fn_err.vv:45:3: error: cannot assign an Option value to a non-option struct field 43 | mut v := Data{ @@ -38,7 +38,7 @@ vlib/v/checker/tests/option_fn_err.vv:49:6: error: cannot use `?int` as `int`, i 48 | v.add(bar(0)) // call method 49 | v.f(bar(0)) // call fn field | ~~~~~~ - 50 | + 50 | 51 | // array vlib/v/checker/tests/option_fn_err.vv:53:6: error: unwrapped Option cannot be used in an infix expression 51 | // array @@ -115,5 +115,12 @@ vlib/v/checker/tests/option_fn_err.vv:69:18: error: type mismatch, `bar` must re 68 | println(arr.any(bar(true))) 69 | println(arr.all(bar(true))) | ~~~~~~~~~ - 70 | + 70 | + 71 | match bar(0) { +vlib/v/checker/tests/option_fn_err.vv:72:3: error: `match` expression with Option type only checks against `none`, to match its value you must unwrap it first `var?` + 70 | 71 | match bar(0) { + 72 | 0 {} + | ^ + 73 | else {} + 74 | }