From bf75a873b5638ed77649379251cf536efa77cd2c Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 28 Apr 2022 13:43:16 +0800 Subject: [PATCH] checker: check error in for_c_stmt with optional call (#14190) --- vlib/v/checker/for.v | 10 ++++++ .../tests/for_c_stmt_with_optional_call.out | 7 +++++ .../tests/for_c_stmt_with_optional_call.vv | 31 +++++++++++++++++++ 3 files changed, 48 insertions(+) create mode 100644 vlib/v/checker/tests/for_c_stmt_with_optional_call.out create mode 100644 vlib/v/checker/tests/for_c_stmt_with_optional_call.vv diff --git a/vlib/v/checker/for.v b/vlib/v/checker/for.v index 494ad01dbc..53a6684d2f 100644 --- a/vlib/v/checker/for.v +++ b/vlib/v/checker/for.v @@ -13,6 +13,16 @@ fn (mut c Checker) for_c_stmt(node ast.ForCStmt) { } c.expr(node.cond) if node.has_inc { + if node.inc is ast.AssignStmt { + for right in node.inc.right { + if right is ast.CallExpr { + if right.or_block.stmts.len > 0 { + c.error('optionals are not allowed in `for statement increment` (yet)', + right.pos) + } + } + } + } c.stmt(node.inc) } c.check_loop_label(node.label, node.pos) diff --git a/vlib/v/checker/tests/for_c_stmt_with_optional_call.out b/vlib/v/checker/tests/for_c_stmt_with_optional_call.out new file mode 100644 index 0000000000..90a424bf9a --- /dev/null +++ b/vlib/v/checker/tests/for_c_stmt_with_optional_call.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/for_c_stmt_with_optional_call.vv:15:31: error: optionals are not allowed in `for statement increment` (yet) + 13 | for t := 0; t < tests; t++ { + 14 | mut v := []bool{len: nmax, init: false} + 15 | for x := 0; !v[x]; x = rand.intn(n) or { 0 } { + | ~~~~~~~ + 16 | v[x] = true + 17 | sum++ diff --git a/vlib/v/checker/tests/for_c_stmt_with_optional_call.vv b/vlib/v/checker/tests/for_c_stmt_with_optional_call.vv new file mode 100644 index 0000000000..bc6184799e --- /dev/null +++ b/vlib/v/checker/tests/for_c_stmt_with_optional_call.vv @@ -0,0 +1,31 @@ +import rand +import math { abs } + +const nmax = 20 + +fn ana(n int) f64 { + return 1.0 // haven't started +} + +fn avg(n int) f64 { + tests := 1e4 + mut sum := 0 + for t := 0; t < tests; t++ { + mut v := []bool{len: nmax, init: false} + for x := 0; !v[x]; x = rand.intn(n) or { 0 } { + v[x] = true + sum++ + } + } + return f64(sum) / tests +} + +fn main() { + println(' N average analytical (error)') + println('=== ========= ============ =========') + for n in 1 .. nmax + 1 { + a := avg(n) + b := ana(n) + println('${n:3} ${a:9.4f} ${b:12.4f} (${(abs(a - b) / b * 100):6.2f}%)') + } +}