From fbbf34e563a376ea1654dce827b9194ba7211b3a Mon Sep 17 00:00:00 2001 From: mlugg Date: Wed, 5 Feb 2025 20:33:39 +0000 Subject: [PATCH] Sema: disable runtime safety checks in comptime blocks Sometimes we emit runtime instructions in comptime scopes. These instructions will be discarded, but they allow comptime blocks to contain intermediate runtime-known values, which is necessary for expressions like `runtime_array.len` to work. Since we will always throw away these runtime instructions, including safety checks is a time waste at best and trips an assertion at worst! Resolves: #20064 --- src/Sema.zig | 16 +++++++++++++--- test/behavior/eval.zig | 11 +++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/Sema.zig b/src/Sema.zig index b04cae9a8f..d66587abb1 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -504,7 +504,17 @@ pub const Block = struct { }; } - pub fn wantSafety(block: *const Block) bool { + fn wantSafeTypes(block: *const Block) bool { + return block.want_safety orelse switch (block.sema.pt.zcu.optimizeMode()) { + .Debug => true, + .ReleaseSafe => true, + .ReleaseFast => false, + .ReleaseSmall => false, + }; + } + + fn wantSafety(block: *const Block) bool { + if (block.isComptime()) return false; // runtime safety checks are pointless in comptime blocks return block.want_safety orelse switch (block.sema.pt.zcu.optimizeMode()) { .Debug => true, .ReleaseSafe => true, @@ -3294,7 +3304,7 @@ fn zirUnionDecl( .tagged else if (small.layout != .auto) .none - else switch (block.wantSafety()) { + else switch (block.wantSafeTypes()) { true => .safety, false => .none, }, @@ -22219,7 +22229,7 @@ fn reifyUnion( .tagged else if (layout != .auto) .none - else switch (block.wantSafety()) { + else switch (block.wantSafeTypes()) { true => .safety, false => .none, }, diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 4c67d29273..0cafa1f676 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -1751,3 +1751,14 @@ test "comptime labeled block implicit exit" { }; comptime assert(result == {}); } + +test "comptime block has intermediate runtime-known values" { + const arr: [2]u8 = .{ 1, 2 }; + + var idx: usize = undefined; + idx = 0; + + comptime { + _ = arr[idx]; + } +}