Error: depends on itself

Hi guys,

I just found the following code will emit error. Not sure why. May someone please take a look? Thanks.

const std = @import("std");

const MyUnion = union(enum) {
    body: []const Element,

    pub const Element = struct { []const u8, MyUnion };
};

test "main" {
    std.debug.print("{}\n", .{@sizeOf(MyUnion)});
}

The error is as follows under zig 0.14.0:

main.zig:3:17: error: union 'main.MyUnion' depends on itself
const MyUnion = union(enum) {

This error does not happen under 0.13.0

Based on my understanding, the memory layout []const Element is determined already, eg, the size of body is determined by ptr and len, not Element itself. So the compiler should deduce the layout.

To confirm this, by changing the tuple to normal struct, the compilation passed:

const std = @import("std");

const MyUnion = union(enum) {
    body: []const Element,

    pub const Element = struct { name: []const u8, desc: MyUnion }; // --change this
};

test "main" {
    std.debug.print("{}\n", .{@sizeOf(MyUnion)});
}

Is it a bug?

3 Likes

As far as I can tell this should be able to compile and the fact that it previously has further supports that.
I am not familiar with the inner workings of Sema.zig and its changes though, so I dont know what could be responsible for this.

Yes, it is a bug.
Please open a new zig issue.

1 Like

Thanks for your reply. Bad news, I raised issue but closed as intendeded. See

please take a look. It reads work as intended,opps

I’m not sure I understand why this is a problem for structural tuple equivalence.

In any case, this compiles:

const SelfReferenceUnion = union(enum) {
    body: []const Element,

    pub const Element = OuterElement;
};

const OuterElement = struct { name: []const u8, desc: SelfReferenceUnion }; 

So a workaround is available.

But if you asked me why this is ok and the other one isn’t, I can’t answer that question.

@mlugg might be willing to help us understand what’s going on here?

4 Likes