| ... | ... | @@ -1927,9 +1927,8 @@ fn analyzeBodyInner( |
| 1927 | 1927 | break :msg msg; |
| 1928 | 1928 | }); |
| 1929 | 1929 | } |
| 1930 | | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); |
| 1931 | | assert(is_non_err != .none); |
| 1932 | | const is_non_err_val = try sema.resolveConstDefinedValue(block, operand_src, is_non_err, null); |
| 1930 | const is_non_err_val = (try sema.resolveIsNonErrVal(block, operand_src, err_union)).?; |
| 1931 | if (is_non_err_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, operand_src, null); |
| 1933 | 1932 | if (is_non_err_val.toBool()) { |
| 1934 | 1933 | break :blk try sema.analyzeErrUnionPayload(block, src, err_union_ty, err_union, operand_src, false); |
| 1935 | 1934 | } |
| ... | ... | @@ -1945,9 +1944,8 @@ fn analyzeBodyInner( |
| 1945 | 1944 | const inline_body = sema.code.bodySlice(extra.end, extra.data.body_len); |
| 1946 | 1945 | const operand = try sema.resolveInst(extra.data.operand); |
| 1947 | 1946 | const err_union = try sema.analyzeLoad(block, src, operand, operand_src); |
| 1948 | | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(block, operand_src, err_union); |
| 1949 | | assert(is_non_err != .none); |
| 1950 | | const is_non_err_val = try sema.resolveConstDefinedValue(block, operand_src, is_non_err, null); |
| 1947 | const is_non_err_val = (try sema.resolveIsNonErrVal(block, operand_src, err_union)).?; |
| 1948 | if (is_non_err_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, operand_src, null); |
| 1951 | 1949 | if (is_non_err_val.toBool()) { |
| 1952 | 1950 | break :blk try sema.analyzeErrUnionPayloadPtr(block, src, operand, false, false); |
| 1953 | 1951 | } |
| ... | ... | @@ -8960,6 +8958,7 @@ fn analyzeErrUnionCode(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air |
| 8960 | 8958 | const result_ty = operand_ty.errorUnionSet(zcu); |
| 8961 | 8959 | |
| 8962 | 8960 | if (try sema.resolveDefinedValue(block, src, operand)) |val| { |
| 8961 | if (val.getErrorName(zcu) == .none) return .unreachable_value; |
| 8963 | 8962 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 8964 | 8963 | .ty = result_ty.toIntern(), |
| 8965 | 8964 | .name = zcu.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name, |
| ... | ... | @@ -8997,7 +8996,7 @@ fn analyzeErrUnionCodePtr(sema: *Sema, block: *Block, src: LazySrcLoc, operand: |
| 8997 | 8996 | |
| 8998 | 8997 | if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { |
| 8999 | 8998 | if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| { |
| 9000 | | assert(val.getErrorName(zcu) != .none); |
| 8999 | if (val.getErrorName(zcu) == .none) return .unreachable_value; |
| 9001 | 9000 | return Air.internedToRef((try pt.intern(.{ .err = .{ |
| 9002 | 9001 | .ty = result_ty.toIntern(), |
| 9003 | 9002 | .name = zcu.intern_pool.indexToKey(val.toIntern()).error_union.val.err_name, |
| ... | ... | @@ -18689,14 +18688,13 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! |
| 18689 | 18688 | break :msg msg; |
| 18690 | 18689 | }); |
| 18691 | 18690 | } |
| 18692 | | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); |
| 18693 | | if (is_non_err != .none) { |
| 18691 | if (try sema.resolveIsNonErrVal(parent_block, operand_src, err_union)) |is_non_err_val| { |
| 18694 | 18692 | // We can propagate `.cold` hints from this branch since it's comptime-known |
| 18695 | 18693 | // to be taken from the parent branch. |
| 18696 | 18694 | const parent_hint = sema.branch_hint; |
| 18697 | 18695 | defer sema.branch_hint = parent_hint orelse if (sema.branch_hint == .cold) .cold else null; |
| 18698 | 18696 | |
| 18699 | | const is_non_err_val = (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)).?; |
| 18697 | if (is_non_err_val.isUndef(zcu)) return sema.failWithUseOfUndef(parent_block, operand_src, null); |
| 18700 | 18698 | if (is_non_err_val.toBool()) { |
| 18701 | 18699 | return sema.analyzeErrUnionPayload(parent_block, src, err_union_ty, err_union, operand_src, false); |
| 18702 | 18700 | } |
| ... | ... | @@ -18753,14 +18751,13 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr |
| 18753 | 18751 | break :msg msg; |
| 18754 | 18752 | }); |
| 18755 | 18753 | } |
| 18756 | | const is_non_err = try sema.analyzeIsNonErrComptimeOnly(parent_block, operand_src, err_union); |
| 18757 | | if (is_non_err != .none) { |
| 18754 | if (try sema.resolveIsNonErrVal(parent_block, operand_src, err_union)) |is_non_err_val| { |
| 18758 | 18755 | // We can propagate `.cold` hints from this branch since it's comptime-known |
| 18759 | 18756 | // to be taken from the parent branch. |
| 18760 | 18757 | const parent_hint = sema.branch_hint; |
| 18761 | 18758 | defer sema.branch_hint = parent_hint orelse if (sema.branch_hint == .cold) .cold else null; |
| 18762 | 18759 | |
| 18763 | | const is_non_err_val = (try sema.resolveDefinedValue(parent_block, operand_src, is_non_err)).?; |
| 18760 | if (is_non_err_val.isUndef(zcu)) return sema.failWithUseOfUndef(parent_block, operand_src, null); |
| 18764 | 18761 | if (is_non_err_val.toBool()) { |
| 18765 | 18762 | return sema.analyzeErrUnionPayloadPtr(parent_block, src, operand, false, false); |
| 18766 | 18763 | } |
| ... | ... | @@ -31800,12 +31797,12 @@ fn analyzeIsNull( |
| 31800 | 31797 | return block.addUnOp(air_tag, operand); |
| 31801 | 31798 | } |
| 31802 | 31799 | |
| 31803 | | fn analyzePtrIsNonErrComptimeOnly( |
| 31800 | fn resolvePtrIsNonErrVal( |
| 31804 | 31801 | sema: *Sema, |
| 31805 | 31802 | block: *Block, |
| 31806 | 31803 | src: LazySrcLoc, |
| 31807 | 31804 | operand: Air.Inst.Ref, |
| 31808 | | ) CompileError!Air.Inst.Ref { |
| 31805 | ) CompileError!?Value { |
| 31809 | 31806 | const pt = sema.pt; |
| 31810 | 31807 | const zcu = pt.zcu; |
| 31811 | 31808 | const ptr_ty = sema.typeOf(operand); |
| ... | ... | @@ -31813,41 +31810,44 @@ fn analyzePtrIsNonErrComptimeOnly( |
| 31813 | 31810 | const child_ty = ptr_ty.childType(zcu); |
| 31814 | 31811 | |
| 31815 | 31812 | const child_tag = child_ty.zigTypeTag(zcu); |
| 31816 | | if (child_tag != .error_set and child_tag != .error_union) return .bool_true; |
| 31817 | | if (child_tag == .error_set) return .bool_false; |
| 31813 | if (child_tag != .error_set and child_tag != .error_union) return .true; |
| 31814 | if (child_tag == .error_set) return .false; |
| 31818 | 31815 | assert(child_tag == .error_union); |
| 31819 | 31816 | |
| 31820 | | _ = block; |
| 31821 | | _ = src; |
| 31822 | | |
| 31823 | | return .none; |
| 31817 | if (try sema.resolveValue(operand)) |ptr_val| { |
| 31818 | if (ptr_val.isUndef(zcu)) return .undef_bool; |
| 31819 | if (try sema.pointerDeref(block, src, ptr_val, ptr_ty)) |val| { |
| 31820 | return try sema.resolveIsNonErrVal(block, src, .fromValue(val)); |
| 31821 | } |
| 31822 | } |
| 31823 | return null; |
| 31824 | 31824 | } |
| 31825 | 31825 | |
| 31826 | | fn analyzeIsNonErrComptimeOnly( |
| 31826 | fn resolveIsNonErrVal( |
| 31827 | 31827 | sema: *Sema, |
| 31828 | 31828 | block: *Block, |
| 31829 | 31829 | src: LazySrcLoc, |
| 31830 | 31830 | operand: Air.Inst.Ref, |
| 31831 | | ) CompileError!Air.Inst.Ref { |
| 31831 | ) CompileError!?Value { |
| 31832 | 31832 | const pt = sema.pt; |
| 31833 | 31833 | const zcu = pt.zcu; |
| 31834 | 31834 | const ip = &zcu.intern_pool; |
| 31835 | 31835 | const operand_ty = sema.typeOf(operand); |
| 31836 | 31836 | const ot = operand_ty.zigTypeTag(zcu); |
| 31837 | | if (ot != .error_set and ot != .error_union) return .bool_true; |
| 31838 | | if (ot == .error_set) return .bool_false; |
| 31837 | if (ot != .error_set and ot != .error_union) return .true; |
| 31838 | if (ot == .error_set) return .false; |
| 31839 | 31839 | assert(ot == .error_union); |
| 31840 | 31840 | |
| 31841 | 31841 | const payload_ty = operand_ty.errorUnionPayload(zcu); |
| 31842 | 31842 | if (payload_ty.zigTypeTag(zcu) == .noreturn) { |
| 31843 | | return .bool_false; |
| 31843 | return .false; |
| 31844 | 31844 | } |
| 31845 | 31845 | |
| 31846 | 31846 | if (operand == .undef) { |
| 31847 | 31847 | return .undef_bool; |
| 31848 | 31848 | } else if (@intFromEnum(operand) < InternPool.static_len) { |
| 31849 | 31849 | // None of the ref tags can be errors. |
| 31850 | | return .bool_true; |
| 31850 | return .true; |
| 31851 | 31851 | } |
| 31852 | 31852 | |
| 31853 | 31853 | const maybe_operand_val = try sema.resolveValue(operand); |
| ... | ... | @@ -31870,23 +31870,23 @@ fn analyzeIsNonErrComptimeOnly( |
| 31870 | 31870 | if (maybe_operand_val != null) break :blk; |
| 31871 | 31871 | |
| 31872 | 31872 | // Try to avoid resolving inferred error set if possible. |
| 31873 | | if (ies.errors.count() != 0) return .none; |
| 31873 | if (ies.errors.count() != 0) return null; |
| 31874 | 31874 | switch (ies.resolved) { |
| 31875 | | .anyerror_type => return .none, |
| 31875 | .anyerror_type => return null, |
| 31876 | 31876 | .none => {}, |
| 31877 | 31877 | else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) { |
| 31878 | | 0 => return .bool_true, |
| 31879 | | else => return .none, |
| 31878 | 0 => return .true, |
| 31879 | else => return null, |
| 31880 | 31880 | }, |
| 31881 | 31881 | } |
| 31882 | 31882 | // We do not have a comptime answer because this inferred error |
| 31883 | 31883 | // set is not resolved, and an instruction later in this function |
| 31884 | 31884 | // body may or may not cause an error to be added to this set. |
| 31885 | | return .none; |
| 31885 | return null; |
| 31886 | 31886 | }, |
| 31887 | 31887 | else => switch (ip.indexToKey(set_ty)) { |
| 31888 | 31888 | .error_set_type => |error_set_type| { |
| 31889 | | if (error_set_type.names.len == 0) return .bool_true; |
| 31889 | if (error_set_type.names.len == 0) return .true; |
| 31890 | 31890 | }, |
| 31891 | 31891 | .inferred_error_set_type => |func_index| blk: { |
| 31892 | 31892 | // If the error set is empty, we must return a comptime true or false. |
| ... | ... | @@ -31902,35 +31902,35 @@ fn analyzeIsNonErrComptimeOnly( |
| 31902 | 31902 | if (sema.fn_ret_ty_ies) |ies| { |
| 31903 | 31903 | if (ies.func == func_index) { |
| 31904 | 31904 | // Try to avoid resolving inferred error set if possible. |
| 31905 | | if (ies.errors.count() != 0) return .none; |
| 31905 | if (ies.errors.count() != 0) return null; |
| 31906 | 31906 | switch (ies.resolved) { |
| 31907 | | .anyerror_type => return .none, |
| 31907 | .anyerror_type => return null, |
| 31908 | 31908 | .none => {}, |
| 31909 | 31909 | else => switch (ip.indexToKey(ies.resolved).error_set_type.names.len) { |
| 31910 | | 0 => return .bool_true, |
| 31911 | | else => return .none, |
| 31910 | 0 => return .true, |
| 31911 | else => return null, |
| 31912 | 31912 | }, |
| 31913 | 31913 | } |
| 31914 | 31914 | // We do not have a comptime answer because this inferred error |
| 31915 | 31915 | // set is not resolved, and an instruction later in this function |
| 31916 | 31916 | // body may or may not cause an error to be added to this set. |
| 31917 | | return .none; |
| 31917 | return null; |
| 31918 | 31918 | } |
| 31919 | 31919 | } |
| 31920 | 31920 | const resolved_ty = try sema.resolveInferredErrorSet(block, src, set_ty); |
| 31921 | 31921 | if (resolved_ty == .anyerror_type) |
| 31922 | 31922 | break :blk; |
| 31923 | 31923 | if (ip.indexToKey(resolved_ty).error_set_type.names.len == 0) |
| 31924 | | return .bool_true; |
| 31924 | return .true; |
| 31925 | 31925 | }, |
| 31926 | 31926 | else => unreachable, |
| 31927 | 31927 | }, |
| 31928 | 31928 | } |
| 31929 | 31929 | |
| 31930 | 31930 | if (maybe_operand_val) |err_union| { |
| 31931 | | return if (err_union.isUndef(zcu)) .undef_bool else if (err_union.getErrorName(zcu) == .none) .bool_true else .bool_false; |
| 31931 | return if (err_union.isUndef(zcu)) .undef_bool else if (err_union.getErrorName(zcu) == .none) .true else .false; |
| 31932 | 31932 | } |
| 31933 | | return .none; |
| 31933 | return null; |
| 31934 | 31934 | } |
| 31935 | 31935 | |
| 31936 | 31936 | fn analyzeIsNonErr( |
| ... | ... | @@ -31939,12 +31939,10 @@ fn analyzeIsNonErr( |
| 31939 | 31939 | src: LazySrcLoc, |
| 31940 | 31940 | operand: Air.Inst.Ref, |
| 31941 | 31941 | ) CompileError!Air.Inst.Ref { |
| 31942 | | const result = try sema.analyzeIsNonErrComptimeOnly(block, src, operand); |
| 31943 | | if (result == .none) { |
| 31944 | | try sema.requireRuntimeBlock(block, src, null); |
| 31945 | | return block.addUnOp(.is_non_err, operand); |
| 31942 | if (try sema.resolveIsNonErrVal(block, src, operand)) |val| { |
| 31943 | return .fromValue(val); |
| 31946 | 31944 | } else { |
| 31947 | | return result; |
| 31945 | return block.addUnOp(.is_non_err, operand); |
| 31948 | 31946 | } |
| 31949 | 31947 | } |
| 31950 | 31948 | |
| ... | ... | @@ -31954,12 +31952,10 @@ fn analyzePtrIsNonErr( |
| 31954 | 31952 | src: LazySrcLoc, |
| 31955 | 31953 | operand: Air.Inst.Ref, |
| 31956 | 31954 | ) CompileError!Air.Inst.Ref { |
| 31957 | | const result = try sema.analyzePtrIsNonErrComptimeOnly(block, src, operand); |
| 31958 | | if (result == .none) { |
| 31959 | | try sema.requireRuntimeBlock(block, src, null); |
| 31960 | | return block.addUnOp(.is_non_err_ptr, operand); |
| 31955 | if (try sema.resolvePtrIsNonErrVal(block, src, operand)) |val| { |
| 31956 | return .fromValue(val); |
| 31961 | 31957 | } else { |
| 31962 | | return result; |
| 31958 | return block.addUnOp(.is_non_err_ptr, operand); |
| 31963 | 31959 | } |
| 31964 | 31960 | } |
| 31965 | 31961 | |