From 5e1a2f6f502b71f14ce7bc5e55a2023c67c7b171 Mon Sep 17 00:00:00 2001 From: yuyi Date: Sat, 3 Sep 2022 15:56:46 +0800 Subject: [PATCH] checker: check if guard with multiple return variable (#15646) --- vlib/v/checker/if.v | 29 ++++++++--------- .../checker/tests/if_guard_variables_err.out | 31 ++++++++++++------- .../v/checker/tests/if_guard_variables_err.vv | 8 +++++ 3 files changed, 42 insertions(+), 26 deletions(-) diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index af9a11da5..d36437bf4 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -54,6 +54,21 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { } } } + if mut branch.cond is ast.IfGuardExpr { + sym := c.table.sym(branch.cond.expr_type) + if sym.kind == .multi_return { + mr_info := sym.info as ast.MultiReturn + if branch.cond.vars.len != mr_info.types.len { + c.error('if guard expects $mr_info.types.len variables, but got $branch.cond.vars.len', + branch.pos) + continue + } else { + for vi, var in branch.cond.vars { + branch.scope.update_var_type(var.name, mr_info.types[vi]) + } + } + } + } if node.is_comptime { // Skip checking if needed // smartcast field type on comptime if mut comptime_field_name := '' @@ -247,20 +262,6 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { branch.pos) } } - if mut branch.cond is ast.IfGuardExpr { - sym := c.table.sym(branch.cond.expr_type) - if sym.kind == .multi_return { - mr_info := sym.info as ast.MultiReturn - if branch.cond.vars.len != mr_info.types.len { - c.error('if guard expects $mr_info.types.len variables, but got $branch.cond.vars.len', - branch.pos) - } else { - for vi, var in branch.cond.vars { - branch.scope.update_var_type(var.name, mr_info.types[vi]) - } - } - } - } // Also check for returns inside a comp.if's statements, even if its contents aren't parsed if has_return := c.has_return(branch.stmts) { if has_return { diff --git a/vlib/v/checker/tests/if_guard_variables_err.out b/vlib/v/checker/tests/if_guard_variables_err.out index 4ed3096e3..b9690c6bc 100644 --- a/vlib/v/checker/tests/if_guard_variables_err.out +++ b/vlib/v/checker/tests/if_guard_variables_err.out @@ -1,14 +1,21 @@ -vlib/v/checker/tests/if_guard_variables_err.vv:6:2: error: if guard expects 3 variables, but got 1 - 4 | - 5 | fn main() { - 6 | if r1 := create() { +vlib/v/checker/tests/if_guard_variables_err.vv:10:2: error: if guard expects 3 variables, but got 1 + 8 | + 9 | fn main() { + 10 | if r1 := create() { | ~~~~~~~~~~~~~~~~~ - 7 | println(r1) - 8 | } -vlib/v/checker/tests/if_guard_variables_err.vv:10:2: error: if guard expects 3 variables, but got 4 - 8 | } - 9 | - 10 | if r1, r2, r3, r4 := create() { - | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11 | println(r1) - 12 | println(r2) + 12 | } +vlib/v/checker/tests/if_guard_variables_err.vv:14:2: error: if guard expects 3 variables, but got 4 + 12 | } + 13 | + 14 | if r1, r2, r3, r4 := create() { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 15 | println(r1) + 16 | println(r2) +vlib/v/checker/tests/if_guard_variables_err.vv:21:2: error: if guard expects 2 variables, but got 1 + 19 | } + 20 | + 21 | if x := maybe() { + | ~~~~~~~~~~~~~~~ + 22 | println('$x') + 23 | } diff --git a/vlib/v/checker/tests/if_guard_variables_err.vv b/vlib/v/checker/tests/if_guard_variables_err.vv index dbd042069..c87a8e81b 100644 --- a/vlib/v/checker/tests/if_guard_variables_err.vv +++ b/vlib/v/checker/tests/if_guard_variables_err.vv @@ -2,6 +2,10 @@ fn create() ?(int, string, bool) { return 5, 'aa', true } +fn maybe() ?(int, int) { + return 1, 2 +} + fn main() { if r1 := create() { println(r1) @@ -13,4 +17,8 @@ fn main() { println(r3) println(r4) } + + if x := maybe() { + println('$x') + } } -- 2.30.2