aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVeikka Tuominen <git@vexu.eu>2023-04-04 13:39:06 +0300
committerVeikka Tuominen <git@vexu.eu>2023-04-05 14:45:56 +0300
commit82a6acca93683fa7272976879f338a0e66e3f82b (patch)
treedc3f566623e8d203ebf1beeb3144daaf4b37e91d /src
parent080136e4adf1efd93867ef5002153d6e02fe21ae (diff)
downloadzig-82a6acca93683fa7272976879f338a0e66e3f82b.tar.gz
zig-82a6acca93683fa7272976879f338a0e66e3f82b.zip
Sema: implement inline switch capture at comptime
Closes #15157
Diffstat (limited to 'src')
-rw-r--r--src/Sema.zig20
1 files changed, 20 insertions, 0 deletions
diff --git a/src/Sema.zig b/src/Sema.zig
index 972efcff72..e816a167ec 100644
--- a/src/Sema.zig
+++ b/src/Sema.zig
@@ -9963,6 +9963,26 @@ fn zirSwitchCapture(
const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(item_val, sema.mod).?);
const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
const field_ty = union_obj.fields.values()[field_index].ty;
+ if (try sema.resolveDefinedValue(block, sema.src, operand_ptr)) |union_val| {
+ if (is_ref) {
+ const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
+ .pointee_type = field_ty,
+ .mutable = operand_ptr_ty.ptrIsMutable(),
+ .@"volatile" = operand_ptr_ty.isVolatilePtr(),
+ .@"addrspace" = operand_ptr_ty.ptrAddressSpace(),
+ });
+ return sema.addConstant(
+ ptr_field_ty,
+ try Value.Tag.field_ptr.create(sema.arena, .{
+ .container_ptr = union_val,
+ .container_ty = operand_ty,
+ .field_index = field_index,
+ }),
+ );
+ }
+ const tag_and_val = union_val.castTag(.@"union").?.data;
+ return sema.addConstant(field_ty, tag_and_val.val);
+ }
if (is_ref) {
const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
.pointee_type = field_ty,