aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/AstGen.zig4
-rw-r--r--src/Module.zig2
-rw-r--r--src/Sema.zig18
-rw-r--r--src/Zir.zig6
-rw-r--r--src/print_zir.zig1
5 files changed, 31 insertions, 0 deletions
diff --git a/src/AstGen.zig b/src/AstGen.zig
index 528ef930e6..0078057eef 100644
--- a/src/AstGen.zig
+++ b/src/AstGen.zig
@@ -1940,6 +1940,9 @@ fn continueExpr(parent_gz: *GenZir, parent_scope: *Scope, node: Ast.Node.Index)
.break_inline
else
.@"break";
+ if (break_tag == .break_inline) {
+ _ = try parent_gz.addNode(.check_comptime_control_flow, node);
+ }
_ = try parent_gz.addBreak(break_tag, continue_block, .void_value);
return Zir.Inst.Ref.unreachable_value;
},
@@ -2473,6 +2476,7 @@ fn unusedResultExpr(gz: *GenZir, scope: *Scope, statement: Ast.Node.Index) Inner
.repeat_inline,
.panic,
.panic_comptime,
+ .check_comptime_control_flow,
=> {
noreturn_src_node = statement;
break :b true;
diff --git a/src/Module.zig b/src/Module.zig
index 397134d911..deff4620b9 100644
--- a/src/Module.zig
+++ b/src/Module.zig
@@ -2283,6 +2283,8 @@ pub const SrcLoc = struct {
.@"while" => tree.whileFull(node).ast.cond_expr,
.for_simple => tree.forSimple(node).ast.cond_expr,
.@"for" => tree.forFull(node).ast.cond_expr,
+ .@"orelse" => node,
+ .@"catch" => node,
else => unreachable,
};
return nodeToSpan(tree, src_node);
diff --git a/src/Sema.zig b/src/Sema.zig
index ac9e24a9be..5a70679b8d 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -1146,6 +1146,24 @@ fn analyzeBodyInner(
i += 1;
continue;
},
+ .check_comptime_control_flow => {
+ if (!block.is_comptime) {
+ if (block.runtime_cond orelse block.runtime_loop) |runtime_src| {
+ const inst_data = sema.code.instructions.items(.data)[inst].node;
+ const src = LazySrcLoc.nodeOffset(inst_data);
+ const msg = msg: {
+ const msg = try sema.errMsg(block, src, "comptime control flow inside runtime block", .{});
+ errdefer msg.destroy(sema.gpa);
+
+ try sema.errNote(block, runtime_src, msg, "runtime control flow here", .{});
+ break :msg msg;
+ };
+ return sema.failWithOwnedErrorMsg(block, msg);
+ }
+ }
+ i += 1;
+ continue;
+ },
// Special case instructions to handle comptime control flow.
.@"break" => {
diff --git a/src/Zir.zig b/src/Zir.zig
index 6e9b133310..4540032605 100644
--- a/src/Zir.zig
+++ b/src/Zir.zig
@@ -280,6 +280,9 @@ pub const Inst = struct {
/// break instruction in a block, and the target block is the parent.
/// Uses the `break` union field.
break_inline,
+ /// Checks that comptime control flow does not happen inside a runtime block.
+ /// Uses the `node` union field.
+ check_comptime_control_flow,
/// Function call.
/// Uses the `pl_node` union field with payload `Call`.
/// AST node is the function call.
@@ -1266,6 +1269,7 @@ pub const Inst = struct {
.repeat_inline,
.panic,
.panic_comptime,
+ .check_comptime_control_flow,
=> true,
};
}
@@ -1315,6 +1319,7 @@ pub const Inst = struct {
.set_runtime_safety,
.memcpy,
.memset,
+ .check_comptime_control_flow,
=> true,
.param,
@@ -1595,6 +1600,7 @@ pub const Inst = struct {
.bool_br_or = .bool_br,
.@"break" = .@"break",
.break_inline = .@"break",
+ .check_comptime_control_flow = .node,
.call = .pl_node,
.cmp_lt = .pl_node,
.cmp_lte = .pl_node,
diff --git a/src/print_zir.zig b/src/print_zir.zig
index de51c271c4..7723446f1c 100644
--- a/src/print_zir.zig
+++ b/src/print_zir.zig
@@ -409,6 +409,7 @@ const Writer = struct {
.alloc_inferred_comptime_mut,
.ret_ptr,
.ret_type,
+ .check_comptime_control_flow,
=> try self.writeNode(stream, inst),
.error_value,