mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
Introduced a new AIR instruction: `tag_name`. Reasons to do this instead of lowering it in Sema to a switch, function call, array lookup, or if-else tower: * Sema is a bottleneck; do less work in Sema whenever possible. * If any optimization passes run, and the operand to becomes comptime-known, then it could change to have a comptime result value instead of lowering to a function or array or something which would then have to be garbage-collected. * Backends may want to choose to use a function and a switch branch, or they may want to use a different strategy. Codegen for `@tagName` is implemented for the LLVM backend but not any others yet. Introduced some new `Type` tags: * `const_slice_u8_sentinel_0` * `manyptr_const_u8_sentinel_0` The motivation for this was to make typeof() on the tag_name AIR instruction non-allocating. A bunch more enum tests are passing now.
50 lines
1.2 KiB
Zig
50 lines
1.2 KiB
Zig
const std = @import("std");
|
|
const expect = std.testing.expect;
|
|
const mem = std.mem;
|
|
const Tag = std.meta.Tag;
|
|
|
|
test "@tagName" {
|
|
try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
|
|
comptime try expect(mem.eql(u8, testEnumTagNameBare(BareNumber.Three), "Three"));
|
|
}
|
|
|
|
fn testEnumTagNameBare(n: anytype) []const u8 {
|
|
return @tagName(n);
|
|
}
|
|
|
|
const BareNumber = enum { One, Two, Three };
|
|
|
|
test "@tagName non-exhaustive enum" {
|
|
try expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B"));
|
|
comptime try expect(mem.eql(u8, testEnumTagNameBare(NonExhaustive.B), "B"));
|
|
}
|
|
const NonExhaustive = enum(u8) { A, B, _ };
|
|
|
|
test "@tagName is null-terminated" {
|
|
const S = struct {
|
|
fn doTheTest(n: BareNumber) !void {
|
|
try expect(@tagName(n)[3] == 0);
|
|
}
|
|
};
|
|
try S.doTheTest(.Two);
|
|
try comptime S.doTheTest(.Two);
|
|
}
|
|
|
|
test "tag name with assigned enum values" {
|
|
const LocalFoo = enum(u8) {
|
|
A = 1,
|
|
B = 0,
|
|
};
|
|
var b = LocalFoo.B;
|
|
try expect(mem.eql(u8, @tagName(b), "B"));
|
|
}
|
|
|
|
const Bar = enum { A, B, C, D };
|
|
|
|
test "enum literal casting to optional" {
|
|
var bar: ?Bar = undefined;
|
|
bar = .B;
|
|
|
|
try expect(bar.? == Bar.B);
|
|
}
|