| author | |
| committer | |
| log | 03c363300fd829f3a656c6a9854a9c9720c9b3f1 |
| tree | 9cf60f26f2d44e9527fac310102fdb80e085d100 |
| parent | 0001f91e4e1e51cd64cdd5c0a21451c8bad67233 |
`break`ing from something which isn't a loop should always be opt-in.
This was a bug in #21257.2 files changed, 19 insertions(+), 2 deletions(-)
lib/std/zig/AstGen.zig+2-2| ... | ... | @@ -7811,9 +7811,7 @@ fn switchExpr( |
| 7811 | 7811 | const switch_block = try parent_gz.makeBlockInst(switch_tag, node); |
| 7812 | 7812 | |
| 7813 | 7813 | if (switch_full.label_token) |label_token| { |
| 7814 | block_scope.break_block = switch_block.toOptional(); | |
| 7815 | 7814 | block_scope.continue_block = switch_block.toOptional(); |
| 7816 | // `break_result_info` already set above | |
| 7817 | 7815 | block_scope.continue_result_info = .{ |
| 7818 | 7816 | .rl = if (any_payload_is_ref) |
| 7819 | 7817 | .{ .ref_coerced_ty = raw_operand_ty_ref } |
| ... | ... | @@ -7825,6 +7823,8 @@ fn switchExpr( |
| 7825 | 7823 | .token = label_token, |
| 7826 | 7824 | .block_inst = switch_block, |
| 7827 | 7825 | }; |
| 7826 | // `break` can target this via `label.block_inst` | |
| 7827 | // `break_result_info` already set by `setBreakResultInfo` | |
| 7828 | 7828 | } |
| 7829 | 7829 | |
| 7830 | 7830 | // We re-use this same scope for all cases, including the special prong, if any. |
test/behavior/switch.zig+17| ... | ... | @@ -985,3 +985,20 @@ test "labeled switch with break" { |
| 985 | 985 | |
| 986 | 986 | comptime assert(comptime_val); |
| 987 | 987 | } |
| 988 | ||
| 989 | test "unlabeled break ignores switch" { | |
| 990 | if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO | |
| 991 | if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO | |
| 992 | if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO | |
| 993 | if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO | |
| 994 | if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest; // TODO | |
| 995 | ||
| 996 | const result = while (true) { | |
| 997 | _ = s: switch (@as(u32, 1)) { | |
| 998 | 1 => continue :s 123, | |
| 999 | else => |x| break x, | |
| 1000 | }; | |
| 1001 | comptime unreachable; // control flow never breaks from the switch | |
| 1002 | }; | |
| 1003 | try expect(result == 123); | |
| 1004 | } |