authorgravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-12-29 12:21:31+08:00
committergravatar for joachim.schmidt557@outlook.comJoachim Schmidt <joachim.schmidt557@outlook.com> 2022-12-29 11:12:08+01:00
log1caf56c5fbbb10fa28f8bf204d073983ce2a6dd5
tree024193b17c0c447172874a360d4fde8a4e10bf67
parent34887cf136878c87357fa0eec52a12db300d8f27

stage2 AArch64: implement errUnion{Err,Payload} for registers


6 files changed, 139 insertions(+), 41 deletions(-)

src/arch/aarch64/CodeGen.zig+139-31
...@@ -3050,19 +3050,60 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {...@@ -3050,19 +3050,60 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void {
3050}3050}
30513051
3052/// Given an error union, returns the error3052/// Given an error union, returns the error
3053fn errUnionErr(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {3053fn errUnionErr(
3054 self: *Self,
3055 error_union_bind: ReadArg.Bind,
3056 error_union_ty: Type,
3057 maybe_inst: ?Air.Inst.Index,
3058) !MCValue {
3054 const err_ty = error_union_ty.errorUnionSet();3059 const err_ty = error_union_ty.errorUnionSet();
3055 const payload_ty = error_union_ty.errorUnionPayload();3060 const payload_ty = error_union_ty.errorUnionPayload();
3056 if (err_ty.errorSetIsEmpty()) {3061 if (err_ty.errorSetIsEmpty()) {
3057 return MCValue{ .immediate = 0 };3062 return MCValue{ .immediate = 0 };
3058 }3063 }
3059 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3064 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3060 return error_union_mcv;3065 return try error_union_bind.resolveToMcv(self);
3061 }3066 }
30623067
3063 const err_offset = @intCast(u32, errUnionErrorOffset(payload_ty, self.target.*));3068 const err_offset = @intCast(u32, errUnionErrorOffset(payload_ty, self.target.*));
3064 switch (error_union_mcv) {3069 switch (try error_union_bind.resolveToMcv(self)) {
3065 .register => return self.fail("TODO errUnionErr for registers", .{}),3070 .register => {
3071 var operand_reg: Register = undefined;
3072 var dest_reg: Register = undefined;
3073
3074 const read_args = [_]ReadArg{
3075 .{ .ty = error_union_ty, .bind = error_union_bind, .class = gp, .reg = &operand_reg },
3076 };
3077 const write_args = [_]WriteArg{
3078 .{ .ty = err_ty, .bind = .none, .class = gp, .reg = &dest_reg },
3079 };
3080 try self.allocRegs(
3081 &read_args,
3082 &write_args,
3083 if (maybe_inst) |inst| .{
3084 .corresponding_inst = inst,
3085 .operand_mapping = &.{0},
3086 } else null,
3087 );
3088
3089 const err_bit_offset = err_offset * 8;
3090 const err_bit_size = @intCast(u32, err_ty.abiSize(self.target.*)) * 8;
3091
3092 _ = try self.addInst(.{
3093 .tag = .ubfx, // errors are unsigned integers
3094 .data = .{
3095 .rr_lsb_width = .{
3096 // Set both registers to the X variant to get the full width
3097 .rd = dest_reg.toX(),
3098 .rn = operand_reg.toX(),
3099 .lsb = @intCast(u6, err_bit_offset),
3100 .width = @intCast(u7, err_bit_size),
3101 },
3102 },
3103 });
3104
3105 return MCValue{ .register = dest_reg };
3106 },
3066 .stack_argument_offset => |off| {3107 .stack_argument_offset => |off| {
3067 return MCValue{ .stack_argument_offset = off + err_offset };3108 return MCValue{ .stack_argument_offset = off + err_offset };
3068 },3109 },
...@@ -3079,27 +3120,69 @@ fn errUnionErr(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCV...@@ -3079,27 +3120,69 @@ fn errUnionErr(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCV
3079fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {3120fn airUnwrapErrErr(self: *Self, inst: Air.Inst.Index) !void {
3080 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3121 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3081 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3122 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3123 const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
3082 const error_union_ty = self.air.typeOf(ty_op.operand);3124 const error_union_ty = self.air.typeOf(ty_op.operand);
3083 const mcv = try self.resolveInst(ty_op.operand);3125
3084 break :result try self.errUnionErr(mcv, error_union_ty);3126 break :result try self.errUnionErr(error_union_bind, error_union_ty, inst);
3085 };3127 };
3086 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });3128 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
3087}3129}
30883130
3089/// Given an error union, returns the payload3131/// Given an error union, returns the payload
3090fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type) !MCValue {3132fn errUnionPayload(
3133 self: *Self,
3134 error_union_bind: ReadArg.Bind,
3135 error_union_ty: Type,
3136 maybe_inst: ?Air.Inst.Index,
3137) !MCValue {
3091 const err_ty = error_union_ty.errorUnionSet();3138 const err_ty = error_union_ty.errorUnionSet();
3092 const payload_ty = error_union_ty.errorUnionPayload();3139 const payload_ty = error_union_ty.errorUnionPayload();
3093 if (err_ty.errorSetIsEmpty()) {3140 if (err_ty.errorSetIsEmpty()) {
3094 return error_union_mcv;3141 return try error_union_bind.resolveToMcv(self);
3095 }3142 }
3096 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {3143 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
3097 return MCValue.none;3144 return MCValue.none;
3098 }3145 }
30993146
3100 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, self.target.*));3147 const payload_offset = @intCast(u32, errUnionPayloadOffset(payload_ty, self.target.*));
3101 switch (error_union_mcv) {3148 switch (try error_union_bind.resolveToMcv(self)) {
3102 .register => return self.fail("TODO errUnionPayload for registers", .{}),3149 .register => {
3150 var operand_reg: Register = undefined;
3151 var dest_reg: Register = undefined;
3152
3153 const read_args = [_]ReadArg{
3154 .{ .ty = error_union_ty, .bind = error_union_bind, .class = gp, .reg = &operand_reg },
3155 };
3156 const write_args = [_]WriteArg{
3157 .{ .ty = err_ty, .bind = .none, .class = gp, .reg = &dest_reg },
3158 };
3159 try self.allocRegs(
3160 &read_args,
3161 &write_args,
3162 if (maybe_inst) |inst| .{
3163 .corresponding_inst = inst,
3164 .operand_mapping = &.{0},
3165 } else null,
3166 );
3167
3168 const payload_bit_offset = payload_offset * 8;
3169 const payload_bit_size = @intCast(u32, payload_ty.abiSize(self.target.*)) * 8;
3170
3171 _ = try self.addInst(.{
3172 .tag = if (payload_ty.isSignedInt()) Mir.Inst.Tag.sbfx else .ubfx,
3173 .data = .{
3174 .rr_lsb_width = .{
3175 // Set both registers to the X variant to get the full width
3176 .rd = dest_reg.toX(),
3177 .rn = operand_reg.toX(),
3178 .lsb = @intCast(u5, payload_bit_offset),
3179 .width = @intCast(u6, payload_bit_size),
3180 },
3181 },
3182 });
3183
3184 return MCValue{ .register = dest_reg };
3185 },
3103 .stack_argument_offset => |off| {3186 .stack_argument_offset => |off| {
3104 return MCValue{ .stack_argument_offset = off + payload_offset };3187 return MCValue{ .stack_argument_offset = off + payload_offset };
3105 },3188 },
...@@ -3116,9 +3199,10 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)...@@ -3116,9 +3199,10 @@ fn errUnionPayload(self: *Self, error_union_mcv: MCValue, error_union_ty: Type)
3116fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {3199fn airUnwrapErrPayload(self: *Self, inst: Air.Inst.Index) !void {
3117 const ty_op = self.air.instructions.items(.data)[inst].ty_op;3200 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
3118 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {3201 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
3202 const error_union_bind: ReadArg.Bind = .{ .inst = ty_op.operand };
3119 const error_union_ty = self.air.typeOf(ty_op.operand);3203 const error_union_ty = self.air.typeOf(ty_op.operand);
3120 const error_union = try self.resolveInst(ty_op.operand);3204
3121 break :result try self.errUnionPayload(error_union, error_union_ty);3205 break :result try self.errUnionPayload(error_union_bind, error_union_ty, inst);
3122 };3206 };
3123 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });3207 return self.finishAir(inst, result, .{ ty_op.operand, .none, .none });
3124}3208}
...@@ -3399,9 +3483,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {...@@ -3399,9 +3483,14 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void {
3399}3483}
34003484
3401fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {3485fn airPtrElemVal(self: *Self, inst: Air.Inst.Index) !void {
3402 const is_volatile = false; // TODO
3403 const bin_op = self.air.instructions.items(.data)[inst].bin_op;3486 const bin_op = self.air.instructions.items(.data)[inst].bin_op;
3404 const result: MCValue = if (!is_volatile and self.liveness.isUnused(inst)) .dead else return self.fail("TODO implement ptr_elem_val for {}", .{self.target.cpu.arch});3487 const ptr_ty = self.air.typeOf(bin_op.lhs);
3488 const result: MCValue = if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) .dead else result: {
3489 const base_bind: ReadArg.Bind = .{ .inst = bin_op.lhs };
3490 const index_bind: ReadArg.Bind = .{ .inst = bin_op.rhs };
3491
3492 break :result try self.ptrElemVal(base_bind, index_bind, ptr_ty, inst);
3493 };
3405 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });3494 return self.finishAir(inst, result, .{ bin_op.lhs, bin_op.rhs, .none });
3406}3495}
34073496
...@@ -4792,19 +4881,27 @@ fn isNonNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue...@@ -4792,19 +4881,27 @@ fn isNonNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue
4792 return MCValue{ .compare_flags = is_null_res.compare_flags.negate() };4881 return MCValue{ .compare_flags = is_null_res.compare_flags.negate() };
4793}4882}
47944883
4795fn isErr(self: *Self, ty: Type, operand: MCValue) !MCValue {4884fn isErr(
4796 const error_type = ty.errorUnionSet();4885 self: *Self,
4886 error_union_bind: ReadArg.Bind,
4887 error_union_ty: Type,
4888) !MCValue {
4889 const error_type = error_union_ty.errorUnionSet();
47974890
4798 if (error_type.errorSetIsEmpty()) {4891 if (error_type.errorSetIsEmpty()) {
4799 return MCValue{ .immediate = 0 }; // always false4892 return MCValue{ .immediate = 0 }; // always false
4800 }4893 }
48014894
4802 const error_mcv = try self.errUnionErr(operand, ty);4895 const error_mcv = try self.errUnionErr(error_union_bind, error_union_ty, null);
4803 return try self.cmp(.{ .mcv = error_mcv }, .{ .mcv = .{ .immediate = 0 } }, error_type, .gt);4896 return try self.cmp(.{ .mcv = error_mcv }, .{ .mcv = .{ .immediate = 0 } }, error_type, .gt);
4804}4897}
48054898
4806fn isNonErr(self: *Self, ty: Type, operand: MCValue) !MCValue {4899fn isNonErr(
4807 const is_err_result = try self.isErr(ty, operand);4900 self: *Self,
4901 error_union_bind: ReadArg.Bind,
4902 error_union_ty: Type,
4903) !MCValue {
4904 const is_err_result = try self.isErr(error_union_bind, error_union_ty);
4808 switch (is_err_result) {4905 switch (is_err_result) {
4809 .compare_flags => |cond| {4906 .compare_flags => |cond| {
4810 assert(cond == .hi);4907 assert(cond == .hi);
...@@ -4873,9 +4970,10 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4873,9 +4970,10 @@ fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void {
4873fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {4970fn airIsErr(self: *Self, inst: Air.Inst.Index) !void {
4874 const un_op = self.air.instructions.items(.data)[inst].un_op;4971 const un_op = self.air.instructions.items(.data)[inst].un_op;
4875 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4972 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4876 const operand = try self.resolveInst(un_op);4973 const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
4877 const ty = self.air.typeOf(un_op);4974 const error_union_ty = self.air.typeOf(un_op);
4878 break :result try self.isErr(ty, operand);4975
4976 break :result try self.isErr(error_union_bind, error_union_ty);
4879 };4977 };
4880 return self.finishAir(inst, result, .{ un_op, .none, .none });4978 return self.finishAir(inst, result, .{ un_op, .none, .none });
4881}4979}
...@@ -4890,7 +4988,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4890,7 +4988,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4890 const operand = try self.allocRegOrMem(elem_ty, true, null);4988 const operand = try self.allocRegOrMem(elem_ty, true, null);
4891 try self.load(operand, operand_ptr, ptr_ty);4989 try self.load(operand, operand_ptr, ptr_ty);
48924990
4893 break :result try self.isErr(elem_ty, operand);4991 break :result try self.isErr(.{ .mcv = operand }, elem_ty);
4894 };4992 };
4895 return self.finishAir(inst, result, .{ un_op, .none, .none });4993 return self.finishAir(inst, result, .{ un_op, .none, .none });
4896}4994}
...@@ -4898,9 +4996,10 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4898,9 +4996,10 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4898fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {4996fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void {
4899 const un_op = self.air.instructions.items(.data)[inst].un_op;4997 const un_op = self.air.instructions.items(.data)[inst].un_op;
4900 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {4998 const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: {
4901 const operand = try self.resolveInst(un_op);4999 const error_union_bind: ReadArg.Bind = .{ .inst = un_op };
4902 const ty = self.air.typeOf(un_op);5000 const error_union_ty = self.air.typeOf(un_op);
4903 break :result try self.isNonErr(ty, operand);5001
5002 break :result try self.isNonErr(error_union_bind, error_union_ty);
4904 };5003 };
4905 return self.finishAir(inst, result, .{ un_op, .none, .none });5004 return self.finishAir(inst, result, .{ un_op, .none, .none });
4906}5005}
...@@ -4915,7 +5014,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {...@@ -4915,7 +5014,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void {
4915 const operand = try self.allocRegOrMem(elem_ty, true, null);5014 const operand = try self.allocRegOrMem(elem_ty, true, null);
4916 try self.load(operand, operand_ptr, ptr_ty);5015 try self.load(operand, operand_ptr, ptr_ty);
49175016
4918 break :result try self.isNonErr(elem_ty, operand);5017 break :result try self.isNonErr(.{ .mcv = operand }, elem_ty);
4919 };5018 };
4920 return self.finishAir(inst, result, .{ un_op, .none, .none });5019 return self.finishAir(inst, result, .{ un_op, .none, .none });
4921}5020}
...@@ -5960,15 +6059,24 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {...@@ -5960,15 +6059,24 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void {
5960 const extra = self.air.extraData(Air.Try, pl_op.payload);6059 const extra = self.air.extraData(Air.Try, pl_op.payload);
5961 const body = self.air.extra[extra.end..][0..extra.data.body_len];6060 const body = self.air.extra[extra.end..][0..extra.data.body_len];
5962 const result: MCValue = result: {6061 const result: MCValue = result: {
6062 const error_union_bind: ReadArg.Bind = .{ .inst = pl_op.operand };
5963 const error_union_ty = self.air.typeOf(pl_op.operand);6063 const error_union_ty = self.air.typeOf(pl_op.operand);
5964 const error_union = try self.resolveInst(pl_op.operand);6064 const error_union_size = @intCast(u32, error_union_ty.abiSize(self.target.*));
5965 const is_err_result = try self.isErr(error_union_ty, error_union);6065 const error_union_align = error_union_ty.abiAlignment(self.target.*);
6066
6067 // The error union will die in the body. However, we need the
6068 // error union after the body in order to extract the payload
6069 // of the error union, so we create a copy of it
6070 const error_union_copy = try self.allocMem(error_union_size, error_union_align, null);
6071 try self.genSetStack(error_union_ty, error_union_copy, try error_union_bind.resolveToMcv(self));
6072
6073 const is_err_result = try self.isErr(error_union_bind, error_union_ty);
5966 const reloc = try self.condBr(is_err_result);6074 const reloc = try self.condBr(is_err_result);
59676075
5968 try self.genBody(body);6076 try self.genBody(body);
5969
5970 try self.performReloc(reloc);6077 try self.performReloc(reloc);
5971 break :result try self.errUnionPayload(error_union, error_union_ty);6078
6079 break :result try self.errUnionPayload(.{ .mcv = .{ .stack_offset = error_union_copy } }, error_union_ty, null);
5972 };6080 };
5973 return self.finishAir(inst, result, .{ pl_op.operand, .none, .none });6081 return self.finishAir(inst, result, .{ pl_op.operand, .none, .none });
5974}6082}
test/behavior/error.zig-3
...@@ -60,7 +60,6 @@ pub fn baz() anyerror!i32 {...@@ -60,7 +60,6 @@ pub fn baz() anyerror!i32 {
60}60}
6161
62test "error wrapping" {62test "error wrapping" {
63 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
64 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO63 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
6564
66 try expect((baz() catch unreachable) == 15);65 try expect((baz() catch unreachable) == 15);
...@@ -100,7 +99,6 @@ test "syntax: optional operator in front of error union operator" {...@@ -100,7 +99,6 @@ test "syntax: optional operator in front of error union operator" {
10099
101test "widen cast integer payload of error union function call" {100test "widen cast integer payload of error union function call" {
102 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;101 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
103 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
104 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO102 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
105103
106 const S = struct {104 const S = struct {
...@@ -715,7 +713,6 @@ test "ret_ptr doesn't cause own inferred error set to be resolved" {...@@ -715,7 +713,6 @@ test "ret_ptr doesn't cause own inferred error set to be resolved" {
715}713}
716714
717test "simple else prong allowed even when all errors handled" {715test "simple else prong allowed even when all errors handled" {
718 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
719 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO716 if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest; // TODO
720 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO717 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
721718
test/behavior/if.zig-1
...@@ -44,7 +44,6 @@ var global_with_val: anyerror!u32 = 0;...@@ -44,7 +44,6 @@ var global_with_val: anyerror!u32 = 0;
44var global_with_err: anyerror!u32 = error.SomeError;44var global_with_err: anyerror!u32 = error.SomeError;
4545
46test "unwrap mutable global var" {46test "unwrap mutable global var" {
47 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
48 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO47 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
4948
50 if (global_with_val) |v| {49 if (global_with_val) |v| {
test/behavior/switch.zig-2
...@@ -390,7 +390,6 @@ fn switchWithUnreachable(x: i32) i32 {...@@ -390,7 +390,6 @@ fn switchWithUnreachable(x: i32) i32 {
390}390}
391391
392test "capture value of switch with all unreachable prongs" {392test "capture value of switch with all unreachable prongs" {
393 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
394 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO393 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
395394
396 const x = return_a_number() catch |err| switch (err) {395 const x = return_a_number() catch |err| switch (err) {
...@@ -494,7 +493,6 @@ test "switch prongs with error set cases make a new error set type for capture v...@@ -494,7 +493,6 @@ test "switch prongs with error set cases make a new error set type for capture v
494}493}
495494
496test "return result loc and then switch with range implicit casted to error union" {495test "return result loc and then switch with range implicit casted to error union" {
497 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
498 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO496 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
499497
500 const S = struct {498 const S = struct {
test/behavior/try.zig-1
...@@ -3,7 +3,6 @@ const builtin = @import("builtin");...@@ -3,7 +3,6 @@ const builtin = @import("builtin");
3const expect = std.testing.expect;3const expect = std.testing.expect;
44
5test "try on error union" {5test "try on error union" {
6 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
7 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO6 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
87
9 try tryOnErrorUnionImpl();8 try tryOnErrorUnionImpl();
test/behavior/while.zig-3
...@@ -175,7 +175,6 @@ test "while with optional as condition with else" {...@@ -175,7 +175,6 @@ test "while with optional as condition with else" {
175175
176test "while with error union condition" {176test "while with error union condition" {
177 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;177 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
178 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
179 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO178 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
180179
181 numbers_left = 10;180 numbers_left = 10;
...@@ -258,7 +257,6 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void {...@@ -258,7 +257,6 @@ fn returnWithImplicitCastFromWhileLoopTest() anyerror!void {
258}257}
259258
260test "while on error union with else result follow else prong" {259test "while on error union with else result follow else prong" {
261 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
262 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO260 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
263261
264 const result = while (returnError()) |value| {262 const result = while (returnError()) |value| {
...@@ -268,7 +266,6 @@ test "while on error union with else result follow else prong" {...@@ -268,7 +266,6 @@ test "while on error union with else result follow else prong" {
268}266}
269267
270test "while on error union with else result follow break prong" {268test "while on error union with else result follow break prong" {
271 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
272 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO269 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
273270
274 const result = while (returnSuccess(10)) |value| {271 const result = while (returnSuccess(10)) |value| {