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:
Andrew Kelley
2021-10-05 21:07:17 -07:00
parent 9ed599b4e3
commit 941b2f0d5e
3 changed files with 92 additions and 221 deletions

View File

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

View File

@@ -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,
};

View File

@@ -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,
};