Commit fbbf34e563

mlugg <mlugg@mlugg.co.uk>
2025-02-05 21:33:39
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
1 parent cac814c
Changed files (2)
src
test
behavior
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,
             },
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];
+    }
+}