| ... | ... | @@ -13565,8 +13565,6 @@ fn analyzeTupleCat( |
| 13565 | 13565 | const lhs_ty = sema.typeOf(lhs); |
| 13566 | 13566 | const rhs_ty = sema.typeOf(rhs); |
| 13567 | 13567 | const src = LazySrcLoc.nodeOffset(src_node); |
| 13568 | | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = src_node }; |
| 13569 | | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node }; |
| 13570 | 13568 | |
| 13571 | 13569 | const lhs_len = lhs_ty.structFieldCount(mod); |
| 13572 | 13570 | const rhs_len = rhs_ty.structFieldCount(mod); |
| ... | ... | @@ -13581,7 +13579,7 @@ fn analyzeTupleCat( |
| 13581 | 13579 | if (rhs_len == 0) { |
| 13582 | 13580 | return lhs; |
| 13583 | 13581 | } |
| 13584 | | const final_len = try sema.usizeCast(block, rhs_src, dest_fields); |
| 13582 | const final_len = try sema.usizeCast(block, src, dest_fields); |
| 13585 | 13583 | |
| 13586 | 13584 | const types = try sema.arena.alloc(InternPool.Index, final_len); |
| 13587 | 13585 | const values = try sema.arena.alloc(InternPool.Index, final_len); |
| ... | ... | @@ -13593,7 +13591,10 @@ fn analyzeTupleCat( |
| 13593 | 13591 | types[i] = lhs_ty.structFieldType(i, mod).toIntern(); |
| 13594 | 13592 | const default_val = lhs_ty.structFieldDefaultValue(i, mod); |
| 13595 | 13593 | values[i] = default_val.toIntern(); |
| 13596 | | const operand_src = lhs_src; // TODO better source location |
| 13594 | const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{ |
| 13595 | .array_cat_offset = src_node, |
| 13596 | .elem_index = i, |
| 13597 | } }; |
| 13597 | 13598 | if (default_val.toIntern() == .unreachable_value) { |
| 13598 | 13599 | runtime_src = operand_src; |
| 13599 | 13600 | values[i] = .none; |
| ... | ... | @@ -13604,7 +13605,10 @@ fn analyzeTupleCat( |
| 13604 | 13605 | types[i + lhs_len] = rhs_ty.structFieldType(i, mod).toIntern(); |
| 13605 | 13606 | const default_val = rhs_ty.structFieldDefaultValue(i, mod); |
| 13606 | 13607 | values[i + lhs_len] = default_val.toIntern(); |
| 13607 | | const operand_src = rhs_src; // TODO better source location |
| 13608 | const operand_src: LazySrcLoc = .{ .array_cat_rhs = .{ |
| 13609 | .array_cat_offset = src_node, |
| 13610 | .elem_index = i, |
| 13611 | } }; |
| 13608 | 13612 | if (default_val.toIntern() == .unreachable_value) { |
| 13609 | 13613 | runtime_src = operand_src; |
| 13610 | 13614 | values[i + lhs_len] = .none; |
| ... | ... | @@ -13632,12 +13636,18 @@ fn analyzeTupleCat( |
| 13632 | 13636 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len); |
| 13633 | 13637 | var i: u32 = 0; |
| 13634 | 13638 | while (i < lhs_len) : (i += 1) { |
| 13635 | | const operand_src = lhs_src; // TODO better source location |
| 13639 | const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{ |
| 13640 | .array_cat_offset = src_node, |
| 13641 | .elem_index = i, |
| 13642 | } }; |
| 13636 | 13643 | element_refs[i] = try sema.tupleFieldValByIndex(block, operand_src, lhs, i, lhs_ty); |
| 13637 | 13644 | } |
| 13638 | 13645 | i = 0; |
| 13639 | 13646 | while (i < rhs_len) : (i += 1) { |
| 13640 | | const operand_src = rhs_src; // TODO better source location |
| 13647 | const operand_src: LazySrcLoc = .{ .array_cat_rhs = .{ |
| 13648 | .array_cat_offset = src_node, |
| 13649 | .elem_index = i, |
| 13650 | } }; |
| 13641 | 13651 | element_refs[i + lhs_len] = |
| 13642 | 13652 | try sema.tupleFieldValByIndex(block, operand_src, rhs, i, rhs_ty); |
| 13643 | 13653 | } |
| ... | ... | @@ -13700,12 +13710,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13700 | 13710 | const rhs_sent = Air.internedToRef(rhs_sent_val.toIntern()); |
| 13701 | 13711 | const lhs_sent_casted = try sema.coerce(block, resolved_elem_ty, lhs_sent, lhs_src); |
| 13702 | 13712 | const rhs_sent_casted = try sema.coerce(block, resolved_elem_ty, rhs_sent, rhs_src); |
| 13703 | | const lhs_sent_casted_val = try sema.resolveConstDefinedValue(block, lhs_src, lhs_sent_casted, .{ |
| 13704 | | .needed_comptime_reason = "array sentinel value must be comptime-known", |
| 13705 | | }); |
| 13706 | | const rhs_sent_casted_val = try sema.resolveConstDefinedValue(block, rhs_src, rhs_sent_casted, .{ |
| 13707 | | .needed_comptime_reason = "array sentinel value must be comptime-known", |
| 13708 | | }); |
| 13713 | const lhs_sent_casted_val = (try sema.resolveDefinedValue(block, lhs_src, lhs_sent_casted)).?; |
| 13714 | const rhs_sent_casted_val = (try sema.resolveDefinedValue(block, rhs_src, rhs_sent_casted)).?; |
| 13709 | 13715 | if (try sema.valuesEqual(lhs_sent_casted_val, rhs_sent_casted_val, resolved_elem_ty)) { |
| 13710 | 13716 | break :s lhs_sent_casted_val; |
| 13711 | 13717 | } else { |
| ... | ... | @@ -13713,18 +13719,14 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13713 | 13719 | } |
| 13714 | 13720 | } else { |
| 13715 | 13721 | const lhs_sent_casted = try sema.coerce(block, resolved_elem_ty, lhs_sent, lhs_src); |
| 13716 | | const lhs_sent_casted_val = try sema.resolveConstDefinedValue(block, lhs_src, lhs_sent_casted, .{ |
| 13717 | | .needed_comptime_reason = "array sentinel value must be comptime-known", |
| 13718 | | }); |
| 13722 | const lhs_sent_casted_val = (try sema.resolveDefinedValue(block, lhs_src, lhs_sent_casted)).?; |
| 13719 | 13723 | break :s lhs_sent_casted_val; |
| 13720 | 13724 | } |
| 13721 | 13725 | } else { |
| 13722 | 13726 | if (rhs_info.sentinel) |rhs_sent_val| { |
| 13723 | 13727 | const rhs_sent = Air.internedToRef(rhs_sent_val.toIntern()); |
| 13724 | 13728 | const rhs_sent_casted = try sema.coerce(block, resolved_elem_ty, rhs_sent, rhs_src); |
| 13725 | | const rhs_sent_casted_val = try sema.resolveConstDefinedValue(block, rhs_src, rhs_sent_casted, .{ |
| 13726 | | .needed_comptime_reason = "array sentinel value must be comptime-known", |
| 13727 | | }); |
| 13729 | const rhs_sent_casted_val = (try sema.resolveDefinedValue(block, rhs_src, rhs_sent_casted)).?; |
| 13728 | 13730 | break :s rhs_sent_casted_val; |
| 13729 | 13731 | } else { |
| 13730 | 13732 | break :s null; |
| ... | ... | @@ -13733,7 +13735,7 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13733 | 13735 | }; |
| 13734 | 13736 | |
| 13735 | 13737 | const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len); |
| 13736 | | const rhs_len = try sema.usizeCast(block, lhs_src, rhs_info.len); |
| 13738 | const rhs_len = try sema.usizeCast(block, rhs_src, rhs_info.len); |
| 13737 | 13739 | const result_len = std.math.add(usize, lhs_len, rhs_len) catch |err| switch (err) { |
| 13738 | 13740 | error.Overflow => return sema.fail( |
| 13739 | 13741 | block, |
| ... | ... | @@ -13775,14 +13777,18 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13775 | 13777 | rhs_val; |
| 13776 | 13778 | |
| 13777 | 13779 | const element_vals = try sema.arena.alloc(InternPool.Index, result_len); |
| 13778 | | var elem_i: usize = 0; |
| 13780 | var elem_i: u32 = 0; |
| 13779 | 13781 | while (elem_i < lhs_len) : (elem_i += 1) { |
| 13780 | 13782 | const lhs_elem_i = elem_i; |
| 13781 | 13783 | const elem_default_val = if (lhs_is_tuple) lhs_ty.structFieldDefaultValue(lhs_elem_i, mod) else Value.@"unreachable"; |
| 13782 | 13784 | const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try lhs_sub_val.elemValue(mod, lhs_elem_i) else elem_default_val; |
| 13783 | 13785 | const elem_val_inst = Air.internedToRef(elem_val.toIntern()); |
| 13784 | | const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, .unneeded); |
| 13785 | | const coerced_elem_val = try sema.resolveConstValue(block, .unneeded, coerced_elem_val_inst, undefined); |
| 13786 | const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{ |
| 13787 | .array_cat_offset = inst_data.src_node, |
| 13788 | .elem_index = elem_i, |
| 13789 | } }; |
| 13790 | const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src); |
| 13791 | const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined); |
| 13786 | 13792 | element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod); |
| 13787 | 13793 | } |
| 13788 | 13794 | while (elem_i < result_len) : (elem_i += 1) { |
| ... | ... | @@ -13790,8 +13796,12 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13790 | 13796 | const elem_default_val = if (rhs_is_tuple) rhs_ty.structFieldDefaultValue(rhs_elem_i, mod) else Value.@"unreachable"; |
| 13791 | 13797 | const elem_val = if (elem_default_val.toIntern() == .unreachable_value) try rhs_sub_val.elemValue(mod, rhs_elem_i) else elem_default_val; |
| 13792 | 13798 | const elem_val_inst = Air.internedToRef(elem_val.toIntern()); |
| 13793 | | const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, .unneeded); |
| 13794 | | const coerced_elem_val = try sema.resolveConstValue(block, .unneeded, coerced_elem_val_inst, undefined); |
| 13799 | const operand_src: LazySrcLoc = .{ .array_cat_rhs = .{ |
| 13800 | .array_cat_offset = inst_data.src_node, |
| 13801 | .elem_index = @intCast(rhs_elem_i), |
| 13802 | } }; |
| 13803 | const coerced_elem_val_inst = try sema.coerce(block, resolved_elem_ty, elem_val_inst, operand_src); |
| 13804 | const coerced_elem_val = try sema.resolveConstValue(block, operand_src, coerced_elem_val_inst, undefined); |
| 13795 | 13805 | element_vals[elem_i] = try coerced_elem_val.intern(resolved_elem_ty, mod); |
| 13796 | 13806 | } |
| 13797 | 13807 | return sema.addConstantMaybeRef(try mod.intern(.{ .aggregate = .{ |
| ... | ... | @@ -13814,19 +13824,28 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13814 | 13824 | .flags = .{ .address_space = ptr_as }, |
| 13815 | 13825 | }); |
| 13816 | 13826 | |
| 13817 | | var elem_i: usize = 0; |
| 13827 | var elem_i: u32 = 0; |
| 13818 | 13828 | while (elem_i < lhs_len) : (elem_i += 1) { |
| 13819 | 13829 | const elem_index = try mod.intRef(Type.usize, elem_i); |
| 13820 | 13830 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); |
| 13821 | | const init = try sema.elemVal(block, lhs_src, lhs, elem_index, src, true); |
| 13822 | | try sema.storePtr2(block, src, elem_ptr, src, init, lhs_src, .store); |
| 13831 | const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{ |
| 13832 | .array_cat_offset = inst_data.src_node, |
| 13833 | .elem_index = elem_i, |
| 13834 | } }; |
| 13835 | const init = try sema.elemVal(block, operand_src, lhs, elem_index, src, true); |
| 13836 | try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store); |
| 13823 | 13837 | } |
| 13824 | 13838 | while (elem_i < result_len) : (elem_i += 1) { |
| 13839 | const rhs_elem_i = elem_i - lhs_len; |
| 13825 | 13840 | const elem_index = try mod.intRef(Type.usize, elem_i); |
| 13826 | | const rhs_index = try mod.intRef(Type.usize, elem_i - lhs_len); |
| 13841 | const rhs_index = try mod.intRef(Type.usize, rhs_elem_i); |
| 13827 | 13842 | const elem_ptr = try block.addPtrElemPtr(alloc, elem_index, elem_ptr_ty); |
| 13828 | | const init = try sema.elemVal(block, rhs_src, rhs, rhs_index, src, true); |
| 13829 | | try sema.storePtr2(block, src, elem_ptr, src, init, rhs_src, .store); |
| 13843 | const operand_src: LazySrcLoc = .{ .array_cat_rhs = .{ |
| 13844 | .array_cat_offset = inst_data.src_node, |
| 13845 | .elem_index = @intCast(rhs_elem_i), |
| 13846 | } }; |
| 13847 | const init = try sema.elemVal(block, operand_src, rhs, rhs_index, src, true); |
| 13848 | try sema.storePtr2(block, src, elem_ptr, src, init, operand_src, .store); |
| 13830 | 13849 | } |
| 13831 | 13850 | if (res_sent_val) |sent_val| { |
| 13832 | 13851 | const elem_index = try mod.intRef(Type.usize, result_len); |
| ... | ... | @@ -13840,16 +13859,25 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 13840 | 13859 | |
| 13841 | 13860 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, result_len); |
| 13842 | 13861 | { |
| 13843 | | var elem_i: usize = 0; |
| 13862 | var elem_i: u32 = 0; |
| 13844 | 13863 | while (elem_i < lhs_len) : (elem_i += 1) { |
| 13845 | 13864 | const index = try mod.intRef(Type.usize, elem_i); |
| 13846 | | const init = try sema.elemVal(block, lhs_src, lhs, index, src, true); |
| 13847 | | element_refs[elem_i] = try sema.coerce(block, resolved_elem_ty, init, lhs_src); |
| 13865 | const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{ |
| 13866 | .array_cat_offset = inst_data.src_node, |
| 13867 | .elem_index = elem_i, |
| 13868 | } }; |
| 13869 | const init = try sema.elemVal(block, operand_src, lhs, index, src, true); |
| 13870 | element_refs[elem_i] = try sema.coerce(block, resolved_elem_ty, init, operand_src); |
| 13848 | 13871 | } |
| 13849 | 13872 | while (elem_i < result_len) : (elem_i += 1) { |
| 13850 | | const index = try mod.intRef(Type.usize, elem_i - lhs_len); |
| 13851 | | const init = try sema.elemVal(block, rhs_src, rhs, index, src, true); |
| 13852 | | element_refs[elem_i] = try sema.coerce(block, resolved_elem_ty, init, rhs_src); |
| 13873 | const rhs_elem_i = elem_i - lhs_len; |
| 13874 | const index = try mod.intRef(Type.usize, rhs_elem_i); |
| 13875 | const operand_src: LazySrcLoc = .{ .array_cat_rhs = .{ |
| 13876 | .array_cat_offset = inst_data.src_node, |
| 13877 | .elem_index = @intCast(rhs_elem_i), |
| 13878 | } }; |
| 13879 | const init = try sema.elemVal(block, operand_src, rhs, index, src, true); |
| 13880 | element_refs[elem_i] = try sema.coerce(block, resolved_elem_ty, init, operand_src); |
| 13853 | 13881 | } |
| 13854 | 13882 | } |
| 13855 | 13883 | |
| ... | ... | @@ -13913,12 +13941,11 @@ fn analyzeTupleMul( |
| 13913 | 13941 | const mod = sema.mod; |
| 13914 | 13942 | const operand_ty = sema.typeOf(operand); |
| 13915 | 13943 | const src = LazySrcLoc.nodeOffset(src_node); |
| 13916 | | const lhs_src: LazySrcLoc = .{ .node_offset_bin_lhs = src_node }; |
| 13917 | | const rhs_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node }; |
| 13944 | const len_src: LazySrcLoc = .{ .node_offset_bin_rhs = src_node }; |
| 13918 | 13945 | |
| 13919 | 13946 | const tuple_len = operand_ty.structFieldCount(mod); |
| 13920 | 13947 | const final_len = std.math.mul(usize, tuple_len, factor) catch |
| 13921 | | return sema.fail(block, rhs_src, "operation results in overflow", .{}); |
| 13948 | return sema.fail(block, len_src, "operation results in overflow", .{}); |
| 13922 | 13949 | |
| 13923 | 13950 | if (final_len == 0) { |
| 13924 | 13951 | return Air.internedToRef(Value.empty_struct.toIntern()); |
| ... | ... | @@ -13931,7 +13958,10 @@ fn analyzeTupleMul( |
| 13931 | 13958 | for (0..tuple_len) |i| { |
| 13932 | 13959 | types[i] = operand_ty.structFieldType(i, mod).toIntern(); |
| 13933 | 13960 | values[i] = operand_ty.structFieldDefaultValue(i, mod).toIntern(); |
| 13934 | | const operand_src = lhs_src; // TODO better source location |
| 13961 | const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{ |
| 13962 | .array_cat_offset = src_node, |
| 13963 | .elem_index = @intCast(i), |
| 13964 | } }; |
| 13935 | 13965 | if (values[i] == .unreachable_value) { |
| 13936 | 13966 | runtime_src = operand_src; |
| 13937 | 13967 | values[i] = .none; // TODO don't treat unreachable_value as special |
| ... | ... | @@ -13963,7 +13993,10 @@ fn analyzeTupleMul( |
| 13963 | 13993 | const element_refs = try sema.arena.alloc(Air.Inst.Ref, final_len); |
| 13964 | 13994 | var i: u32 = 0; |
| 13965 | 13995 | while (i < tuple_len) : (i += 1) { |
| 13966 | | const operand_src = lhs_src; // TODO better source location |
| 13996 | const operand_src: LazySrcLoc = .{ .array_cat_lhs = .{ |
| 13997 | .array_cat_offset = src_node, |
| 13998 | .elem_index = i, |
| 13999 | } }; |
| 13967 | 14000 | element_refs[i] = try sema.tupleFieldValByIndex(block, operand_src, operand, @intCast(i), operand_ty); |
| 13968 | 14001 | } |
| 13969 | 14002 | i = 1; |