mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-10-28 10:45:48 +08:00
399 lines
13 KiB
Zig
399 lines
13 KiB
Zig
const builtin = @import("builtin");
|
|
const std = @import("std");
|
|
const expect = std.testing.expect;
|
|
const assert = std.debug.assert;
|
|
|
|
const E1 = enum(u8) {
|
|
a,
|
|
b,
|
|
c,
|
|
d,
|
|
const expected = .{
|
|
.val = @as(E1, .b),
|
|
.int = @as(@typeInfo(E1).@"enum".tag_type, 1),
|
|
};
|
|
};
|
|
const E2 = enum(i20) {
|
|
x,
|
|
y,
|
|
z = -5,
|
|
const expected = .{
|
|
.val = @as(E2, .z),
|
|
.int = @as(@typeInfo(E2).@"enum".tag_type, -5),
|
|
};
|
|
};
|
|
const E3 = enum(i32) {
|
|
_,
|
|
const zero: E3 = @bitCast(@as(i32, 0));
|
|
const expected = .{
|
|
.val = @as(E3, .zero),
|
|
.int = @as(@typeInfo(E3).@"enum".tag_type, 0),
|
|
};
|
|
};
|
|
const E4 = enum(i200) {
|
|
min = -(1 << 199),
|
|
const expected = .{
|
|
.val = @as(E4, .min),
|
|
.int = @as(@typeInfo(E4).@"enum".tag_type, -(1 << 199)),
|
|
};
|
|
};
|
|
const E5 = enum(u0) {
|
|
a,
|
|
const expected = .{
|
|
.val = @as(E5, .a),
|
|
.int = @as(@typeInfo(E5).@"enum".tag_type, 0),
|
|
};
|
|
};
|
|
|
|
test "@backingInt with enums" {
|
|
if (builtin.cpu.arch.isSpirv() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
|
|
|
|
const static = struct {
|
|
fn doTheTest(v1: E1, v2: E2, v3: E3, v4: E4, v5: E5) !void {
|
|
const b1 = @backingInt(v1);
|
|
comptime assert(@TypeOf(b1) == @typeInfo(E1).@"enum".tag_type);
|
|
try expect(b1 == E1.expected.int);
|
|
|
|
const b2 = @backingInt(v2);
|
|
comptime assert(@TypeOf(b2) == @typeInfo(E2).@"enum".tag_type);
|
|
try expect(b2 == E2.expected.int);
|
|
|
|
const b3 = @backingInt(v3);
|
|
comptime assert(@TypeOf(b3) == @typeInfo(E3).@"enum".tag_type);
|
|
try expect(b3 == E3.expected.int);
|
|
|
|
const b4 = @backingInt(v4);
|
|
comptime assert(@TypeOf(b4) == @typeInfo(E4).@"enum".tag_type);
|
|
try expect(b4 == E4.expected.int);
|
|
|
|
const b5 = @backingInt(v5);
|
|
comptime assert(@TypeOf(b5) == @typeInfo(E5).@"enum".tag_type);
|
|
try expect(b5 == E5.expected.int);
|
|
}
|
|
};
|
|
try static.doTheTest(E1.expected.val, E2.expected.val, E3.expected.val, E4.expected.val, E5.expected.val);
|
|
try comptime static.doTheTest(E1.expected.val, E2.expected.val, E3.expected.val, E4.expected.val, E5.expected.val);
|
|
}
|
|
|
|
test "@fromBackingInt with enums" {
|
|
if (builtin.cpu.arch.isSpirv() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
|
|
|
|
const static = struct {
|
|
fn doTheTest(
|
|
b1: @typeInfo(E1).@"enum".tag_type,
|
|
b2: @typeInfo(E2).@"enum".tag_type,
|
|
b3: @typeInfo(E3).@"enum".tag_type,
|
|
b4: @typeInfo(E4).@"enum".tag_type,
|
|
b5: @typeInfo(E5).@"enum".tag_type,
|
|
) !void {
|
|
const v1: E1 = @fromBackingInt(b1);
|
|
try expect(v1 == E1.expected.val);
|
|
|
|
const v2: E2 = @fromBackingInt(b2);
|
|
try expect(v2 == E2.expected.val);
|
|
|
|
const v3: E3 = @fromBackingInt(b3);
|
|
try expect(v3 == E3.expected.val);
|
|
|
|
const v4: E4 = @fromBackingInt(b4);
|
|
try expect(v4 == E4.expected.val);
|
|
|
|
const v5: E5 = @fromBackingInt(b5);
|
|
try expect(v5 == E5.expected.val);
|
|
}
|
|
};
|
|
try static.doTheTest(E1.expected.int, E2.expected.int, E3.expected.int, E4.expected.int, E5.expected.int);
|
|
try comptime static.doTheTest(E1.expected.int, E2.expected.int, E3.expected.int, E4.expected.int, E5.expected.int);
|
|
}
|
|
|
|
const T1 = union(E1) {
|
|
a: u8,
|
|
b: []const u16,
|
|
c: []const u8,
|
|
d: i32,
|
|
const expected = .{
|
|
.val = @unionInit(T1, @tagName(E1.expected.val), &.{ 1, 2, 3 }),
|
|
.int = E1.expected.int,
|
|
};
|
|
};
|
|
const T2 = union(E2) {
|
|
x,
|
|
y: i32,
|
|
z,
|
|
const expected = .{
|
|
.val = @unionInit(T2, @tagName(E2.expected.val), {}),
|
|
.int = E2.expected.int,
|
|
};
|
|
};
|
|
const T4 = union(E4) {
|
|
min: f32,
|
|
const expected = .{
|
|
.val = @unionInit(T4, @tagName(E4.expected.val), 0.123),
|
|
.int = E4.expected.int,
|
|
};
|
|
};
|
|
const T5 = union(E5) {
|
|
a: u0,
|
|
const expected = .{
|
|
.val = @unionInit(T5, @tagName(E5.expected.val), 0),
|
|
.int = E5.expected.int,
|
|
};
|
|
};
|
|
|
|
test "@backingInt with tagged unions" {
|
|
if (builtin.cpu.arch.isSpirv()) return error.SkipZigTest;
|
|
|
|
const static = struct {
|
|
fn doTheTest(v1: T1, v2: T2, v4: T4, v5: T5) !void {
|
|
const b1 = @backingInt(v1);
|
|
comptime assert(@TypeOf(b1) == @typeInfo(@typeInfo(T1).@"union".tag_type.?).@"enum".tag_type);
|
|
try expect(b1 == E1.expected.int);
|
|
|
|
const b2 = @backingInt(v2);
|
|
comptime assert(@TypeOf(b2) == @typeInfo(@typeInfo(T2).@"union".tag_type.?).@"enum".tag_type);
|
|
try expect(b2 == E2.expected.int);
|
|
|
|
const b4 = @backingInt(v4);
|
|
comptime assert(@TypeOf(b4) == @typeInfo(@typeInfo(T4).@"union".tag_type.?).@"enum".tag_type);
|
|
try expect(b4 == E4.expected.int);
|
|
|
|
const b5 = @backingInt(v5);
|
|
comptime assert(@TypeOf(b5) == @typeInfo(@typeInfo(T5).@"union".tag_type.?).@"enum".tag_type);
|
|
try expect(b5 == E5.expected.int);
|
|
}
|
|
};
|
|
try static.doTheTest(T1.expected.val, T2.expected.val, T4.expected.val, T5.expected.val);
|
|
try comptime static.doTheTest(T1.expected.val, T2.expected.val, T4.expected.val, T5.expected.val);
|
|
}
|
|
|
|
const S1 = packed struct(u8) {
|
|
a: u4,
|
|
b: i4,
|
|
const expected = .{
|
|
.val = @as(S1, .{ .a = 0b1000, .b = 0b0010 }),
|
|
.int = @as(@typeInfo(S1).@"struct".backing_integer.?, 0b0010_1000),
|
|
};
|
|
};
|
|
const S2 = packed struct(i20) {
|
|
a: u10,
|
|
b: enum(i10) { x, y, z },
|
|
const expected = .{
|
|
.val = @as(S2, .{ .a = 0b0011001100, .b = .z }),
|
|
.int = @as(@typeInfo(S2).@"struct".backing_integer.?, 0b0000000010_0011001100),
|
|
};
|
|
};
|
|
const S3 = packed struct(i32) {
|
|
a: packed struct(u12) {
|
|
x: u8,
|
|
y: i4,
|
|
},
|
|
b: packed union(i20) {
|
|
x: i20,
|
|
y: enum(u20) { u, v },
|
|
},
|
|
const expected = .{
|
|
.val = @as(S3, .{ .a = .{ .x = 0b10010001, .y = 0b0110 }, .b = .{ .y = .v } }),
|
|
.int = @as(@typeInfo(S3).@"struct".backing_integer.?, 0b00000000000000000001_0110_10010001),
|
|
};
|
|
};
|
|
const S4 = packed struct(i200) {
|
|
a: u200,
|
|
const expected = .{
|
|
.val = @as(S4, .{ .a = (1 << 199) + 10 }),
|
|
.int = @as(@typeInfo(S4).@"struct".backing_integer.?, @bitCast(@as(u200, (1 << 199) + 10))),
|
|
};
|
|
};
|
|
const S5 = packed struct(u0) {
|
|
a: u0,
|
|
const expected = .{
|
|
.val = @as(S5, .{ .a = 0 }),
|
|
.int = @as(@typeInfo(S5).@"struct".backing_integer.?, 0),
|
|
};
|
|
};
|
|
|
|
test "@backingInt with packed structs" {
|
|
if (builtin.cpu.arch.isSpirv() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
|
|
|
|
const static = struct {
|
|
fn doTheTest(v1: S1, v2: S2, v3: S3, v4: S4, v5: S5) !void {
|
|
const b1 = @backingInt(v1);
|
|
comptime assert(@TypeOf(b1) == @typeInfo(S1).@"struct".backing_integer.?);
|
|
try expect(b1 == S1.expected.int);
|
|
|
|
const b2 = @backingInt(v2);
|
|
comptime assert(@TypeOf(b2) == @typeInfo(S2).@"struct".backing_integer.?);
|
|
try expect(b2 == S2.expected.int);
|
|
|
|
const b3 = @backingInt(v3);
|
|
comptime assert(@TypeOf(b3) == @typeInfo(S3).@"struct".backing_integer.?);
|
|
try expect(b3 == S3.expected.int);
|
|
|
|
const b4 = @backingInt(v4);
|
|
comptime assert(@TypeOf(b4) == @typeInfo(S4).@"struct".backing_integer.?);
|
|
try expect(b4 == S4.expected.int);
|
|
|
|
const b5 = @backingInt(v5);
|
|
comptime assert(@TypeOf(b5) == @typeInfo(S5).@"struct".backing_integer.?);
|
|
try expect(b5 == S5.expected.int);
|
|
}
|
|
};
|
|
try static.doTheTest(S1.expected.val, S2.expected.val, S3.expected.val, S4.expected.val, S5.expected.val);
|
|
try comptime static.doTheTest(S1.expected.val, S2.expected.val, S3.expected.val, S4.expected.val, S5.expected.val);
|
|
}
|
|
|
|
test "@fromBackingInt with packed structs" {
|
|
if (builtin.cpu.arch.isSpirv() and builtin.zig_backend == .stage2_llvm) return error.SkipZigTest;
|
|
|
|
const static = struct {
|
|
fn doTheTest(
|
|
b1: @typeInfo(S1).@"struct".backing_integer.?,
|
|
b2: @typeInfo(S2).@"struct".backing_integer.?,
|
|
b3: @typeInfo(S3).@"struct".backing_integer.?,
|
|
b4: @typeInfo(S4).@"struct".backing_integer.?,
|
|
b5: @typeInfo(S5).@"struct".backing_integer.?,
|
|
) !void {
|
|
const v1: S1 = @fromBackingInt(b1);
|
|
try expect(v1 == S1.expected.val);
|
|
|
|
const v2: S2 = @fromBackingInt(b2);
|
|
try expect(v2 == S2.expected.val);
|
|
|
|
const v3: S3 = @fromBackingInt(b3);
|
|
try expect(v3 == S3.expected.val);
|
|
|
|
// https://codeberg.org/ziglang/zig/issues/35982
|
|
if (builtin.zig_backend != .stage2_x86_64) {
|
|
const v4: S4 = @fromBackingInt(b4);
|
|
try expect(v4 == S4.expected.val);
|
|
}
|
|
|
|
const v5: S5 = @fromBackingInt(b5);
|
|
try expect(v5 == S5.expected.val);
|
|
}
|
|
};
|
|
try static.doTheTest(S1.expected.int, S2.expected.int, S3.expected.int, S4.expected.int, S5.expected.int);
|
|
try comptime static.doTheTest(S1.expected.int, S2.expected.int, S3.expected.int, S4.expected.int, S5.expected.int);
|
|
}
|
|
|
|
const U1 = packed union(u8) {
|
|
a: u8,
|
|
b: i8,
|
|
const expected = .{
|
|
.val = @as(U1, .{ .b = -123 }),
|
|
.int = @as(@typeInfo(U1).@"union".backing_integer.?, @bitCast(@as(i8, -123))),
|
|
};
|
|
};
|
|
const U2 = packed union(i20) {
|
|
a: u20,
|
|
b: enum(i20) { x, y, z },
|
|
const expected = .{
|
|
.val = @as(U2, .{ .b = .z }),
|
|
.int = @as(@typeInfo(U2).@"union".backing_integer.?, 0b00000000000000000000000000000010),
|
|
};
|
|
};
|
|
const U3 = packed union(i32) {
|
|
a: packed struct(u32) {
|
|
x: u18,
|
|
y: i14,
|
|
},
|
|
b: packed union(u32) {
|
|
x: i32,
|
|
y: enum(u32) { u, v },
|
|
},
|
|
const expected = .{
|
|
.val = @as(U3, .{ .b = .{ .y = .v } }),
|
|
.int = @as(@typeInfo(U3).@"union".backing_integer.?, 0b00000000000000000000000000000001),
|
|
};
|
|
};
|
|
const U4 = packed union(i200) {
|
|
a: u200,
|
|
const expected = .{
|
|
.val = @as(U4, .{ .a = (1 << 199) + 10 }),
|
|
.int = @as(@typeInfo(U4).@"union".backing_integer.?, @bitCast(@as(u200, (1 << 199) + 10))),
|
|
};
|
|
};
|
|
const U5 = packed union(u0) {
|
|
a: u0,
|
|
const expected = .{
|
|
.val = @as(U5, .{ .a = 0 }),
|
|
.int = @as(@typeInfo(U5).@"union".backing_integer.?, 0),
|
|
};
|
|
};
|
|
|
|
test "@backingInt with packed unions" {
|
|
if (builtin.cpu.arch.isSpirv()) return error.SkipZigTest;
|
|
|
|
const static = struct {
|
|
fn doTheTest(v1: U1, v2: U2, v3: U3, v4: U4, v5: U5) !void {
|
|
const b1 = @backingInt(v1);
|
|
comptime assert(@TypeOf(b1) == @typeInfo(U1).@"union".backing_integer.?);
|
|
try expect(b1 == U1.expected.int);
|
|
|
|
const b2 = @backingInt(v2);
|
|
comptime assert(@TypeOf(b2) == @typeInfo(U2).@"union".backing_integer.?);
|
|
try expect(b2 == U2.expected.int);
|
|
|
|
const b3 = @backingInt(v3);
|
|
comptime assert(@TypeOf(b3) == @typeInfo(U3).@"union".backing_integer.?);
|
|
try expect(b3 == U3.expected.int);
|
|
|
|
const b4 = @backingInt(v4);
|
|
comptime assert(@TypeOf(b4) == @typeInfo(U4).@"union".backing_integer.?);
|
|
try expect(b4 == U4.expected.int);
|
|
|
|
const b5 = @backingInt(v5);
|
|
comptime assert(@TypeOf(b5) == @typeInfo(U5).@"union".backing_integer.?);
|
|
try expect(b5 == U5.expected.int);
|
|
}
|
|
};
|
|
try static.doTheTest(U1.expected.val, U2.expected.val, U3.expected.val, U4.expected.val, U5.expected.val);
|
|
try comptime static.doTheTest(U1.expected.val, U2.expected.val, U3.expected.val, U4.expected.val, U5.expected.val);
|
|
}
|
|
|
|
test "@fromBackingInt with packed unions" {
|
|
if (builtin.cpu.arch.isSpirv()) return error.SkipZigTest;
|
|
|
|
const static = struct {
|
|
fn doTheTest(
|
|
b1: @typeInfo(U1).@"union".backing_integer.?,
|
|
b2: @typeInfo(U2).@"union".backing_integer.?,
|
|
b3: @typeInfo(U3).@"union".backing_integer.?,
|
|
b4: @typeInfo(U4).@"union".backing_integer.?,
|
|
b5: @typeInfo(U5).@"union".backing_integer.?,
|
|
) !void {
|
|
const v1: U1 = @fromBackingInt(b1);
|
|
try expect(v1 == U1.expected.val);
|
|
|
|
const v2: U2 = @fromBackingInt(b2);
|
|
try expect(v2 == U2.expected.val);
|
|
|
|
const v3: U3 = @fromBackingInt(b3);
|
|
try expect(v3 == U3.expected.val);
|
|
|
|
// https://codeberg.org/ziglang/zig/issues/35982
|
|
if (builtin.zig_backend != .stage2_x86_64) {
|
|
const v4: U4 = @fromBackingInt(b4);
|
|
try expect(v4 == U4.expected.val);
|
|
}
|
|
|
|
const v5: U5 = @fromBackingInt(b5);
|
|
try expect(v5 == U5.expected.val);
|
|
}
|
|
};
|
|
try static.doTheTest(U1.expected.int, U2.expected.int, U3.expected.int, U4.expected.int, U5.expected.int);
|
|
try comptime static.doTheTest(U1.expected.int, U2.expected.int, U3.expected.int, U4.expected.int, U5.expected.int);
|
|
}
|
|
|
|
test "@fromBackingInt provides result type to its argument" {
|
|
const E = enum(u32) { a, b, c };
|
|
const static = struct {
|
|
fn doTheTest(x: u8) !void {
|
|
const e: E = @fromBackingInt(x);
|
|
try expect(e == .b);
|
|
try expect(@backingInt(e) == x);
|
|
}
|
|
};
|
|
try static.doTheTest(1);
|
|
try comptime static.doTheTest(1);
|
|
}
|