zig/test/behavior/union.zig
Andrew Kelley 8b88274781 stage2: improved union support
* `Module.Union.getFullyQualifiedName` returns a sentinel-terminated
   slice so that backends that need null-termination do not need an
   additional copy.
 * Module.Union: implement a `getLayout` function which returns
   information about ABI size and alignment so that the LLVM backend can
   properly lower union types into llvm types.
 * Sema: `resolveType` now returns `error.GenericPoison` rather than a
   Type with tag `generic_poison`. Callsites that want to allow that
   need to bypass this higher-level function.
 * Sema: implement coercion of enums and enum literals to unions.
 * Sema: fix comptime mutation of pointers to unions
 * LLVM backend: fully implement proper lowering of union types and
   values according to the union layout, and update the handling of AIR
   instructions that deal with unions to support union layouts.
 * LLVM backend: handle `decl_ref_mut`
   - Maybe this should be unreachable since comptime vars should be
     changed to be non-mutable when they go out of scope, but it's
     harmless for the LLVM backend to support lowering the value.
 * Type: fix `requiresComptime` for optionals, pointers, and some other
   types. This function is still wrong for structs, unions, and enums.
2021-10-14 17:44:46 -07:00

74 lines
1.4 KiB
Zig

const std = @import("std");
const expect = std.testing.expect;
const expectEqual = std.testing.expectEqual;
const Tag = std.meta.Tag;
const Foo = union {
float: f64,
int: i32,
};
test "basic unions" {
var foo = Foo{ .int = 1 };
try expect(foo.int == 1);
foo = Foo{ .float = 12.34 };
try expect(foo.float == 12.34);
}
test "init union with runtime value" {
var foo: Foo = undefined;
setFloat(&foo, 12.34);
try expect(foo.float == 12.34);
setInt(&foo, 42);
try expect(foo.int == 42);
}
fn setFloat(foo: *Foo, x: f64) void {
foo.* = Foo{ .float = x };
}
fn setInt(foo: *Foo, x: i32) void {
foo.* = Foo{ .int = x };
}
test "comptime union field access" {
comptime {
var foo = Foo{ .int = 0 };
try expect(foo.int == 0);
foo = Foo{ .float = 42.42 };
try expect(foo.float == 42.42);
}
}
const FooExtern = extern union {
float: f64,
int: i32,
};
test "basic extern unions" {
var foo = FooExtern{ .int = 1 };
try expect(foo.int == 1);
foo.float = 12.34;
try expect(foo.float == 12.34);
}
const ExternPtrOrInt = extern union {
ptr: *u8,
int: u64,
};
test "extern union size" {
comptime try expect(@sizeOf(ExternPtrOrInt) == 8);
}
test "0-sized extern union definition" {
const U = extern union {
a: void,
const f = 1;
};
try expect(U.f == 1);
}