authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-04-04 13:39:06+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-04-05 14:45:56+03:00
log82a6acca93683fa7272976879f338a0e66e3f82b
treedc3f566623e8d203ebf1beeb3144daaf4b37e91d
parent080136e4adf1efd93867ef5002153d6e02fe21ae

Sema: implement inline switch capture at comptime

Closes #15157

2 files changed, 32 insertions(+), 0 deletions(-)

src/Sema.zig+20
...@@ -9963,6 +9963,26 @@ fn zirSwitchCapture(...@@ -9963,6 +9963,26 @@ fn zirSwitchCapture(
9963 const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(item_val, sema.mod).?);9963 const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(item_val, sema.mod).?);
9964 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;9964 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
9965 const field_ty = union_obj.fields.values()[field_index].ty;9965 const field_ty = union_obj.fields.values()[field_index].ty;
9966 if (try sema.resolveDefinedValue(block, sema.src, operand_ptr)) |union_val| {
9967 if (is_ref) {
9968 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
9969 .pointee_type = field_ty,
9970 .mutable = operand_ptr_ty.ptrIsMutable(),
9971 .@"volatile" = operand_ptr_ty.isVolatilePtr(),
9972 .@"addrspace" = operand_ptr_ty.ptrAddressSpace(),
9973 });
9974 return sema.addConstant(
9975 ptr_field_ty,
9976 try Value.Tag.field_ptr.create(sema.arena, .{
9977 .container_ptr = union_val,
9978 .container_ty = operand_ty,
9979 .field_index = field_index,
9980 }),
9981 );
9982 }
9983 const tag_and_val = union_val.castTag(.@"union").?.data;
9984 return sema.addConstant(field_ty, tag_and_val.val);
9985 }
9966 if (is_ref) {9986 if (is_ref) {
9967 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{9987 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
9968 .pointee_type = field_ty,9988 .pointee_type = field_ty,
test/behavior/switch.zig+12
...@@ -694,3 +694,15 @@ test "switch item sizeof" {...@@ -694,3 +694,15 @@ test "switch item sizeof" {
694 try S.doTheTest();694 try S.doTheTest();
695 comptime try S.doTheTest();695 comptime try S.doTheTest();
696}696}
697
698test "comptime inline switch" {
699 const U = union(enum) { a: type, b: type };
700 const value = comptime blk: {
701 var u: U = .{ .a = u32 };
702 break :blk switch (u) {
703 inline .a, .b => |v| v,
704 };
705 };
706
707 try expectEqual(u32, value);
708}