| author | |
| committer | |
| log | 9be8a9000faead40b1aec4877506ff10b066659c |
| tree | 6dd2ebc0520ed61c8221e04a01b4b2f715f5520c |
| parent | a7de02e05216db9a04e438703ddf1b6b12f3fbef |
This reverts commit a7de02e05216db9a04e438703ddf1b6b12f3fbef.
This did not implement the accepted proposal, and I did not sign off
on the changes. I would like a chance to review this, please.25 files changed, 1 insertions(+), 202 deletions(-)
doc/langref.html.in-8| ... | @@ -4799,14 +4799,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val | ... | @@ -4799,14 +4799,6 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val |
| 4799 | {#see_also|@export#} | 4799 | {#see_also|@export#} |
| 4800 | {#header_close#} | 4800 | {#header_close#} |
| 4801 | 4801 | ||
| 4802 | {#header_open|@expect#} | ||
| 4803 | <pre>{#syntax#}@expect(operand: bool, expected: bool) bool{#endsyntax#}</pre> | ||
| 4804 | <p> | ||
| 4805 | Informs the optimizer that {#syntax#}operand{#endsyntax#} will likely be {#syntax#}expected{#endsyntax#}, which influences branch compilation to prefer generating the true branch first. | ||
| 4806 | </p> | ||
| 4807 | {#code|expect_if.zig#} | ||
| 4808 | {#header_close#} | ||
| 4809 | |||
| 4810 | {#header_open|@fence#} | 4802 | {#header_open|@fence#} |
| 4811 | <pre>{#syntax#}@fence(order: AtomicOrder) void{#endsyntax#}</pre> | 4803 | <pre>{#syntax#}@fence(order: AtomicOrder) void{#endsyntax#}</pre> |
| 4812 | <p> | 4804 | <p> |
doc/langref/expect_if.zig deleted-15| ... | @@ -1,15 +0,0 @@ | ||
| 1 | pub fn a(x: u32) void { | ||
| 2 | if (@expect(x == 0, false)) { | ||
| 3 | // condition check falls through at code generation | ||
| 4 | return; | ||
| 5 | } else { | ||
| 6 | // condition is branched to at code generation | ||
| 7 | return; | ||
| 8 | } | ||
| 9 | } | ||
| 10 | |||
| 11 | test "expect" { | ||
| 12 | a(10); | ||
| 13 | } | ||
| 14 | |||
| 15 | // test | ||
lib/std/zig/AstGen.zig+1-9| ... | @@ -2823,7 +2823,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As | ... | @@ -2823,7 +2823,6 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As |
| 2823 | .set_float_mode, | 2823 | .set_float_mode, |
| 2824 | .set_align_stack, | 2824 | .set_align_stack, |
| 2825 | .set_cold, | 2825 | .set_cold, |
| 2826 | .expect, | ||
| 2827 | => break :b true, | 2826 | => break :b true, |
| 2828 | else => break :b false, | 2827 | else => break :b false, |
| 2829 | }, | 2828 | }, |
| ... | @@ -9293,14 +9292,7 @@ fn builtinCall( | ... | @@ -9293,14 +9292,7 @@ fn builtinCall( |
| 9293 | }); | 9292 | }); |
| 9294 | return rvalue(gz, ri, .void_value, node); | 9293 | return rvalue(gz, ri, .void_value, node); |
| 9295 | }, | 9294 | }, |
| 9296 | .expect => { | 9295 | |
| 9297 | const val = try gz.addExtendedPayload(.expect, Zir.Inst.BinNode{ | ||
| 9298 | .node = gz.nodeIndexToRelative(node), | ||
| 9299 | .lhs = try expr(gz, scope, .{ .rl = .{ .ty = .bool_type } }, params[0]), | ||
| 9300 | .rhs = try expr(gz, scope, .{ .rl = .{ .ty = .bool_type } }, params[1]), | ||
| 9301 | }); | ||
| 9302 | return rvalue(gz, ri, val, node); | ||
| 9303 | }, | ||
| 9304 | .src => { | 9296 | .src => { |
| 9305 | const token_starts = tree.tokens.items(.start); | 9297 | const token_starts = tree.tokens.items(.start); |
| 9306 | const node_start = token_starts[tree.firstToken(node)]; | 9298 | const node_start = token_starts[tree.firstToken(node)]; |
lib/std/zig/AstRlAnnotate.zig-5| ... | @@ -1100,10 +1100,5 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. | ... | @@ -1100,10 +1100,5 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast. |
| 1100 | _ = try astrl.expr(args[4], block, ResultInfo.type_only); | 1100 | _ = try astrl.expr(args[4], block, ResultInfo.type_only); |
| 1101 | return false; | 1101 | return false; |
| 1102 | }, | 1102 | }, |
| 1103 | .expect => { | ||
| 1104 | _ = try astrl.expr(args[0], block, ResultInfo.none); | ||
| 1105 | _ = try astrl.expr(args[1], block, ResultInfo.none); | ||
| 1106 | return false; | ||
| 1107 | }, | ||
| 1108 | } | 1103 | } |
| 1109 | } | 1104 | } |
lib/std/zig/BuiltinFn.zig-8| ... | @@ -82,7 +82,6 @@ pub const Tag = enum { | ... | @@ -82,7 +82,6 @@ pub const Tag = enum { |
| 82 | select, | 82 | select, |
| 83 | set_align_stack, | 83 | set_align_stack, |
| 84 | set_cold, | 84 | set_cold, |
| 85 | expect, | ||
| 86 | set_eval_branch_quota, | 85 | set_eval_branch_quota, |
| 87 | set_float_mode, | 86 | set_float_mode, |
| 88 | set_runtime_safety, | 87 | set_runtime_safety, |
| ... | @@ -744,13 +743,6 @@ pub const list = list: { | ... | @@ -744,13 +743,6 @@ pub const list = list: { |
| 744 | .illegal_outside_function = true, | 743 | .illegal_outside_function = true, |
| 745 | }, | 744 | }, |
| 746 | }, | 745 | }, |
| 747 | .{ | ||
| 748 | "@expect", | ||
| 749 | .{ | ||
| 750 | .tag = .expect, | ||
| 751 | .param_count = 2, | ||
| 752 | }, | ||
| 753 | }, | ||
| 754 | .{ | 746 | .{ |
| 755 | "@setEvalBranchQuota", | 747 | "@setEvalBranchQuota", |
| 756 | .{ | 748 | .{ |
lib/std/zig/Zir.zig-3| ... | @@ -2060,9 +2060,6 @@ pub const Inst = struct { | ... | @@ -2060,9 +2060,6 @@ pub const Inst = struct { |
| 2060 | /// Guaranteed to not have the `ptr_cast` flag. | 2060 | /// Guaranteed to not have the `ptr_cast` flag. |
| 2061 | /// Uses the `pl_node` union field with payload `FieldParentPtr`. | 2061 | /// Uses the `pl_node` union field with payload `FieldParentPtr`. |
| 2062 | field_parent_ptr, | 2062 | field_parent_ptr, |
| 2063 | /// Implements the `@expect` builtin. | ||
| 2064 | /// `operand` is BinOp | ||
| 2065 | expect, | ||
| 2066 | 2063 | ||
| 2067 | pub const InstData = struct { | 2064 | pub const InstData = struct { |
| 2068 | opcode: Extended, | 2065 | opcode: Extended, |
lib/zig.h-6| ... | @@ -318,12 +318,6 @@ typedef char bool; | ... | @@ -318,12 +318,6 @@ typedef char bool; |
| 318 | #define zig_noreturn | 318 | #define zig_noreturn |
| 319 | #endif | 319 | #endif |
| 320 | 320 | ||
| 321 | #if defined(__GNUC__) || defined(__clang__) | ||
| 322 | #define zig_expect(op, exp) __builtin_expect(op, exp) | ||
| 323 | #else | ||
| 324 | #define zig_expect(op, exp) (op) | ||
| 325 | #endif | ||
| 326 | |||
| 327 | #define zig_bitSizeOf(T) (CHAR_BIT * sizeof(T)) | 321 | #define zig_bitSizeOf(T) (CHAR_BIT * sizeof(T)) |
| 328 | 322 | ||
| 329 | #define zig_compiler_rt_abbrev_uint32_t si | 323 | #define zig_compiler_rt_abbrev_uint32_t si |
src/Air.zig-7| ... | @@ -848,10 +848,6 @@ pub const Inst = struct { | ... | @@ -848,10 +848,6 @@ pub const Inst = struct { |
| 848 | /// Operand is unused and set to Ref.none | 848 | /// Operand is unused and set to Ref.none |
| 849 | work_group_id, | 849 | work_group_id, |
| 850 | 850 | ||
| 851 | /// Implements @expect builtin. | ||
| 852 | /// Uses the `bin_op` field. | ||
| 853 | expect, | ||
| 854 | |||
| 855 | pub fn fromCmpOp(op: std.math.CompareOperator, optimized: bool) Tag { | 851 | pub fn fromCmpOp(op: std.math.CompareOperator, optimized: bool) Tag { |
| 856 | switch (op) { | 852 | switch (op) { |
| 857 | .lt => return if (optimized) .cmp_lt_optimized else .cmp_lt, | 853 | .lt => return if (optimized) .cmp_lt_optimized else .cmp_lt, |
| ... | @@ -1521,8 +1517,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) | ... | @@ -1521,8 +1517,6 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) |
| 1521 | .work_group_id, | 1517 | .work_group_id, |
| 1522 | => return Type.u32, | 1518 | => return Type.u32, |
| 1523 | 1519 | ||
| 1524 | .expect => return Type.bool, | ||
| 1525 | |||
| 1526 | .inferred_alloc => unreachable, | 1520 | .inferred_alloc => unreachable, |
| 1527 | .inferred_alloc_comptime => unreachable, | 1521 | .inferred_alloc_comptime => unreachable, |
| 1528 | } | 1522 | } |
| ... | @@ -1640,7 +1634,6 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { | ... | @@ -1640,7 +1634,6 @@ pub fn mustLower(air: Air, inst: Air.Inst.Index, ip: *const InternPool) bool { |
| 1640 | .add_safe, | 1634 | .add_safe, |
| 1641 | .sub_safe, | 1635 | .sub_safe, |
| 1642 | .mul_safe, | 1636 | .mul_safe, |
| 1643 | .expect, | ||
| 1644 | => true, | 1637 | => true, |
| 1645 | 1638 | ||
| 1646 | .add, | 1639 | .add, |
src/Liveness.zig-2| ... | @@ -286,7 +286,6 @@ pub fn categorizeOperand( | ... | @@ -286,7 +286,6 @@ pub fn categorizeOperand( |
| 286 | .cmp_gte_optimized, | 286 | .cmp_gte_optimized, |
| 287 | .cmp_gt_optimized, | 287 | .cmp_gt_optimized, |
| 288 | .cmp_neq_optimized, | 288 | .cmp_neq_optimized, |
| 289 | .expect, | ||
| 290 | => { | 289 | => { |
| 291 | const o = air_datas[@intFromEnum(inst)].bin_op; | 290 | const o = air_datas[@intFromEnum(inst)].bin_op; |
| 292 | if (o.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none); | 291 | if (o.lhs == operand_ref) return matchOperandSmallIndex(l, inst, 0, .none); |
| ... | @@ -956,7 +955,6 @@ fn analyzeInst( | ... | @@ -956,7 +955,6 @@ fn analyzeInst( |
| 956 | .memset, | 955 | .memset, |
| 957 | .memset_safe, | 956 | .memset_safe, |
| 958 | .memcpy, | 957 | .memcpy, |
| 959 | .expect, | ||
| 960 | => { | 958 | => { |
| 961 | const o = inst_datas[@intFromEnum(inst)].bin_op; | 959 | const o = inst_datas[@intFromEnum(inst)].bin_op; |
| 962 | return analyzeOperands(a, pass, data, inst, .{ o.lhs, o.rhs, .none }); | 960 | return analyzeOperands(a, pass, data, inst, .{ o.lhs, o.rhs, .none }); |
src/Liveness/Verify.zig-1| ... | @@ -257,7 +257,6 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { | ... | @@ -257,7 +257,6 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { |
| 257 | .memset, | 257 | .memset, |
| 258 | .memset_safe, | 258 | .memset_safe, |
| 259 | .memcpy, | 259 | .memcpy, |
| 260 | .expect, | ||
| 261 | => { | 260 | => { |
| 262 | const bin_op = data[@intFromEnum(inst)].bin_op; | 261 | const bin_op = data[@intFromEnum(inst)].bin_op; |
| 263 | try self.verifyInstOperands(inst, .{ bin_op.lhs, bin_op.rhs, .none }); | 262 | try self.verifyInstOperands(inst, .{ bin_op.lhs, bin_op.rhs, .none }); |
src/Module.zig-1| ... | @@ -5546,7 +5546,6 @@ pub const Feature = enum { | ... | @@ -5546,7 +5546,6 @@ pub const Feature = enum { |
| 5546 | /// to generate better machine code in the backends. All backends should migrate to | 5546 | /// to generate better machine code in the backends. All backends should migrate to |
| 5547 | /// enabling this feature. | 5547 | /// enabling this feature. |
| 5548 | safety_checked_instructions, | 5548 | safety_checked_instructions, |
| 5549 | can_expect, | ||
| 5550 | }; | 5549 | }; |
| 5551 | 5550 | ||
| 5552 | pub fn backendSupportsFeature(zcu: Module, feature: Feature) bool { | 5551 | pub fn backendSupportsFeature(zcu: Module, feature: Feature) bool { |
src/Sema.zig-29| ... | @@ -1258,7 +1258,6 @@ fn analyzeBodyInner( | ... | @@ -1258,7 +1258,6 @@ fn analyzeBodyInner( |
| 1258 | .work_group_size => try sema.zirWorkItem( block, extended, extended.opcode), | 1258 | .work_group_size => try sema.zirWorkItem( block, extended, extended.opcode), |
| 1259 | .work_group_id => try sema.zirWorkItem( block, extended, extended.opcode), | 1259 | .work_group_id => try sema.zirWorkItem( block, extended, extended.opcode), |
| 1260 | .in_comptime => try sema.zirInComptime( block), | 1260 | .in_comptime => try sema.zirInComptime( block), |
| 1261 | .expect => try sema.zirExpect( block, extended), | ||
| 1262 | .closure_get => try sema.zirClosureGet( block, extended), | 1261 | .closure_get => try sema.zirClosureGet( block, extended), |
| 1263 | // zig fmt: on | 1262 | // zig fmt: on |
| 1264 | 1263 | ||
| ... | @@ -17554,34 +17553,6 @@ fn zirThis( | ... | @@ -17554,34 +17553,6 @@ fn zirThis( |
| 17554 | return sema.analyzeDeclVal(block, src, this_decl_index); | 17553 | return sema.analyzeDeclVal(block, src, this_decl_index); |
| 17555 | } | 17554 | } |
| 17556 | 17555 | ||
| 17557 | fn zirExpect(sema: *Sema, block: *Block, inst: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | ||
| 17558 | const bin_op = sema.code.extraData(Zir.Inst.BinNode, inst.operand).data; | ||
| 17559 | const operand = try sema.resolveInst(bin_op.lhs); | ||
| 17560 | const expected = try sema.resolveInst(bin_op.rhs); | ||
| 17561 | |||
| 17562 | const expected_src = LazySrcLoc{ .node_offset_builtin_call_arg1 = bin_op.node }; | ||
| 17563 | |||
| 17564 | if (!try sema.isComptimeKnown(expected)) { | ||
| 17565 | return sema.fail(block, expected_src, "@expect 'expected' must be comptime-known", .{}); | ||
| 17566 | } | ||
| 17567 | |||
| 17568 | if (try sema.resolveValue(operand)) |op| { | ||
| 17569 | return Air.internedToRef(op.toIntern()); | ||
| 17570 | } | ||
| 17571 | |||
| 17572 | if (sema.mod.backendSupportsFeature(.can_expect) and sema.mod.optimizeMode() != .Debug) { | ||
| 17573 | return try block.addInst(.{ | ||
| 17574 | .tag = .expect, | ||
| 17575 | .data = .{ .bin_op = .{ | ||
| 17576 | .lhs = operand, | ||
| 17577 | .rhs = expected, | ||
| 17578 | } }, | ||
| 17579 | }); | ||
| 17580 | } else { | ||
| 17581 | return operand; | ||
| 17582 | } | ||
| 17583 | } | ||
| 17584 | |||
| 17585 | fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { | 17556 | fn zirClosureGet(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { |
| 17586 | const mod = sema.mod; | 17557 | const mod = sema.mod; |
| 17587 | const ip = &mod.intern_pool; | 17558 | const ip = &mod.intern_pool; |
src/arch/aarch64/CodeGen.zig-2| ... | @@ -803,8 +803,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -803,8 +803,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 803 | .@"try" => try self.airTry(inst), | 803 | .@"try" => try self.airTry(inst), |
| 804 | .try_ptr => try self.airTryPtr(inst), | 804 | .try_ptr => try self.airTryPtr(inst), |
| 805 | 805 | ||
| 806 | .expect => unreachable, | ||
| 807 | |||
| 808 | .dbg_stmt => try self.airDbgStmt(inst), | 806 | .dbg_stmt => try self.airDbgStmt(inst), |
| 809 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | 807 | .dbg_inline_block => try self.airDbgInlineBlock(inst), |
| 810 | .dbg_var_ptr, | 808 | .dbg_var_ptr, |
src/arch/arm/CodeGen.zig-2| ... | @@ -844,8 +844,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -844,8 +844,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 844 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), | 844 | .wrap_errunion_payload => try self.airWrapErrUnionPayload(inst), |
| 845 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), | 845 | .wrap_errunion_err => try self.airWrapErrUnionErr(inst), |
| 846 | 846 | ||
| 847 | .expect => unreachable, | ||
| 848 | |||
| 849 | .add_optimized, | 847 | .add_optimized, |
| 850 | .sub_optimized, | 848 | .sub_optimized, |
| 851 | .mul_optimized, | 849 | .mul_optimized, |
src/arch/riscv64/CodeGen.zig-2| ... | @@ -1200,8 +1200,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -1200,8 +1200,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 1200 | .@"try" => try self.airTry(inst), | 1200 | .@"try" => try self.airTry(inst), |
| 1201 | .try_ptr => return self.fail("TODO: try_ptr", .{}), | 1201 | .try_ptr => return self.fail("TODO: try_ptr", .{}), |
| 1202 | 1202 | ||
| 1203 | .expect => unreachable, | ||
| 1204 | |||
| 1205 | .dbg_var_ptr, | 1203 | .dbg_var_ptr, |
| 1206 | .dbg_var_val, | 1204 | .dbg_var_val, |
| 1207 | => try self.airDbgVar(inst), | 1205 | => try self.airDbgVar(inst), |
src/arch/sparc64/CodeGen.zig-2| ... | @@ -636,8 +636,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -636,8 +636,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 636 | .@"try" => try self.airTry(inst), | 636 | .@"try" => try self.airTry(inst), |
| 637 | .try_ptr => @panic("TODO try self.airTryPtr(inst)"), | 637 | .try_ptr => @panic("TODO try self.airTryPtr(inst)"), |
| 638 | 638 | ||
| 639 | .expect => unreachable, | ||
| 640 | |||
| 641 | .dbg_stmt => try self.airDbgStmt(inst), | 639 | .dbg_stmt => try self.airDbgStmt(inst), |
| 642 | .dbg_inline_block => try self.airDbgInlineBlock(inst), | 640 | .dbg_inline_block => try self.airDbgInlineBlock(inst), |
| 643 | .dbg_var_ptr, | 641 | .dbg_var_ptr, |
src/arch/wasm/CodeGen.zig-2| ... | @@ -2016,8 +2016,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -2016,8 +2016,6 @@ fn genInst(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 2016 | .c_va_start, | 2016 | .c_va_start, |
| 2017 | => |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}), | 2017 | => |tag| return func.fail("TODO: Implement wasm inst: {s}", .{@tagName(tag)}), |
| 2018 | 2018 | ||
| 2019 | .expect => unreachable, | ||
| 2020 | |||
| 2021 | .atomic_load => func.airAtomicLoad(inst), | 2019 | .atomic_load => func.airAtomicLoad(inst), |
| 2022 | .atomic_store_unordered, | 2020 | .atomic_store_unordered, |
| 2023 | .atomic_store_monotonic, | 2021 | .atomic_store_monotonic, |
src/arch/x86_64/CodeGen.zig-2| ... | @@ -2014,8 +2014,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { | ... | @@ -2014,8 +2014,6 @@ fn genBody(self: *Self, body: []const Air.Inst.Index) InnerError!void { |
| 2014 | 2014 | ||
| 2015 | .abs => try self.airAbs(inst), | 2015 | .abs => try self.airAbs(inst), |
| 2016 | 2016 | ||
| 2017 | .expect => unreachable, | ||
| 2018 | |||
| 2019 | .add_with_overflow => try self.airAddSubWithOverflow(inst), | 2017 | .add_with_overflow => try self.airAddSubWithOverflow(inst), |
| 2020 | .sub_with_overflow => try self.airAddSubWithOverflow(inst), | 2018 | .sub_with_overflow => try self.airAddSubWithOverflow(inst), |
| 2021 | .mul_with_overflow => try self.airMulWithOverflow(inst), | 2019 | .mul_with_overflow => try self.airMulWithOverflow(inst), |
src/codegen/c.zig-23| ... | @@ -3343,8 +3343,6 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, | ... | @@ -3343,8 +3343,6 @@ fn genBodyInner(f: *Function, body: []const Air.Inst.Index) error{ AnalysisFail, |
| 3343 | 3343 | ||
| 3344 | .@"try" => try airTry(f, inst), | 3344 | .@"try" => try airTry(f, inst), |
| 3345 | .try_ptr => try airTryPtr(f, inst), | 3345 | .try_ptr => try airTryPtr(f, inst), |
| 3346 | |||
| 3347 | .expect => try airExpect(f, inst), | ||
| 3348 | 3346 | ||
| 3349 | .dbg_stmt => try airDbgStmt(f, inst), | 3347 | .dbg_stmt => try airDbgStmt(f, inst), |
| 3350 | .dbg_inline_block => try airDbgInlineBlock(f, inst), | 3348 | .dbg_inline_block => try airDbgInlineBlock(f, inst), |
| ... | @@ -4706,27 +4704,6 @@ fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4706,27 +4704,6 @@ fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4706 | return lowerTry(f, inst, extra.data.ptr, body, err_union_ty, true); | 4704 | return lowerTry(f, inst, extra.data.ptr, body, err_union_ty, true); |
| 4707 | } | 4705 | } |
| 4708 | 4706 | ||
| 4709 | fn airExpect(f: *Function, inst: Air.Inst.Index) !CValue { | ||
| 4710 | const bin_op = f.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | ||
| 4711 | const operand = try f.resolveInst(bin_op.lhs); | ||
| 4712 | const expected = try f.resolveInst(bin_op.rhs); | ||
| 4713 | |||
| 4714 | const writer = f.object.writer(); | ||
| 4715 | const local = try f.allocLocal(inst, Type.bool); | ||
| 4716 | const a = try Assignment.start(f, writer, CType.bool); | ||
| 4717 | try f.writeCValue(writer, local, .Other); | ||
| 4718 | try a.assign(f, writer); | ||
| 4719 | |||
| 4720 | try writer.writeAll("zig_expect("); | ||
| 4721 | try f.writeCValue(writer, operand, .FunctionArgument); | ||
| 4722 | try writer.writeAll(", "); | ||
| 4723 | try f.writeCValue(writer, expected, .FunctionArgument); | ||
| 4724 | try writer.writeAll(")"); | ||
| 4725 | |||
| 4726 | try a.end(f, writer); | ||
| 4727 | return local; | ||
| 4728 | } | ||
| 4729 | |||
| 4730 | fn lowerTry( | 4707 | fn lowerTry( |
| 4731 | f: *Function, | 4708 | f: *Function, |
| 4732 | inst: Air.Inst.Index, | 4709 | inst: Air.Inst.Index, |
src/codegen/llvm.zig-22| ... | @@ -5038,8 +5038,6 @@ pub const FuncGen = struct { | ... | @@ -5038,8 +5038,6 @@ pub const FuncGen = struct { |
| 5038 | .slice_ptr => try self.airSliceField(inst, 0), | 5038 | .slice_ptr => try self.airSliceField(inst, 0), |
| 5039 | .slice_len => try self.airSliceField(inst, 1), | 5039 | .slice_len => try self.airSliceField(inst, 1), |
| 5040 | 5040 | ||
| 5041 | .expect => try self.airExpect(inst), | ||
| 5042 | |||
| 5043 | .call => try self.airCall(inst, .auto), | 5041 | .call => try self.airCall(inst, .auto), |
| 5044 | .call_always_tail => try self.airCall(inst, .always_tail), | 5042 | .call_always_tail => try self.airCall(inst, .always_tail), |
| 5045 | .call_never_tail => try self.airCall(inst, .never_tail), | 5043 | .call_never_tail => try self.airCall(inst, .never_tail), |
| ... | @@ -6367,26 +6365,6 @@ pub const FuncGen = struct { | ... | @@ -6367,26 +6365,6 @@ pub const FuncGen = struct { |
| 6367 | return result; | 6365 | return result; |
| 6368 | } | 6366 | } |
| 6369 | 6367 | ||
| 6370 | // Note that the LowerExpectPass only runs in Release modes | ||
| 6371 | fn airExpect(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { | ||
| 6372 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | ||
| 6373 | |||
| 6374 | const operand = try self.resolveInst(bin_op.lhs); | ||
| 6375 | const expected = try self.resolveInst(bin_op.rhs); | ||
| 6376 | |||
| 6377 | return try self.wip.callIntrinsic( | ||
| 6378 | .normal, | ||
| 6379 | .none, | ||
| 6380 | .expect, | ||
| 6381 | &.{operand.typeOfWip(&self.wip)}, | ||
| 6382 | &.{ | ||
| 6383 | operand, | ||
| 6384 | expected, | ||
| 6385 | }, | ||
| 6386 | "", | ||
| 6387 | ); | ||
| 6388 | } | ||
| 6389 | |||
| 6390 | fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { | 6368 | fn sliceOrArrayPtr(fg: *FuncGen, ptr: Builder.Value, ty: Type) Allocator.Error!Builder.Value { |
| 6391 | const o = fg.dg.object; | 6369 | const o = fg.dg.object; |
| 6392 | const mod = o.module; | 6370 | const mod = o.module; |
src/print_air.zig-1| ... | @@ -162,7 +162,6 @@ const Writer = struct { | ... | @@ -162,7 +162,6 @@ const Writer = struct { |
| 162 | .memcpy, | 162 | .memcpy, |
| 163 | .memset, | 163 | .memset, |
| 164 | .memset_safe, | 164 | .memset_safe, |
| 165 | .expect, | ||
| 166 | => try w.writeBinOp(s, inst), | 165 | => try w.writeBinOp(s, inst), |
| 167 | 166 | ||
| 168 | .is_null, | 167 | .is_null, |
src/print_zir.zig-1| ... | @@ -591,7 +591,6 @@ const Writer = struct { | ... | @@ -591,7 +591,6 @@ const Writer = struct { |
| 591 | .wasm_memory_grow, | 591 | .wasm_memory_grow, |
| 592 | .prefetch, | 592 | .prefetch, |
| 593 | .c_va_arg, | 593 | .c_va_arg, |
| 594 | .expect, | ||
| 595 | => { | 594 | => { |
| 596 | const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data; | 595 | const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data; |
| 597 | const src = LazySrcLoc.nodeOffset(inst_data.node); | 596 | const src = LazySrcLoc.nodeOffset(inst_data.node); |
src/target.zig-1| ... | @@ -535,6 +535,5 @@ pub fn backendSupportsFeature( | ... | @@ -535,6 +535,5 @@ pub fn backendSupportsFeature( |
| 535 | .error_set_has_value => use_llvm or cpu_arch.isWasm(), | 535 | .error_set_has_value => use_llvm or cpu_arch.isWasm(), |
| 536 | .field_reordering => ofmt == .c or use_llvm, | 536 | .field_reordering => ofmt == .c or use_llvm, |
| 537 | .safety_checked_instructions => use_llvm, | 537 | .safety_checked_instructions => use_llvm, |
| 538 | .can_expect => use_llvm or ofmt == .c, | ||
| 539 | }; | 538 | }; |
| 540 | } | 539 | } |
test/behavior/expect.zig deleted-37| ... | @@ -1,37 +0,0 @@ | ||
| 1 | const std = @import("std"); | ||
| 2 | const expect = std.testing.expect; | ||
| 3 | |||
| 4 | test "@expect if-statement" { | ||
| 5 | const x: u32 = 10; | ||
| 6 | _ = &x; | ||
| 7 | if (@expect(x == 20, true)) {} | ||
| 8 | } | ||
| 9 | |||
| 10 | test "@expect runtime if-statement" { | ||
| 11 | var x: u32 = 10; | ||
| 12 | var y: u32 = 20; | ||
| 13 | _ = &x; | ||
| 14 | _ = &y; | ||
| 15 | if (@expect(x != y, false)) {} | ||
| 16 | } | ||
| 17 | |||
| 18 | test "@expect bool input/output" { | ||
| 19 | const b: bool = true; | ||
| 20 | try expect(@TypeOf(@expect(b, false)) == bool); | ||
| 21 | } | ||
| 22 | |||
| 23 | test "@expect bool is transitive" { | ||
| 24 | const a: bool = true; | ||
| 25 | const b = @expect(a, false); | ||
| 26 | |||
| 27 | const c = @intFromBool(!b); | ||
| 28 | std.mem.doNotOptimizeAway(c); | ||
| 29 | |||
| 30 | try expect(c == 0); | ||
| 31 | try expect(@expect(c != 0, false) == false); | ||
| 32 | } | ||
| 33 | |||
| 34 | test "@expect at comptime" { | ||
| 35 | const a: bool = true; | ||
| 36 | comptime try expect(@expect(a, true) == true); | ||
| 37 | } | ||
test/cases/compile_errors/@expect_non_bool.zig deleted-11| ... | @@ -1,11 +0,0 @@ | ||
| 1 | export fn a() void { | ||
| 2 | var x: u32 = 10; | ||
| 3 | _ = &x; | ||
| 4 | _ = @expect(x, true); | ||
| 5 | } | ||
| 6 | |||
| 7 | // error | ||
| 8 | // backend=stage2 | ||
| 9 | // target=native | ||
| 10 | // | ||
| 11 | // :4:17: error: expected type 'bool', found 'u32' | ||