authorgravatar for mitchell.hashimoto@gmail.comMitchell Hashimoto <mitchell.hashimoto@gmail.com> 2022-03-18 08:22:42-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-18 11:40:39-07:00
log3e74acb1390e7b18a1d0febf9540585e165b52bd
treea3659a55985453be2c29708be2de0b22dda245af
parent13321c8070b52afb24f3c1b57eecbb2aa77fc4ec

AstGen: labeled blocks should always complete with a normal break

They aren't inline blocks by nature of being labeled. Fixes #11213

3 files changed, 39 insertions(+), 1 deletions(-)

src/AstGen.zig+1-1
......@@ -2018,7 +2018,7 @@ fn labeledBlockExpr(
20182018
20192019 try blockExprStmts(&block_scope, &block_scope.base, statements);
20202020 if (!block_scope.endsWithNoReturn()) {
2021 _ = try block_scope.addBreak(.break_inline, block_inst, .void_value);
2021 _ = try block_scope.addBreak(.@"break", block_inst, .void_value);
20222022 }
20232023
20242024 if (!block_scope.label.?.used) {
test/behavior.zig+1
......@@ -70,6 +70,7 @@ test {
7070 _ = @import("behavior/bugs/11165.zig");
7171 _ = @import("behavior/bugs/11181.zig");
7272 _ = @import("behavior/bugs/11182.zig");
73 _ = @import("behavior/bugs/11213.zig");
7374 _ = @import("behavior/call.zig");
7475 _ = @import("behavior/cast.zig");
7576 _ = @import("behavior/comptime_memory.zig");
test/behavior/bugs/11213.zig created+37
......@@ -0,0 +1,37 @@
1const std = @import("std");
2const builtin = @import("builtin");
3const testing = std.testing;
4
5test {
6 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
7 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
8 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
9
10 const g: error{Test}!void = error.Test;
11
12 var v: u32 = 0;
13 hash(&v, g);
14 try testing.expect(v == 1);
15}
16
17fn hash(v: *u32, key: anytype) void {
18 const Key = @TypeOf(key);
19
20 if (@typeInfo(Key) == .ErrorSet) {
21 v.* += 1;
22 return;
23 }
24
25 switch (@typeInfo(Key)) {
26 .ErrorUnion => blk: {
27 const payload = key catch |err| {
28 hash(v, err);
29 break :blk;
30 };
31
32 hash(v, payload);
33 },
34
35 else => unreachable,
36 }
37}