diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/AstGen.zig | 4 | ||||
| -rw-r--r-- | src/Module.zig | 2 | ||||
| -rw-r--r-- | src/Sema.zig | 18 | ||||
| -rw-r--r-- | src/Zir.zig | 6 | ||||
| -rw-r--r-- | src/print_zir.zig | 1 |
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, |
