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(
99639963 const field_index = @intCast(u32, operand_ty.unionTagFieldIndex(item_val, sema.mod).?);
99649964 const union_obj = operand_ty.cast(Type.Payload.Union).?.data;
99659965 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 }
99669986 if (is_ref) {
99679987 const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{
99689988 .pointee_type = field_ty,
test/behavior/switch.zig+12
......@@ -694,3 +694,15 @@ test "switch item sizeof" {
694694 try S.doTheTest();
695695 comptime try S.doTheTest();
696696}
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}