Is this an inconsistency or intended?

In the following code, the switch block compiles okay, but the if blocks fail to compile.

const Triple = enum {
    false,
    true,
    pending,

    const default: @This() = .pending;
};

var t: Triple = .pending;

pub fn main() void {
    if (t == .default) {} else {}
    if (t == comptime .default) {} else {}
    comptime if (t == .default) {} else {};
    
    switch(t) {
        .default => {},
        else => {},
    }
}
1 Like

Related: Decl literals and packed struct equality - #9 by gwenzek

It’s because == does Peer Type Resolution (PTR), which doesn’t resolve decl literals the same way an assignment or in fact switches would. Since default is a declaration and not an actual value of the enum, PTR is currently unable to resolve it. I think it’s an inconsistency, but don’t yet know of a concrete plan to resolve this (which isn’t to say there isn’t one).

4 Likes

I don’t understand what is the difficulty here. If one operand is enum literal or declaration literal and the other operand is a typed value, then just use the type of typed value as the context. I don’t see any difference between handling assign a declaration literal to a typed value and handling compare a declaration literal with a typed value.

1 Like

This would make a great comment on an issue or pull request.

1 Like

Does anyone know there is such an issue or PR?

After that thread (linked above) I made a comment on the existing “Simplify PTR” proposal, where I proposed an additional change to make if (t == .default) work: https://codeberg.org/ziglang/zig/issues/35197#issuecomment-20339539

Feel free to give it a thumbs up or add your own comment

4 Likes