1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: check if guard with multiple return variable (#15646)

This commit is contained in:
yuyi 2022-09-03 15:56:46 +08:00 committed by GitHub
parent a5aad6f791
commit 5e1a2f6f50
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 42 additions and 26 deletions

View File

@ -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 {

View File

@ -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 | }

View File

@ -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')
}
}