aboutsummaryrefslogtreecommitdiff
path: root/src/AstGen.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2022-02-19 20:26:57 -0700
committerAndrew Kelley <andrew@ziglang.org>2022-02-19 20:26:57 -0700
commitbfff8544e1049fc7aa3310883f619efb3f394948 (patch)
tree62ba7c3594d2d7e091b26525811f53d8e3d51e34 /src/AstGen.zig
parent8841a71aa675f76c0ff7658339872a5faa5e4d5b (diff)
downloadzig-bfff8544e1049fc7aa3310883f619efb3f394948.tar.gz
zig-bfff8544e1049fc7aa3310883f619efb3f394948.zip
AstGen: emit break_inline for corresponding inline loops
Prior to this commit there would be a `break` ZIR instruction to break from a `block_inline` which is a mismatch.
Diffstat (limited to 'src/AstGen.zig')
-rw-r--r--src/AstGen.zig14
1 files changed, 10 insertions, 4 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index bf34ce4780..048eb8479a 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -1729,8 +1729,10 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
continue;
};
+ const break_tag: Zir.Inst.Tag = if (block_gz.is_inline) .break_inline else .@"break";
+
if (rhs == 0) {
- _ = try parent_gz.addBreak(.@"break", block_inst, .void_value);
+ _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
return Zir.Inst.Ref.unreachable_value;
}
block_gz.break_count += 1;
@@ -1746,7 +1748,7 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
switch (block_gz.break_result_loc) {
.block_ptr => {
- const br = try parent_gz.addBreak(.@"break", block_inst, operand);
+ const br = try parent_gz.addBreak(break_tag, block_inst, operand);
try block_gz.labeled_breaks.append(astgen.gpa, br);
// if list grew as much as rvalue_rl_count, then a break
@@ -1765,10 +1767,10 @@ fn breakExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index) Inn
.ptr => {
// In this case we don't have any mechanism to intercept it;
// we assume the result location is written, and we break with void.
- _ = try parent_gz.addBreak(.@"break", block_inst, .void_value);
+ _ = try parent_gz.addBreak(break_tag, block_inst, .void_value);
},
else => {
- _ = try parent_gz.addBreak(.@"break", block_inst, operand);
+ _ = try parent_gz.addBreak(break_tag, block_inst, operand);
},
}
return Zir.Inst.Ref.unreachable_value;
@@ -5300,6 +5302,7 @@ fn whileExpr(
try parent_gz.instructions.append(astgen.gpa, loop_block);
var loop_scope = parent_gz.makeSubBlock(scope);
+ loop_scope.is_inline = is_inline;
loop_scope.setBreakResultLoc(rl);
defer loop_scope.unstack();
defer loop_scope.labeled_breaks.deinit(astgen.gpa);
@@ -5550,6 +5553,7 @@ fn forExpr(
try parent_gz.instructions.append(astgen.gpa, loop_block);
var loop_scope = parent_gz.makeSubBlock(scope);
+ loop_scope.is_inline = is_inline;
loop_scope.setBreakResultLoc(rl);
defer loop_scope.unstack();
defer loop_scope.labeled_breaks.deinit(astgen.gpa);
@@ -9492,6 +9496,8 @@ const GenZir = struct {
const base_tag: Scope.Tag = .gen_zir;
base: Scope = Scope{ .tag = base_tag },
force_comptime: bool,
+ /// This is set to true for inline loops; false otherwise.
+ is_inline: bool = false,
in_defer: bool,
c_import: bool = false,
/// How decls created in this scope should be named.