authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-03-18 14:50:40-04:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-03-18 14:50:40-04:00
log5765755fcd6bd8570494057255e7d92d489ef35e
tree9b53e9f1ad4d391e318e71a08b1bfafb7fe4024c
parent13321c8070b52afb24f3c1b57eecbb2aa77fc4ec
parentde8f3bc885c7bfd1a084478c1302f0814d98bb62
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #11218 from mitchellh/labeled-break

AstGen: labeled blocks should always complete with a normal break

3 files changed, 41 insertions(+), 6 deletions(-)

src/AstGen.zig+3-6
...@@ -1939,7 +1939,7 @@ fn blockExpr(...@@ -1939,7 +1939,7 @@ fn blockExpr(
1939 if (token_tags[lbrace - 1] == .colon and1939 if (token_tags[lbrace - 1] == .colon and
1940 token_tags[lbrace - 2] == .identifier)1940 token_tags[lbrace - 2] == .identifier)
1941 {1941 {
1942 return labeledBlockExpr(gz, scope, rl, block_node, statements, .block);1942 return labeledBlockExpr(gz, scope, rl, block_node, statements);
1943 }1943 }
19441944
1945 try blockExprStmts(gz, scope, statements);1945 try blockExprStmts(gz, scope, statements);
...@@ -1984,13 +1984,10 @@ fn labeledBlockExpr(...@@ -1984,13 +1984,10 @@ fn labeledBlockExpr(
1984 rl: ResultLoc,1984 rl: ResultLoc,
1985 block_node: Ast.Node.Index,1985 block_node: Ast.Node.Index,
1986 statements: []const Ast.Node.Index,1986 statements: []const Ast.Node.Index,
1987 zir_tag: Zir.Inst.Tag,
1988) InnerError!Zir.Inst.Ref {1987) InnerError!Zir.Inst.Ref {
1989 const tracy = trace(@src());1988 const tracy = trace(@src());
1990 defer tracy.end();1989 defer tracy.end();
19911990
1992 assert(zir_tag == .block);
1993
1994 const astgen = gz.astgen;1991 const astgen = gz.astgen;
1995 const tree = astgen.tree;1992 const tree = astgen.tree;
1996 const main_tokens = tree.nodes.items(.main_token);1993 const main_tokens = tree.nodes.items(.main_token);
...@@ -2004,7 +2001,7 @@ fn labeledBlockExpr(...@@ -2004,7 +2001,7 @@ fn labeledBlockExpr(
20042001
2005 // Reserve the Block ZIR instruction index so that we can put it into the GenZir struct2002 // Reserve the Block ZIR instruction index so that we can put it into the GenZir struct
2006 // so that break statements can reference it.2003 // so that break statements can reference it.
2007 const block_inst = try gz.makeBlockInst(zir_tag, block_node);2004 const block_inst = try gz.makeBlockInst(.block, block_node);
2008 try gz.instructions.append(astgen.gpa, block_inst);2005 try gz.instructions.append(astgen.gpa, block_inst);
20092006
2010 var block_scope = gz.makeSubBlock(parent_scope);2007 var block_scope = gz.makeSubBlock(parent_scope);
...@@ -2018,7 +2015,7 @@ fn labeledBlockExpr(...@@ -2018,7 +2015,7 @@ fn labeledBlockExpr(
20182015
2019 try blockExprStmts(&block_scope, &block_scope.base, statements);2016 try blockExprStmts(&block_scope, &block_scope.base, statements);
2020 if (!block_scope.endsWithNoReturn()) {2017 if (!block_scope.endsWithNoReturn()) {
2021 _ = try block_scope.addBreak(.break_inline, block_inst, .void_value);2018 _ = try block_scope.addBreak(.@"break", block_inst, .void_value);
2022 }2019 }
20232020
2024 if (!block_scope.label.?.used) {2021 if (!block_scope.label.?.used) {
test/behavior.zig+1
...@@ -70,6 +70,7 @@ test {...@@ -70,6 +70,7 @@ test {
70 _ = @import("behavior/bugs/11165.zig");70 _ = @import("behavior/bugs/11165.zig");
71 _ = @import("behavior/bugs/11181.zig");71 _ = @import("behavior/bugs/11181.zig");
72 _ = @import("behavior/bugs/11182.zig");72 _ = @import("behavior/bugs/11182.zig");
73 _ = @import("behavior/bugs/11213.zig");
73 _ = @import("behavior/call.zig");74 _ = @import("behavior/call.zig");
74 _ = @import("behavior/cast.zig");75 _ = @import("behavior/cast.zig");
75 _ = @import("behavior/comptime_memory.zig");76 _ = @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}