mirror of
https://github.com/ziglang/zig.git
synced 2024-11-26 23:22:44 +00:00
Sema: detect comptime-known union initializations
Follow a similar pattern as we already do for validate_array_init and validate_struct_init. I threw in a bit of behavior test cleanup on top of it.
This commit is contained in:
parent
220708e7c3
commit
1c8a86f063
160
src/Sema.zig
160
src/Sema.zig
@ -2737,6 +2737,7 @@ fn zirValidateStructInit(
|
||||
init_src,
|
||||
instrs,
|
||||
object_ptr,
|
||||
is_comptime,
|
||||
),
|
||||
else => unreachable,
|
||||
}
|
||||
@ -2749,6 +2750,7 @@ fn validateUnionInit(
|
||||
init_src: LazySrcLoc,
|
||||
instrs: []const Zir.Inst.Index,
|
||||
union_ptr: Air.Inst.Ref,
|
||||
is_comptime: bool,
|
||||
) CompileError!void {
|
||||
if (instrs.len != 1) {
|
||||
const msg = msg: {
|
||||
@ -2771,6 +2773,11 @@ fn validateUnionInit(
|
||||
return sema.failWithOwnedErrorMsg(msg);
|
||||
}
|
||||
|
||||
if (is_comptime or block.is_comptime) {
|
||||
// In this case, comptime machinery already did everything. No work to do here.
|
||||
return;
|
||||
}
|
||||
|
||||
const field_ptr = instrs[0];
|
||||
const field_ptr_data = sema.code.instructions.items(.data)[field_ptr].pl_node;
|
||||
const field_src: LazySrcLoc = .{ .node_offset_back2tok = field_ptr_data.src_node };
|
||||
@ -2779,44 +2786,72 @@ fn validateUnionInit(
|
||||
const field_index_big = union_obj.fields.getIndex(field_name) orelse
|
||||
return sema.failWithBadUnionFieldAccess(block, union_obj, field_src, field_name);
|
||||
const field_index = @intCast(u32, field_index_big);
|
||||
const air_tags = sema.air_instructions.items(.tag);
|
||||
const air_datas = sema.air_instructions.items(.data);
|
||||
const field_ptr_air_ref = sema.inst_map.get(field_ptr).?;
|
||||
const field_ptr_air_inst = Air.refToIndex(field_ptr_air_ref).?;
|
||||
|
||||
// Handle the possibility of the union value being comptime-known.
|
||||
const union_ptr_inst = Air.refToIndex(union_ptr).?;
|
||||
switch (sema.air_instructions.items(.tag)[union_ptr_inst]) {
|
||||
.constant => {
|
||||
if (try sema.resolveDefinedValue(block, init_src, union_ptr)) |ptr_val| {
|
||||
if (ptr_val.isComptimeMutablePtr()) {
|
||||
// In this case the tag has already been set. No validation to do.
|
||||
// Our task here is to determine if the union is comptime-known. In such case,
|
||||
// we erase the runtime AIR instructions for initializing the union, and replace
|
||||
// the mapping with the comptime value. Either way, we will need to populate the tag.
|
||||
|
||||
// We expect to see something like this in the current block AIR:
|
||||
// %a = alloc(*const U)
|
||||
// %b = bitcast(*U, %a)
|
||||
// %c = field_ptr(..., %b)
|
||||
// %e!= store(%c!, %d!)
|
||||
// If %d is a comptime operand, the union is comptime.
|
||||
// If the union is comptime, we want `first_block_index`
|
||||
// to point at %c so that the bitcast becomes the last instruction in the block.
|
||||
//
|
||||
// In the case of a comptime-known pointer to a union, the
|
||||
// the field_ptr instruction is missing, so we have to pattern-match
|
||||
// based only on the store instructions.
|
||||
// `first_block_index` needs to point to the `field_ptr` if it exists;
|
||||
// the `store` otherwise.
|
||||
//
|
||||
// It's also possible for there to be no store instruction, in the case
|
||||
// of nested `coerce_result_ptr` instructions. If we see the `field_ptr`
|
||||
// but we have not found a `store`, treat as a runtime-known field.
|
||||
var first_block_index = block.instructions.items.len;
|
||||
var block_index = block.instructions.items.len - 1;
|
||||
var init_val: ?Value = null;
|
||||
while (block_index > 0) : (block_index -= 1) {
|
||||
const store_inst = block.instructions.items[block_index];
|
||||
if (store_inst == field_ptr_air_inst) break;
|
||||
if (air_tags[store_inst] != .store) continue;
|
||||
const bin_op = air_datas[store_inst].bin_op;
|
||||
if (bin_op.lhs != field_ptr_air_ref) continue;
|
||||
if (block_index > 0 and
|
||||
field_ptr_air_inst == block.instructions.items[block_index - 1])
|
||||
{
|
||||
first_block_index = @minimum(first_block_index, block_index - 1);
|
||||
} else {
|
||||
first_block_index = @minimum(first_block_index, block_index);
|
||||
}
|
||||
init_val = try sema.resolveMaybeUndefValAllowVariables(block, init_src, bin_op.rhs);
|
||||
break;
|
||||
}
|
||||
|
||||
const tag_val = try Value.Tag.enum_field_index.create(sema.arena, field_index);
|
||||
|
||||
if (init_val) |val| {
|
||||
// Our task is to delete all the `field_ptr` and `store` instructions, and insert
|
||||
// instead a single `store` to the result ptr with a comptime union value.
|
||||
block.instructions.shrinkRetainingCapacity(first_block_index);
|
||||
|
||||
const union_val = try Value.Tag.@"union".create(sema.arena, .{
|
||||
.tag = tag_val,
|
||||
.val = val,
|
||||
});
|
||||
const union_ty = sema.typeOf(union_ptr).childType();
|
||||
const union_init = try sema.addConstant(union_ty, union_val);
|
||||
try sema.storePtr2(block, init_src, union_ptr, init_src, union_init, init_src, .store);
|
||||
return;
|
||||
}
|
||||
}
|
||||
},
|
||||
.bitcast => {
|
||||
// TODO here we need to go back and see if we need to convert the union
|
||||
// to a comptime-known value. In such case, we must delete all the instructions
|
||||
// added to the current block starting with the bitcast.
|
||||
// If the bitcast result ptr is an alloc, the alloc should be replaced with
|
||||
// a constant decl_ref.
|
||||
// Otherwise, the bitcast should be preserved and a store instruction should be
|
||||
// emitted to store the constant union value through the bitcast.
|
||||
},
|
||||
.alloc => {},
|
||||
else => |t| {
|
||||
if (std.debug.runtime_safety) {
|
||||
std.debug.panic("unexpected AIR tag for union pointer: {s}", .{@tagName(t)});
|
||||
} else {
|
||||
unreachable;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Otherwise, we set the new union tag now.
|
||||
const new_tag = try sema.addConstant(
|
||||
union_obj.tag_ty,
|
||||
try Value.Tag.enum_field_index.create(sema.arena, field_index),
|
||||
);
|
||||
|
||||
try sema.requireRuntimeBlock(block, init_src);
|
||||
const new_tag = try sema.addConstant(union_obj.tag_ty, tag_val);
|
||||
_ = try block.addBinOp(.set_union_tag, union_ptr, new_tag);
|
||||
}
|
||||
|
||||
@ -3084,7 +3119,7 @@ fn zirValidateArrayInit(
|
||||
}
|
||||
|
||||
var array_is_comptime = true;
|
||||
var first_block_index: usize = std.math.maxInt(u32);
|
||||
var first_block_index = block.instructions.items.len;
|
||||
|
||||
// Collect the comptime element values in case the array literal ends up
|
||||
// being comptime-known.
|
||||
@ -15147,7 +15182,32 @@ fn unionFieldPtr(
|
||||
});
|
||||
|
||||
if (try sema.resolveDefinedValue(block, src, union_ptr)) |union_ptr_val| {
|
||||
// TODO detect inactive union field and emit compile error
|
||||
switch (union_obj.layout) {
|
||||
.Auto => {
|
||||
// TODO emit the access of inactive union field error commented out below.
|
||||
// In order to do that, we need to first solve the problem that AstGen
|
||||
// emits field_ptr instructions in order to initialize union values.
|
||||
// In such case we need to know that the field_ptr instruction (which is
|
||||
// calling this unionFieldPtr function) is *initializing* the union,
|
||||
// in which case we would skip this check, and in fact we would actually
|
||||
// set the union tag here and the payload to undefined.
|
||||
|
||||
//const tag_and_val = union_val.castTag(.@"union").?.data;
|
||||
//var field_tag_buf: Value.Payload.U32 = .{
|
||||
// .base = .{ .tag = .enum_field_index },
|
||||
// .data = field_index,
|
||||
//};
|
||||
//const field_tag = Value.initPayload(&field_tag_buf.base);
|
||||
//const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);
|
||||
//if (!tag_matches) {
|
||||
// // TODO enhance this saying which one was active
|
||||
// // and which one was accessed, and showing where the union was declared.
|
||||
// return sema.fail(block, src, "access of inactive union field", .{});
|
||||
//}
|
||||
// TODO add runtime safety check for the active tag
|
||||
},
|
||||
.Packed, .Extern => {},
|
||||
}
|
||||
return sema.addConstant(
|
||||
ptr_field_ty,
|
||||
try Value.Tag.field_ptr.create(arena, .{
|
||||
@ -15183,9 +15243,33 @@ fn unionFieldVal(
|
||||
if (try sema.resolveMaybeUndefVal(block, src, union_byval)) |union_val| {
|
||||
if (union_val.isUndef()) return sema.addConstUndef(field.ty);
|
||||
|
||||
// TODO detect inactive union field and emit compile error
|
||||
const active_val = union_val.castTag(.@"union").?.data.val;
|
||||
return sema.addConstant(field.ty, active_val);
|
||||
const tag_and_val = union_val.castTag(.@"union").?.data;
|
||||
var field_tag_buf: Value.Payload.U32 = .{
|
||||
.base = .{ .tag = .enum_field_index },
|
||||
.data = field_index,
|
||||
};
|
||||
const field_tag = Value.initPayload(&field_tag_buf.base);
|
||||
const tag_matches = tag_and_val.tag.eql(field_tag, union_obj.tag_ty);
|
||||
switch (union_obj.layout) {
|
||||
.Auto => {
|
||||
if (tag_matches) {
|
||||
return sema.addConstant(field.ty, tag_and_val.val);
|
||||
} else {
|
||||
// TODO enhance this saying which one was active
|
||||
// and which one was accessed, and showing where the union was declared.
|
||||
return sema.fail(block, src, "access of inactive union field", .{});
|
||||
}
|
||||
},
|
||||
.Packed, .Extern => {
|
||||
if (tag_matches) {
|
||||
return sema.addConstant(field.ty, tag_and_val.val);
|
||||
} else {
|
||||
const old_ty = union_ty.unionFieldType(tag_and_val.tag);
|
||||
const new_val = try sema.bitCastVal(block, src, tag_and_val.val, old_ty, field.ty);
|
||||
return sema.addConstant(field.ty, new_val);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
try sema.requireRuntimeBlock(block, src);
|
||||
|
@ -51,6 +51,7 @@ test {
|
||||
_ = @import("behavior/defer.zig");
|
||||
_ = @import("behavior/enum.zig");
|
||||
_ = @import("behavior/error.zig");
|
||||
_ = @import("behavior/floatop.zig");
|
||||
_ = @import("behavior/fn.zig");
|
||||
_ = @import("behavior/fn_delegation.zig");
|
||||
_ = @import("behavior/fn_in_struct_in_comptime.zig");
|
||||
@ -79,6 +80,7 @@ test {
|
||||
_ = @import("behavior/slice_sentinel_comptime.zig");
|
||||
_ = @import("behavior/src.zig");
|
||||
_ = @import("behavior/struct.zig");
|
||||
_ = @import("behavior/switch.zig");
|
||||
_ = @import("behavior/this.zig");
|
||||
_ = @import("behavior/truncate.zig");
|
||||
_ = @import("behavior/try.zig");
|
||||
@ -93,7 +95,6 @@ test {
|
||||
_ = @import("behavior/void.zig");
|
||||
_ = @import("behavior/while.zig");
|
||||
|
||||
// tests that don't pass for stage1
|
||||
if (builtin.zig_backend != .stage1) {
|
||||
_ = @import("behavior/decltest.zig");
|
||||
}
|
||||
@ -116,13 +117,11 @@ test {
|
||||
if (builtin.zig_backend != .stage2_c) {
|
||||
// Tests that pass for stage1 and the llvm backend.
|
||||
_ = @import("behavior/atomics.zig");
|
||||
_ = @import("behavior/floatop.zig");
|
||||
_ = @import("behavior/math.zig");
|
||||
_ = @import("behavior/maximum_minimum.zig");
|
||||
_ = @import("behavior/popcount.zig");
|
||||
_ = @import("behavior/saturating_arithmetic.zig");
|
||||
_ = @import("behavior/sizeof_and_typeof.zig");
|
||||
_ = @import("behavior/switch.zig");
|
||||
_ = @import("behavior/widening.zig");
|
||||
_ = @import("behavior/bugs/421.zig");
|
||||
_ = @import("behavior/bugs/726.zig");
|
||||
|
@ -108,15 +108,19 @@ test "array len field" {
|
||||
}
|
||||
|
||||
test "array with sentinels" {
|
||||
if (builtin.zig_backend == .stage1) {
|
||||
// Stage1 test coverage disabled at runtime because of
|
||||
// https://github.com/ziglang/zig/issues/4372
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest(is_ct: bool) !void {
|
||||
if (is_ct or builtin.zig_backend != .stage1) {
|
||||
{
|
||||
var zero_sized: [0:0xde]u8 = [_:0xde]u8{};
|
||||
// Stage1 test coverage disabled at runtime because of
|
||||
// https://github.com/ziglang/zig/issues/4372
|
||||
try expect(zero_sized[0] == 0xde);
|
||||
var reinterpreted = @ptrCast(*[1]u8, &zero_sized);
|
||||
try expect(reinterpreted[0] == 0xde);
|
||||
|
@ -1050,9 +1050,9 @@ fn incrementVoidPtrArray(array: ?*anyopaque, len: usize) void {
|
||||
}
|
||||
|
||||
test "compile time int to ptr of function" {
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
@ -1060,11 +1060,13 @@ test "compile time int to ptr of function" {
|
||||
try foobar(FUNCTION_CONSTANT);
|
||||
}
|
||||
|
||||
pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, maxInt(usize));
|
||||
// On some architectures function pointers must be aligned.
|
||||
const hardcoded_fn_addr = maxInt(usize) & ~@as(usize, 0xf);
|
||||
pub const FUNCTION_CONSTANT = @intToPtr(PFN_void, hardcoded_fn_addr);
|
||||
pub const PFN_void = *const fn (*anyopaque) callconv(.C) void;
|
||||
|
||||
fn foobar(func: PFN_void) !void {
|
||||
try std.testing.expect(@ptrToInt(func) == maxInt(usize));
|
||||
try std.testing.expect(@ptrToInt(func) == hardcoded_fn_addr);
|
||||
}
|
||||
|
||||
test "implicit ptr to *anyopaque" {
|
||||
|
@ -21,6 +21,12 @@ fn epsForType(comptime T: type) T {
|
||||
}
|
||||
|
||||
test "floating point comparisons" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testFloatComparisons();
|
||||
comptime try testFloatComparisons();
|
||||
}
|
||||
@ -51,6 +57,12 @@ fn testFloatComparisons() !void {
|
||||
}
|
||||
|
||||
test "different sized float comparisons" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testDifferentSizedFloatComparisons();
|
||||
comptime try testDifferentSizedFloatComparisons();
|
||||
}
|
||||
@ -81,12 +93,24 @@ fn testDifferentSizedFloatComparisons() !void {
|
||||
//}
|
||||
|
||||
test "negative f128 floatToInt at compile-time" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const a: f128 = -2;
|
||||
var b = @floatToInt(i64, a);
|
||||
try expect(@as(i64, -2) == b);
|
||||
}
|
||||
|
||||
test "@sqrt" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testSqrt();
|
||||
try testSqrt();
|
||||
}
|
||||
@ -129,6 +153,12 @@ fn testSqrt() !void {
|
||||
}
|
||||
|
||||
test "more @sqrt f16 tests" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
// TODO these are not all passing at comptime
|
||||
try expect(@sqrt(@as(f16, 0.0)) == 0.0);
|
||||
try expect(math.approxEqAbs(f16, @sqrt(@as(f16, 2.0)), 1.414214, epsilon));
|
||||
@ -149,14 +179,21 @@ test "more @sqrt f16 tests" {
|
||||
}
|
||||
|
||||
test "@sin" {
|
||||
if (builtin.zig_backend == .stage1) {
|
||||
// stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)`
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testSin();
|
||||
try testSin();
|
||||
}
|
||||
|
||||
fn testSin() !void {
|
||||
// stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)`
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
|
||||
inline for ([_]type{ f16, f32, f64 }) |ty| {
|
||||
const eps = epsForType(ty);
|
||||
try expect(@sin(@as(ty, 0)) == 0);
|
||||
@ -176,14 +213,21 @@ fn testSin() !void {
|
||||
}
|
||||
|
||||
test "@cos" {
|
||||
if (builtin.zig_backend == .stage1) {
|
||||
// stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)`
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testCos();
|
||||
try testCos();
|
||||
}
|
||||
|
||||
fn testCos() !void {
|
||||
// stage1 emits an incorrect compile error for `@as(ty, std.math.pi / 2)`
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
|
||||
inline for ([_]type{ f16, f32, f64 }) |ty| {
|
||||
const eps = epsForType(ty);
|
||||
try expect(@cos(@as(ty, 0)) == 1);
|
||||
@ -203,6 +247,12 @@ fn testCos() !void {
|
||||
}
|
||||
|
||||
test "@exp" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testExp();
|
||||
try testExp();
|
||||
}
|
||||
@ -226,6 +276,12 @@ fn testExp() !void {
|
||||
}
|
||||
|
||||
test "@exp2" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testExp2();
|
||||
try testExp2();
|
||||
}
|
||||
@ -249,7 +305,7 @@ fn testExp2() !void {
|
||||
}
|
||||
|
||||
test "@log" {
|
||||
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testLog();
|
||||
try testLog();
|
||||
@ -285,7 +341,7 @@ fn testLog() !void {
|
||||
}
|
||||
|
||||
test "@log2" {
|
||||
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testLog2();
|
||||
try testLog2();
|
||||
@ -310,7 +366,7 @@ fn testLog2() !void {
|
||||
}
|
||||
|
||||
test "@log10" {
|
||||
if (builtin.zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testLog10();
|
||||
try testLog10();
|
||||
@ -335,6 +391,12 @@ fn testLog10() !void {
|
||||
}
|
||||
|
||||
test "@fabs" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testFabs();
|
||||
try testFabs();
|
||||
}
|
||||
@ -367,6 +429,12 @@ fn testFabs() !void {
|
||||
}
|
||||
|
||||
test "@floor" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testFloor();
|
||||
try testFloor();
|
||||
}
|
||||
@ -394,6 +462,12 @@ fn testFloor() !void {
|
||||
}
|
||||
|
||||
test "@ceil" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testCeil();
|
||||
try testCeil();
|
||||
}
|
||||
@ -421,6 +495,12 @@ fn testCeil() !void {
|
||||
}
|
||||
|
||||
test "@trunc" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
comptime try testTrunc();
|
||||
try testTrunc();
|
||||
}
|
||||
@ -449,7 +529,11 @@ fn testTrunc() !void {
|
||||
|
||||
test "negation" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
if (builtin.os.tag == .freebsd) return error.SkipZigTest;
|
||||
|
||||
if (builtin.os.tag == .freebsd) {
|
||||
// TODO file issue to track this failure
|
||||
return error.SkipZigTest;
|
||||
}
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
|
@ -2,7 +2,6 @@ const builtin = @import("builtin");
|
||||
|
||||
test "casting integer address to function pointer" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_llvm and builtin.cpu.arch == .aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
|
||||
@ -11,7 +10,7 @@ test "casting integer address to function pointer" {
|
||||
}
|
||||
|
||||
fn addressToFunction() void {
|
||||
var addr: usize = 0xdeadbeef;
|
||||
var addr: usize = 0xdeadbee0;
|
||||
_ = @intToPtr(*const fn () void, addr);
|
||||
}
|
||||
|
||||
|
@ -1175,7 +1175,11 @@ test "for loop over pointers to struct, getting field from struct pointer" {
|
||||
|
||||
test "anon init through error unions and optionals" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
a: u32,
|
||||
@ -1200,7 +1204,11 @@ test "anon init through error unions and optionals" {
|
||||
|
||||
test "anon init through optional" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
a: u32,
|
||||
@ -1218,7 +1226,11 @@ test "anon init through optional" {
|
||||
|
||||
test "anon init through error union" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
a: u32,
|
||||
@ -1236,7 +1248,11 @@ test "anon init through error union" {
|
||||
|
||||
test "typed init through error unions and optionals" {
|
||||
if (builtin.zig_backend == .stage1) return error.SkipZigTest;
|
||||
if (builtin.zig_backend != .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
a: u32,
|
||||
|
@ -1,9 +1,13 @@
|
||||
const builtin = @import("builtin");
|
||||
const std = @import("std");
|
||||
const expect = std.testing.expect;
|
||||
const expectError = std.testing.expectError;
|
||||
const expectEqual = std.testing.expectEqual;
|
||||
|
||||
test "switch with numbers" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testSwitchWithNumbers(13);
|
||||
}
|
||||
|
||||
@ -17,6 +21,9 @@ fn testSwitchWithNumbers(x: u32) !void {
|
||||
}
|
||||
|
||||
test "switch with all ranges" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try expect(testSwitchWithAllRanges(50, 3) == 1);
|
||||
try expect(testSwitchWithAllRanges(101, 0) == 2);
|
||||
try expect(testSwitchWithAllRanges(300, 5) == 3);
|
||||
@ -48,6 +55,9 @@ test "implicit comptime switch" {
|
||||
}
|
||||
|
||||
test "switch on enum" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const fruit = Fruit.Orange;
|
||||
nonConstSwitchOnEnum(fruit);
|
||||
}
|
||||
@ -65,6 +75,9 @@ fn nonConstSwitchOnEnum(fruit: Fruit) void {
|
||||
}
|
||||
|
||||
test "switch statement" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try nonConstSwitch(SwitchStatementFoo.C);
|
||||
}
|
||||
fn nonConstSwitch(foo: SwitchStatementFoo) !void {
|
||||
@ -79,6 +92,10 @@ fn nonConstSwitch(foo: SwitchStatementFoo) !void {
|
||||
const SwitchStatementFoo = enum { A, B, C, D };
|
||||
|
||||
test "switch with multiple expressions" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const x = switch (returnsFive()) {
|
||||
1, 2, 3 => 1,
|
||||
4, 5, 6 => 2,
|
||||
@ -91,6 +108,9 @@ fn returnsFive() i32 {
|
||||
}
|
||||
|
||||
test "switch on type" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try expect(trueIfBoolFalseOtherwise(bool));
|
||||
try expect(!trueIfBoolFalseOtherwise(i32));
|
||||
}
|
||||
@ -103,6 +123,10 @@ fn trueIfBoolFalseOtherwise(comptime T: type) bool {
|
||||
}
|
||||
|
||||
test "switching on booleans" {
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testSwitchOnBools();
|
||||
comptime try testSwitchOnBools();
|
||||
}
|
||||
@ -154,6 +178,9 @@ test "undefined.u0" {
|
||||
}
|
||||
|
||||
test "switch with disjoint range" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
var q: u8 = 0;
|
||||
switch (q) {
|
||||
0...125 => {},
|
||||
@ -163,6 +190,9 @@ test "switch with disjoint range" {
|
||||
}
|
||||
|
||||
test "switch variable for range and multiple prongs" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
var u: u8 = 16;
|
||||
@ -196,6 +226,9 @@ fn poll() void {
|
||||
}
|
||||
|
||||
test "switch on global mutable var isn't constant-folded" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
while (state < 2) {
|
||||
poll();
|
||||
}
|
||||
@ -208,6 +241,10 @@ const SwitchProngWithVarEnum = union(enum) {
|
||||
};
|
||||
|
||||
test "switch prong with variable" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try switchProngWithVarFn(SwitchProngWithVarEnum{ .One = 13 });
|
||||
try switchProngWithVarFn(SwitchProngWithVarEnum{ .Two = 13.0 });
|
||||
try switchProngWithVarFn(SwitchProngWithVarEnum{ .Meh = {} });
|
||||
@ -228,6 +265,9 @@ fn switchProngWithVarFn(a: SwitchProngWithVarEnum) !void {
|
||||
}
|
||||
|
||||
test "switch on enum using pointer capture" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testSwitchEnumPtrCapture();
|
||||
comptime try testSwitchEnumPtrCapture();
|
||||
}
|
||||
@ -245,6 +285,10 @@ fn testSwitchEnumPtrCapture() !void {
|
||||
}
|
||||
|
||||
test "switch handles all cases of number" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testSwitchHandleAllCases();
|
||||
comptime try testSwitchHandleAllCases();
|
||||
}
|
||||
@ -282,6 +326,9 @@ fn testSwitchHandleAllCasesRange(x: u8) u8 {
|
||||
}
|
||||
|
||||
test "switch on union with some prongs capturing" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const X = union(enum) {
|
||||
a,
|
||||
b: i32,
|
||||
@ -311,10 +358,16 @@ fn returnsFalse() bool {
|
||||
}
|
||||
}
|
||||
test "switch on const enum with var" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try expect(!returnsFalse());
|
||||
}
|
||||
|
||||
test "anon enum literal used in switch on union enum" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const Foo = union(enum) {
|
||||
a: i32,
|
||||
};
|
||||
@ -328,6 +381,9 @@ test "anon enum literal used in switch on union enum" {
|
||||
}
|
||||
|
||||
test "switch all prongs unreachable" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
try testAllProngsUnreachable();
|
||||
comptime try testAllProngsUnreachable();
|
||||
}
|
||||
@ -349,6 +405,9 @@ fn switchWithUnreachable(x: i32) i32 {
|
||||
}
|
||||
|
||||
test "capture value of switch with all unreachable prongs" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const x = return_a_number() catch |err| switch (err) {
|
||||
else => unreachable,
|
||||
};
|
||||
@ -360,6 +419,10 @@ fn return_a_number() anyerror!i32 {
|
||||
}
|
||||
|
||||
test "switch on integer with else capturing expr" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
var x: i32 = 5;
|
||||
@ -375,7 +438,7 @@ test "switch on integer with else capturing expr" {
|
||||
}
|
||||
|
||||
test "else prong of switch on error set excludes other cases" {
|
||||
if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@ -407,7 +470,7 @@ test "else prong of switch on error set excludes other cases" {
|
||||
}
|
||||
|
||||
test "switch prongs with error set cases make a new error set type for capture value" {
|
||||
if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@ -441,6 +504,9 @@ test "switch prongs with error set cases make a new error set type for capture v
|
||||
}
|
||||
|
||||
test "return result loc and then switch with range implicit casted to error union" {
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
try expect((func(0xb) catch unreachable) == 0xb);
|
||||
@ -457,6 +523,10 @@ test "return result loc and then switch with range implicit casted to error unio
|
||||
}
|
||||
|
||||
test "switch with null and T peer types and inferred result location type" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest(c: u8) !void {
|
||||
if (switch (c) {
|
||||
@ -473,7 +543,7 @@ test "switch with null and T peer types and inferred result location type" {
|
||||
}
|
||||
|
||||
test "switch prongs with cases with identical payload types" {
|
||||
if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
const Union = union(enum) {
|
||||
A: usize,
|
||||
@ -515,7 +585,11 @@ test "switch prongs with cases with identical payload types" {
|
||||
}
|
||||
|
||||
test "switch on pointer type" {
|
||||
if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
const X = struct {
|
||||
@ -544,7 +618,7 @@ test "switch on pointer type" {
|
||||
}
|
||||
|
||||
test "switch on error set with single else" {
|
||||
if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
@ -563,7 +637,7 @@ test "switch on error set with single else" {
|
||||
}
|
||||
|
||||
test "switch capture copies its payload" {
|
||||
if (@import("builtin").zig_backend == .stage2_llvm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn doTheTest() !void {
|
||||
|
@ -878,8 +878,6 @@ test "union with comptime_int tag" {
|
||||
}
|
||||
|
||||
test "extern union doesn't trigger field check at comptime" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
|
||||
const U = extern union {
|
||||
x: u32,
|
||||
y: u8,
|
||||
@ -890,7 +888,8 @@ test "extern union doesn't trigger field check at comptime" {
|
||||
}
|
||||
|
||||
test "anonymous union literal syntax" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
const Number = union {
|
||||
@ -914,7 +913,8 @@ test "anonymous union literal syntax" {
|
||||
}
|
||||
|
||||
test "function call result coerces from tagged union to the tag" {
|
||||
if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
const Arch = union(enum) {
|
||||
@ -1104,9 +1104,9 @@ test "union enum type gets a separate scope" {
|
||||
test "global variable struct contains union initialized to non-most-aligned field" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
|
||||
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;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const T = struct {
|
||||
const U = union(enum) {
|
||||
|
Loading…
Reference in New Issue
Block a user