authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-05-26 18:56:31-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:55-07:00
log1dc01f11401b6ec0be1e7685cdc445d1b10d4f19
treea64c1aa2d0f7f136325971e01ac1ec4ddd79ef13
parent9cd0ca9f482ef7f76d3f3ca683913e9aceaa47fe

InternPool: fix build-exe and compiler-rt crashes


7 files changed, 191 insertions(+), 92 deletions(-)

src/InternPool.zig+83-1
...@@ -2817,6 +2817,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {...@@ -2817,6 +2817,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
2817 },2817 },
2818 .ptr_type => |ptr_type| {2818 .ptr_type => |ptr_type| {
2819 assert(ptr_type.elem_type != .none);2819 assert(ptr_type.elem_type != .none);
2820 assert(ptr_type.sentinel == .none or ip.typeOf(ptr_type.sentinel) == ptr_type.elem_type);
28202821
2821 if (ptr_type.size == .Slice) {2822 if (ptr_type.size == .Slice) {
2822 _ = ip.map.pop();2823 _ = ip.map.pop();
...@@ -4780,7 +4781,88 @@ pub fn stringToSliceUnwrap(ip: InternPool, s: OptionalNullTerminatedString) ?[:0...@@ -4780,7 +4781,88 @@ pub fn stringToSliceUnwrap(ip: InternPool, s: OptionalNullTerminatedString) ?[:0
4780}4781}
47814782
4782pub fn typeOf(ip: InternPool, index: Index) Index {4783pub fn typeOf(ip: InternPool, index: Index) Index {
4783 return ip.indexToKey(index).typeOf();4784 // This optimization of static keys is required so that typeOf can be called
4785 // on static keys that haven't been added yet during static key initialization.
4786 // An alternative would be to topological sort the static keys, but this would
4787 // mean that the range of type indices would not be dense.
4788 return switch (index) {
4789 .u1_type,
4790 .u8_type,
4791 .i8_type,
4792 .u16_type,
4793 .i16_type,
4794 .u29_type,
4795 .u32_type,
4796 .i32_type,
4797 .u64_type,
4798 .i64_type,
4799 .u80_type,
4800 .u128_type,
4801 .i128_type,
4802 .usize_type,
4803 .isize_type,
4804 .c_char_type,
4805 .c_short_type,
4806 .c_ushort_type,
4807 .c_int_type,
4808 .c_uint_type,
4809 .c_long_type,
4810 .c_ulong_type,
4811 .c_longlong_type,
4812 .c_ulonglong_type,
4813 .c_longdouble_type,
4814 .f16_type,
4815 .f32_type,
4816 .f64_type,
4817 .f80_type,
4818 .f128_type,
4819 .anyopaque_type,
4820 .bool_type,
4821 .void_type,
4822 .type_type,
4823 .anyerror_type,
4824 .comptime_int_type,
4825 .comptime_float_type,
4826 .noreturn_type,
4827 .anyframe_type,
4828 .null_type,
4829 .undefined_type,
4830 .enum_literal_type,
4831 .atomic_order_type,
4832 .atomic_rmw_op_type,
4833 .calling_convention_type,
4834 .address_space_type,
4835 .float_mode_type,
4836 .reduce_op_type,
4837 .call_modifier_type,
4838 .prefetch_options_type,
4839 .export_options_type,
4840 .extern_options_type,
4841 .type_info_type,
4842 .manyptr_u8_type,
4843 .manyptr_const_u8_type,
4844 .manyptr_const_u8_sentinel_0_type,
4845 .single_const_pointer_to_comptime_int_type,
4846 .slice_const_u8_type,
4847 .slice_const_u8_sentinel_0_type,
4848 .anyerror_void_error_union_type,
4849 .generic_poison_type,
4850 .empty_struct_type,
4851 => .type_type,
4852 .undef => .undefined_type,
4853 .zero, .one, .negative_one => .comptime_int_type,
4854 .zero_usize, .one_usize => .usize_type,
4855 .zero_u8, .one_u8, .four_u8 => .u8_type,
4856 .calling_convention_c, .calling_convention_inline => .calling_convention_type,
4857 .void_value => .void_type,
4858 .unreachable_value => .noreturn_type,
4859 .null_value => .null_type,
4860 .bool_true, .bool_false => .bool_type,
4861 .empty_struct => .empty_struct_type,
4862 .generic_poison => .generic_poison_type,
4863 .var_args_param_type, .none => unreachable,
4864 _ => ip.indexToKey(index).typeOf(),
4865 };
4784}4866}
47854867
4786/// Assumes that the enum's field indexes equal its value tags.4868/// Assumes that the enum's field indexes equal its value tags.
src/Module.zig-4
...@@ -6898,10 +6898,6 @@ pub fn enumValueFieldIndex(mod: *Module, ty: Type, field_index: u32) Allocator.E...@@ -6898,10 +6898,6 @@ pub fn enumValueFieldIndex(mod: *Module, ty: Type, field_index: u32) Allocator.E
6898}6898}
68996899
6900pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {6900pub fn intValue(mod: *Module, ty: Type, x: anytype) Allocator.Error!Value {
6901 if (std.debug.runtime_safety) {
6902 const tag = ty.zigTypeTag(mod);
6903 assert(tag == .Int or tag == .ComptimeInt);
6904 }
6905 if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted);6901 if (std.math.cast(u64, x)) |casted| return intValue_u64(mod, ty, casted);
6906 if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted);6902 if (std.math.cast(i64, x)) |casted| return intValue_i64(mod, ty, casted);
6907 var limbs_buffer: [4]usize = undefined;6903 var limbs_buffer: [4]usize = undefined;
src/Sema.zig+92-76
...@@ -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 and855 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);
96789677
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
1079110790
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 {
1164711646
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);
1165211651
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);
1245612455
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);
1352113520
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 }
1380713806
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);
1381113810
...@@ -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 else13882 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);
1457714576
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);
1457914579
14580 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;14580 const is_int = scalar_tag == .Int or scalar_tag == .ComptimeInt;
1458114581
...@@ -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}
1882218830
18823fn zirFrame(18831fn 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(
2244822456
22449 // Compute the final bounds based on the runtime type and the comptime-known bound type22457 // 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) >= ct22460 .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(
2599626004
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 or26125 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;
2612026128
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 }
2617026178
...@@ -26190,7 +26198,7 @@ fn coerceExtra(...@@ -26190,7 +26198,7 @@ fn coerceExtra(
26190 // pointer to tuple to slice26198 // 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 }
2621926227
26220 if (dest_info.sentinel == null or inst_info.sentinel == null or26228 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;
2622326231
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 number26266 // 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 error26341 // 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 type26384 // 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);
2649926507
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 }
2650726515
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);
2651126519
26512 // E!T to T26520 // 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);
2652926537
26530 // Add notes about function return type26538 // 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 }
2654026548
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 }
2654426552
26545 // TODO maybe add "cannot store an error in type '{}'" note26553 // 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;
2763027638
27631 // We have a pointer-to-array and a pointer-to-vector. If the elements and27639 // 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) and27641 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.
34486fn 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}
src/arch/x86_64/CodeGen.zig+1-1
...@@ -4895,7 +4895,7 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {...@@ -4895,7 +4895,7 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void {
4895 });4895 });
48964896
4897 const sign_val = switch (tag) {4897 const sign_val = switch (tag) {
4898 .neg => try vec_ty.minInt(mod),4898 .neg => try vec_ty.minInt(mod, vec_ty),
4899 .fabs => try vec_ty.maxInt(mod, vec_ty),4899 .fabs => try vec_ty.maxInt(mod, vec_ty),
4900 else => unreachable,4900 else => unreachable,
4901 };4901 };
src/codegen/c.zig+1-1
...@@ -6723,7 +6723,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {...@@ -6723,7 +6723,7 @@ fn airReduce(f: *Function, inst: Air.Inst.Index) !CValue {
6723 },6723 },
6724 .Max => switch (scalar_ty.zigTypeTag(mod)) {6724 .Max => switch (scalar_ty.zigTypeTag(mod)) {
6725 .Bool => try mod.intValue(scalar_ty, 0),6725 .Bool => try mod.intValue(scalar_ty, 0),
6726 .Int => try scalar_ty.minInt(mod),6726 .Int => try scalar_ty.minInt(mod, scalar_ty),
6727 .Float => try mod.floatValue(scalar_ty, std.math.nan_f128),6727 .Float => try mod.floatValue(scalar_ty, std.math.nan_f128),
6728 else => unreachable,6728 else => unreachable,
6729 },6729 },
src/type.zig+9-9
...@@ -2865,23 +2865,23 @@ pub const Type = struct {...@@ -2865,23 +2865,23 @@ pub const Type = struct {
2865 }2865 }
28662866
2867 // Works for vectors and vectors of integers.2867 // Works for vectors and vectors of integers.
2868 pub fn minInt(ty: Type, mod: *Module) !Value {2868 pub fn minInt(ty: Type, mod: *Module, dest_ty: Type) !Value {
2869 const scalar = try minIntScalar(ty.scalarType(mod), mod);2869 const scalar = try minIntScalar(ty.scalarType(mod), mod, dest_ty);
2870 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{2870 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{
2871 .ty = ty.toIntern(),2871 .ty = dest_ty.toIntern(),
2872 .storage = .{ .repeated_elem = scalar.toIntern() },2872 .storage = .{ .repeated_elem = scalar.toIntern() },
2873 } })).toValue() else scalar;2873 } })).toValue() else scalar;
2874 }2874 }
28752875
2876 /// Asserts that the type is an integer.2876 /// Asserts that the type is an integer.
2877 pub fn minIntScalar(ty: Type, mod: *Module) !Value {2877 pub fn minIntScalar(ty: Type, mod: *Module, dest_ty: Type) !Value {
2878 const info = ty.intInfo(mod);2878 const info = ty.intInfo(mod);
2879 if (info.signedness == .unsigned) return mod.intValue(ty, 0);2879 if (info.signedness == .unsigned) return mod.intValue(dest_ty, 0);
2880 if (info.bits == 0) return mod.intValue(ty, -1);2880 if (info.bits == 0) return mod.intValue(dest_ty, -1);
28812881
2882 if (std.math.cast(u6, info.bits - 1)) |shift| {2882 if (std.math.cast(u6, info.bits - 1)) |shift| {
2883 const n = @as(i64, std.math.minInt(i64)) >> (63 - shift);2883 const n = @as(i64, std.math.minInt(i64)) >> (63 - shift);
2884 return mod.intValue(Type.comptime_int, n);2884 return mod.intValue(dest_ty, n);
2885 }2885 }
28862886
2887 var res = try std.math.big.int.Managed.init(mod.gpa);2887 var res = try std.math.big.int.Managed.init(mod.gpa);
...@@ -2889,7 +2889,7 @@ pub const Type = struct {...@@ -2889,7 +2889,7 @@ pub const Type = struct {
28892889
2890 try res.setTwosCompIntLimit(.min, info.signedness, info.bits);2890 try res.setTwosCompIntLimit(.min, info.signedness, info.bits);
28912891
2892 return mod.intValue_big(Type.comptime_int, res.toConst());2892 return mod.intValue_big(dest_ty, res.toConst());
2893 }2893 }
28942894
2895 // Works for vectors and vectors of integers.2895 // Works for vectors and vectors of integers.
...@@ -2897,7 +2897,7 @@ pub const Type = struct {...@@ -2897,7 +2897,7 @@ pub const Type = struct {
2897 pub fn maxInt(ty: Type, mod: *Module, dest_ty: Type) !Value {2897 pub fn maxInt(ty: Type, mod: *Module, dest_ty: Type) !Value {
2898 const scalar = try maxIntScalar(ty.scalarType(mod), mod, dest_ty);2898 const scalar = try maxIntScalar(ty.scalarType(mod), mod, dest_ty);
2899 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{2899 return if (ty.zigTypeTag(mod) == .Vector) (try mod.intern(.{ .aggregate = .{
2900 .ty = ty.toIntern(),2900 .ty = dest_ty.toIntern(),
2901 .storage = .{ .repeated_elem = scalar.toIntern() },2901 .storage = .{ .repeated_elem = scalar.toIntern() },
2902 } })).toValue() else scalar;2902 } })).toValue() else scalar;
2903 }2903 }
src/value.zig+5
...@@ -3166,6 +3166,11 @@ pub const Value = struct {...@@ -3166,6 +3166,11 @@ pub const Value = struct {
3166 .len = undefined,3166 .len = undefined,
3167 };3167 };
3168 result_bigint.shiftLeft(lhs_bigint, shift);3168 result_bigint.shiftLeft(lhs_bigint, shift);
3169 if (ty.toIntern() != .comptime_int_type) {
3170 const int_info = ty.intInfo(mod);
3171 result_bigint.truncate(result_bigint.toConst(), int_info.signedness, int_info.bits);
3172 }
3173
3169 return mod.intValue_big(ty, result_bigint.toConst());3174 return mod.intValue_big(ty, result_bigint.toConst());
3170 }3175 }
31713176