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
This commit is contained in:
mlugg 2025-02-05 20:33:39 +00:00
parent cac814cf58
commit fbbf34e563
No known key found for this signature in database
GPG key ID: 3F5B7DCCBF4AF02E
2 changed files with 24 additions and 3 deletions

View file

@ -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()) { return block.want_safety orelse switch (block.sema.pt.zcu.optimizeMode()) {
.Debug => true, .Debug => true,
.ReleaseSafe => true, .ReleaseSafe => true,
@ -3294,7 +3304,7 @@ fn zirUnionDecl(
.tagged .tagged
else if (small.layout != .auto) else if (small.layout != .auto)
.none .none
else switch (block.wantSafety()) { else switch (block.wantSafeTypes()) {
true => .safety, true => .safety,
false => .none, false => .none,
}, },
@ -22219,7 +22229,7 @@ fn reifyUnion(
.tagged .tagged
else if (layout != .auto) else if (layout != .auto)
.none .none
else switch (block.wantSafety()) { else switch (block.wantSafeTypes()) {
true => .safety, true => .safety,
false => .none, false => .none,
}, },

View file

@ -1751,3 +1751,14 @@ test "comptime labeled block implicit exit" {
}; };
comptime assert(result == {}); 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];
}
}