zig/test/behavior/enum_llvm.zig
Andrew Kelley c8fb36b36c stage2: LLVM backend: implement @tagName for enums
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.
2021-12-27 01:14:50 -07:00

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);
}