Is it possible to check the type of a field of a comptime struct?

I want to create a generic structure with functions that can modify the value of fields in the comptime type. This works fine in my testing, but I want to make sure that types missing the proper fields cannot be passed into the generic. In the code below is there a way to check the type of .pointer in T?

fn getMyGeneric(comptime T: type) type {
    comptime {
        if (!@hasField(T, "pointer")) @compileError("No pointer");
        if (@TypeOf( ??? ) != *T) @compileError("pointer is not type *T"); //How to check that pointer is of type *T
    }

    return struct {
        pointer: *T,
        const Self = @This();

        pub fn set(self: *Self, obj: *T) void {
            obj.pointer = self.pointer;
        }
    };
}
1 Like

I’ve understood that a type T has pointer field of type *T.

const std = @import("std");

fn getMyGeneric(comptime T: type) type {
    comptime {
        // `type` fileld only has `struct` or `union`
        const info = @typeInfo(T);
        std.debug.assert((info == .Struct) or (info == .Union));

        const field_info = std.meta.fieldInfo(T, .pointer);
        std.debug.assert(field_info.type == *T);
    }
    

    return struct {
        pointer: *T,
        const Self = @This();

        pub fn set(self: *Self, obj: *T) void {
            obj.pointer = self.pointer;
        }
    };
}

const FooX = struct {
    pointer: *FooX,
};

const FooY = struct {
    pointer: *FooX,
};

test "test getMyGeneric" {
    const Foo = FooX;
    // const Foo = FooY; // <- expected compile error
    const MyFoo = getMyGeneric(Foo);

    const allocator = std.heap.page_allocator;

    const obj_parent = try allocator.create(Foo);
    obj_parent.* = .{.pointer = undefined };
    defer allocator.destroy(obj_parent);

    const obj_child = try allocator.create(Foo);
    obj_child.* = .{.pointer = undefined };
    defer allocator.destroy(obj_child);

    const foo = try allocator.create(MyFoo);
    foo.* = .{.pointer = obj_parent};
    defer allocator.destroy(foo);

    foo.set(obj_child);

    try std.testing.expectEqual(obj_child.pointer, obj_parent);
}

Note:

This code has checked by Zig 0.14.0-dev.6+0ba64e9ce.
In current main branch of Zig , std.builtin.Type is modified.
So this code will be error.