Testing equality between `[]type` with `std.mem.eql` always return `true`

Apparently, it is not possible to use std.mem.eql to test equality on arrays of types.

const std = @import("std");

pub fn main() void {
    const a = [_]type{ bool, f32 };
    const b = [_]type{ u8, bool };
    const c = [_]type{bool};
    std.debug.print("{}\n", .{std.mem.eql(type, &a, &b)});
    // true
    std.debug.print("{}\n", .{std.mem.eql(type, &a, &c)});
    // true
}

Why is it so ? Is it a bug ? Am I doing something wrong ?

does type has length 0 ?

sorry, I was wrong. let me check it again

Ok I found the issue, the first line in std.mem.eql

    if (@sizeOf(T) == 0) return true;

and if you check the following:

    std.debug.print("{}\n", .{@sizeOf(type) == 0});
    // true

So this should be the reason std.mem.eql returns true

1 Like

Also, for the sake of argument, here’s one that does work:

pub fn eql(
    comptime a: []const type,
    comptime b: []const type,
) bool {
    comptime {
        if (a.len != b.len) 
          return false;

        // returns true if both are empty
        return for (a, b) |t, u| {
            if (t != u) break false;
        } else true;
    }
}

pub fn main() !void {
    const a = [_]type{ bool, f32 };
    const b = [_]type{ u8, bool };
    const c = [_]type{bool};

    std.debug.print("{}\n", .{ comptime eql(a[0..], a[0..]) });
    std.debug.print("{}\n", .{ comptime eql(a[0..], b[0..]) });
    std.debug.print("{}\n", .{ comptime eql(a[0..], c[0..]) });
}
2 Likes

Good catch!

That’s a weird behaviour because I can test equality between types with ==

const std = @import("std");

const A = struct {
    foo: u8,
};

const B = struct {
    foo: u8,
};

const C = struct {
    foo: u16,
};

pub fn main() void {
    std.debug.print("{}\n", .{f32 == f32}); // true
    std.debug.print("{}\n", .{f32 == u8}); // false
    std.debug.print("{}\n", .{A == A}); // true
    std.debug.print("{}\n", .{A == B}); // false
    std.debug.print("{}\n", .{A == C}); // false
}