| ... | @@ -848,13 +848,12 @@ pub fn analyzeBodyBreak( | ... | @@ -848,13 +848,12 @@ pub fn analyzeBodyBreak( |
| 848 | block: *Block, | 848 | block: *Block, |
| 849 | body: []const Zir.Inst.Index, | 849 | body: []const Zir.Inst.Index, |
| 850 | ) CompileError!?BreakData { | 850 | ) CompileError!?BreakData { |
| 851 | const mod = sema.mod; | | |
| 852 | const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) { | 851 | const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) { |
| 853 | error.ComptimeBreak => sema.comptime_break_inst, | 852 | error.ComptimeBreak => sema.comptime_break_inst, |
| 854 | else => |e| return e, | 853 | else => |e| return e, |
| 855 | }; | 854 | }; |
| 856 | if (block.instructions.items.len != 0 and | 855 | if (block.instructions.items.len != 0 and |
| 857 | sema.typeOf(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1])).isNoReturn(mod)) | 856 | sema.isNoReturn(Air.indexToRef(block.instructions.items[block.instructions.items.len - 1]))) |
| 858 | return null; | 857 | return null; |
| 859 | const break_data = sema.code.instructions.items(.data)[break_inst].@"break"; | 858 | const break_data = sema.code.instructions.items(.data)[break_inst].@"break"; |
| 860 | const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; | 859 | const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; |
| ... | @@ -9671,9 +9670,9 @@ fn intCast( | ... | @@ -9671,9 +9670,9 @@ fn intCast( |
| 9671 | // range to account for negative values. | 9670 | // range to account for negative values. |
| 9672 | const dest_range_val = if (wanted_info.signedness == .signed) range_val: { | 9671 | const dest_range_val = if (wanted_info.signedness == .signed) range_val: { |
| 9673 | const one = try mod.intValue(unsigned_operand_ty, 1); | 9672 | const one = try mod.intValue(unsigned_operand_ty, 1); |
| 9674 | const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, sema.mod); | 9673 | const range_minus_one = try dest_max_val.shl(one, unsigned_operand_ty, sema.arena, mod); |
| 9675 | break :range_val try sema.intAdd(range_minus_one, one, unsigned_operand_ty); | 9674 | break :range_val try sema.intAdd(range_minus_one, one, unsigned_operand_ty); |
| 9676 | } else dest_max_val; | 9675 | } else try mod.getCoerced(dest_max_val, unsigned_operand_ty); |
| 9677 | const dest_range = try sema.addConstant(unsigned_operand_ty, dest_range_val); | 9676 | const dest_range = try sema.addConstant(unsigned_operand_ty, dest_range_val); |
| 9678 | | 9677 | |
| 9679 | const ok = if (is_vector) ok: { | 9678 | const ok = if (is_vector) ok: { |
| ... | @@ -10791,7 +10790,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError | ... | @@ -10791,7 +10790,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10791 | | 10790 | |
| 10792 | check_range: { | 10791 | check_range: { |
| 10793 | if (operand_ty.zigTypeTag(mod) == .Int) { | 10792 | if (operand_ty.zigTypeTag(mod) == .Int) { |
| 10794 | const min_int = try operand_ty.minInt(mod); | 10793 | const min_int = try operand_ty.minInt(mod, operand_ty); |
| 10795 | const max_int = try operand_ty.maxInt(mod, operand_ty); | 10794 | const max_int = try operand_ty.maxInt(mod, operand_ty); |
| 10796 | if (try range_set.spans(min_int, max_int, operand_ty)) { | 10795 | if (try range_set.spans(min_int, max_int, operand_ty)) { |
| 10797 | if (special_prong == .@"else") { | 10796 | if (special_prong == .@"else") { |
| ... | @@ -11647,7 +11646,7 @@ const RangeSetUnhandledIterator = struct { | ... | @@ -11647,7 +11646,7 @@ const RangeSetUnhandledIterator = struct { |
| 11647 | | 11646 | |
| 11648 | fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator { | 11647 | fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator { |
| 11649 | const mod = sema.mod; | 11648 | const mod = sema.mod; |
| 11650 | const min = try ty.minInt(mod); | 11649 | const min = try ty.minInt(mod, ty); |
| 11651 | const max = try ty.maxInt(mod, ty); | 11650 | const max = try ty.maxInt(mod, ty); |
| 11652 | | 11651 | |
| 11653 | return RangeSetUnhandledIterator{ | 11652 | return RangeSetUnhandledIterator{ |
| ... | @@ -12452,7 +12451,7 @@ fn zirShr( | ... | @@ -12452,7 +12451,7 @@ fn zirShr( |
| 12452 | if (block.wantSafety()) { | 12451 | if (block.wantSafety()) { |
| 12453 | const bit_count = scalar_ty.intInfo(mod).bits; | 12452 | const bit_count = scalar_ty.intInfo(mod).bits; |
| 12454 | if (!std.math.isPowerOfTwo(bit_count)) { | 12453 | if (!std.math.isPowerOfTwo(bit_count)) { |
| 12455 | const bit_count_val = try mod.intValue(scalar_ty, bit_count); | 12454 | const bit_count_val = try mod.intValue(rhs_ty.scalarType(mod), bit_count); |
| 12456 | | 12455 | |
| 12457 | const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: { | 12456 | const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: { |
| 12458 | const bit_count_inst = try sema.addConstant(rhs_ty, try sema.splat(rhs_ty, bit_count_val)); | 12457 | const bit_count_inst = try sema.addConstant(rhs_ty, try sema.splat(rhs_ty, bit_count_val)); |
| ... | @@ -13297,7 +13296,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins | ... | @@ -13297,7 +13296,7 @@ fn zirDiv(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Ins |
| 13297 | if (!lhs_val.isUndef(mod)) { | 13296 | if (!lhs_val.isUndef(mod)) { |
| 13298 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 13297 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13299 | const scalar_zero = switch (scalar_tag) { | 13298 | const scalar_zero = switch (scalar_tag) { |
| 13300 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), | 13299 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), |
| 13301 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 13300 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13302 | else => unreachable, | 13301 | else => unreachable, |
| 13303 | }; | 13302 | }; |
| ... | @@ -13437,7 +13436,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13437,7 +13436,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13437 | } else { | 13436 | } else { |
| 13438 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 13437 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13439 | const scalar_zero = switch (scalar_tag) { | 13438 | const scalar_zero = switch (scalar_tag) { |
| 13440 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), | 13439 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), |
| 13441 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 13440 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13442 | else => unreachable, | 13441 | else => unreachable, |
| 13443 | }; | 13442 | }; |
| ... | @@ -13520,7 +13519,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13520,7 +13519,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13520 | const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs); | 13519 | const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs); |
| 13521 | | 13520 | |
| 13522 | const scalar_zero = switch (scalar_tag) { | 13521 | const scalar_zero = switch (scalar_tag) { |
| 13523 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), | 13522 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), |
| 13524 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 13523 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13525 | else => unreachable, | 13524 | else => unreachable, |
| 13526 | }; | 13525 | }; |
| ... | @@ -13608,7 +13607,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13608,7 +13607,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13608 | if (!lhs_val.isUndef(mod)) { | 13607 | if (!lhs_val.isUndef(mod)) { |
| 13609 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 13608 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13610 | const scalar_zero = switch (scalar_tag) { | 13609 | const scalar_zero = switch (scalar_tag) { |
| 13611 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), | 13610 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), |
| 13612 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 13611 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13613 | else => unreachable, | 13612 | else => unreachable, |
| 13614 | }; | 13613 | }; |
| ... | @@ -13725,7 +13724,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai | ... | @@ -13725,7 +13724,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13725 | if (!lhs_val.isUndef(mod)) { | 13724 | if (!lhs_val.isUndef(mod)) { |
| 13726 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 13725 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13727 | const scalar_zero = switch (scalar_tag) { | 13726 | const scalar_zero = switch (scalar_tag) { |
| 13728 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), | 13727 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), |
| 13729 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 13728 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13730 | else => unreachable, | 13729 | else => unreachable, |
| 13731 | }; | 13730 | }; |
| ... | @@ -13805,7 +13804,7 @@ fn addDivIntOverflowSafety( | ... | @@ -13805,7 +13804,7 @@ fn addDivIntOverflowSafety( |
| 13805 | return; | 13804 | return; |
| 13806 | } | 13805 | } |
| 13807 | | 13806 | |
| 13808 | const min_int = try resolved_type.minInt(mod); | 13807 | const min_int = try resolved_type.minInt(mod, resolved_type); |
| 13809 | const neg_one_scalar = try mod.intValue(lhs_scalar_ty, -1); | 13808 | const neg_one_scalar = try mod.intValue(lhs_scalar_ty, -1); |
| 13810 | const neg_one = try sema.splat(resolved_type, neg_one_scalar); | 13809 | const neg_one = try sema.splat(resolved_type, neg_one_scalar); |
| 13811 | | 13810 | |
| ... | @@ -13881,7 +13880,7 @@ fn addDivByZeroSafety( | ... | @@ -13881,7 +13880,7 @@ fn addDivByZeroSafety( |
| 13881 | const scalar_zero = if (is_int) | 13880 | const scalar_zero = if (is_int) |
| 13882 | try mod.intValue(resolved_type.scalarType(mod), 0) | 13881 | try mod.intValue(resolved_type.scalarType(mod), 0) |
| 13883 | else | 13882 | else |
| 13884 | try mod.floatValue(resolved_type.scalarType(mod), 0); | 13883 | try mod.floatValue(resolved_type.scalarType(mod), 0.0); |
| 13885 | const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: { | 13884 | const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: { |
| 13886 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 13885 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 13887 | const zero = try sema.addConstant(resolved_type, zero_val); | 13886 | const zero = try sema.addConstant(resolved_type, zero_val); |
| ... | @@ -13967,7 +13966,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. | ... | @@ -13967,7 +13966,7 @@ fn zirModRem(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. |
| 13967 | } | 13966 | } |
| 13968 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { | 13967 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13969 | const scalar_zero = switch (scalar_tag) { | 13968 | const scalar_zero = switch (scalar_tag) { |
| 13970 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), | 13969 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0.0), |
| 13971 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 13970 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13972 | else => unreachable, | 13971 | else => unreachable, |
| 13973 | }; | 13972 | }; |
| ... | @@ -14575,7 +14574,8 @@ fn analyzeArithmetic( | ... | @@ -14575,7 +14574,8 @@ fn analyzeArithmetic( |
| 14575 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); | 14574 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 14576 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); | 14575 | const casted_rhs = try sema.coerce(block, resolved_type, rhs, rhs_src); |
| 14577 | | 14576 | |
| 14578 | const scalar_tag = resolved_type.scalarType(mod).zigTypeTag(mod); | 14577 | const scalar_type = resolved_type.scalarType(mod); |
| | 14578 | const scalar_tag = scalar_type.zigTypeTag(mod); |
| 14579 | | 14579 | |
| 14580 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; | 14580 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 14581 | | 14581 | |
| ... | @@ -14797,8 +14797,13 @@ fn analyzeArithmetic( | ... | @@ -14797,8 +14797,13 @@ fn analyzeArithmetic( |
| 14797 | // the result is nan. | 14797 | // the result is nan. |
| 14798 | // If either of the operands are nan, the result is nan. | 14798 | // If either of the operands are nan, the result is nan. |
| 14799 | const scalar_zero = switch (scalar_tag) { | 14799 | const scalar_zero = switch (scalar_tag) { |
| 14800 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), | 14800 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0), |
| 14801 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 14801 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 0), |
| | 14802 | else => unreachable, |
| | 14803 | }; |
| | 14804 | const scalar_one = switch (scalar_tag) { |
| | 14805 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 1.0), |
| | 14806 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 1), |
| 14802 | else => unreachable, | 14807 | else => unreachable, |
| 14803 | }; | 14808 | }; |
| 14804 | if (maybe_lhs_val) |lhs_val| { | 14809 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -14823,7 +14828,7 @@ fn analyzeArithmetic( | ... | @@ -14823,7 +14828,7 @@ fn analyzeArithmetic( |
| 14823 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 14828 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 14824 | return sema.addConstant(resolved_type, zero_val); | 14829 | return sema.addConstant(resolved_type, zero_val); |
| 14825 | } | 14830 | } |
| 14826 | if (try sema.compareAll(lhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) { | 14831 | if (try sema.compareAll(lhs_val, .eq, try sema.splat(resolved_type, scalar_one), resolved_type)) { |
| 14827 | return casted_rhs; | 14832 | return casted_rhs; |
| 14828 | } | 14833 | } |
| 14829 | } | 14834 | } |
| ... | @@ -14854,7 +14859,7 @@ fn analyzeArithmetic( | ... | @@ -14854,7 +14859,7 @@ fn analyzeArithmetic( |
| 14854 | const zero_val = try sema.splat(resolved_type, scalar_zero); | 14859 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 14855 | return sema.addConstant(resolved_type, zero_val); | 14860 | return sema.addConstant(resolved_type, zero_val); |
| 14856 | } | 14861 | } |
| 14857 | if (try sema.compareAll(rhs_val, .eq, try mod.intValue(resolved_type, 1), resolved_type)) { | 14862 | if (try sema.compareAll(rhs_val, .eq, try sema.splat(resolved_type, scalar_one), resolved_type)) { |
| 14858 | return casted_lhs; | 14863 | return casted_lhs; |
| 14859 | } | 14864 | } |
| 14860 | if (maybe_lhs_val) |lhs_val| { | 14865 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -14887,8 +14892,8 @@ fn analyzeArithmetic( | ... | @@ -14887,8 +14892,8 @@ fn analyzeArithmetic( |
| 14887 | // If either of the operands are one, result is the other operand. | 14892 | // If either of the operands are one, result is the other operand. |
| 14888 | // If either of the operands are undefined, result is undefined. | 14893 | // If either of the operands are undefined, result is undefined. |
| 14889 | const scalar_zero = switch (scalar_tag) { | 14894 | const scalar_zero = switch (scalar_tag) { |
| 14890 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), | 14895 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0), |
| 14891 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 14896 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 0), |
| 14892 | else => unreachable, | 14897 | else => unreachable, |
| 14893 | }; | 14898 | }; |
| 14894 | if (maybe_lhs_val) |lhs_val| { | 14899 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -14931,8 +14936,8 @@ fn analyzeArithmetic( | ... | @@ -14931,8 +14936,8 @@ fn analyzeArithmetic( |
| 14931 | // If either of the operands are one, result is the other operand. | 14936 | // If either of the operands are one, result is the other operand. |
| 14932 | // If either of the operands are undefined, result is undefined. | 14937 | // If either of the operands are undefined, result is undefined. |
| 14933 | const scalar_zero = switch (scalar_tag) { | 14938 | const scalar_zero = switch (scalar_tag) { |
| 14934 | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), | 14939 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0), |
| 14935 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), | 14940 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 0), |
| 14936 | else => unreachable, | 14941 | else => unreachable, |
| 14937 | }; | 14942 | }; |
| 14938 | if (maybe_lhs_val) |lhs_val| { | 14943 | if (maybe_lhs_val) |lhs_val| { |
| ... | @@ -18817,7 +18822,10 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { | ... | @@ -18817,7 +18822,10 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 18817 | { | 18822 | { |
| 18818 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); | 18823 | return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); |
| 18819 | } | 18824 | } |
| 18820 | return sema.addConstant(opt_ptr_stack_trace_ty, Value.null); | 18825 | return sema.addConstant(opt_ptr_stack_trace_ty, (try mod.intern(.{ .opt = .{ |
| | 18826 | .ty = opt_ptr_stack_trace_ty.toIntern(), |
| | 18827 | .val = .none, |
| | 18828 | } })).toValue()); |
| 18821 | } | 18829 | } |
| 18822 | | 18830 | |
| 18823 | fn zirFrame( | 18831 | fn zirFrame( |
| ... | @@ -20103,8 +20111,8 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! | ... | @@ -20103,8 +20111,8 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 20103 | if (block.wantSafety()) { | 20111 | if (block.wantSafety()) { |
| 20104 | const back = try block.addTyOp(.int_to_float, operand_ty, result); | 20112 | const back = try block.addTyOp(.int_to_float, operand_ty, result); |
| 20105 | const diff = try block.addBinOp(.sub, operand, back); | 20113 | const diff = try block.addBinOp(.sub, operand, back); |
| 20106 | const ok_pos = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_lt_optimized else .cmp_lt, diff, try sema.addConstant(operand_ty, try mod.intValue(operand_ty, 1))); | 20114 | const ok_pos = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_lt_optimized else .cmp_lt, diff, try sema.addConstant(operand_ty, try mod.floatValue(operand_ty, 1.0))); |
| 20107 | const ok_neg = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_gt_optimized else .cmp_gt, diff, try sema.addConstant(operand_ty, try mod.intValue(operand_ty, -1))); | 20115 | const ok_neg = try block.addBinOp(if (block.float_mode == .Optimized) .cmp_gt_optimized else .cmp_gt, diff, try sema.addConstant(operand_ty, try mod.floatValue(operand_ty, -1.0))); |
| 20108 | const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg); | 20116 | const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg); |
| 20109 | try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds); | 20117 | try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds); |
| 20110 | } | 20118 | } |
| ... | @@ -22448,8 +22456,8 @@ fn analyzeMinMax( | ... | @@ -22448,8 +22456,8 @@ fn analyzeMinMax( |
| 22448 | | 22456 | |
| 22449 | // Compute the final bounds based on the runtime type and the comptime-known bound type | 22457 | // Compute the final bounds based on the runtime type and the comptime-known bound type |
| 22450 | const min_val = switch (air_tag) { | 22458 | const min_val = switch (air_tag) { |
| 22451 | .min => try unrefined_elem_ty.minInt(mod), | 22459 | .min => try unrefined_elem_ty.minInt(mod, unrefined_elem_ty), |
| 22452 | .max => try comptime_elem_ty.minInt(mod), // @max(ct, rt) >= ct | 22460 | .max => try comptime_elem_ty.minInt(mod, comptime_elem_ty), // @max(ct, rt) >= ct |
| 22453 | else => unreachable, | 22461 | else => unreachable, |
| 22454 | }; | 22462 | }; |
| 22455 | const max_val = switch (air_tag) { | 22463 | const max_val = switch (air_tag) { |
| ... | @@ -25996,7 +26004,7 @@ fn coerceExtra( | ... | @@ -25996,7 +26004,7 @@ fn coerceExtra( |
| 25996 | | 26004 | |
| 25997 | if (dest_info.sentinel) |dest_sent| { | 26005 | if (dest_info.sentinel) |dest_sent| { |
| 25998 | if (array_ty.sentinel(mod)) |inst_sent| { | 26006 | if (array_ty.sentinel(mod)) |inst_sent| { |
| 25999 | if (!dest_sent.eql(inst_sent, dst_elem_type, sema.mod)) { | 26007 | if (!dest_sent.eql(inst_sent, dst_elem_type, mod)) { |
| 26000 | in_memory_result = .{ .ptr_sentinel = .{ | 26008 | in_memory_result = .{ .ptr_sentinel = .{ |
| 26001 | .actual = inst_sent, | 26009 | .actual = inst_sent, |
| 26002 | .wanted = dest_sent, | 26010 | .wanted = dest_sent, |
| ... | @@ -26115,7 +26123,7 @@ fn coerceExtra( | ... | @@ -26115,7 +26123,7 @@ fn coerceExtra( |
| 26115 | if (inst_info.size == .Slice) { | 26123 | if (inst_info.size == .Slice) { |
| 26116 | assert(dest_info.sentinel == null); | 26124 | assert(dest_info.sentinel == null); |
| 26117 | if (inst_info.sentinel == null or | 26125 | if (inst_info.sentinel == null or |
| 26118 | !inst_info.sentinel.?.eql(try mod.intValue(dest_info.pointee_type, 0), dest_info.pointee_type, sema.mod)) | 26126 | !inst_info.sentinel.?.eql(try mod.intValue(dest_info.pointee_type, 0), dest_info.pointee_type, mod)) |
| 26119 | break :p; | 26127 | break :p; |
| 26120 | | 26128 | |
| 26121 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); | 26129 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); |
| ... | @@ -26164,7 +26172,7 @@ fn coerceExtra( | ... | @@ -26164,7 +26172,7 @@ fn coerceExtra( |
| 26164 | block, | 26172 | block, |
| 26165 | inst_src, | 26173 | inst_src, |
| 26166 | "array literal requires address-of operator (&) to coerce to slice type '{}'", | 26174 | "array literal requires address-of operator (&) to coerce to slice type '{}'", |
| 26167 | .{dest_ty.fmt(sema.mod)}, | 26175 | .{dest_ty.fmt(mod)}, |
| 26168 | ); | 26176 | ); |
| 26169 | } | 26177 | } |
| 26170 | | 26178 | |
| ... | @@ -26190,7 +26198,7 @@ fn coerceExtra( | ... | @@ -26190,7 +26198,7 @@ fn coerceExtra( |
| 26190 | // pointer to tuple to slice | 26198 | // pointer to tuple to slice |
| 26191 | if (dest_info.mutable) { | 26199 | if (dest_info.mutable) { |
| 26192 | const err_msg = err_msg: { | 26200 | const err_msg = err_msg: { |
| 26193 | const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(sema.mod)}); | 26201 | const err_msg = try sema.errMsg(block, inst_src, "cannot cast pointer to tuple to '{}'", .{dest_ty.fmt(mod)}); |
| 26194 | errdefer err_msg.deinit(sema.gpa); | 26202 | errdefer err_msg.deinit(sema.gpa); |
| 26195 | try sema.errNote(block, dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{}); | 26203 | try sema.errNote(block, dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{}); |
| 26196 | break :err_msg err_msg; | 26204 | break :err_msg err_msg; |
| ... | @@ -26218,7 +26226,7 @@ fn coerceExtra( | ... | @@ -26218,7 +26226,7 @@ fn coerceExtra( |
| 26218 | } | 26226 | } |
| 26219 | | 26227 | |
| 26220 | if (dest_info.sentinel == null or inst_info.sentinel == null or | 26228 | if (dest_info.sentinel == null or inst_info.sentinel == null or |
| 26221 | !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, sema.mod)) | 26229 | !dest_info.sentinel.?.eql(inst_info.sentinel.?, dest_info.pointee_type, mod)) |
| 26222 | break :p; | 26230 | break :p; |
| 26223 | | 26231 | |
| 26224 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); | 26232 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); |
| ... | @@ -26244,7 +26252,7 @@ fn coerceExtra( | ... | @@ -26244,7 +26252,7 @@ fn coerceExtra( |
| 26244 | block, | 26252 | block, |
| 26245 | inst_src, | 26253 | inst_src, |
| 26246 | "fractional component prevents float value '{}' from coercion to type '{}'", | 26254 | "fractional component prevents float value '{}' from coercion to type '{}'", |
| 26247 | .{ val.fmtValue(inst_ty, sema.mod), dest_ty.fmt(sema.mod) }, | 26255 | .{ val.fmtValue(inst_ty, mod), dest_ty.fmt(mod) }, |
| 26248 | ); | 26256 | ); |
| 26249 | } | 26257 | } |
| 26250 | const result_val = try sema.floatToInt(block, inst_src, val, inst_ty, dest_ty); | 26258 | const result_val = try sema.floatToInt(block, inst_src, val, inst_ty, dest_ty); |
| ... | @@ -26258,7 +26266,7 @@ fn coerceExtra( | ... | @@ -26258,7 +26266,7 @@ fn coerceExtra( |
| 26258 | // comptime-known integer to other number | 26266 | // comptime-known integer to other number |
| 26259 | if (!(try sema.intFitsInType(val, dest_ty, null))) { | 26267 | if (!(try sema.intFitsInType(val, dest_ty, null))) { |
| 26260 | if (!opts.report_err) return error.NotCoercible; | 26268 | if (!opts.report_err) return error.NotCoercible; |
| 26261 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) }); | 26269 | return sema.fail(block, inst_src, "type '{}' cannot represent integer value '{}'", .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) }); |
| 26262 | } | 26270 | } |
| 26263 | return try sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty)); | 26271 | return try sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty)); |
| 26264 | } | 26272 | } |
| ... | @@ -26296,12 +26304,12 @@ fn coerceExtra( | ... | @@ -26296,12 +26304,12 @@ fn coerceExtra( |
| 26296 | } | 26304 | } |
| 26297 | if (try sema.resolveMaybeUndefVal(inst)) |val| { | 26305 | if (try sema.resolveMaybeUndefVal(inst)) |val| { |
| 26298 | const result_val = try val.floatCast(dest_ty, mod); | 26306 | const result_val = try val.floatCast(dest_ty, mod); |
| 26299 | if (!val.eql(result_val, inst_ty, sema.mod)) { | 26307 | if (!val.eql(try result_val.floatCast(inst_ty, mod), inst_ty, mod)) { |
| 26300 | return sema.fail( | 26308 | return sema.fail( |
| 26301 | block, | 26309 | block, |
| 26302 | inst_src, | 26310 | inst_src, |
| 26303 | "type '{}' cannot represent float value '{}'", | 26311 | "type '{}' cannot represent float value '{}'", |
| 26304 | .{ dest_ty.fmt(sema.mod), val.fmtValue(inst_ty, sema.mod) }, | 26312 | .{ dest_ty.fmt(mod), val.fmtValue(inst_ty, mod) }, |
| 26305 | ); | 26313 | ); |
| 26306 | } | 26314 | } |
| 26307 | return try sema.addConstant(dest_ty, result_val); | 26315 | return try sema.addConstant(dest_ty, result_val); |
| ... | @@ -26329,7 +26337,7 @@ fn coerceExtra( | ... | @@ -26329,7 +26337,7 @@ fn coerceExtra( |
| 26329 | } | 26337 | } |
| 26330 | break :int; | 26338 | break :int; |
| 26331 | }; | 26339 | }; |
| 26332 | const result_val = try val.intToFloatAdvanced(sema.arena, inst_ty, dest_ty, sema.mod, sema); | 26340 | const result_val = try val.intToFloatAdvanced(sema.arena, inst_ty, dest_ty, mod, sema); |
| 26333 | // TODO implement this compile error | 26341 | // TODO implement this compile error |
| 26334 | //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty); | 26342 | //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty); |
| 26335 | //if (!int_again_val.eql(val, inst_ty, mod)) { | 26343 | //if (!int_again_val.eql(val, inst_ty, mod)) { |
| ... | @@ -26337,7 +26345,7 @@ fn coerceExtra( | ... | @@ -26337,7 +26345,7 @@ fn coerceExtra( |
| 26337 | // block, | 26345 | // block, |
| 26338 | // inst_src, | 26346 | // inst_src, |
| 26339 | // "type '{}' cannot represent integer value '{}'", | 26347 | // "type '{}' cannot represent integer value '{}'", |
| 26340 | // .{ dest_ty.fmt(sema.mod), val }, | 26348 | // .{ dest_ty.fmt(mod), val }, |
| 26341 | // ); | 26349 | // ); |
| 26342 | //} | 26350 | //} |
| 26343 | return try sema.addConstant(dest_ty, result_val); | 26351 | return try sema.addConstant(dest_ty, result_val); |
| ... | @@ -26359,7 +26367,7 @@ fn coerceExtra( | ... | @@ -26359,7 +26367,7 @@ fn coerceExtra( |
| 26359 | block, | 26367 | block, |
| 26360 | inst_src, | 26368 | inst_src, |
| 26361 | "no field named '{s}' in enum '{}'", | 26369 | "no field named '{s}' in enum '{}'", |
| 26362 | .{ bytes, dest_ty.fmt(sema.mod) }, | 26370 | .{ bytes, dest_ty.fmt(mod) }, |
| 26363 | ); | 26371 | ); |
| 26364 | errdefer msg.destroy(sema.gpa); | 26372 | errdefer msg.destroy(sema.gpa); |
| 26365 | try sema.addDeclaredHereNote(msg, dest_ty); | 26373 | try sema.addDeclaredHereNote(msg, dest_ty); |
| ... | @@ -26375,7 +26383,7 @@ fn coerceExtra( | ... | @@ -26375,7 +26383,7 @@ fn coerceExtra( |
| 26375 | .Union => blk: { | 26383 | .Union => blk: { |
| 26376 | // union to its own tag type | 26384 | // union to its own tag type |
| 26377 | const union_tag_ty = inst_ty.unionTagType(mod) orelse break :blk; | 26385 | const union_tag_ty = inst_ty.unionTagType(mod) orelse break :blk; |
| 26378 | if (union_tag_ty.eql(dest_ty, sema.mod)) { | 26386 | if (union_tag_ty.eql(dest_ty, mod)) { |
| 26379 | return sema.unionToTag(block, dest_ty, inst, inst_src); | 26387 | return sema.unionToTag(block, dest_ty, inst, inst_src); |
| 26380 | } | 26388 | } |
| 26381 | }, | 26389 | }, |
| ... | @@ -26498,15 +26506,15 @@ fn coerceExtra( | ... | @@ -26498,15 +26506,15 @@ fn coerceExtra( |
| 26498 | errdefer msg.destroy(sema.gpa); | 26506 | errdefer msg.destroy(sema.gpa); |
| 26499 | | 26507 | |
| 26500 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; | 26508 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; |
| 26501 | const src_decl = sema.mod.declPtr(sema.func.?.owner_decl); | 26509 | const src_decl = mod.declPtr(sema.func.?.owner_decl); |
| 26502 | try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "'noreturn' declared here", .{}); | 26510 | try mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "'noreturn' declared here", .{}); |
| 26503 | break :msg msg; | 26511 | break :msg msg; |
| 26504 | }; | 26512 | }; |
| 26505 | return sema.failWithOwnedErrorMsg(msg); | 26513 | return sema.failWithOwnedErrorMsg(msg); |
| 26506 | } | 26514 | } |
| 26507 | | 26515 | |
| 26508 | const msg = msg: { | 26516 | const msg = msg: { |
| 26509 | const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(sema.mod), inst_ty.fmt(sema.mod) }); | 26517 | const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{ dest_ty.fmt(mod), inst_ty.fmt(mod) }); |
| 26510 | errdefer msg.destroy(sema.gpa); | 26518 | errdefer msg.destroy(sema.gpa); |
| 26511 | | 26519 | |
| 26512 | // E!T to T | 26520 | // E!T to T |
| ... | @@ -26528,18 +26536,18 @@ fn coerceExtra( | ... | @@ -26528,18 +26536,18 @@ fn coerceExtra( |
| 26528 | try in_memory_result.report(sema, block, inst_src, msg); | 26536 | try in_memory_result.report(sema, block, inst_src, msg); |
| 26529 | | 26537 | |
| 26530 | // Add notes about function return type | 26538 | // Add notes about function return type |
| 26531 | if (opts.is_ret and sema.mod.test_functions.get(sema.func.?.owner_decl) == null) { | 26539 | if (opts.is_ret and mod.test_functions.get(sema.func.?.owner_decl) == null) { |
| 26532 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; | 26540 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; |
| 26533 | const src_decl = sema.mod.declPtr(sema.func.?.owner_decl); | 26541 | const src_decl = mod.declPtr(sema.func.?.owner_decl); |
| 26534 | if (inst_ty.isError(mod) and !dest_ty.isError(mod)) { | 26542 | if (inst_ty.isError(mod) and !dest_ty.isError(mod)) { |
| 26535 | try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "function cannot return an error", .{}); | 26543 | try mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "function cannot return an error", .{}); |
| 26536 | } else { | 26544 | } else { |
| 26537 | try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "function return type declared here", .{}); | 26545 | try mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "function return type declared here", .{}); |
| 26538 | } | 26546 | } |
| 26539 | } | 26547 | } |
| 26540 | | 26548 | |
| 26541 | if (try opts.param_src.get(sema)) |param_src| { | 26549 | if (try opts.param_src.get(sema)) |param_src| { |
| 26542 | try sema.mod.errNoteNonLazy(param_src, msg, "parameter type declared here", .{}); | 26550 | try mod.errNoteNonLazy(param_src, msg, "parameter type declared here", .{}); |
| 26543 | } | 26551 | } |
| 26544 | | 26552 | |
| 26545 | // TODO maybe add "cannot store an error in type '{}'" note | 26553 | // TODO maybe add "cannot store an error in type '{}'" note |
| ... | @@ -26679,7 +26687,7 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -26679,7 +26687,7 @@ const InMemoryCoercionResult = union(enum) { |
| 26679 | }, | 26687 | }, |
| 26680 | .error_union_payload => |pair| { | 26688 | .error_union_payload => |pair| { |
| 26681 | try sema.errNote(block, src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{ | 26689 | try sema.errNote(block, src, msg, "error union payload '{}' cannot cast into error union payload '{}'", .{ |
| 26682 | pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod), | 26690 | pair.actual.fmt(mod), pair.wanted.fmt(mod), |
| 26683 | }); | 26691 | }); |
| 26684 | cur = pair.child; | 26692 | cur = pair.child; |
| 26685 | }, | 26693 | }, |
| ... | @@ -26692,18 +26700,18 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -26692,18 +26700,18 @@ const InMemoryCoercionResult = union(enum) { |
| 26692 | .array_sentinel => |sentinel| { | 26700 | .array_sentinel => |sentinel| { |
| 26693 | if (sentinel.actual.toIntern() != .unreachable_value) { | 26701 | if (sentinel.actual.toIntern() != .unreachable_value) { |
| 26694 | try sema.errNote(block, src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{ | 26702 | try sema.errNote(block, src, msg, "array sentinel '{}' cannot cast into array sentinel '{}'", .{ |
| 26695 | sentinel.actual.fmtValue(sentinel.ty, sema.mod), sentinel.wanted.fmtValue(sentinel.ty, sema.mod), | 26703 | sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod), |
| 26696 | }); | 26704 | }); |
| 26697 | } else { | 26705 | } else { |
| 26698 | try sema.errNote(block, src, msg, "destination array requires '{}' sentinel", .{ | 26706 | try sema.errNote(block, src, msg, "destination array requires '{}' sentinel", .{ |
| 26699 | sentinel.wanted.fmtValue(sentinel.ty, sema.mod), | 26707 | sentinel.wanted.fmtValue(sentinel.ty, mod), |
| 26700 | }); | 26708 | }); |
| 26701 | } | 26709 | } |
| 26702 | break; | 26710 | break; |
| 26703 | }, | 26711 | }, |
| 26704 | .array_elem => |pair| { | 26712 | .array_elem => |pair| { |
| 26705 | try sema.errNote(block, src, msg, "array element type '{}' cannot cast into array element type '{}'", .{ | 26713 | try sema.errNote(block, src, msg, "array element type '{}' cannot cast into array element type '{}'", .{ |
| 26706 | pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod), | 26714 | pair.actual.fmt(mod), pair.wanted.fmt(mod), |
| 26707 | }); | 26715 | }); |
| 26708 | cur = pair.child; | 26716 | cur = pair.child; |
| 26709 | }, | 26717 | }, |
| ... | @@ -26715,19 +26723,19 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -26715,19 +26723,19 @@ const InMemoryCoercionResult = union(enum) { |
| 26715 | }, | 26723 | }, |
| 26716 | .vector_elem => |pair| { | 26724 | .vector_elem => |pair| { |
| 26717 | try sema.errNote(block, src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{ | 26725 | try sema.errNote(block, src, msg, "vector element type '{}' cannot cast into vector element type '{}'", .{ |
| 26718 | pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod), | 26726 | pair.actual.fmt(mod), pair.wanted.fmt(mod), |
| 26719 | }); | 26727 | }); |
| 26720 | cur = pair.child; | 26728 | cur = pair.child; |
| 26721 | }, | 26729 | }, |
| 26722 | .optional_shape => |pair| { | 26730 | .optional_shape => |pair| { |
| 26723 | try sema.errNote(block, src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{ | 26731 | try sema.errNote(block, src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{ |
| 26724 | pair.actual.optionalChild(mod).fmt(sema.mod), pair.wanted.optionalChild(mod).fmt(sema.mod), | 26732 | pair.actual.optionalChild(mod).fmt(mod), pair.wanted.optionalChild(mod).fmt(mod), |
| 26725 | }); | 26733 | }); |
| 26726 | break; | 26734 | break; |
| 26727 | }, | 26735 | }, |
| 26728 | .optional_child => |pair| { | 26736 | .optional_child => |pair| { |
| 26729 | try sema.errNote(block, src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{ | 26737 | try sema.errNote(block, src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{ |
| 26730 | pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod), | 26738 | pair.actual.fmt(mod), pair.wanted.fmt(mod), |
| 26731 | }); | 26739 | }); |
| 26732 | cur = pair.child; | 26740 | cur = pair.child; |
| 26733 | }, | 26741 | }, |
| ... | @@ -26792,7 +26800,7 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -26792,7 +26800,7 @@ const InMemoryCoercionResult = union(enum) { |
| 26792 | }, | 26800 | }, |
| 26793 | .fn_param => |param| { | 26801 | .fn_param => |param| { |
| 26794 | try sema.errNote(block, src, msg, "parameter {d} '{}' cannot cast into '{}'", .{ | 26802 | try sema.errNote(block, src, msg, "parameter {d} '{}' cannot cast into '{}'", .{ |
| 26795 | param.index, param.actual.fmt(sema.mod), param.wanted.fmt(sema.mod), | 26803 | param.index, param.actual.fmt(mod), param.wanted.fmt(mod), |
| 26796 | }); | 26804 | }); |
| 26797 | cur = param.child; | 26805 | cur = param.child; |
| 26798 | }, | 26806 | }, |
| ... | @@ -26802,13 +26810,13 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -26802,13 +26810,13 @@ const InMemoryCoercionResult = union(enum) { |
| 26802 | }, | 26810 | }, |
| 26803 | .fn_return_type => |pair| { | 26811 | .fn_return_type => |pair| { |
| 26804 | try sema.errNote(block, src, msg, "return type '{}' cannot cast into return type '{}'", .{ | 26812 | try sema.errNote(block, src, msg, "return type '{}' cannot cast into return type '{}'", .{ |
| 26805 | pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod), | 26813 | pair.actual.fmt(mod), pair.wanted.fmt(mod), |
| 26806 | }); | 26814 | }); |
| 26807 | cur = pair.child; | 26815 | cur = pair.child; |
| 26808 | }, | 26816 | }, |
| 26809 | .ptr_child => |pair| { | 26817 | .ptr_child => |pair| { |
| 26810 | try sema.errNote(block, src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{ | 26818 | try sema.errNote(block, src, msg, "pointer type child '{}' cannot cast into pointer type child '{}'", .{ |
| 26811 | pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod), | 26819 | pair.actual.fmt(mod), pair.wanted.fmt(mod), |
| 26812 | }); | 26820 | }); |
| 26813 | cur = pair.child; | 26821 | cur = pair.child; |
| 26814 | }, | 26822 | }, |
| ... | @@ -26819,11 +26827,11 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -26819,11 +26827,11 @@ const InMemoryCoercionResult = union(enum) { |
| 26819 | .ptr_sentinel => |sentinel| { | 26827 | .ptr_sentinel => |sentinel| { |
| 26820 | if (sentinel.actual.toIntern() != .unreachable_value) { | 26828 | if (sentinel.actual.toIntern() != .unreachable_value) { |
| 26821 | try sema.errNote(block, src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{ | 26829 | try sema.errNote(block, src, msg, "pointer sentinel '{}' cannot cast into pointer sentinel '{}'", .{ |
| 26822 | sentinel.actual.fmtValue(sentinel.ty, sema.mod), sentinel.wanted.fmtValue(sentinel.ty, sema.mod), | 26830 | sentinel.actual.fmtValue(sentinel.ty, mod), sentinel.wanted.fmtValue(sentinel.ty, mod), |
| 26823 | }); | 26831 | }); |
| 26824 | } else { | 26832 | } else { |
| 26825 | try sema.errNote(block, src, msg, "destination pointer requires '{}' sentinel", .{ | 26833 | try sema.errNote(block, src, msg, "destination pointer requires '{}' sentinel", .{ |
| 26826 | sentinel.wanted.fmtValue(sentinel.ty, sema.mod), | 26834 | sentinel.wanted.fmtValue(sentinel.ty, mod), |
| 26827 | }); | 26835 | }); |
| 26828 | } | 26836 | } |
| 26829 | break; | 26837 | break; |
| ... | @@ -26847,11 +26855,11 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -26847,11 +26855,11 @@ const InMemoryCoercionResult = union(enum) { |
| 26847 | const actual_allow_zero = pair.actual.ptrAllowsZero(mod); | 26855 | const actual_allow_zero = pair.actual.ptrAllowsZero(mod); |
| 26848 | if (actual_allow_zero and !wanted_allow_zero) { | 26856 | if (actual_allow_zero and !wanted_allow_zero) { |
| 26849 | try sema.errNote(block, src, msg, "'{}' could have null values which are illegal in type '{}'", .{ | 26857 | try sema.errNote(block, src, msg, "'{}' could have null values which are illegal in type '{}'", .{ |
| 26850 | pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod), | 26858 | pair.actual.fmt(mod), pair.wanted.fmt(mod), |
| 26851 | }); | 26859 | }); |
| 26852 | } else { | 26860 | } else { |
| 26853 | try sema.errNote(block, src, msg, "mutable '{}' allows illegal null values stored to type '{}'", .{ | 26861 | try sema.errNote(block, src, msg, "mutable '{}' allows illegal null values stored to type '{}'", .{ |
| 26854 | pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod), | 26862 | pair.actual.fmt(mod), pair.wanted.fmt(mod), |
| 26855 | }); | 26863 | }); |
| 26856 | } | 26864 | } |
| 26857 | break; | 26865 | break; |
| ... | @@ -26877,13 +26885,13 @@ const InMemoryCoercionResult = union(enum) { | ... | @@ -26877,13 +26885,13 @@ const InMemoryCoercionResult = union(enum) { |
| 26877 | }, | 26885 | }, |
| 26878 | .double_ptr_to_anyopaque => |pair| { | 26886 | .double_ptr_to_anyopaque => |pair| { |
| 26879 | try sema.errNote(block, src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{ | 26887 | try sema.errNote(block, src, msg, "cannot implicitly cast double pointer '{}' to anyopaque pointer '{}'", .{ |
| 26880 | pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod), | 26888 | pair.actual.fmt(mod), pair.wanted.fmt(mod), |
| 26881 | }); | 26889 | }); |
| 26882 | break; | 26890 | break; |
| 26883 | }, | 26891 | }, |
| 26884 | .slice_to_anyopaque => |pair| { | 26892 | .slice_to_anyopaque => |pair| { |
| 26885 | try sema.errNote(block, src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{ | 26893 | try sema.errNote(block, src, msg, "cannot implicitly cast slice '{}' to anyopaque pointer '{}'", .{ |
| 26886 | pair.actual.fmt(sema.mod), pair.wanted.fmt(sema.mod), | 26894 | pair.actual.fmt(mod), pair.wanted.fmt(mod), |
| 26887 | }); | 26895 | }); |
| 26888 | try sema.errNote(block, src, msg, "consider using '.ptr'", .{}); | 26896 | try sema.errNote(block, src, msg, "consider using '.ptr'", .{}); |
| 26889 | break; | 26897 | break; |
| ... | @@ -27616,25 +27624,24 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { | ... | @@ -27616,25 +27624,24 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { |
| 27616 | const mod = sema.mod; | 27624 | const mod = sema.mod; |
| 27617 | const array_ty = sema.typeOf(ptr).childType(mod); | 27625 | const array_ty = sema.typeOf(ptr).childType(mod); |
| 27618 | if (array_ty.zigTypeTag(mod) != .Array) return null; | 27626 | if (array_ty.zigTypeTag(mod) != .Array) return null; |
| 27619 | var ptr_inst = Air.refToIndex(ptr) orelse return null; | 27627 | var ptr_ref = ptr; |
| | 27628 | var ptr_inst = Air.refToIndex(ptr_ref) orelse return null; |
| 27620 | const air_datas = sema.air_instructions.items(.data); | 27629 | const air_datas = sema.air_instructions.items(.data); |
| 27621 | const air_tags = sema.air_instructions.items(.tag); | 27630 | const air_tags = sema.air_instructions.items(.tag); |
| 27622 | const prev_ptr = while (air_tags[ptr_inst] == .bitcast) { | 27631 | const vector_ty = while (air_tags[ptr_inst] == .bitcast) { |
| 27623 | const prev_ptr = air_datas[ptr_inst].ty_op.operand; | 27632 | ptr_ref = air_datas[ptr_inst].ty_op.operand; |
| 27624 | const prev_ptr_ty = sema.typeOf(prev_ptr); | 27633 | if (!sema.isKnownZigType(ptr_ref, .Pointer)) return null; |
| 27625 | if (prev_ptr_ty.zigTypeTag(mod) != .Pointer) return null; | 27634 | const child_ty = sema.typeOf(ptr_ref).childType(mod); |
| 27626 | const prev_ptr_child_ty = prev_ptr_ty.childType(mod); | 27635 | if (child_ty.zigTypeTag(mod) == .Vector) break child_ty; |
| 27627 | if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr; | 27636 | ptr_inst = Air.refToIndex(ptr_ref) orelse return null; |
| 27628 | ptr_inst = Air.refToIndex(prev_ptr) orelse return null; | | |
| 27629 | } else return null; | 27637 | } else return null; |
| 27630 | | 27638 | |
| 27631 | // We have a pointer-to-array and a pointer-to-vector. If the elements and | 27639 | // We have a pointer-to-array and a pointer-to-vector. If the elements and |
| 27632 | // lengths match, return the result. | 27640 | // lengths match, return the result. |
| 27633 | const vector_ty = sema.typeOf(prev_ptr).childType(mod); | | |
| 27634 | if (array_ty.childType(mod).eql(vector_ty.childType(mod), sema.mod) and | 27641 | if (array_ty.childType(mod).eql(vector_ty.childType(mod), sema.mod) and |
| 27635 | array_ty.arrayLen(mod) == vector_ty.vectorLen(mod)) | 27642 | array_ty.arrayLen(mod) == vector_ty.vectorLen(mod)) |
| 27636 | { | 27643 | { |
| 27637 | return prev_ptr; | 27644 | return ptr_ref; |
| 27638 | } else { | 27645 | } else { |
| 27639 | return null; | 27646 | return null; |
| 27640 | } | 27647 | } |
| ... | @@ -34474,3 +34481,12 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool { | ... | @@ -34474,3 +34481,12 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool { |
| 34474 | }; | 34481 | }; |
| 34475 | return sema.typeOf(ref).isNoReturn(sema.mod); | 34482 | return sema.typeOf(ref).isNoReturn(sema.mod); |
| 34476 | } | 34483 | } |
| | 34484 | |
| | 34485 | /// Avoids crashing the compiler when asking if inferred allocations are known to be a certain type. |
| | 34486 | fn isKnownZigType(sema: *Sema, ref: Air.Inst.Ref, tag: std.builtin.TypeId) bool { |
| | 34487 | if (Air.refToIndex(ref)) |inst| switch (sema.air_instructions.items(.tag)[inst]) { |
| | 34488 | .inferred_alloc, .inferred_alloc_comptime => return false, |
| | 34489 | else => {}, |
| | 34490 | }; |
| | 34491 | return sema.typeOf(ref).zigTypeTag(sema.mod) == tag; |
| | 34492 | } |