| ... | ... | @@ -848,13 +848,12 @@ pub fn analyzeBodyBreak( |
| 848 | 848 | block: *Block, |
| 849 | 849 | body: []const Zir.Inst.Index, |
| 850 | 850 | ) CompileError!?BreakData { |
| 851 | | const mod = sema.mod; |
| 852 | 851 | const break_inst = sema.analyzeBodyInner(block, body) catch |err| switch (err) { |
| 853 | 852 | error.ComptimeBreak => sema.comptime_break_inst, |
| 854 | 853 | else => |e| return e, |
| 855 | 854 | }; |
| 856 | 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 | 857 | return null; |
| 859 | 858 | const break_data = sema.code.instructions.items(.data)[break_inst].@"break"; |
| 860 | 859 | const extra = sema.code.extraData(Zir.Inst.Break, break_data.payload_index).data; |
| ... | ... | @@ -9671,9 +9670,9 @@ fn intCast( |
| 9671 | 9670 | // range to account for negative values. |
| 9672 | 9671 | const dest_range_val = if (wanted_info.signedness == .signed) range_val: { |
| 9673 | 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 | 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 | 9676 | const dest_range = try sema.addConstant(unsigned_operand_ty, dest_range_val); |
| 9678 | 9677 | |
| 9679 | 9678 | const ok = if (is_vector) ok: { |
| ... | ... | @@ -10791,7 +10790,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError |
| 10791 | 10790 | |
| 10792 | 10791 | check_range: { |
| 10793 | 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 | 10794 | const max_int = try operand_ty.maxInt(mod, operand_ty); |
| 10796 | 10795 | if (try range_set.spans(min_int, max_int, operand_ty)) { |
| 10797 | 10796 | if (special_prong == .@"else") { |
| ... | ... | @@ -11647,7 +11646,7 @@ const RangeSetUnhandledIterator = struct { |
| 11647 | 11646 | |
| 11648 | 11647 | fn init(sema: *Sema, ty: Type, range_set: RangeSet) !RangeSetUnhandledIterator { |
| 11649 | 11648 | const mod = sema.mod; |
| 11650 | | const min = try ty.minInt(mod); |
| 11649 | const min = try ty.minInt(mod, ty); |
| 11651 | 11650 | const max = try ty.maxInt(mod, ty); |
| 11652 | 11651 | |
| 11653 | 11652 | return RangeSetUnhandledIterator{ |
| ... | ... | @@ -12452,7 +12451,7 @@ fn zirShr( |
| 12452 | 12451 | if (block.wantSafety()) { |
| 12453 | 12452 | const bit_count = scalar_ty.intInfo(mod).bits; |
| 12454 | 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 | 12456 | const ok = if (rhs_ty.zigTypeTag(mod) == .Vector) ok: { |
| 12458 | 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 | 13296 | if (!lhs_val.isUndef(mod)) { |
| 13298 | 13297 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13299 | 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 | 13300 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13302 | 13301 | else => unreachable, |
| 13303 | 13302 | }; |
| ... | ... | @@ -13437,7 +13436,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13437 | 13436 | } else { |
| 13438 | 13437 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13439 | 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 | 13440 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13442 | 13441 | else => unreachable, |
| 13443 | 13442 | }; |
| ... | ... | @@ -13520,7 +13519,7 @@ fn zirDivExact(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13520 | 13519 | const remainder = try block.addBinOp(.rem, casted_lhs, casted_rhs); |
| 13521 | 13520 | |
| 13522 | 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 | 13523 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13525 | 13524 | else => unreachable, |
| 13526 | 13525 | }; |
| ... | ... | @@ -13608,7 +13607,7 @@ fn zirDivFloor(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13608 | 13607 | if (!lhs_val.isUndef(mod)) { |
| 13609 | 13608 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13610 | 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 | 13611 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13613 | 13612 | else => unreachable, |
| 13614 | 13613 | }; |
| ... | ... | @@ -13725,7 +13724,7 @@ fn zirDivTrunc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13725 | 13724 | if (!lhs_val.isUndef(mod)) { |
| 13726 | 13725 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13727 | 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 | 13728 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13730 | 13729 | else => unreachable, |
| 13731 | 13730 | }; |
| ... | ... | @@ -13805,7 +13804,7 @@ fn addDivIntOverflowSafety( |
| 13805 | 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 | 13808 | const neg_one_scalar = try mod.intValue(lhs_scalar_ty, -1); |
| 13810 | 13809 | const neg_one = try sema.splat(resolved_type, neg_one_scalar); |
| 13811 | 13810 | |
| ... | ... | @@ -13881,7 +13880,7 @@ fn addDivByZeroSafety( |
| 13881 | 13880 | const scalar_zero = if (is_int) |
| 13882 | 13881 | try mod.intValue(resolved_type.scalarType(mod), 0) |
| 13883 | 13882 | else |
| 13884 | | try mod.floatValue(resolved_type.scalarType(mod), 0); |
| 13883 | try mod.floatValue(resolved_type.scalarType(mod), 0.0); |
| 13885 | 13884 | const ok = if (resolved_type.zigTypeTag(mod) == .Vector) ok: { |
| 13886 | 13885 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 13887 | 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 | 13966 | } |
| 13968 | 13967 | if (try lhs_val.compareAllWithZeroAdvanced(.eq, sema)) { |
| 13969 | 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 | 13970 | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 13972 | 13971 | else => unreachable, |
| 13973 | 13972 | }; |
| ... | ... | @@ -14575,7 +14574,8 @@ fn analyzeArithmetic( |
| 14575 | 14574 | const casted_lhs = try sema.coerce(block, resolved_type, lhs, lhs_src); |
| 14576 | 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 | 14580 | const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt; |
| 14581 | 14581 | |
| ... | ... | @@ -14797,8 +14797,13 @@ fn analyzeArithmetic( |
| 14797 | 14797 | // the result is nan. |
| 14798 | 14798 | // If either of the operands are nan, the result is nan. |
| 14799 | 14799 | const scalar_zero = switch (scalar_tag) { |
| 14800 | | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), |
| 14801 | | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 14800 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.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 | 14807 | else => unreachable, |
| 14803 | 14808 | }; |
| 14804 | 14809 | if (maybe_lhs_val) |lhs_val| { |
| ... | ... | @@ -14823,7 +14828,7 @@ fn analyzeArithmetic( |
| 14823 | 14828 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 14824 | 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 | 14832 | return casted_rhs; |
| 14828 | 14833 | } |
| 14829 | 14834 | } |
| ... | ... | @@ -14854,7 +14859,7 @@ fn analyzeArithmetic( |
| 14854 | 14859 | const zero_val = try sema.splat(resolved_type, scalar_zero); |
| 14855 | 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 | 14863 | return casted_lhs; |
| 14859 | 14864 | } |
| 14860 | 14865 | if (maybe_lhs_val) |lhs_val| { |
| ... | ... | @@ -14887,8 +14892,8 @@ fn analyzeArithmetic( |
| 14887 | 14892 | // If either of the operands are one, result is the other operand. |
| 14888 | 14893 | // If either of the operands are undefined, result is undefined. |
| 14889 | 14894 | const scalar_zero = switch (scalar_tag) { |
| 14890 | | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), |
| 14891 | | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 14895 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0), |
| 14896 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 0), |
| 14892 | 14897 | else => unreachable, |
| 14893 | 14898 | }; |
| 14894 | 14899 | if (maybe_lhs_val) |lhs_val| { |
| ... | ... | @@ -14931,8 +14936,8 @@ fn analyzeArithmetic( |
| 14931 | 14936 | // If either of the operands are one, result is the other operand. |
| 14932 | 14937 | // If either of the operands are undefined, result is undefined. |
| 14933 | 14938 | const scalar_zero = switch (scalar_tag) { |
| 14934 | | .ComptimeFloat, .Float => try mod.floatValue(resolved_type.scalarType(mod), 0), |
| 14935 | | .ComptimeInt, .Int => try mod.intValue(resolved_type.scalarType(mod), 0), |
| 14939 | .ComptimeFloat, .Float => try mod.floatValue(scalar_type, 0.0), |
| 14940 | .ComptimeInt, .Int => try mod.intValue(scalar_type, 0), |
| 14936 | 14941 | else => unreachable, |
| 14937 | 14942 | }; |
| 14938 | 14943 | if (maybe_lhs_val) |lhs_val| { |
| ... | ... | @@ -18817,7 +18822,10 @@ fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { |
| 18817 | 18822 | { |
| 18818 | 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 | 18831 | fn zirFrame( |
| ... | ... | @@ -20103,8 +20111,8 @@ fn zirFloatToInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! |
| 20103 | 20111 | if (block.wantSafety()) { |
| 20104 | 20112 | const back = try block.addTyOp(.int_to_float, operand_ty, result); |
| 20105 | 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))); |
| 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))); |
| 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))); |
| 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 | 20116 | const ok = try block.addBinOp(.bool_and, ok_pos, ok_neg); |
| 20109 | 20117 | try sema.addSafetyCheck(block, ok, .integer_part_out_of_bounds); |
| 20110 | 20118 | } |
| ... | ... | @@ -22448,8 +22456,8 @@ fn analyzeMinMax( |
| 22448 | 22456 | |
| 22449 | 22457 | // Compute the final bounds based on the runtime type and the comptime-known bound type |
| 22450 | 22458 | const min_val = switch (air_tag) { |
| 22451 | | .min => try unrefined_elem_ty.minInt(mod), |
| 22452 | | .max => try comptime_elem_ty.minInt(mod), // @max(ct, rt) >= ct |
| 22459 | .min => try unrefined_elem_ty.minInt(mod, unrefined_elem_ty), |
| 22460 | .max => try comptime_elem_ty.minInt(mod, comptime_elem_ty), // @max(ct, rt) >= ct |
| 22453 | 22461 | else => unreachable, |
| 22454 | 22462 | }; |
| 22455 | 22463 | const max_val = switch (air_tag) { |
| ... | ... | @@ -25996,7 +26004,7 @@ fn coerceExtra( |
| 25996 | 26004 | |
| 25997 | 26005 | if (dest_info.sentinel) |dest_sent| { |
| 25998 | 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 | 26008 | in_memory_result = .{ .ptr_sentinel = .{ |
| 26001 | 26009 | .actual = inst_sent, |
| 26002 | 26010 | .wanted = dest_sent, |
| ... | ... | @@ -26115,7 +26123,7 @@ fn coerceExtra( |
| 26115 | 26123 | if (inst_info.size == .Slice) { |
| 26116 | 26124 | assert(dest_info.sentinel == null); |
| 26117 | 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 | 26127 | break :p; |
| 26120 | 26128 | |
| 26121 | 26129 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); |
| ... | ... | @@ -26164,7 +26172,7 @@ fn coerceExtra( |
| 26164 | 26172 | block, |
| 26165 | 26173 | inst_src, |
| 26166 | 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 | 26198 | // pointer to tuple to slice |
| 26191 | 26199 | if (dest_info.mutable) { |
| 26192 | 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 | 26202 | errdefer err_msg.deinit(sema.gpa); |
| 26195 | 26203 | try sema.errNote(block, dest_ty_src, err_msg, "pointers to tuples can only coerce to constant pointers", .{}); |
| 26196 | 26204 | break :err_msg err_msg; |
| ... | ... | @@ -26218,7 +26226,7 @@ fn coerceExtra( |
| 26218 | 26226 | } |
| 26219 | 26227 | |
| 26220 | 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 | 26230 | break :p; |
| 26223 | 26231 | |
| 26224 | 26232 | const slice_ptr = try sema.analyzeSlicePtr(block, inst_src, inst, inst_ty); |
| ... | ... | @@ -26244,7 +26252,7 @@ fn coerceExtra( |
| 26244 | 26252 | block, |
| 26245 | 26253 | inst_src, |
| 26246 | 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 | 26258 | const result_val = try sema.floatToInt(block, inst_src, val, inst_ty, dest_ty); |
| ... | ... | @@ -26258,7 +26266,7 @@ fn coerceExtra( |
| 26258 | 26266 | // comptime-known integer to other number |
| 26259 | 26267 | if (!(try sema.intFitsInType(val, dest_ty, null))) { |
| 26260 | 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 | 26271 | return try sema.addConstant(dest_ty, try mod.getCoerced(val, dest_ty)); |
| 26264 | 26272 | } |
| ... | ... | @@ -26296,12 +26304,12 @@ fn coerceExtra( |
| 26296 | 26304 | } |
| 26297 | 26305 | if (try sema.resolveMaybeUndefVal(inst)) |val| { |
| 26298 | 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 | 26308 | return sema.fail( |
| 26301 | 26309 | block, |
| 26302 | 26310 | inst_src, |
| 26303 | 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 | 26315 | return try sema.addConstant(dest_ty, result_val); |
| ... | ... | @@ -26329,7 +26337,7 @@ fn coerceExtra( |
| 26329 | 26337 | } |
| 26330 | 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 | 26341 | // TODO implement this compile error |
| 26334 | 26342 | //const int_again_val = try result_val.floatToInt(sema.arena, inst_ty); |
| 26335 | 26343 | //if (!int_again_val.eql(val, inst_ty, mod)) { |
| ... | ... | @@ -26337,7 +26345,7 @@ fn coerceExtra( |
| 26337 | 26345 | // block, |
| 26338 | 26346 | // inst_src, |
| 26339 | 26347 | // "type '{}' cannot represent integer value '{}'", |
| 26340 | | // .{ dest_ty.fmt(sema.mod), val }, |
| 26348 | // .{ dest_ty.fmt(mod), val }, |
| 26341 | 26349 | // ); |
| 26342 | 26350 | //} |
| 26343 | 26351 | return try sema.addConstant(dest_ty, result_val); |
| ... | ... | @@ -26359,7 +26367,7 @@ fn coerceExtra( |
| 26359 | 26367 | block, |
| 26360 | 26368 | inst_src, |
| 26361 | 26369 | "no field named '{s}' in enum '{}'", |
| 26362 | | .{ bytes, dest_ty.fmt(sema.mod) }, |
| 26370 | .{ bytes, dest_ty.fmt(mod) }, |
| 26363 | 26371 | ); |
| 26364 | 26372 | errdefer msg.destroy(sema.gpa); |
| 26365 | 26373 | try sema.addDeclaredHereNote(msg, dest_ty); |
| ... | ... | @@ -26375,7 +26383,7 @@ fn coerceExtra( |
| 26375 | 26383 | .Union => blk: { |
| 26376 | 26384 | // union to its own tag type |
| 26377 | 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 | 26387 | return sema.unionToTag(block, dest_ty, inst, inst_src); |
| 26380 | 26388 | } |
| 26381 | 26389 | }, |
| ... | ... | @@ -26498,15 +26506,15 @@ fn coerceExtra( |
| 26498 | 26506 | errdefer msg.destroy(sema.gpa); |
| 26499 | 26507 | |
| 26500 | 26508 | const ret_ty_src: LazySrcLoc = .{ .node_offset_fn_type_ret_ty = 0 }; |
| 26501 | | const src_decl = sema.mod.declPtr(sema.func.?.owner_decl); |
| 26502 | | try sema.mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "'noreturn' declared here", .{}); |
| 26509 | const src_decl = mod.declPtr(sema.func.?.owner_decl); |
| 26510 | try mod.errNoteNonLazy(ret_ty_src.toSrcLoc(src_decl, mod), msg, "'noreturn' declared here", .{}); |
| 26503 | 26511 | break :msg msg; |
| 26504 | 26512 | }; |
| 26505 | 26513 | return sema.failWithOwnedErrorMsg(msg); |
| 26506 | 26514 | } |
| 26507 | 26515 | |
| 26508 | 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 | 26518 | errdefer msg.destroy(sema.gpa); |
| 26511 | 26519 | |
| 26512 | 26520 | // E!T to T |
| ... | ... | @@ -26528,18 +26536,18 @@ fn coerceExtra( |
| 26528 | 26536 | try in_memory_result.report(sema, block, inst_src, msg); |
| 26529 | 26537 | |
| 26530 | 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 | 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 | 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 | 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 | 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 | 26553 | // TODO maybe add "cannot store an error in type '{}'" note |
| ... | ... | @@ -26679,7 +26687,7 @@ const InMemoryCoercionResult = union(enum) { |
| 26679 | 26687 | }, |
| 26680 | 26688 | .error_union_payload => |pair| { |
| 26681 | 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 | 26692 | cur = pair.child; |
| 26685 | 26693 | }, |
| ... | ... | @@ -26692,18 +26700,18 @@ const InMemoryCoercionResult = union(enum) { |
| 26692 | 26700 | .array_sentinel => |sentinel| { |
| 26693 | 26701 | if (sentinel.actual.toIntern() != .unreachable_value) { |
| 26694 | 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 | 26705 | } else { |
| 26698 | 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 | 26710 | break; |
| 26703 | 26711 | }, |
| 26704 | 26712 | .array_elem => |pair| { |
| 26705 | 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 | 26716 | cur = pair.child; |
| 26709 | 26717 | }, |
| ... | ... | @@ -26715,19 +26723,19 @@ const InMemoryCoercionResult = union(enum) { |
| 26715 | 26723 | }, |
| 26716 | 26724 | .vector_elem => |pair| { |
| 26717 | 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 | 26728 | cur = pair.child; |
| 26721 | 26729 | }, |
| 26722 | 26730 | .optional_shape => |pair| { |
| 26723 | 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 | 26734 | break; |
| 26727 | 26735 | }, |
| 26728 | 26736 | .optional_child => |pair| { |
| 26729 | 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 | 26740 | cur = pair.child; |
| 26733 | 26741 | }, |
| ... | ... | @@ -26792,7 +26800,7 @@ const InMemoryCoercionResult = union(enum) { |
| 26792 | 26800 | }, |
| 26793 | 26801 | .fn_param => |param| { |
| 26794 | 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 | 26805 | cur = param.child; |
| 26798 | 26806 | }, |
| ... | ... | @@ -26802,13 +26810,13 @@ const InMemoryCoercionResult = union(enum) { |
| 26802 | 26810 | }, |
| 26803 | 26811 | .fn_return_type => |pair| { |
| 26804 | 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 | 26815 | cur = pair.child; |
| 26808 | 26816 | }, |
| 26809 | 26817 | .ptr_child => |pair| { |
| 26810 | 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 | 26821 | cur = pair.child; |
| 26814 | 26822 | }, |
| ... | ... | @@ -26819,11 +26827,11 @@ const InMemoryCoercionResult = union(enum) { |
| 26819 | 26827 | .ptr_sentinel => |sentinel| { |
| 26820 | 26828 | if (sentinel.actual.toIntern() != .unreachable_value) { |
| 26821 | 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 | 26832 | } else { |
| 26825 | 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 | 26837 | break; |
| ... | ... | @@ -26847,11 +26855,11 @@ const InMemoryCoercionResult = union(enum) { |
| 26847 | 26855 | const actual_allow_zero = pair.actual.ptrAllowsZero(mod); |
| 26848 | 26856 | if (actual_allow_zero and !wanted_allow_zero) { |
| 26849 | 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 | 26860 | } else { |
| 26853 | 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 | 26865 | break; |
| ... | ... | @@ -26877,13 +26885,13 @@ const InMemoryCoercionResult = union(enum) { |
| 26877 | 26885 | }, |
| 26878 | 26886 | .double_ptr_to_anyopaque => |pair| { |
| 26879 | 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 | 26890 | break; |
| 26883 | 26891 | }, |
| 26884 | 26892 | .slice_to_anyopaque => |pair| { |
| 26885 | 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 | 26896 | try sema.errNote(block, src, msg, "consider using '.ptr'", .{}); |
| 26889 | 26897 | break; |
| ... | ... | @@ -27616,25 +27624,24 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { |
| 27616 | 27624 | const mod = sema.mod; |
| 27617 | 27625 | const array_ty = sema.typeOf(ptr).childType(mod); |
| 27618 | 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 | 27629 | const air_datas = sema.air_instructions.items(.data); |
| 27621 | 27630 | const air_tags = sema.air_instructions.items(.tag); |
| 27622 | | const prev_ptr = while (air_tags[ptr_inst] == .bitcast) { |
| 27623 | | const prev_ptr = air_datas[ptr_inst].ty_op.operand; |
| 27624 | | const prev_ptr_ty = sema.typeOf(prev_ptr); |
| 27625 | | if (prev_ptr_ty.zigTypeTag(mod) != .Pointer) return null; |
| 27626 | | const prev_ptr_child_ty = prev_ptr_ty.childType(mod); |
| 27627 | | if (prev_ptr_child_ty.zigTypeTag(mod) == .Vector) break prev_ptr; |
| 27628 | | ptr_inst = Air.refToIndex(prev_ptr) orelse return null; |
| 27631 | const vector_ty = while (air_tags[ptr_inst] == .bitcast) { |
| 27632 | ptr_ref = air_datas[ptr_inst].ty_op.operand; |
| 27633 | if (!sema.isKnownZigType(ptr_ref, .Pointer)) return null; |
| 27634 | const child_ty = sema.typeOf(ptr_ref).childType(mod); |
| 27635 | if (child_ty.zigTypeTag(mod) == .Vector) break child_ty; |
| 27636 | ptr_inst = Air.refToIndex(ptr_ref) orelse return null; |
| 27629 | 27637 | } else return null; |
| 27630 | 27638 | |
| 27631 | 27639 | // We have a pointer-to-array and a pointer-to-vector. If the elements and |
| 27632 | 27640 | // lengths match, return the result. |
| 27633 | | const vector_ty = sema.typeOf(prev_ptr).childType(mod); |
| 27634 | 27641 | if (array_ty.childType(mod).eql(vector_ty.childType(mod), sema.mod) and |
| 27635 | 27642 | array_ty.arrayLen(mod) == vector_ty.vectorLen(mod)) |
| 27636 | 27643 | { |
| 27637 | | return prev_ptr; |
| 27644 | return ptr_ref; |
| 27638 | 27645 | } else { |
| 27639 | 27646 | return null; |
| 27640 | 27647 | } |
| ... | ... | @@ -34474,3 +34481,12 @@ fn isNoReturn(sema: *Sema, ref: Air.Inst.Ref) bool { |
| 34474 | 34481 | }; |
| 34475 | 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 | } |