authorgravatar for alichraghi@proton.meAli Chraghi <alichraghi@proton.me> 2026-06-21 08:31:03+03:30
committergravatar for alichraghi@noreply.codeberg.orgAli Cheraghi <alichraghi@noreply.codeberg.org> 2026-06-25 15:47:10+02:00
log6e8a83282f10bcce7f80c9f213d2ae6407651163
tree01bfa610dde25d34dfb1bf9508d485e162405e30
parent64c5cc80471ccd167af2403741dc2037824e0c8c

Sema: implement `@typeInfo` for spirv types

Forgotten in #35461

3 files changed, 90 insertions(+), 2 deletions(-)

src/Sema.zig+37-1
......@@ -16793,7 +16793,43 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai
1679316793 .val = (try pt.aggregateValue(type_opaque_ty, &field_values)).toIntern(),
1679416794 })));
1679516795 },
16796 .spirv => unreachable, // TODO: ALI
16796 .spirv => {
16797 const spirv_info = ip.loadSpirvType(ty.toIntern());
16798 const spirv_union_ty = try sema.getStdLangType(src, .@"Type.Spirv");
16799 const spirv_tag_ty = spirv_union_ty.unionTagType(zcu).?;
16800 const spirv_tag_val = try pt.enumValueFieldIndex(spirv_tag_ty, @intFromEnum(spirv_info.flags.tag));
16801 const spirv_payload_val: Value = switch (spirv_info.flags.tag) {
16802 .sampler => .void,
16803 .sampled_image, .runtime_array => .fromInterned(spirv_info.ty),
16804 .image => image: {
16805 const image_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image");
16806 const usage_union_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image.Usage");
16807 const format_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image.Format");
16808 const dim_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image.Dimensionality");
16809 const depth_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image.Depth");
16810 const access_ty = try sema.getStdLangType(src, .@"Type.Spirv.Image.Access");
16811 const usage_tag_ty = usage_union_ty.unionTagType(zcu).?;
16812 const usage_tag_val = try pt.enumValueFieldIndex(usage_tag_ty, @intFromEnum(spirv_info.flags.usage));
16813 const usage_val = try pt.unionValue(usage_union_ty, usage_tag_val, .fromInterned(spirv_info.ty));
16814 const image_field_vals = [_]InternPool.Index{
16815 usage_val.toIntern(),
16816 (try pt.enumValueFieldIndex(format_ty, @intFromEnum(spirv_info.flags.format))).toIntern(),
16817 (try pt.enumValueFieldIndex(dim_ty, @intFromEnum(spirv_info.flags.dim))).toIntern(),
16818 (try pt.enumValueFieldIndex(depth_ty, @intFromEnum(spirv_info.flags.depth))).toIntern(),
16819 (try pt.enumValueFieldIndex(access_ty, @intFromEnum(spirv_info.flags.access))).toIntern(),
16820 Value.makeBool(spirv_info.flags.is_arrayed).toIntern(),
16821 Value.makeBool(spirv_info.flags.is_multisampled).toIntern(),
16822 };
16823 break :image try pt.aggregateValue(image_ty, &image_field_vals);
16824 },
16825 };
16826 const spirv_val = try pt.unionValue(spirv_union_ty, spirv_tag_val, spirv_payload_val);
16827 return Air.internedToRef((try pt.internUnion(.{
16828 .ty = type_info_ty.toIntern(),
16829 .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.lang.TypeId.spirv))).toIntern(),
16830 .val = spirv_val.toIntern(),
16831 })));
16832 },
1679716833 .frame => return sema.failWithUseOfAsync(block, src),
1679816834 .@"anyframe" => return sema.failWithUseOfAsync(block, src),
1679916835 }
src/Zcu.zig+13-1
......@@ -469,6 +469,12 @@ pub const StdLangDecl = enum {
469469 @"Type.ContainerLayout",
470470 @"Type.Opaque",
471471 @"Type.Spirv",
472 @"Type.Spirv.Image",
473 @"Type.Spirv.Image.Usage",
474 @"Type.Spirv.Image.Format",
475 @"Type.Spirv.Image.Dimensionality",
476 @"Type.Spirv.Image.Depth",
477 @"Type.Spirv.Image.Access",
472478
473479 panic,
474480 @"panic.call",
......@@ -550,6 +556,12 @@ pub const StdLangDecl = enum {
550556 .@"Type.ContainerLayout",
551557 .@"Type.Opaque",
552558 .@"Type.Spirv",
559 .@"Type.Spirv.Image",
560 .@"Type.Spirv.Image.Usage",
561 .@"Type.Spirv.Image.Format",
562 .@"Type.Spirv.Image.Dimensionality",
563 .@"Type.Spirv.Image.Depth",
564 .@"Type.Spirv.Image.Access",
553565 => .type,
554566
555567 .panic => .type,
......@@ -603,7 +615,7 @@ pub const StdLangDecl = enum {
603615 .VaList => .va_list,
604616 .assembly, .@"assembly.Clobbers" => .assembly,
605617 else => {
606 if (@intFromEnum(decl) <= @intFromEnum(StdLangDecl.@"Type.Spirv")) {
618 if (@intFromEnum(decl) <= @intFromEnum(StdLangDecl.@"Type.Spirv.Image.Access")) {
607619 return .main;
608620 } else {
609621 return .panic;
test/behavior/type_info.zig+40
......@@ -613,3 +613,43 @@ test "@typeInfo function with generic return type and inferred error set" {
613613 const ret_ty = @typeInfo(@TypeOf(S.testFn)).@"fn".return_type;
614614 comptime assert(ret_ty == null);
615615}
616
617test "type info: spirv info" {
618 if (builtin.zig_backend != .stage2_spirv) return error.SkipZigTest;
619
620 try testSpirv();
621 try comptime testSpirv();
622}
623
624fn testSpirv() !void {
625 const image_info = @typeInfo(Image);
626 try expect(image_info.spirv.image.usage.sampled == f32);
627 try expect(image_info.spirv.image.format == .unknown);
628 try expect(image_info.spirv.image.dim == .@"2d");
629 try expect(image_info.spirv.image.depth == .not_depth);
630 try expect(image_info.spirv.image.arrayed == false);
631 try expect(image_info.spirv.image.multisampled == false);
632 try expect(image_info.spirv.image.access == .unknown);
633
634 const sampled_image_info = @typeInfo(SampledImage);
635 try expect(sampled_image_info.spirv.sampled_image == Image);
636
637 const sampler_info = @typeInfo(Sampler);
638 try expect(sampler_info.spirv.sampler == {});
639
640 const runtime_array_info = @typeInfo(RuntimeArray);
641 try expect(runtime_array_info.spirv.runtime_array == f32);
642}
643
644pub const Image = @SpirvType(.{ .image = .{
645 .usage = .{ .sampled = f32 },
646 .format = .unknown,
647 .dim = .@"2d",
648 .depth = .not_depth,
649 .arrayed = false,
650 .multisampled = false,
651 .access = .unknown,
652} });
653pub const SampledImage = @SpirvType(.{ .sampled_image = Image });
654pub const Sampler = @SpirvType(.sampler);
655pub const RuntimeArray = @SpirvType(.{ .runtime_array = f32 });