From 941b2f0d5e50521c41e6db3912085a72b6c16813 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 5 Oct 2021 21:07:17 -0700 Subject: [PATCH] move tagged union behavior tests to the appropriate place tagged unions used to be called "enums" but now they are called "tagged unions". --- test/behavior/enum.zig | 138 ++------------------------------- test/behavior/enum_stage1.zig | 88 +-------------------- test/behavior/union_stage1.zig | 87 ++++++++++++++++++++- 3 files changed, 92 insertions(+), 221 deletions(-) diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 1324fa0e4a..bd47481b5f 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -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); diff --git a/test/behavior/enum_stage1.zig b/test/behavior/enum_stage1.zig index c34a3b1264..2e73e55aa4 100644 --- a/test/behavior/enum_stage1.zig +++ b/test/behavior/enum_stage1.zig @@ -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, }; diff --git a/test/behavior/union_stage1.zig b/test/behavior/union_stage1.zig index 725d7bd028..43da1d7e68 100644 --- a/test/behavior/union_stage1.zig +++ b/test/behavior/union_stage1.zig @@ -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, +};