example.zig:16:28: error: expected type '?*example.MyData.MyData__opaque_3335', found '?*example.CType'
example.zig:16:28: note: pointer type child 'example.CType' cannot cast into pointer type child 'example.MyData.MyData__opaque_3335'
example.zig:4:15: note: opaque declared here
example.zig:11:15: note: opaque declared here
I tried using @ptrCast() or @as() to cast the result to ?*opaque{}, but of course that doesn’t work.
Each declaration of an opaque type is distinct and will not coerce to a different opaque. The opaque in const CType = opaque {} is a different type from the one in native: ?*opaque {}. This is similar to how two struct types with the exact same fields and decls are still considered distinct types.
If you change the type of the native field to ?*CType, they will be one and the same type and your code will work as is.
The alternative is to change the data.native = cFunction() line to data.native = @ptrCast(cFunction()), but if the types truly represent the same type, it would probably make the most sense to declare them both as ?*CType.
Definitely true. For the real code, CType comes from cImport in a different file, so it is more like ?*c.wl_display, and I don’t want to sprinkle cImport types throughout the codebase.
But your comment gave me an idea to create a separate type, const BackendPtr = *opaque{}, which @ptrCast is happy to cast to.