Decl literals and packed struct equality

Extend decl literals to work with packed struct equality
i.e if (vec == .zero)
It’s just weird that they don’t work here

Would be particularly nice with switch on packed structs

3 Likes

i suspect that the “problem” here is that expressions like a == b are subject to a different form of type resolution than you’re holding in your head: in particular, T == @Type(.enum_literal) doesn’t automatically attempt to cast the RHS to be of type T

Yes, what’s happening here is peer type resolution instead of result location semantics, I’m not surprised that it doesn’t work.
But I think it’s reasonable to have

I wouldn’t be surprised if it just works for switches when that gets implemented. In which case, it would be even weirder that it doesn’t work with ==

2 Likes

Just found out packed == .{...} doesn’t work either, should be the same issue as with decl literals.

+1

Concrete use case:
I have a memory register that I define as a packed struct:


pub const FMMUAttributes = packed struct(u128) {
    logical_start_address: u32,
    length: u16,
    logical_start_bit: u3,
    _reserved: u5 = 0,
    logical_end_bit: u3,
    _reserved2: u5 = 0,
    physical_start_address: u16,
    physical_start_bit: u3,
    _reserved3: u5 = 0,
    read_enable: bool,
    write_enable: bool,
    _reserved4: u6 = 0,
    enable: bool,
    _reserved5: u7 = 0,
    _reserved6: u24 = 0,

    pub const unused = std.mem.zeroes(FMMUAttributes);4
}

I would like to be able to compare to the .unused special value:

pub fn addSM(self: *FMMUConfiguration, sm_assign: SMPDOAssign) !void {
    // Find if an existing FMMU can be used, else make one.
    // Existing FMMU can be used if sync manager lines up with end of FMMU
    // (FMMU can be extented to cover both SMs).
    search_for_usable_fmmu: for (&self.fmmus) |*fmmu| {
        if (fmmu.* == esc.FMMUAttributes.unused) continue;  // < ---------------------
        assert(fmmu.* != esc.FMMUAttributes.unused);        // < ---------------------
        // all FMMUs are byte-aligned (for simplicity)
        assert(fmmu.physical_start_bit == 0);
        assert(fmmu.logical_start_bit == 0);
        // fmmu must be read or write, not both
        assert(!(fmmu.write_enable and fmmu.read_enable));
        // fmmu must be enabled
        assert(fmmu.enable);
        // since sync managers are byte aligned, I guess fmmu better be too if we want
        // to add on to the end of it.
        ...
1 Like