move tagged union behavior tests to the appropriate place
tagged unions used to be called "enums" but now they are called "tagged unions".
This commit is contained in:
@@ -3,68 +3,20 @@ const expect = std.testing.expect;
|
||||
const mem = std.mem;
|
||||
const Tag = std.meta.Tag;
|
||||
|
||||
const Point = struct {
|
||||
x: u64,
|
||||
y: u64,
|
||||
};
|
||||
const Foo = union(enum) {
|
||||
One: i32,
|
||||
Two: Point,
|
||||
Three: void,
|
||||
};
|
||||
const FooNoVoid = union(enum) {
|
||||
One: i32,
|
||||
Two: Point,
|
||||
};
|
||||
const Bar = enum {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
};
|
||||
|
||||
fn returnAnInt(x: i32) Foo {
|
||||
return Foo{ .One = x };
|
||||
}
|
||||
|
||||
fn shouldBeEmpty(x: AnEnumWithPayload) void {
|
||||
switch (x) {
|
||||
AnEnumWithPayload.Empty => {},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn shouldBeNotEmpty(x: AnEnumWithPayload) void {
|
||||
switch (x) {
|
||||
AnEnumWithPayload.Empty => unreachable,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
const AnEnumWithPayload = union(enum) {
|
||||
Empty: void,
|
||||
Full: i32,
|
||||
};
|
||||
|
||||
const Number = enum { Zero, One, Two, Three, Four };
|
||||
|
||||
fn shouldEqual(n: Number, expected: u3) !void {
|
||||
try expect(@enumToInt(n) == expected);
|
||||
}
|
||||
|
||||
fn testEnumTagNameBare(n: anytype) []const u8 {
|
||||
return @tagName(n);
|
||||
test "enum to int" {
|
||||
try shouldEqual(Number.Zero, 0);
|
||||
try shouldEqual(Number.One, 1);
|
||||
try shouldEqual(Number.Two, 2);
|
||||
try shouldEqual(Number.Three, 3);
|
||||
try shouldEqual(Number.Four, 4);
|
||||
}
|
||||
|
||||
const BareNumber = enum { One, Two, Three };
|
||||
|
||||
const NonExhaustive = enum(u8) { A, B, _ };
|
||||
|
||||
const AlignTestEnum = union(enum) {
|
||||
A: [9]u8,
|
||||
B: u64,
|
||||
};
|
||||
|
||||
const ValueCount1 = enum {
|
||||
I0,
|
||||
};
|
||||
@@ -590,84 +542,6 @@ const ValueCount257 = enum {
|
||||
I256,
|
||||
};
|
||||
|
||||
const Small2 = enum(u2) { One, Two };
|
||||
const Small = enum(u2) { One, Two, Three, Four };
|
||||
|
||||
const A = enum(u3) { One, Two, Three, Four, One2, Two2, Three2, Four2 };
|
||||
const B = enum(u3) { One3, Two3, Three3, Four3, One23, Two23, Three23, Four23 };
|
||||
const C = enum(u2) { One4, Two4, Three4, Four4 };
|
||||
|
||||
const BitFieldOfEnums = packed struct {
|
||||
a: A,
|
||||
b: B,
|
||||
c: C,
|
||||
};
|
||||
|
||||
const bit_field_1 = BitFieldOfEnums{
|
||||
.a = A.Two,
|
||||
.b = B.Three3,
|
||||
.c = C.Four4,
|
||||
};
|
||||
|
||||
fn getA(data: *const BitFieldOfEnums) A {
|
||||
return data.a;
|
||||
}
|
||||
|
||||
fn getB(data: *const BitFieldOfEnums) B {
|
||||
return data.b;
|
||||
}
|
||||
|
||||
fn getC(data: *const BitFieldOfEnums) C {
|
||||
return data.c;
|
||||
}
|
||||
|
||||
const MultipleChoice = enum(u32) {
|
||||
A = 20,
|
||||
B = 40,
|
||||
C = 60,
|
||||
D = 1000,
|
||||
};
|
||||
|
||||
const MultipleChoice2 = enum(u32) {
|
||||
Unspecified1,
|
||||
A = 20,
|
||||
Unspecified2,
|
||||
B = 40,
|
||||
Unspecified3,
|
||||
C = 60,
|
||||
Unspecified4,
|
||||
D = 1000,
|
||||
Unspecified5,
|
||||
};
|
||||
|
||||
const EnumWithOneMember = enum { Eof };
|
||||
|
||||
fn doALoopThing(id: EnumWithOneMember) void {
|
||||
while (true) {
|
||||
if (id == EnumWithOneMember.Eof) {
|
||||
break;
|
||||
}
|
||||
@compileError("above if condition should be comptime");
|
||||
}
|
||||
}
|
||||
|
||||
const State = enum { Start };
|
||||
|
||||
const EnumWithTagValues = enum(u4) {
|
||||
A = 1 << 0,
|
||||
B = 1 << 1,
|
||||
C = 1 << 2,
|
||||
D = 1 << 3,
|
||||
};
|
||||
|
||||
test "enum to int" {
|
||||
try shouldEqual(Number.Zero, 0);
|
||||
try shouldEqual(Number.One, 1);
|
||||
try shouldEqual(Number.Two, 2);
|
||||
try shouldEqual(Number.Three, 3);
|
||||
try shouldEqual(Number.Four, 4);
|
||||
}
|
||||
|
||||
test "enum sizes" {
|
||||
comptime {
|
||||
try expect(@sizeOf(ValueCount1) == 0);
|
||||
|
||||
@@ -100,81 +100,7 @@ test "single field non-exhaustive enum" {
|
||||
comptime try S.doTheTest(23);
|
||||
}
|
||||
|
||||
test "enum type" {
|
||||
const foo1 = Foo{ .One = 13 };
|
||||
const foo2 = Foo{
|
||||
.Two = Point{
|
||||
.x = 1234,
|
||||
.y = 5678,
|
||||
},
|
||||
};
|
||||
try expect(foo1.One == 13);
|
||||
try expect(foo2.Two.x == 1234 and foo2.Two.y == 5678);
|
||||
const bar = Bar.B;
|
||||
|
||||
try expect(bar == Bar.B);
|
||||
try expect(@typeInfo(Foo).Union.fields.len == 3);
|
||||
try expect(@typeInfo(Bar).Enum.fields.len == 4);
|
||||
try expect(@sizeOf(Foo) == @sizeOf(FooNoVoid));
|
||||
try expect(@sizeOf(Bar) == 1);
|
||||
}
|
||||
|
||||
test "enum as return value" {
|
||||
switch (returnAnInt(13)) {
|
||||
Foo.One => |value| try expect(value == 13),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
const Point = struct {
|
||||
x: u64,
|
||||
y: u64,
|
||||
};
|
||||
const Foo = union(enum) {
|
||||
One: i32,
|
||||
Two: Point,
|
||||
Three: void,
|
||||
};
|
||||
const FooNoVoid = union(enum) {
|
||||
One: i32,
|
||||
Two: Point,
|
||||
};
|
||||
const Bar = enum {
|
||||
A,
|
||||
B,
|
||||
C,
|
||||
D,
|
||||
};
|
||||
|
||||
fn returnAnInt(x: i32) Foo {
|
||||
return Foo{ .One = x };
|
||||
}
|
||||
|
||||
test "constant enum with payload" {
|
||||
var empty = AnEnumWithPayload{ .Empty = {} };
|
||||
var full = AnEnumWithPayload{ .Full = 13 };
|
||||
shouldBeEmpty(empty);
|
||||
shouldBeNotEmpty(full);
|
||||
}
|
||||
|
||||
fn shouldBeEmpty(x: AnEnumWithPayload) void {
|
||||
switch (x) {
|
||||
AnEnumWithPayload.Empty => {},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn shouldBeNotEmpty(x: AnEnumWithPayload) void {
|
||||
switch (x) {
|
||||
AnEnumWithPayload.Empty => unreachable,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
const AnEnumWithPayload = union(enum) {
|
||||
Empty: void,
|
||||
Full: i32,
|
||||
};
|
||||
const Bar = enum { A, B, C, D };
|
||||
|
||||
const Number = enum { Zero, One, Two, Three, Four };
|
||||
|
||||
@@ -208,18 +134,6 @@ const BareNumber = enum { One, Two, Three };
|
||||
|
||||
const NonExhaustive = enum(u8) { A, B, _ };
|
||||
|
||||
test "enum alignment" {
|
||||
comptime {
|
||||
try expect(@alignOf(AlignTestEnum) >= @alignOf([9]u8));
|
||||
try expect(@alignOf(AlignTestEnum) >= @alignOf(u64));
|
||||
}
|
||||
}
|
||||
|
||||
const AlignTestEnum = union(enum) {
|
||||
A: [9]u8,
|
||||
B: u64,
|
||||
};
|
||||
|
||||
const ValueCount1 = enum {
|
||||
I0,
|
||||
};
|
||||
|
||||
@@ -770,6 +770,89 @@ test "union enum type gets a separate scope" {
|
||||
try S.doTheTest();
|
||||
}
|
||||
test "anytype union field: issue #9233" {
|
||||
const Baz = union(enum) { bar: anytype };
|
||||
_ = Baz;
|
||||
const Quux = union(enum) { bar: anytype };
|
||||
_ = Quux;
|
||||
}
|
||||
|
||||
const Point = struct {
|
||||
x: u64,
|
||||
y: u64,
|
||||
};
|
||||
const TaggedFoo = union(enum) {
|
||||
One: i32,
|
||||
Two: Point,
|
||||
Three: void,
|
||||
};
|
||||
const FooNoVoid = union(enum) {
|
||||
One: i32,
|
||||
Two: Point,
|
||||
};
|
||||
const Baz = enum { A, B, C, D };
|
||||
|
||||
test "tagged union type" {
|
||||
const foo1 = TaggedFoo{ .One = 13 };
|
||||
const foo2 = TaggedFoo{
|
||||
.Two = Point{
|
||||
.x = 1234,
|
||||
.y = 5678,
|
||||
},
|
||||
};
|
||||
try expect(foo1.One == 13);
|
||||
try expect(foo2.Two.x == 1234 and foo2.Two.y == 5678);
|
||||
const baz = Baz.B;
|
||||
|
||||
try expect(baz == Baz.B);
|
||||
try expect(@typeInfo(TaggedFoo).Union.fields.len == 3);
|
||||
try expect(@typeInfo(Baz).Enum.fields.len == 4);
|
||||
try expect(@sizeOf(TaggedFoo) == @sizeOf(FooNoVoid));
|
||||
try expect(@sizeOf(Baz) == 1);
|
||||
}
|
||||
|
||||
test "tagged union as return value" {
|
||||
switch (returnAnInt(13)) {
|
||||
TaggedFoo.One => |value| try expect(value == 13),
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn returnAnInt(x: i32) TaggedFoo {
|
||||
return TaggedFoo{ .One = x };
|
||||
}
|
||||
|
||||
test "constant tagged union with payload" {
|
||||
var empty = TaggedUnionWithPayload{ .Empty = {} };
|
||||
var full = TaggedUnionWithPayload{ .Full = 13 };
|
||||
shouldBeEmpty(empty);
|
||||
shouldBeNotEmpty(full);
|
||||
}
|
||||
|
||||
fn shouldBeEmpty(x: TaggedUnionWithPayload) void {
|
||||
switch (x) {
|
||||
TaggedUnionWithPayload.Empty => {},
|
||||
else => unreachable,
|
||||
}
|
||||
}
|
||||
|
||||
fn shouldBeNotEmpty(x: TaggedUnionWithPayload) void {
|
||||
switch (x) {
|
||||
TaggedUnionWithPayload.Empty => unreachable,
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
const TaggedUnionWithPayload = union(enum) {
|
||||
Empty: void,
|
||||
Full: i32,
|
||||
};
|
||||
|
||||
test "enum alignment" {
|
||||
comptime {
|
||||
try expect(@alignOf(AlignTestTaggedUnion) >= @alignOf([9]u8));
|
||||
try expect(@alignOf(AlignTestTaggedUnion) >= @alignOf(u64));
|
||||
}
|
||||
}
|
||||
|
||||
const AlignTestTaggedUnion = union(enum) {
|
||||
A: [9]u8,
|
||||
B: u64,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user