| ... | @@ -768,18 +768,75 @@ const DeclGen = struct { | ... | @@ -768,18 +768,75 @@ const DeclGen = struct { |
| 768 | }; | 768 | }; |
| 769 | } | 769 | } |
| 770 | | 770 | |
| 771 | /// Construct a composite value at runtime. If the parameters are in direct | 771 | /// Construct a struct at runtime. |
| 772 | /// representation, then the result is also in direct representation. Otherwise, | 772 | /// ty must be a struct type. |
| 773 | /// if the parameters are in indirect representation, then the result is too. | 773 | /// Constituents should be in `indirect` representation (as the elements of a struct should be). |
| 774 | fn constructComposite(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { | 774 | /// Result is in `direct` representation. |
| 775 | const constituents_id = self.spv.allocId(); | 775 | fn constructStruct(self: *DeclGen, ty: Type, types: []const Type, constituents: []const IdRef) !IdRef { |
| 776 | const type_id = try self.resolveType(ty, .direct); | 776 | assert(types.len == constituents.len); |
| 777 | try self.func.body.emit(self.spv.gpa, .OpCompositeConstruct, .{ | 777 | // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which' |
| 778 | .id_result_type = self.typeId(type_id), | 778 | // operands are not constant. |
| 779 | .id_result = constituents_id, | 779 | // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349 |
| 780 | .constituents = constituents, | 780 | // For now, just initialize the struct by setting the fields manually... |
| 781 | }); | 781 | // TODO: Make this OpCompositeConstruct when we can |
| 782 | return constituents_id; | 782 | const ptr_composite_id = try self.alloc(ty, .{ .storage_class = .Function }); |
| | 783 | for (constituents, types, 0..) |constitent_id, member_ty, index| { |
| | 784 | const ptr_member_ty_ref = try self.ptrType(member_ty, .Function); |
| | 785 | const ptr_id = try self.accessChain(ptr_member_ty_ref, ptr_composite_id, &.{@as(u32, @intCast(index))}); |
| | 786 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ |
| | 787 | .pointer = ptr_id, |
| | 788 | .object = constitent_id, |
| | 789 | }); |
| | 790 | } |
| | 791 | return try self.load(ty, ptr_composite_id, .{}); |
| | 792 | } |
| | 793 | |
| | 794 | /// Construct a vector at runtime. |
| | 795 | /// ty must be an vector type. |
| | 796 | /// Constituents should be in `indirect` representation (as the elements of an vector should be). |
| | 797 | /// Result is in `direct` representation. |
| | 798 | fn constructVector(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { |
| | 799 | // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which' |
| | 800 | // operands are not constant. |
| | 801 | // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349 |
| | 802 | // For now, just initialize the struct by setting the fields manually... |
| | 803 | // TODO: Make this OpCompositeConstruct when we can |
| | 804 | const mod = self.module; |
| | 805 | const ptr_composite_id = try self.alloc(ty, .{ .storage_class = .Function }); |
| | 806 | const ptr_elem_ty_ref = try self.ptrType(ty.elemType2(mod), .Function); |
| | 807 | for (constituents, 0..) |constitent_id, index| { |
| | 808 | const ptr_id = try self.accessChain(ptr_elem_ty_ref, ptr_composite_id, &.{@as(u32, @intCast(index))}); |
| | 809 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ |
| | 810 | .pointer = ptr_id, |
| | 811 | .object = constitent_id, |
| | 812 | }); |
| | 813 | } |
| | 814 | |
| | 815 | return try self.load(ty, ptr_composite_id, .{}); |
| | 816 | } |
| | 817 | |
| | 818 | /// Construct an array at runtime. |
| | 819 | /// ty must be an array type. |
| | 820 | /// Constituents should be in `indirect` representation (as the elements of an array should be). |
| | 821 | /// Result is in `direct` representation. |
| | 822 | fn constructArray(self: *DeclGen, ty: Type, constituents: []const IdRef) !IdRef { |
| | 823 | // The Khronos LLVM-SPIRV translator crashes because it cannot construct structs which' |
| | 824 | // operands are not constant. |
| | 825 | // See https://github.com/KhronosGroup/SPIRV-LLVM-Translator/issues/1349 |
| | 826 | // For now, just initialize the struct by setting the fields manually... |
| | 827 | // TODO: Make this OpCompositeConstruct when we can |
| | 828 | const mod = self.module; |
| | 829 | const ptr_composite_id = try self.alloc(ty, .{ .storage_class = .Function }); |
| | 830 | const ptr_elem_ty_ref = try self.ptrType(ty.elemType2(mod), .Function); |
| | 831 | for (constituents, 0..) |constitent_id, index| { |
| | 832 | const ptr_id = try self.accessChain(ptr_elem_ty_ref, ptr_composite_id, &.{@as(u32, @intCast(index))}); |
| | 833 | try self.func.body.emit(self.spv.gpa, .OpStore, .{ |
| | 834 | .pointer = ptr_id, |
| | 835 | .object = constitent_id, |
| | 836 | }); |
| | 837 | } |
| | 838 | |
| | 839 | return try self.load(ty, ptr_composite_id, .{}); |
| 783 | } | 840 | } |
| 784 | | 841 | |
| 785 | /// This function generates a load for a constant in direct (ie, non-memory) representation. | 842 | /// This function generates a load for a constant in direct (ie, non-memory) representation. |
| ... | @@ -887,15 +944,18 @@ const DeclGen = struct { | ... | @@ -887,15 +944,18 @@ const DeclGen = struct { |
| 887 | }); | 944 | }); |
| 888 | | 945 | |
| 889 | var constituents: [2]IdRef = undefined; | 946 | var constituents: [2]IdRef = undefined; |
| | 947 | var types: [2]Type = undefined; |
| 890 | if (eu_layout.error_first) { | 948 | if (eu_layout.error_first) { |
| 891 | constituents[0] = try self.constant(err_ty, err_val, .indirect); | 949 | constituents[0] = try self.constant(err_ty, err_val, .indirect); |
| 892 | constituents[1] = try self.constant(payload_ty, payload_val, .indirect); | 950 | constituents[1] = try self.constant(payload_ty, payload_val, .indirect); |
| | 951 | types = .{ err_ty, payload_ty }; |
| 893 | } else { | 952 | } else { |
| 894 | constituents[0] = try self.constant(payload_ty, payload_val, .indirect); | 953 | constituents[0] = try self.constant(payload_ty, payload_val, .indirect); |
| 895 | constituents[1] = try self.constant(err_ty, err_val, .indirect); | 954 | constituents[1] = try self.constant(err_ty, err_val, .indirect); |
| | 955 | types = .{ payload_ty, err_ty }; |
| 896 | } | 956 | } |
| 897 | | 957 | |
| 898 | return try self.constructComposite(ty, &constituents); | 958 | return try self.constructStruct(ty, &types, &constituents); |
| 899 | }, | 959 | }, |
| 900 | .enum_tag => { | 960 | .enum_tag => { |
| 901 | const int_val = try val.intFromEnum(ty, mod); | 961 | const int_val = try val.intFromEnum(ty, mod); |
| ... | @@ -907,7 +967,11 @@ const DeclGen = struct { | ... | @@ -907,7 +967,11 @@ const DeclGen = struct { |
| 907 | const ptr_ty = ty.slicePtrFieldType(mod); | 967 | const ptr_ty = ty.slicePtrFieldType(mod); |
| 908 | const ptr_id = try self.constantPtr(ptr_ty, Value.fromInterned(slice.ptr)); | 968 | const ptr_id = try self.constantPtr(ptr_ty, Value.fromInterned(slice.ptr)); |
| 909 | const len_id = try self.constant(Type.usize, Value.fromInterned(slice.len), .indirect); | 969 | const len_id = try self.constant(Type.usize, Value.fromInterned(slice.len), .indirect); |
| 910 | return self.constructComposite(ty, &.{ ptr_id, len_id }); | 970 | return self.constructStruct( |
| | 971 | ty, |
| | 972 | &.{ ptr_ty, Type.usize }, |
| | 973 | &.{ ptr_id, len_id }, |
| | 974 | ); |
| 911 | }, | 975 | }, |
| 912 | .opt => { | 976 | .opt => { |
| 913 | const payload_ty = ty.optionalChild(mod); | 977 | const payload_ty = ty.optionalChild(mod); |
| ... | @@ -934,7 +998,11 @@ const DeclGen = struct { | ... | @@ -934,7 +998,11 @@ const DeclGen = struct { |
| 934 | else | 998 | else |
| 935 | try self.spv.constUndef(try self.resolveType(payload_ty, .indirect)); | 999 | try self.spv.constUndef(try self.resolveType(payload_ty, .indirect)); |
| 936 | | 1000 | |
| 937 | return try self.constructComposite(ty, &.{ payload_id, has_pl_id }); | 1001 | return try self.constructStruct( |
| | 1002 | ty, |
| | 1003 | &.{ payload_ty, Type.bool }, |
| | 1004 | &.{ payload_id, has_pl_id }, |
| | 1005 | ); |
| 938 | }, | 1006 | }, |
| 939 | .aggregate => |aggregate| switch (ip.indexToKey(ty.ip_index)) { | 1007 | .aggregate => |aggregate| switch (ip.indexToKey(ty.ip_index)) { |
| 940 | inline .array_type, .vector_type => |array_type, tag| { | 1008 | inline .array_type, .vector_type => |array_type, tag| { |
| ... | @@ -971,9 +1039,9 @@ const DeclGen = struct { | ... | @@ -971,9 +1039,9 @@ const DeclGen = struct { |
| 971 | const sentinel = Value.fromInterned(array_type.sentinel); | 1039 | const sentinel = Value.fromInterned(array_type.sentinel); |
| 972 | constituents[constituents.len - 1] = try self.constant(elem_ty, sentinel, .indirect); | 1040 | constituents[constituents.len - 1] = try self.constant(elem_ty, sentinel, .indirect); |
| 973 | } | 1041 | } |
| 974 | return self.constructComposite(ty, constituents); | 1042 | return self.constructArray(ty, constituents); |
| 975 | }, | 1043 | }, |
| 976 | inline .vector_type => return self.constructComposite(ty, constituents), | 1044 | inline .vector_type => return self.constructVector(ty, constituents), |
| 977 | else => unreachable, | 1045 | else => unreachable, |
| 978 | } | 1046 | } |
| 979 | }, | 1047 | }, |
| ... | @@ -983,6 +1051,9 @@ const DeclGen = struct { | ... | @@ -983,6 +1051,9 @@ const DeclGen = struct { |
| 983 | return self.todo("packed struct constants", .{}); | 1051 | return self.todo("packed struct constants", .{}); |
| 984 | } | 1052 | } |
| 985 | | 1053 | |
| | 1054 | var types = std.ArrayList(Type).init(self.gpa); |
| | 1055 | defer types.deinit(); |
| | 1056 | |
| 986 | var constituents = std.ArrayList(IdRef).init(self.gpa); | 1057 | var constituents = std.ArrayList(IdRef).init(self.gpa); |
| 987 | defer constituents.deinit(); | 1058 | defer constituents.deinit(); |
| 988 | | 1059 | |
| ... | @@ -998,10 +1069,11 @@ const DeclGen = struct { | ... | @@ -998,10 +1069,11 @@ const DeclGen = struct { |
| 998 | const field_val = try val.fieldValue(mod, field_index); | 1069 | const field_val = try val.fieldValue(mod, field_index); |
| 999 | const field_id = try self.constant(field_ty, field_val, .indirect); | 1070 | const field_id = try self.constant(field_ty, field_val, .indirect); |
| 1000 | | 1071 | |
| | 1072 | try types.append(field_ty); |
| 1001 | try constituents.append(field_id); | 1073 | try constituents.append(field_id); |
| 1002 | } | 1074 | } |
| 1003 | | 1075 | |
| 1004 | return try self.constructComposite(ty, constituents.items); | 1076 | return try self.constructStruct(ty, types.items, constituents.items); |
| 1005 | }, | 1077 | }, |
| 1006 | .anon_struct_type => unreachable, // TODO | 1078 | .anon_struct_type => unreachable, // TODO |
| 1007 | else => unreachable, | 1079 | else => unreachable, |
| ... | @@ -1841,7 +1913,7 @@ const DeclGen = struct { | ... | @@ -1841,7 +1913,7 @@ const DeclGen = struct { |
| 1841 | for (wip.results) |*result| { | 1913 | for (wip.results) |*result| { |
| 1842 | result.* = try wip.dg.convertToIndirect(wip.ty, result.*); | 1914 | result.* = try wip.dg.convertToIndirect(wip.ty, result.*); |
| 1843 | } | 1915 | } |
| 1844 | return try wip.dg.constructComposite(wip.result_ty, wip.results); | 1916 | return try wip.dg.constructArray(wip.result_ty, wip.results); |
| 1845 | } else { | 1917 | } else { |
| 1846 | return wip.results[0]; | 1918 | return wip.results[0]; |
| 1847 | } | 1919 | } |
| ... | @@ -2792,8 +2864,9 @@ const DeclGen = struct { | ... | @@ -2792,8 +2864,9 @@ const DeclGen = struct { |
| 2792 | ov_id.* = try self.intFromBool(wip_ov.ty_ref, overflowed_id); | 2864 | ov_id.* = try self.intFromBool(wip_ov.ty_ref, overflowed_id); |
| 2793 | } | 2865 | } |
| 2794 | | 2866 | |
| 2795 | return try self.constructComposite( | 2867 | return try self.constructStruct( |
| 2796 | result_ty, | 2868 | result_ty, |
| | 2869 | &.{ operand_ty, ov_ty }, |
| 2797 | &.{ try wip_result.finalize(), try wip_ov.finalize() }, | 2870 | &.{ try wip_result.finalize(), try wip_ov.finalize() }, |
| 2798 | ); | 2871 | ); |
| 2799 | } | 2872 | } |
| ... | @@ -2885,8 +2958,9 @@ const DeclGen = struct { | ... | @@ -2885,8 +2958,9 @@ const DeclGen = struct { |
| 2885 | ov_id.* = try self.intFromBool(wip_ov.ty_ref, overflowed_id); | 2958 | ov_id.* = try self.intFromBool(wip_ov.ty_ref, overflowed_id); |
| 2886 | } | 2959 | } |
| 2887 | | 2960 | |
| 2888 | return try self.constructComposite( | 2961 | return try self.constructStruct( |
| 2889 | result_ty, | 2962 | result_ty, |
| | 2963 | &.{ operand_ty, ov_ty }, |
| 2890 | &.{ try wip_result.finalize(), try wip_ov.finalize() }, | 2964 | &.{ try wip_result.finalize(), try wip_ov.finalize() }, |
| 2891 | ); | 2965 | ); |
| 2892 | } | 2966 | } |
| ... | @@ -3588,7 +3662,11 @@ const DeclGen = struct { | ... | @@ -3588,7 +3662,11 @@ const DeclGen = struct { |
| 3588 | // Convert the pointer-to-array to a pointer to the first element. | 3662 | // Convert the pointer-to-array to a pointer to the first element. |
| 3589 | try self.accessChain(elem_ptr_ty_ref, array_ptr_id, &.{0}); | 3663 | try self.accessChain(elem_ptr_ty_ref, array_ptr_id, &.{0}); |
| 3590 | | 3664 | |
| 3591 | return try self.constructComposite(slice_ty, &.{ elem_ptr_id, len_id }); | 3665 | return try self.constructStruct( |
| | 3666 | slice_ty, |
| | 3667 | &.{ elem_ptr_ty, Type.usize }, |
| | 3668 | &.{ elem_ptr_id, len_id }, |
| | 3669 | ); |
| 3592 | } | 3670 | } |
| 3593 | | 3671 | |
| 3594 | fn airSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3672 | fn airSlice(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| ... | @@ -3596,11 +3674,16 @@ const DeclGen = struct { | ... | @@ -3596,11 +3674,16 @@ const DeclGen = struct { |
| 3596 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 3674 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| 3597 | const ptr_id = try self.resolve(bin_op.lhs); | 3675 | const ptr_id = try self.resolve(bin_op.lhs); |
| 3598 | const len_id = try self.resolve(bin_op.rhs); | 3676 | const len_id = try self.resolve(bin_op.rhs); |
| | 3677 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 3599 | const slice_ty = self.typeOfIndex(inst); | 3678 | const slice_ty = self.typeOfIndex(inst); |
| 3600 | | 3679 | |
| 3601 | // Note: Types should not need to be converted to direct, these types | 3680 | // Note: Types should not need to be converted to direct, these types |
| 3602 | // dont need to be converted. | 3681 | // dont need to be converted. |
| 3603 | return try self.constructComposite(slice_ty, &.{ ptr_id, len_id }); | 3682 | return try self.constructStruct( |
| | 3683 | slice_ty, |
| | 3684 | &.{ ptr_ty, Type.usize }, |
| | 3685 | &.{ ptr_id, len_id }, |
| | 3686 | ); |
| 3604 | } | 3687 | } |
| 3605 | | 3688 | |
| 3606 | fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 3689 | fn airAggregateInit(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| ... | @@ -3618,6 +3701,8 @@ const DeclGen = struct { | ... | @@ -3618,6 +3701,8 @@ const DeclGen = struct { |
| 3618 | unreachable; // TODO | 3701 | unreachable; // TODO |
| 3619 | } | 3702 | } |
| 3620 | | 3703 | |
| | 3704 | const types = try self.gpa.alloc(Type, elements.len); |
| | 3705 | defer self.gpa.free(types); |
| 3621 | const constituents = try self.gpa.alloc(IdRef, elements.len); | 3706 | const constituents = try self.gpa.alloc(IdRef, elements.len); |
| 3622 | defer self.gpa.free(constituents); | 3707 | defer self.gpa.free(constituents); |
| 3623 | var index: usize = 0; | 3708 | var index: usize = 0; |
| ... | @@ -3629,6 +3714,7 @@ const DeclGen = struct { | ... | @@ -3629,6 +3714,7 @@ const DeclGen = struct { |
| 3629 | assert(Type.fromInterned(field_ty).hasRuntimeBits(mod)); | 3714 | assert(Type.fromInterned(field_ty).hasRuntimeBits(mod)); |
| 3630 | | 3715 | |
| 3631 | const id = try self.resolve(element); | 3716 | const id = try self.resolve(element); |
| | 3717 | types[index] = Type.fromInterned(field_ty); |
| 3632 | constituents[index] = try self.convertToIndirect(Type.fromInterned(field_ty), id); | 3718 | constituents[index] = try self.convertToIndirect(Type.fromInterned(field_ty), id); |
| 3633 | index += 1; | 3719 | index += 1; |
| 3634 | } | 3720 | } |
| ... | @@ -3643,6 +3729,7 @@ const DeclGen = struct { | ... | @@ -3643,6 +3729,7 @@ const DeclGen = struct { |
| 3643 | assert(field_ty.hasRuntimeBitsIgnoreComptime(mod)); | 3729 | assert(field_ty.hasRuntimeBitsIgnoreComptime(mod)); |
| 3644 | | 3730 | |
| 3645 | const id = try self.resolve(element); | 3731 | const id = try self.resolve(element); |
| | 3732 | types[index] = field_ty; |
| 3646 | constituents[index] = try self.convertToIndirect(field_ty, id); | 3733 | constituents[index] = try self.convertToIndirect(field_ty, id); |
| 3647 | index += 1; | 3734 | index += 1; |
| 3648 | } | 3735 | } |
| ... | @@ -3650,7 +3737,11 @@ const DeclGen = struct { | ... | @@ -3650,7 +3737,11 @@ const DeclGen = struct { |
| 3650 | else => unreachable, | 3737 | else => unreachable, |
| 3651 | } | 3738 | } |
| 3652 | | 3739 | |
| 3653 | return try self.constructComposite(result_ty, constituents[0..index]); | 3740 | return try self.constructStruct( |
| | 3741 | result_ty, |
| | 3742 | types[0..index], |
| | 3743 | constituents[0..index], |
| | 3744 | ); |
| 3654 | }, | 3745 | }, |
| 3655 | .Vector => { | 3746 | .Vector => { |
| 3656 | const n_elems = result_ty.vectorLen(mod); | 3747 | const n_elems = result_ty.vectorLen(mod); |
| ... | @@ -3662,7 +3753,7 @@ const DeclGen = struct { | ... | @@ -3662,7 +3753,7 @@ const DeclGen = struct { |
| 3662 | elem_ids[i] = try self.convertToIndirect(result_ty.childType(mod), id); | 3753 | elem_ids[i] = try self.convertToIndirect(result_ty.childType(mod), id); |
| 3663 | } | 3754 | } |
| 3664 | | 3755 | |
| 3665 | return try self.constructComposite(result_ty, elem_ids); | 3756 | return try self.constructVector(result_ty, elem_ids); |
| 3666 | }, | 3757 | }, |
| 3667 | .Array => { | 3758 | .Array => { |
| 3668 | const array_info = result_ty.arrayInfo(mod); | 3759 | const array_info = result_ty.arrayInfo(mod); |
| ... | @@ -3679,7 +3770,7 @@ const DeclGen = struct { | ... | @@ -3679,7 +3770,7 @@ const DeclGen = struct { |
| 3679 | elem_ids[n_elems - 1] = try self.constant(array_info.elem_type, sentinel_val, .indirect); | 3770 | elem_ids[n_elems - 1] = try self.constant(array_info.elem_type, sentinel_val, .indirect); |
| 3680 | } | 3771 | } |
| 3681 | | 3772 | |
| 3682 | return try self.constructComposite(result_ty, elem_ids); | 3773 | return try self.constructArray(result_ty, elem_ids); |
| 3683 | }, | 3774 | }, |
| 3684 | else => unreachable, | 3775 | else => unreachable, |
| 3685 | } | 3776 | } |
| ... | @@ -4792,7 +4883,11 @@ const DeclGen = struct { | ... | @@ -4792,7 +4883,11 @@ const DeclGen = struct { |
| 4792 | members[eu_layout.errorFieldIndex()] = operand_id; | 4883 | members[eu_layout.errorFieldIndex()] = operand_id; |
| 4793 | members[eu_layout.payloadFieldIndex()] = try self.spv.constUndef(payload_ty_ref); | 4884 | members[eu_layout.payloadFieldIndex()] = try self.spv.constUndef(payload_ty_ref); |
| 4794 | | 4885 | |
| 4795 | return try self.constructComposite(err_union_ty, &members); | 4886 | var types: [2]Type = undefined; |
| | 4887 | types[eu_layout.errorFieldIndex()] = Type.anyerror; |
| | 4888 | types[eu_layout.payloadFieldIndex()] = payload_ty; |
| | 4889 | |
| | 4890 | return try self.constructStruct(err_union_ty, &types, &members); |
| 4796 | } | 4891 | } |
| 4797 | | 4892 | |
| 4798 | fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { | 4893 | fn airWrapErrUnionPayload(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { |
| ... | @@ -4811,7 +4906,11 @@ const DeclGen = struct { | ... | @@ -4811,7 +4906,11 @@ const DeclGen = struct { |
| 4811 | members[eu_layout.errorFieldIndex()] = try self.constInt(err_ty_ref, 0); | 4906 | members[eu_layout.errorFieldIndex()] = try self.constInt(err_ty_ref, 0); |
| 4812 | members[eu_layout.payloadFieldIndex()] = try self.convertToIndirect(payload_ty, operand_id); | 4907 | members[eu_layout.payloadFieldIndex()] = try self.convertToIndirect(payload_ty, operand_id); |
| 4813 | | 4908 | |
| 4814 | return try self.constructComposite(err_union_ty, &members); | 4909 | var types: [2]Type = undefined; |
| | 4910 | types[eu_layout.errorFieldIndex()] = Type.anyerror; |
| | 4911 | types[eu_layout.payloadFieldIndex()] = payload_ty; |
| | 4912 | |
| | 4913 | return try self.constructStruct(err_union_ty, &types, &members); |
| 4815 | } | 4914 | } |
| 4816 | | 4915 | |
| 4817 | fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef { | 4916 | fn airIsNull(self: *DeclGen, inst: Air.Inst.Index, is_pointer: bool, pred: enum { is_null, is_non_null }) !?IdRef { |
| ... | @@ -4978,7 +5077,8 @@ const DeclGen = struct { | ... | @@ -4978,7 +5077,8 @@ const DeclGen = struct { |
| 4978 | | 5077 | |
| 4979 | const payload_id = try self.convertToIndirect(payload_ty, operand_id); | 5078 | const payload_id = try self.convertToIndirect(payload_ty, operand_id); |
| 4980 | const members = [_]IdRef{ payload_id, try self.constBool(true, .indirect) }; | 5079 | const members = [_]IdRef{ payload_id, try self.constBool(true, .indirect) }; |
| 4981 | return try self.constructComposite(optional_ty, &members); | 5080 | const types = [_]Type{ payload_ty, Type.bool }; |
| | 5081 | return try self.constructStruct(optional_ty, &types, &members); |
| 4982 | } | 5082 | } |
| 4983 | | 5083 | |
| 4984 | fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void { | 5084 | fn airSwitchBr(self: *DeclGen, inst: Air.Inst.Index) !void { |