From cf015e507379c30f9510be5a189ce0d2b1015729 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Tue, 6 Dec 2022 12:27:59 -0300 Subject: [PATCH] checker: add clearer errors for `break`/`continue` used within a `$for` loop (#16600) --- vlib/v/checker/checker.v | 6 +++- ...heck_wrong_usage_of_break_and_continue.out | 28 +++++++++++++++++++ ...check_wrong_usage_of_break_and_continue.vv | 19 +++++++++++++ vlib/v/tests/comptime_for_break_test.v | 17 +++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.out create mode 100644 vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.vv create mode 100644 vlib/v/tests/comptime_for_break_test.v diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 1df582cddb..eb2c7927e2 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1828,7 +1828,11 @@ fn (mut c Checker) branch_stmt(node ast.BranchStmt) { c.error('`${node.kind.str()}` is not allowed in defer statements', node.pos) } if c.in_for_count == 0 { - c.error('${node.kind.str()} statement not within a loop', node.pos) + if c.inside_comptime_for_field { + c.error('${node.kind.str()} is not allowed within a compile-time loop', node.pos) + } else { + c.error('${node.kind.str()} statement not within a loop', node.pos) + } } if node.label.len > 0 { if node.label != c.loop_label { diff --git a/vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.out b/vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.out new file mode 100644 index 0000000000..e8851f46c8 --- /dev/null +++ b/vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.out @@ -0,0 +1,28 @@ +vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.vv:9:3: error: continue is not allowed within a compile-time loop + 7 | $for field in Test.fields { + 8 | println(field) + 9 | continue + | ~~~~~~~~ + 10 | } + 11 | $for field in Test.fields { +vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.vv:13:3: error: break is not allowed within a compile-time loop + 11 | $for field in Test.fields { + 12 | println(field) + 13 | break + | ~~~~~ + 14 | } + 15 | { +vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.vv:16:3: error: break statement not within a loop + 14 | } + 15 | { + 16 | break + | ~~~~~ + 17 | continue + 18 | } +vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.vv:17:3: error: continue statement not within a loop + 15 | { + 16 | break + 17 | continue + | ~~~~~~~~ + 18 | } + 19 | } diff --git a/vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.vv b/vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.vv new file mode 100644 index 0000000000..dc67a6465e --- /dev/null +++ b/vlib/v/checker/tests/check_wrong_usage_of_break_and_continue.vv @@ -0,0 +1,19 @@ +struct Test { + a string + b string +} + +fn main() { + $for field in Test.fields { + println(field) + continue + } + $for field in Test.fields { + println(field) + break + } + { + break + continue + } +} \ No newline at end of file diff --git a/vlib/v/tests/comptime_for_break_test.v b/vlib/v/tests/comptime_for_break_test.v new file mode 100644 index 0000000000..d9be41eb08 --- /dev/null +++ b/vlib/v/tests/comptime_for_break_test.v @@ -0,0 +1,17 @@ +struct Test { + a string + b string +} + +fn test_for() { + $for field in Test.fields { + for attr in field.attrs { + break + } + } + $for field in Test.fields { + for attr in field.attrs { + continue + } + } +}