Files
zig/doc/langref/test_inline_else.zig
T
2026-05-27 10:03:51 +01:00

51 lines
1.4 KiB
Zig

const std = @import("std");
const expectEqual = std.testing.expectEqual;
const SliceTypeA = extern struct {
len: usize,
ptr: [*]u32,
};
const SliceTypeB = extern struct {
ptr: [*]SliceTypeA,
len: usize,
};
const AnySlice = union(enum) {
a: SliceTypeA,
b: SliceTypeB,
c: []const u8,
d: []AnySlice,
};
fn withFor(any: AnySlice) usize {
const Tag = @typeInfo(AnySlice).@"union".tag_type.?;
const info = @typeInfo(Tag).@"enum";
inline for (info.field_names, info.field_values) |field_name, field_value| {
// With `inline for` the function gets generated as
// a series of `if` statements relying on the optimizer
// to convert it to a switch.
if (field_value == @intFromEnum(any)) {
return @field(any, field_name).len;
}
}
// When using `inline for` the compiler doesn't know that every
// possible case has been handled requiring an explicit `unreachable`.
unreachable;
}
fn withSwitch(any: AnySlice) usize {
return switch (any) {
// With `inline else` the function is explicitly generated
// as the desired switch and the compiler can check that
// every possible case is handled.
inline else => |slice| slice.len,
};
}
test "inline for and inline else similarity" {
const any = AnySlice{ .c = "hello" };
try expectEqual(5, withFor(any));
try expectEqual(5, withSwitch(any));
}
// test