zig icon indicating copy to clipboard operation
zig copied to clipboard

sema: allow compare .lazy_size with a signed rhs value. fixes #12498

Open bfredl opened this issue 3 years ago • 7 comments

not sure if this is the right fix. but resolving the layout unconditionally causes another test to fail (@sizeOf(T) == 0 doesn't force resolving struct size) and based on @andrewrk labeling of my example failure, #12498, only doing it for possibly signed rhs seems like one possible fix.

bfredl avatar Aug 20 '22 22:08 bfredl

doesn't seem to fully fix it in my original repo. I suppose we need to resolve @sizeOf(S) > unsigned_runtime_val as well? (but not with == ? or is just comptime zero rhs special)?

bfredl avatar Aug 20 '22 23:08 bfredl

I guess the root of the question is under what circumstances the following kind of code, which exists in the test suite, is okay.

test "@sizeOf(T) == 0 doesn't force resolving struct size" {
    const S = struct {
        const Foo = struct {
            y: if (@sizeOf(Foo) == 0) u64 else u32,
        };
    };
    try expect(@sizeOf(S.Foo) == 4);
}

What if u64 or u32 in the if/else was replaced with void ? what is the exact rule that says whenever this kind of self-reference is okay?

bfredl avatar Aug 20 '22 23:08 bfredl

test "foobar" {
    const S = struct {
        const Foo = struct {
            y: if (@sizeOf(Foo) == 0) u64 else void,
        };
    };

    try expect(@sizeOf(S.Foo) == 0);
}

so this passes on master, but I expect it shouldn't?

bfredl avatar Aug 20 '22 23:08 bfredl

Why is this specific to signed integers and lhs being a lazy value? Swapping the order or making the other type unsigned immediately breaks again.

@Vexu it was suggested this was about signedness when @andrewrk made a reduced failure from my code in https://github.com/ziglang/zig/issues/12498. but given this can be problematic even for comparison with zero, perhaps it was a red herring?

I already made the change for rhs as well locally, but this is blocked on the much larger question: what is the exact rule that says whenever struct layout is allow to self-referentially depend on @sizeOf(Foo) which in turn obviously depends on the struct layout? As I already pointed out the test suite suggest this should be allowed sometimes but there is no easy rule I can infer from it. Once this has been decided, I could try to update the implementation accordingly, for both lhs and rhs.

bfredl avatar Aug 28 '22 19:08 bfredl

I already made the change for rhs as well locally, but this is blocked on the much larger question: what is the exact rule that says whenever struct layout is allow to self-referentially depend on @sizeOf(Foo) which in turn obviously depends on the struct layout? As I already pointed out the test suite suggest this should be allowed sometimes but there is no easy rule I can infer from it. Once this has been decided, I could try to update the implementation accordingly, for both lhs and rhs.

I'm not sure I understand. If you mean when can we avoid resolving the layout then I think it is only with comparisons against zero.

Vexu avatar Aug 30 '22 11:08 Vexu

I posted two examples above. https://github.com/ziglang/zig/pull/12539#issuecomment-1221423767 is currently in the test suite and looks fine in isolation. But also https://github.com/ziglang/zig/pull/12539#issuecomment-1221425691 passes and I don't think it should. I don't really see the rationale for allowing @sizeOf(Foo) == 0 inside layout and how it could be done safely, while avoid contradictions like that.

If we allow to break the existing example in the test suite, fixing this issue is trivial. but there could be some rationale why it was added as an allowed escape hatch to start with?

bfredl avatar Aug 30 '22 16:08 bfredl

I don't think either of those examples should pass. The original implementation of this in stage1 seems to have missed that issue 0512beca9d694a667e3ad12a656835b44457fbcd.

The second case in that commit could be made to work in stage2 but that would require implementing some sort of resolveIsZeroBit.

cc @andrewrk

Vexu avatar Sep 01 '22 10:09 Vexu

Superseded by #13744

Vexu avatar Dec 04 '22 12:12 Vexu