From 7453f56e678c80928ababa2868c69cfe41647fed Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 24 Aug 2022 20:27:11 -0700 Subject: stage2: explicitly tagged enums no longer have one possible value Previously, Zig had inconsistent semantics for an enum like this: `enum(u8){zero = 0}` Although in theory this can only hold one possible value, the tag `zero`, Zig no longer will treat the type this way. It will do loads and stores, as if the type has runtime bits. Closes #12619 Tests passed locally: * test-behavior * test-cases --- test/behavior/enum.zig | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'test/behavior/enum.zig') diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index 709d30af33..9e96163cc0 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -1,6 +1,7 @@ const builtin = @import("builtin"); const std = @import("std"); const expect = std.testing.expect; +const assert = std.debug.assert; const mem = std.mem; const Tag = std.meta.Tag; @@ -1128,3 +1129,44 @@ test "tag name functions are unique" { _ = a; } } + +test "size of enum with only one tag which has explicit integer tag type" { + if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; + if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; + + const E = enum(u8) { nope = 10 }; + const S0 = struct { e: E }; + const S1 = extern struct { e: E }; + //const U = union(E) { nope: void }; + comptime assert(@sizeOf(E) == 1); + comptime assert(@sizeOf(S0) == 1); + comptime assert(@sizeOf(S1) == 1); + //comptime assert(@sizeOf(U) == 1); + + var s1: S1 = undefined; + s1.e = .nope; + try expect(s1.e == .nope); + const ptr = @ptrCast(*u8, &s1); + try expect(ptr.* == 10); + + var s0: S0 = undefined; + s0.e = .nope; + try expect(s0.e == .nope); +} + +test "switch on an extern enum with negative value" { + // TODO x86, wasm backends fail because they assume that enum tag types are unsigned + if (@import("builtin").zig_backend == .stage2_x86_64) return error.SkipZigTest; + if (@import("builtin").zig_backend == .stage2_wasm) return error.SkipZigTest; + + const Foo = enum(c_int) { + Bar = -1, + }; + + const v = Foo.Bar; + + switch (v) { + Foo.Bar => return, + } +} -- cgit v1.2.3