From 5e636643d2a36c777a607b65cfd1abbb1822ad1e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 4 May 2023 20:30:25 -0700 Subject: [PATCH] stage2: move many Type encodings to InternPool Notably, `vector`. Additionally, all alternate encodings of `pointer`, `optional`, and `array`. --- src/Air.zig | 13 +- src/InternPool.zig | 92 +- src/Liveness.zig | 8 +- src/Liveness/Verify.zig | 2 +- src/Module.zig | 41 +- src/Sema.zig | 1073 ++++++++++----------- src/TypedValue.zig | 32 +- src/arch/aarch64/CodeGen.zig | 80 +- src/arch/arm/CodeGen.zig | 83 +- src/arch/riscv64/CodeGen.zig | 14 +- src/arch/sparc64/CodeGen.zig | 37 +- src/arch/wasm/CodeGen.zig | 168 ++-- src/arch/x86_64/CodeGen.zig | 314 +++--- src/arch/x86_64/abi.zig | 6 +- src/codegen.zig | 36 +- src/codegen/c.zig | 203 ++-- src/codegen/c/type.zig | 9 +- src/codegen/llvm.zig | 326 +++---- src/codegen/spirv.zig | 64 +- src/codegen/spirv/Module.zig | 3 +- src/link/Dwarf.zig | 11 +- src/link/Wasm.zig | 4 +- src/print_air.zig | 6 +- src/type.zig | 1770 +++++++++------------------------- src/value.zig | 208 ++-- 25 files changed, 1833 insertions(+), 2770 deletions(-) diff --git a/src/Air.zig b/src/Air.zig index 4124788605..64212d3b9a 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -1375,7 +1375,7 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type { .bool_to_int => return Type.u1, - .tag_name, .error_name => return Type.initTag(.const_slice_u8_sentinel_0), + .tag_name, .error_name => return Type.const_slice_u8_sentinel_0, .call, .call_always_tail, .call_never_tail, .call_never_inline => { const callee_ty = air.typeOf(datas[inst].pl_op.operand, ip); @@ -1384,18 +1384,21 @@ pub fn typeOfIndex(air: Air, inst: Air.Inst.Index, ip: InternPool) Type { .slice_elem_val, .ptr_elem_val, .array_elem_val => { const ptr_ty = air.typeOf(datas[inst].bin_op.lhs, ip); - return ptr_ty.elemType(); + return ptr_ty.childTypeIp(ip); }, .atomic_load => { const ptr_ty = air.typeOf(datas[inst].atomic_load.ptr, ip); - return ptr_ty.elemType(); + return ptr_ty.childTypeIp(ip); }, .atomic_rmw => { const ptr_ty = air.typeOf(datas[inst].pl_op.operand, ip); - return ptr_ty.elemType(); + return ptr_ty.childTypeIp(ip); }, - .reduce, .reduce_optimized => return air.typeOf(datas[inst].reduce.operand, ip).childType(), + .reduce, .reduce_optimized => { + const operand_ty = air.typeOf(datas[inst].reduce.operand, ip); + return ip.indexToKey(operand_ty.ip_index).vector_type.child.toType(); + }, .mul_add => return air.typeOf(datas[inst].pl_op.operand, ip), .select => { diff --git a/src/InternPool.zig b/src/InternPool.zig index 3ecc18c426..295a694e2a 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -31,28 +31,10 @@ const KeyAdapter = struct { pub const Key = union(enum) { int_type: IntType, - ptr_type: struct { - elem_type: Index, - sentinel: Index = .none, - alignment: u16 = 0, - size: std.builtin.Type.Pointer.Size, - is_const: bool = false, - is_volatile: bool = false, - is_allowzero: bool = false, - address_space: std.builtin.AddressSpace = .generic, - }, - array_type: struct { - len: u64, - child: Index, - sentinel: Index, - }, - vector_type: struct { - len: u32, - child: Index, - }, - optional_type: struct { - payload_type: Index, - }, + ptr_type: PtrType, + array_type: ArrayType, + vector_type: VectorType, + opt_type: Index, error_union_type: struct { error_set_type: Index, payload_type: Index, @@ -87,6 +69,47 @@ pub const Key = union(enum) { pub const IntType = std.builtin.Type.Int; + pub const PtrType = struct { + elem_type: Index, + sentinel: Index = .none, + /// If zero use pointee_type.abiAlignment() + /// When creating pointer types, if alignment is equal to pointee type + /// abi alignment, this value should be set to 0 instead. + alignment: u16 = 0, + /// If this is non-zero it means the pointer points to a sub-byte + /// range of data, which is backed by a "host integer" with this + /// number of bytes. + /// When host_size=pointee_abi_size and bit_offset=0, this must be + /// represented with host_size=0 instead. + host_size: u16 = 0, + bit_offset: u16 = 0, + vector_index: VectorIndex = .none, + size: std.builtin.Type.Pointer.Size = .One, + is_const: bool = false, + is_volatile: bool = false, + is_allowzero: bool = false, + /// See src/target.zig defaultAddressSpace function for how to obtain + /// an appropriate value for this field. + address_space: std.builtin.AddressSpace = .generic, + + pub const VectorIndex = enum(u32) { + none = std.math.maxInt(u32), + runtime = std.math.maxInt(u32) - 1, + _, + }; + }; + + pub const ArrayType = struct { + len: u64, + child: Index, + sentinel: Index, + }; + + pub const VectorType = struct { + len: u32, + child: Index, + }; + pub fn hash32(key: Key) u32 { return @truncate(u32, key.hash64()); } @@ -106,7 +129,7 @@ pub const Key = union(enum) { .ptr_type, .array_type, .vector_type, - .optional_type, + .opt_type, .error_union_type, .simple_type, .simple_value, @@ -159,8 +182,8 @@ pub const Key = union(enum) { const b_info = b.vector_type; return std.meta.eql(a_info, b_info); }, - .optional_type => |a_info| { - const b_info = b.optional_type; + .opt_type => |a_info| { + const b_info = b.opt_type; return std.meta.eql(a_info, b_info); }, .error_union_type => |a_info| { @@ -220,7 +243,7 @@ pub const Key = union(enum) { .ptr_type, .array_type, .vector_type, - .optional_type, + .opt_type, .error_union_type, .simple_type, .struct_type, @@ -630,6 +653,7 @@ pub const Tag = enum(u8) { /// data is payload to Vector. type_vector, /// A fully explicitly specified pointer type. + /// TODO actually this is missing some stuff like bit_offset /// data is payload to Pointer. type_pointer, /// An optional type. @@ -893,7 +917,7 @@ pub fn indexToKey(ip: InternPool, index: Index) Key { } }; }, - .type_optional => .{ .optional_type = .{ .payload_type = @intToEnum(Index, data) } }, + .type_optional => .{ .opt_type = @intToEnum(Index, data) }, .type_error_union => @panic("TODO"), .type_enum_simple => @panic("TODO"), @@ -971,10 +995,10 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index { }), }); }, - .optional_type => |optional_type| { + .opt_type => |opt_type| { ip.items.appendAssumeCapacity(.{ .tag = .type_optional, - .data = @enumToInt(optional_type.payload_type), + .data = @enumToInt(opt_type), }); }, .error_union_type => |error_union_type| { @@ -1192,3 +1216,13 @@ test "basic usage" { } }); try std.testing.expect(another_array_i32 == array_i32); } + +pub fn childType(ip: InternPool, i: Index) Index { + return switch (ip.indexToKey(i)) { + .ptr_type => |ptr_type| ptr_type.elem_type, + .vector_type => |vector_type| vector_type.child, + .array_type => |array_type| array_type.child, + .opt_type => |child| child, + else => unreachable, + }; +} diff --git a/src/Liveness.zig b/src/Liveness.zig index 01fbee9e36..19659940af 100644 --- a/src/Liveness.zig +++ b/src/Liveness.zig @@ -225,6 +225,7 @@ pub fn categorizeOperand( air: Air, inst: Air.Inst.Index, operand: Air.Inst.Index, + ip: InternPool, ) OperandCategory { const air_tags = air.instructions.items(.tag); const air_datas = air.instructions.items(.data); @@ -534,7 +535,7 @@ pub fn categorizeOperand( .aggregate_init => { const ty_pl = air_datas[inst].ty_pl; const aggregate_ty = air.getRefType(ty_pl.ty); - const len = @intCast(usize, aggregate_ty.arrayLen()); + const len = @intCast(usize, aggregate_ty.arrayLenIp(ip)); const elements = @ptrCast([]const Air.Inst.Ref, air.extra[ty_pl.payload..][0..len]); if (elements.len <= bpi - 1) { @@ -625,7 +626,7 @@ pub fn categorizeOperand( var operand_live: bool = true; for (air.extra[cond_extra.end..][0..2]) |cond_inst| { - if (l.categorizeOperand(air, cond_inst, operand) == .tomb) + if (l.categorizeOperand(air, cond_inst, operand, ip) == .tomb) operand_live = false; switch (air_tags[cond_inst]) { @@ -872,6 +873,7 @@ fn analyzeInst( data: *LivenessPassData(pass), inst: Air.Inst.Index, ) Allocator.Error!void { + const ip = a.intern_pool; const inst_tags = a.air.instructions.items(.tag); const inst_datas = a.air.instructions.items(.data); @@ -1140,7 +1142,7 @@ fn analyzeInst( .aggregate_init => { const ty_pl = inst_datas[inst].ty_pl; const aggregate_ty = a.air.getRefType(ty_pl.ty); - const len = @intCast(usize, aggregate_ty.arrayLen()); + const len = @intCast(usize, aggregate_ty.arrayLenIp(ip.*)); const elements = @ptrCast([]const Air.Inst.Ref, a.air.extra[ty_pl.payload..][0..len]); if (elements.len <= bpi - 1) { diff --git a/src/Liveness/Verify.zig b/src/Liveness/Verify.zig index e05f1814ce..7059fec507 100644 --- a/src/Liveness/Verify.zig +++ b/src/Liveness/Verify.zig @@ -325,7 +325,7 @@ fn verifyBody(self: *Verify, body: []const Air.Inst.Index) Error!void { .aggregate_init => { const ty_pl = data[inst].ty_pl; const aggregate_ty = self.air.getRefType(ty_pl.ty); - const len = @intCast(usize, aggregate_ty.arrayLen()); + const len = @intCast(usize, aggregate_ty.arrayLenIp(ip.*)); const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]); var bt = self.liveness.iterateBigTomb(inst); diff --git a/src/Module.zig b/src/Module.zig index 5c84b123c1..67ca91266c 100644 --- a/src/Module.zig +++ b/src/Module.zig @@ -5805,7 +5805,7 @@ pub fn analyzeFnBody(mod: *Module, func: *Fn, arena: Allocator) SemaError!Air { // is unused so it just has to be a no-op. sema.air_instructions.set(ptr_inst.*, .{ .tag = .alloc, - .data = .{ .ty = Type.initTag(.single_const_pointer_to_comptime_int) }, + .data = .{ .ty = Type.single_const_pointer_to_comptime_int }, }); } } @@ -6545,7 +6545,7 @@ pub fn populateTestFunctions( } const decl = mod.declPtr(decl_index); var buf: Type.SlicePtrFieldTypeBuffer = undefined; - const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).elemType(); + const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).childType(mod); const array_decl_index = d: { // Add mod.test_functions to an array decl then make the test_functions @@ -6575,7 +6575,7 @@ pub fn populateTestFunctions( errdefer name_decl_arena.deinit(); const bytes = try name_decl_arena.allocator().dupe(u8, test_name_slice); const test_name_decl_index = try mod.createAnonymousDeclFromDecl(array_decl, array_decl.src_namespace, null, .{ - .ty = try Type.Tag.array_u8.create(name_decl_arena.allocator(), bytes.len), + .ty = try Type.array(name_decl_arena.allocator(), bytes.len, null, Type.u8, mod), .val = try Value.Tag.bytes.create(name_decl_arena.allocator(), bytes), }); try mod.declPtr(test_name_decl_index).finalizeNewArena(&name_decl_arena); @@ -6609,7 +6609,12 @@ pub fn populateTestFunctions( { // This copy accesses the old Decl Type/Value so it must be done before `clearValues`. - const new_ty = try Type.Tag.const_slice.create(arena, try tmp_test_fn_ty.copy(arena)); + const new_ty = try Type.ptr(arena, mod, .{ + .size = .Slice, + .pointee_type = try tmp_test_fn_ty.copy(arena), + .mutable = false, + .@"addrspace" = .generic, + }); const new_var = try gpa.create(Var); errdefer gpa.destroy(new_var); new_var.* = decl.val.castTag(.variable).?.data.*; @@ -6819,6 +6824,34 @@ pub fn intType(mod: *Module, signedness: std.builtin.Signedness, bits: u16) Allo return i.toType(); } +pub fn arrayType(mod: *Module, info: InternPool.Key.ArrayType) Allocator.Error!Type { + const i = try intern(mod, .{ .array_type = info }); + return i.toType(); +} + +pub fn vectorType(mod: *Module, info: InternPool.Key.VectorType) Allocator.Error!Type { + const i = try intern(mod, .{ .vector_type = info }); + return i.toType(); +} + +pub fn optionalType(mod: *Module, child_type: InternPool.Index) Allocator.Error!Type { + const i = try intern(mod, .{ .opt_type = child_type }); + return i.toType(); +} + +pub fn ptrType(mod: *Module, info: InternPool.Key.PtrType) Allocator.Error!Type { + const i = try intern(mod, .{ .ptr_type = info }); + return i.toType(); +} + +pub fn singleMutPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { + return ptrType(mod, .{ .elem_type = child_type.ip_index }); +} + +pub fn singleConstPtrType(mod: *Module, child_type: Type) Allocator.Error!Type { + return ptrType(mod, .{ .elem_type = child_type.ip_index, .is_const = true }); +} + pub fn smallestUnsignedInt(mod: *Module, max: u64) Allocator.Error!Type { return intType(mod, .unsigned, Type.smallestUnsignedBits(max)); } diff --git a/src/Sema.zig b/src/Sema.zig index 7389719301..87df2f23e1 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -585,13 +585,18 @@ pub const Block = struct { } fn addCmpVector(block: *Block, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref, cmp_op: std.math.CompareOperator) !Air.Inst.Ref { + const sema = block.sema; + const mod = sema.mod; return block.addInst(.{ .tag = if (block.float_mode == .Optimized) .cmp_vector_optimized else .cmp_vector, .data = .{ .ty_pl = .{ - .ty = try block.sema.addType( - try Type.vector(block.sema.arena, block.sema.typeOf(lhs).vectorLen(), Type.bool), + .ty = try sema.addType( + try mod.vectorType(.{ + .len = sema.typeOf(lhs).vectorLen(mod), + .child = .bool_type, + }), ), - .payload = try block.sema.addExtra(Air.VectorCmp{ + .payload = try sema.addExtra(Air.VectorCmp{ .lhs = lhs, .rhs = rhs, .op = Air.VectorCmp.encodeOp(cmp_op), @@ -1760,7 +1765,7 @@ pub fn resolveConstString( reason: []const u8, ) ![]u8 { const air_inst = try sema.resolveInst(zir_ref); - const wanted_type = Type.initTag(.const_slice_u8); + const wanted_type = Type.const_slice_u8; const coerced_inst = try sema.coerce(block, wanted_type, air_inst, src); const val = try sema.resolveConstValue(block, src, coerced_inst, reason); return val.toAllocatedBytes(wanted_type, sema.arena, sema.mod); @@ -1788,7 +1793,8 @@ fn analyzeAsType( } pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) !void { - if (!sema.mod.backendSupportsFeature(.error_return_trace)) return; + const mod = sema.mod; + if (!mod.backendSupportsFeature(.error_return_trace)) return; assert(!block.is_comptime); var err_trace_block = block.makeSubBlock(); @@ -1798,13 +1804,13 @@ pub fn setupErrorReturnTrace(sema: *Sema, block: *Block, last_arg_index: usize) // var addrs: [err_return_trace_addr_count]usize = undefined; const err_return_trace_addr_count = 32; - const addr_arr_ty = try Type.array(sema.arena, err_return_trace_addr_count, null, Type.usize, sema.mod); - const addrs_ptr = try err_trace_block.addTy(.alloc, try Type.Tag.single_mut_pointer.create(sema.arena, addr_arr_ty)); + const addr_arr_ty = try Type.array(sema.arena, err_return_trace_addr_count, null, Type.usize, mod); + const addrs_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(addr_arr_ty)); // var st: StackTrace = undefined; const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); - const st_ptr = try err_trace_block.addTy(.alloc, try Type.Tag.single_mut_pointer.create(sema.arena, stack_trace_ty)); + const st_ptr = try err_trace_block.addTy(.alloc, try mod.singleMutPtrType(stack_trace_ty)); // st.instruction_addresses = &addrs; const addr_field_ptr = try sema.fieldPtr(&err_trace_block, src, st_ptr, "instruction_addresses", src, true); @@ -2101,11 +2107,10 @@ fn failWithUseOfAsync(sema: *Sema, block: *Block, src: LazySrcLoc) CompileError fn failWithInvalidFieldAccess(sema: *Sema, block: *Block, src: LazySrcLoc, object_ty: Type, field_name: []const u8) CompileError { const mod = sema.mod; - const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType() else object_ty; + const inner_ty = if (object_ty.isSinglePointer(mod)) object_ty.childType(mod) else object_ty; if (inner_ty.zigTypeTag(mod) == .Optional) opt: { - var buf: Type.Payload.ElemType = undefined; - const child_ty = inner_ty.optionalChild(&buf); + const child_ty = inner_ty.optionalChild(mod); if (!typeSupportsFieldAccess(mod, child_ty, field_name)) break :opt; const msg = msg: { const msg = try sema.errMsg(block, src, "optional type '{}' does not support field access", .{object_ty.fmt(sema.mod)}); @@ -2132,7 +2137,7 @@ fn typeSupportsFieldAccess(mod: *const Module, ty: Type, field_name: []const u8) switch (ty.zigTypeTag(mod)) { .Array => return mem.eql(u8, field_name, "len"), .Pointer => { - const ptr_info = ty.ptrInfo().data; + const ptr_info = ty.ptrInfo(mod); if (ptr_info.size == .Slice) { return mem.eql(u8, field_name, "ptr") or mem.eql(u8, field_name, "len"); } else if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) { @@ -2504,6 +2509,7 @@ fn coerceResultPtr( dummy_operand: Air.Inst.Ref, trash_block: *Block, ) CompileError!Air.Inst.Ref { + const mod = sema.mod; const target = sema.mod.getTarget(); const addr_space = target_util.defaultAddressSpace(target, .local); const pointee_ty = sema.typeOf(dummy_operand); @@ -2547,7 +2553,7 @@ fn coerceResultPtr( return sema.addConstant(ptr_ty, ptr_val); } if (pointee_ty.eql(Type.null, sema.mod)) { - const opt_ty = sema.typeOf(new_ptr).childType(); + const opt_ty = sema.typeOf(new_ptr).childType(mod); const null_inst = try sema.addConstant(opt_ty, Value.null); _ = try block.addBinOp(.store, new_ptr, null_inst); return Air.Inst.Ref.void_value; @@ -3394,7 +3400,7 @@ fn zirEnsureErrUnionPayloadVoid(sema: *Sema, block: *Block, inst: Zir.Inst.Index const operand = try sema.resolveInst(inst_data.operand); const operand_ty = sema.typeOf(operand); const err_union_ty = if (operand_ty.zigTypeTag(mod) == .Pointer) - operand_ty.childType() + operand_ty.childType(mod) else operand_ty; if (err_union_ty.zigTypeTag(mod) != .ErrorUnion) return; @@ -3430,7 +3436,7 @@ fn indexablePtrLen( const mod = sema.mod; const object_ty = sema.typeOf(object); const is_pointer_to = object_ty.isSinglePointer(mod); - const indexable_ty = if (is_pointer_to) object_ty.childType() else object_ty; + const indexable_ty = if (is_pointer_to) object_ty.childType(mod) else object_ty; try checkIndexable(sema, block, src, indexable_ty); return sema.fieldVal(block, src, object, "len", src); } @@ -3441,9 +3447,10 @@ fn indexablePtrLenOrNone( src: LazySrcLoc, operand: Air.Inst.Ref, ) CompileError!Air.Inst.Ref { + const mod = sema.mod; const operand_ty = sema.typeOf(operand); try checkMemOperand(sema, block, src, operand_ty); - if (operand_ty.ptrSize() == .Many) return .none; + if (operand_ty.ptrSize(mod) == .Many) return .none; return sema.fieldVal(block, src, operand, "len", src); } @@ -3529,11 +3536,12 @@ fn zirAllocComptime(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr } fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { + const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[inst].un_node; const alloc = try sema.resolveInst(inst_data.operand); const alloc_ty = sema.typeOf(alloc); - var ptr_info = alloc_ty.ptrInfo().data; + var ptr_info = alloc_ty.ptrInfo(mod); const elem_ty = ptr_info.pointee_type; // Detect if all stores to an `.alloc` were comptime-known. @@ -3589,9 +3597,10 @@ fn zirMakePtrConst(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro } fn makePtrConst(sema: *Sema, block: *Block, alloc: Air.Inst.Ref) CompileError!Air.Inst.Ref { + const mod = sema.mod; const alloc_ty = sema.typeOf(alloc); - var ptr_info = alloc_ty.ptrInfo().data; + var ptr_info = alloc_ty.ptrInfo(mod); ptr_info.mutable = false; const const_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info); @@ -3947,13 +3956,13 @@ fn zirArrayBasePtr( const start_ptr = try sema.resolveInst(inst_data.operand); var base_ptr = start_ptr; - while (true) switch (sema.typeOf(base_ptr).childType().zigTypeTag(mod)) { + while (true) switch (sema.typeOf(base_ptr).childType(mod).zigTypeTag(mod)) { .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true), .Optional => base_ptr = try sema.analyzeOptionalPayloadPtr(block, src, base_ptr, false, true), else => break, }; - const elem_ty = sema.typeOf(base_ptr).childType(); + const elem_ty = sema.typeOf(base_ptr).childType(mod); switch (elem_ty.zigTypeTag(mod)) { .Array, .Vector => return base_ptr, .Struct => if (elem_ty.isTuple()) { @@ -3962,7 +3971,7 @@ fn zirArrayBasePtr( }, else => {}, } - return sema.failWithArrayInitNotSupported(block, src, sema.typeOf(start_ptr).childType()); + return sema.failWithArrayInitNotSupported(block, src, sema.typeOf(start_ptr).childType(mod)); } fn zirFieldBasePtr( @@ -3976,18 +3985,18 @@ fn zirFieldBasePtr( const start_ptr = try sema.resolveInst(inst_data.operand); var base_ptr = start_ptr; - while (true) switch (sema.typeOf(base_ptr).childType().zigTypeTag(mod)) { + while (true) switch (sema.typeOf(base_ptr).childType(mod).zigTypeTag(mod)) { .ErrorUnion => base_ptr = try sema.analyzeErrUnionPayloadPtr(block, src, base_ptr, false, true), .Optional => base_ptr = try sema.analyzeOptionalPayloadPtr(block, src, base_ptr, false, true), else => break, }; - const elem_ty = sema.typeOf(base_ptr).childType(); + const elem_ty = sema.typeOf(base_ptr).childType(mod); switch (elem_ty.zigTypeTag(mod)) { .Struct, .Union => return base_ptr, else => {}, } - return sema.failWithStructInitNotSupported(block, src, sema.typeOf(start_ptr).childType()); + return sema.failWithStructInitNotSupported(block, src, sema.typeOf(start_ptr).childType(mod)); } fn zirForLen(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { @@ -4129,7 +4138,7 @@ fn validateArrayInitTy( switch (ty.zigTypeTag(mod)) { .Array => { - const array_len = ty.arrayLen(); + const array_len = ty.arrayLen(mod); if (extra.init_count != array_len) { return sema.fail(block, src, "expected {d} array elements; found {d}", .{ array_len, extra.init_count, @@ -4138,7 +4147,7 @@ fn validateArrayInitTy( return; }, .Vector => { - const array_len = ty.arrayLen(); + const array_len = ty.arrayLen(mod); if (extra.init_count != array_len) { return sema.fail(block, src, "expected {d} vector elements; found {d}", .{ array_len, extra.init_count, @@ -4148,7 +4157,7 @@ fn validateArrayInitTy( }, .Struct => if (ty.isTuple()) { _ = try sema.resolveTypeFields(ty); - const array_len = ty.arrayLen(); + const array_len = ty.arrayLen(mod); if (extra.init_count > array_len) { return sema.fail(block, src, "expected at most {d} tuple fields; found {d}", .{ array_len, extra.init_count, @@ -4194,7 +4203,7 @@ fn zirValidateStructInit( const field_ptr_data = sema.code.instructions.items(.data)[instrs[0]].pl_node; const field_ptr_extra = sema.code.extraData(Zir.Inst.Field, field_ptr_data.payload_index).data; const object_ptr = try sema.resolveInst(field_ptr_extra.lhs); - const agg_ty = sema.typeOf(object_ptr).childType(); + const agg_ty = sema.typeOf(object_ptr).childType(mod); switch (agg_ty.zigTypeTag(mod)) { .Struct => return sema.validateStructInit( block, @@ -4350,6 +4359,7 @@ fn validateStructInit( init_src: LazySrcLoc, instrs: []const Zir.Inst.Index, ) CompileError!void { + const mod = sema.mod; const gpa = sema.gpa; // Maps field index to field_ptr index of where it was already initialized. @@ -4425,14 +4435,13 @@ fn validateStructInit( try sema.tupleFieldPtr(block, init_src, struct_ptr, field_src, @intCast(u32, i), true) else try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(u32, i), field_src, struct_ty, true); - const field_ty = sema.typeOf(default_field_ptr).childType(); + const field_ty = sema.typeOf(default_field_ptr).childType(mod); const init = try sema.addConstant(field_ty, default_val); try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); } if (root_msg) |msg| { if (struct_ty.castTag(.@"struct")) |struct_obj| { - const mod = sema.mod; const fqn = try struct_obj.data.getFullyQualifiedName(mod); defer gpa.free(fqn); try mod.errNoteNonLazy( @@ -4605,7 +4614,7 @@ fn validateStructInit( try sema.tupleFieldPtr(block, init_src, struct_ptr, field_src, @intCast(u32, i), true) else try sema.structFieldPtrByIndex(block, init_src, struct_ptr, @intCast(u32, i), field_src, struct_ty, true); - const field_ty = sema.typeOf(default_field_ptr).childType(); + const field_ty = sema.typeOf(default_field_ptr).childType(mod); const init = try sema.addConstant(field_ty, field_values[i]); try sema.storePtr2(block, init_src, default_field_ptr, init_src, init, field_src, .store); } @@ -4624,8 +4633,8 @@ fn zirValidateArrayInit( const first_elem_ptr_data = sema.code.instructions.items(.data)[instrs[0]].pl_node; const elem_ptr_extra = sema.code.extraData(Zir.Inst.ElemPtrImm, first_elem_ptr_data.payload_index).data; const array_ptr = try sema.resolveInst(elem_ptr_extra.ptr); - const array_ty = sema.typeOf(array_ptr).childType(); - const array_len = array_ty.arrayLen(); + const array_ty = sema.typeOf(array_ptr).childType(mod); + const array_len = array_ty.arrayLen(mod); if (instrs.len != array_len) switch (array_ty.zigTypeTag(mod)) { .Struct => { @@ -4670,10 +4679,10 @@ fn zirValidateArrayInit( // at comptime so we have almost nothing to do here. However, in case of a // sentinel-terminated array, the sentinel will not have been populated by // any ZIR instructions at comptime; we need to do that here. - if (array_ty.sentinel()) |sentinel_val| { + if (array_ty.sentinel(mod)) |sentinel_val| { const array_len_ref = try sema.addIntUnsigned(Type.usize, array_len); const sentinel_ptr = try sema.elemPtrArray(block, init_src, init_src, array_ptr, init_src, array_len_ref, true, true); - const sentinel = try sema.addConstant(array_ty.childType(), sentinel_val); + const sentinel = try sema.addConstant(array_ty.childType(mod), sentinel_val); try sema.storePtr2(block, init_src, sentinel_ptr, init_src, sentinel, init_src, .store); } return; @@ -4685,7 +4694,7 @@ fn zirValidateArrayInit( // Collect the comptime element values in case the array literal ends up // being comptime-known. - const array_len_s = try sema.usizeCast(block, init_src, array_ty.arrayLenIncludingSentinel()); + const array_len_s = try sema.usizeCast(block, init_src, array_ty.arrayLenIncludingSentinel(mod)); const element_vals = try sema.arena.alloc(Value, array_len_s); const opt_opv = try sema.typeHasOnePossibleValue(array_ty); const air_tags = sema.air_instructions.items(.tag); @@ -4784,7 +4793,7 @@ fn zirValidateArrayInit( // Our task is to delete all the `elem_ptr` and `store` instructions, and insert // instead a single `store` to the array_ptr with a comptime struct value. // Also to populate the sentinel value, if any. - if (array_ty.sentinel()) |sentinel_val| { + if (array_ty.sentinel(mod)) |sentinel_val| { element_vals[instrs.len] = sentinel_val; } @@ -4806,13 +4815,13 @@ fn zirValidateDeref(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr if (operand_ty.zigTypeTag(mod) != .Pointer) { return sema.fail(block, src, "cannot dereference non-pointer type '{}'", .{operand_ty.fmt(sema.mod)}); - } else switch (operand_ty.ptrSize()) { + } else switch (operand_ty.ptrSize(mod)) { .One, .C => {}, .Many => return sema.fail(block, src, "index syntax required for unknown-length pointer type '{}'", .{operand_ty.fmt(sema.mod)}), .Slice => return sema.fail(block, src, "index syntax required for slice type '{}'", .{operand_ty.fmt(sema.mod)}), } - if ((try sema.typeHasOnePossibleValue(operand_ty.childType())) != null) { + if ((try sema.typeHasOnePossibleValue(operand_ty.childType(mod))) != null) { // No need to validate the actual pointer value, we don't need it! return; } @@ -5132,7 +5141,7 @@ fn addStrLit(sema: *Sema, block: *Block, zir_bytes: []const u8) CompileError!Air defer anon_decl.deinit(); const decl_index = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), gop.key_ptr.len), + try Type.array(anon_decl.arena(), gop.key_ptr.len, Value.zero, Type.u8, mod), try Value.Tag.str_lit.create(anon_decl.arena(), gop.key_ptr.*), 0, // default alignment ); @@ -6003,10 +6012,11 @@ fn addDbgVar( air_tag: Air.Inst.Tag, name: []const u8, ) CompileError!void { + const mod = sema.mod; const operand_ty = sema.typeOf(operand); switch (air_tag) { .dbg_var_ptr => { - if (!(try sema.typeHasRuntimeBits(operand_ty.childType()))) return; + if (!(try sema.typeHasRuntimeBits(operand_ty.childType(mod)))) return; }, .dbg_var_val => { if (!(try sema.typeHasRuntimeBits(operand_ty))) return; @@ -6238,7 +6248,7 @@ fn popErrorReturnTrace( const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); - const ptr_stack_trace_ty = try Type.Tag.single_mut_pointer.create(sema.arena, stack_trace_ty); + const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty); const field_ptr = try sema.structFieldPtr(block, src, err_return_trace, "index", src, stack_trace_ty, true); try sema.storePtr2(block, src, field_ptr, src, saved_error_trace_index, src, .store); @@ -6263,7 +6273,7 @@ fn popErrorReturnTrace( // If non-error, then pop the error return trace by restoring the index. const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); - const ptr_stack_trace_ty = try Type.Tag.single_mut_pointer.create(sema.arena, stack_trace_ty); + const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); const err_return_trace = try then_block.addTy(.err_return_trace, ptr_stack_trace_ty); const field_ptr = try sema.structFieldPtr(&then_block, src, err_return_trace, "index", src, stack_trace_ty, true); try sema.storePtr2(&then_block, src, field_ptr, src, saved_error_trace_index, src, .store); @@ -6456,16 +6466,15 @@ fn checkCallArgumentCount( switch (callee_ty.zigTypeTag(mod)) { .Fn => break :func_ty callee_ty, .Pointer => { - const ptr_info = callee_ty.ptrInfo().data; + const ptr_info = callee_ty.ptrInfo(mod); if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) { break :func_ty ptr_info.pointee_type; } }, .Optional => { - var buf: Type.Payload.ElemType = undefined; - const opt_child = callee_ty.optionalChild(&buf); + const opt_child = callee_ty.optionalChild(mod); if (opt_child.zigTypeTag(mod) == .Fn or (opt_child.isSinglePointer(mod) and - opt_child.childType().zigTypeTag(mod) == .Fn)) + opt_child.childType(mod).zigTypeTag(mod) == .Fn)) { const msg = msg: { const msg = try sema.errMsg(block, func_src, "cannot call optional type '{}'", .{ @@ -6529,7 +6538,7 @@ fn callBuiltin( switch (callee_ty.zigTypeTag(mod)) { .Fn => break :func_ty callee_ty, .Pointer => { - const ptr_info = callee_ty.ptrInfo().data; + const ptr_info = callee_ty.ptrInfo(mod); if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Fn) { break :func_ty ptr_info.pointee_type; } @@ -7929,7 +7938,7 @@ fn zirOptionalType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErro } else if (child_type.zigTypeTag(mod) == .Null) { return sema.fail(block, operand_src, "type '{}' cannot be optional", .{child_type.fmt(sema.mod)}); } - const opt_type = try Type.optional(sema.arena, child_type); + const opt_type = try Type.optional(sema.arena, child_type, mod); return sema.addType(opt_type); } @@ -7949,16 +7958,17 @@ fn zirElemTypeIndex(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr } fn zirVectorType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { + const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const elem_type_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const len_src: LazySrcLoc = .{ .node_offset_builtin_call_arg1 = inst_data.src_node }; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; - const len = try sema.resolveInt(block, len_src, extra.lhs, Type.u32, "vector length must be comptime-known"); + const len = @intCast(u32, try sema.resolveInt(block, len_src, extra.lhs, Type.u32, "vector length must be comptime-known")); const elem_type = try sema.resolveType(block, elem_type_src, extra.rhs); try sema.checkVectorElemType(block, elem_type_src, elem_type); - const vector_type = try Type.Tag.vector.create(sema.arena, .{ - .len = @intCast(u32, len), - .elem_type = elem_type, + const vector_type = try mod.vectorType(.{ + .len = len, + .child = elem_type.ip_index, }); return sema.addType(vector_type); } @@ -8377,16 +8387,16 @@ fn analyzeOptionalPayloadPtr( const optional_ptr_ty = sema.typeOf(optional_ptr); assert(optional_ptr_ty.zigTypeTag(mod) == .Pointer); - const opt_type = optional_ptr_ty.elemType(); + const opt_type = optional_ptr_ty.childType(mod); if (opt_type.zigTypeTag(mod) != .Optional) { return sema.fail(block, src, "expected optional type, found '{}'", .{opt_type.fmt(sema.mod)}); } - const child_type = try opt_type.optionalChildAlloc(sema.arena); + const child_type = opt_type.optionalChild(mod); const child_pointer = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = child_type, .mutable = !optional_ptr_ty.isConstPtr(), - .@"addrspace" = optional_ptr_ty.ptrAddressSpace(), + .@"addrspace" = optional_ptr_ty.ptrAddressSpace(mod), }); if (try sema.resolveDefinedValue(block, src, optional_ptr)) |ptr_val| { @@ -8401,7 +8411,7 @@ fn analyzeOptionalPayloadPtr( child_pointer, try Value.Tag.opt_payload_ptr.create(sema.arena, .{ .container_ptr = ptr_val, - .container_ty = optional_ptr_ty.childType(), + .container_ty = optional_ptr_ty.childType(mod), }), ); } @@ -8414,7 +8424,7 @@ fn analyzeOptionalPayloadPtr( child_pointer, try Value.Tag.opt_payload_ptr.create(sema.arena, .{ .container_ptr = ptr_val, - .container_ty = optional_ptr_ty.childType(), + .container_ty = optional_ptr_ty.childType(mod), }), ); } @@ -8448,14 +8458,14 @@ fn zirOptionalPayload( const operand = try sema.resolveInst(inst_data.operand); const operand_ty = sema.typeOf(operand); const result_ty = switch (operand_ty.zigTypeTag(mod)) { - .Optional => try operand_ty.optionalChildAlloc(sema.arena), + .Optional => operand_ty.optionalChild(mod), .Pointer => t: { - if (operand_ty.ptrSize() != .C) { + if (operand_ty.ptrSize(mod) != .C) { return sema.failWithExpectedOptionalType(block, src, operand_ty); } // TODO https://github.com/ziglang/zig/issues/6597 if (true) break :t operand_ty; - const ptr_info = operand_ty.ptrInfo().data; + const ptr_info = operand_ty.ptrInfo(mod); break :t try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = try ptr_info.pointee_type.copy(sema.arena), .@"align" = ptr_info.@"align", @@ -8569,18 +8579,18 @@ fn analyzeErrUnionPayloadPtr( const operand_ty = sema.typeOf(operand); assert(operand_ty.zigTypeTag(mod) == .Pointer); - if (operand_ty.elemType().zigTypeTag(mod) != .ErrorUnion) { + if (operand_ty.childType(mod).zigTypeTag(mod) != .ErrorUnion) { return sema.fail(block, src, "expected error union type, found '{}'", .{ - operand_ty.elemType().fmt(sema.mod), + operand_ty.childType(mod).fmt(sema.mod), }); } - const err_union_ty = operand_ty.elemType(); + const err_union_ty = operand_ty.childType(mod); const payload_ty = err_union_ty.errorUnionPayload(); const operand_pointer_ty = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = payload_ty, .mutable = !operand_ty.isConstPtr(), - .@"addrspace" = operand_ty.ptrAddressSpace(), + .@"addrspace" = operand_ty.ptrAddressSpace(mod), }); if (try sema.resolveDefinedValue(block, src, operand)) |ptr_val| { @@ -8596,7 +8606,7 @@ fn analyzeErrUnionPayloadPtr( operand_pointer_ty, try Value.Tag.eu_payload_ptr.create(sema.arena, .{ .container_ptr = ptr_val, - .container_ty = operand_ty.elemType(), + .container_ty = operand_ty.childType(mod), }), ); } @@ -8609,7 +8619,7 @@ fn analyzeErrUnionPayloadPtr( operand_pointer_ty, try Value.Tag.eu_payload_ptr.create(sema.arena, .{ .container_ptr = ptr_val, - .container_ty = operand_ty.elemType(), + .container_ty = operand_ty.childType(mod), }), ); } @@ -8674,13 +8684,13 @@ fn zirErrUnionCodePtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE const operand_ty = sema.typeOf(operand); assert(operand_ty.zigTypeTag(mod) == .Pointer); - if (operand_ty.elemType().zigTypeTag(mod) != .ErrorUnion) { + if (operand_ty.childType(mod).zigTypeTag(mod) != .ErrorUnion) { return sema.fail(block, src, "expected error union type, found '{}'", .{ - operand_ty.elemType().fmt(sema.mod), + operand_ty.childType(mod).fmt(sema.mod), }); } - const result_ty = operand_ty.elemType().errorUnionSet(); + const result_ty = operand_ty.childType(mod).errorUnionSet(); if (try sema.resolveDefinedValue(block, src, operand)) |pointer_val| { if (try sema.pointerDeref(block, src, pointer_val, operand_ty)) |val| { @@ -10119,7 +10129,7 @@ fn zirSwitchCapture( const operand_is_ref = cond_tag == .switch_cond_ref; const operand_ptr = try sema.resolveInst(cond_info.operand); const operand_ptr_ty = sema.typeOf(operand_ptr); - const operand_ty = if (operand_is_ref) operand_ptr_ty.childType() else operand_ptr_ty; + const operand_ty = if (operand_is_ref) operand_ptr_ty.childType(mod) else operand_ptr_ty; if (block.inline_case_capture != .none) { const item_val = sema.resolveConstValue(block, .unneeded, block.inline_case_capture, undefined) catch unreachable; @@ -10131,9 +10141,9 @@ fn zirSwitchCapture( if (is_ref) { const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = field_ty, - .mutable = operand_ptr_ty.ptrIsMutable(), + .mutable = operand_ptr_ty.ptrIsMutable(mod), .@"volatile" = operand_ptr_ty.isVolatilePtr(), - .@"addrspace" = operand_ptr_ty.ptrAddressSpace(), + .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod), }); return sema.addConstant( ptr_field_ty, @@ -10150,9 +10160,9 @@ fn zirSwitchCapture( if (is_ref) { const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = field_ty, - .mutable = operand_ptr_ty.ptrIsMutable(), + .mutable = operand_ptr_ty.ptrIsMutable(mod), .@"volatile" = operand_ptr_ty.isVolatilePtr(), - .@"addrspace" = operand_ptr_ty.ptrAddressSpace(), + .@"addrspace" = operand_ptr_ty.ptrAddressSpace(mod), }); return block.addStructFieldPtr(operand_ptr, field_index, ptr_field_ty); } else { @@ -10235,7 +10245,7 @@ fn zirSwitchCapture( const field_ty_ptr = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = first_field.ty, .@"addrspace" = .generic, - .mutable = operand_ptr_ty.ptrIsMutable(), + .mutable = operand_ptr_ty.ptrIsMutable(mod), }); if (try sema.resolveDefinedValue(block, operand_src, operand_ptr)) |op_ptr_val| { @@ -10311,7 +10321,7 @@ fn zirSwitchCaptureTag(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compile const cond_data = zir_datas[Zir.refToIndex(inst_data.operand).?].un_node; const operand_ptr = try sema.resolveInst(cond_data.operand); const operand_ptr_ty = sema.typeOf(operand_ptr); - const operand_ty = if (is_ref) operand_ptr_ty.childType() else operand_ptr_ty; + const operand_ty = if (is_ref) operand_ptr_ty.childType(mod) else operand_ptr_ty; if (operand_ty.zigTypeTag(mod) != .Union) { const msg = msg: { @@ -10448,7 +10458,7 @@ fn zirSwitchBlock(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError const cond_index = Zir.refToIndex(extra.data.operand).?; const raw_operand = sema.resolveInst(zir_data[cond_index].un_node.operand) catch unreachable; const target_ty = sema.typeOf(raw_operand); - break :blk if (zir_tags[cond_index] == .switch_cond_ref) target_ty.elemType() else target_ty; + break :blk if (zir_tags[cond_index] == .switch_cond_ref) target_ty.childType(mod) else target_ty; }; const union_originally = maybe_union_ty.zigTypeTag(mod) == .Union; @@ -12132,7 +12142,7 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A // into the final binary, and never loads the data into memory. // - When a Decl is destroyed, it can free the `*Module.EmbedFile`. embed_file.owner_decl = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), embed_file.bytes.len), + try Type.array(anon_decl.arena(), embed_file.bytes.len, Value.zero, Type.u8, mod), try Value.Tag.bytes.create(anon_decl.arena(), bytes_including_null), 0, // default alignment ); @@ -12200,7 +12210,7 @@ fn zirShl( const bit_value = Value.initPayload(&bits_payload.base); if (rhs_ty.zigTypeTag(mod) == .Vector) { var i: usize = 0; - while (i < rhs_ty.vectorLen()) : (i += 1) { + while (i < rhs_ty.vectorLen(mod)) : (i += 1) { var elem_value_buf: Value.ElemValueBuffer = undefined; const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf); if (rhs_elem.compareHetero(.gte, bit_value, mod)) { @@ -12220,7 +12230,7 @@ fn zirShl( } if (rhs_ty.zigTypeTag(mod) == .Vector) { var i: usize = 0; - while (i < rhs_ty.vectorLen()) : (i += 1) { + while (i < rhs_ty.vectorLen(mod)) : (i += 1) { var elem_value_buf: Value.ElemValueBuffer = undefined; const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf); if (rhs_elem.compareHetero(.lt, Value.zero, mod)) { @@ -12388,7 +12398,7 @@ fn zirShr( const bit_value = Value.initPayload(&bits_payload.base); if (rhs_ty.zigTypeTag(mod) == .Vector) { var i: usize = 0; - while (i < rhs_ty.vectorLen()) : (i += 1) { + while (i < rhs_ty.vectorLen(mod)) : (i += 1) { var elem_value_buf: Value.ElemValueBuffer = undefined; const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf); if (rhs_elem.compareHetero(.gte, bit_value, mod)) { @@ -12408,7 +12418,7 @@ fn zirShr( } if (rhs_ty.zigTypeTag(mod) == .Vector) { var i: usize = 0; - while (i < rhs_ty.vectorLen()) : (i += 1) { + while (i < rhs_ty.vectorLen(mod)) : (i += 1) { var elem_value_buf: Value.ElemValueBuffer = undefined; const rhs_elem = rhs_val.elemValueBuffer(sema.mod, i, &elem_value_buf); if (rhs_elem.compareHetero(.lt, Value.zero, mod)) { @@ -12571,7 +12581,7 @@ fn zirBitNot(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. if (val.isUndef()) { return sema.addConstUndef(operand_type); } else if (operand_type.zigTypeTag(mod) == .Vector) { - const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen()); + const vec_len = try sema.usizeCast(block, operand_src, operand_type.vectorLen(mod)); var elem_val_buf: Value.ElemValueBuffer = undefined; const elems = try sema.arena.alloc(Value, vec_len); for (elems, 0..) |*elem, i| { @@ -12768,8 +12778,8 @@ fn zirArrayCat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const result_ty = try Type.array(sema.arena, result_len, res_sent_val, resolved_elem_ty, sema.mod); const mod = sema.mod; const ptr_addrspace = p: { - if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(); - if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace(); + if (lhs_ty.zigTypeTag(mod) == .Pointer) break :p lhs_ty.ptrAddressSpace(mod); + if (rhs_ty.zigTypeTag(mod) == .Pointer) break :p rhs_ty.ptrAddressSpace(mod); break :p null; }; @@ -12883,9 +12893,9 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins const mod = sema.mod; const operand_ty = sema.typeOf(operand); switch (operand_ty.zigTypeTag(mod)) { - .Array => return operand_ty.arrayInfo(), + .Array => return operand_ty.arrayInfo(mod), .Pointer => { - const ptr_info = operand_ty.ptrInfo().data; + const ptr_info = operand_ty.ptrInfo(mod); switch (ptr_info.size) { // TODO: in the Many case here this should only work if the type // has a sentinel, and this code should compute the length based @@ -12900,7 +12910,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins }, .One => { if (ptr_info.pointee_type.zigTypeTag(mod) == .Array) { - return ptr_info.pointee_type.arrayInfo(); + return ptr_info.pointee_type.arrayInfo(mod); } }, .C => {}, @@ -12912,7 +12922,7 @@ fn getArrayCatInfo(sema: *Sema, block: *Block, src: LazySrcLoc, operand: Air.Ins return .{ .elem_type = peer_ty.elemType2(mod), .sentinel = null, - .len = operand_ty.arrayLen(), + .len = operand_ty.arrayLen(mod), }; } }, @@ -13035,7 +13045,7 @@ fn zirArrayMul(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const result_ty = try Type.array(sema.arena, result_len, lhs_info.sentinel, lhs_info.elem_type, sema.mod); - const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace() else null; + const ptr_addrspace = if (lhs_ty.zigTypeTag(mod) == .Pointer) lhs_ty.ptrAddressSpace(mod) else null; const lhs_len = try sema.usizeCast(block, lhs_src, lhs_info.len); if (try sema.resolveDefinedValue(block, lhs_src, lhs)) |lhs_val| { @@ -14022,7 +14032,7 @@ fn intRem( ) CompileError!Value { const mod = sema.mod; if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try sema.arena.alloc(Value, ty.vectorLen()); + const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -14484,7 +14494,10 @@ fn maybeRepeated(sema: *Sema, ty: Type, val: Value) !Value { fn overflowArithmeticTupleType(sema: *Sema, ty: Type) !Type { const mod = sema.mod; - const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try Type.vector(sema.arena, ty.vectorLen(), Type.u1) else Type.u1; + const ov_ty = if (ty.zigTypeTag(mod) == .Vector) try mod.vectorType(.{ + .len = ty.vectorLen(mod), + .child = .u1_type, + }) else Type.u1; const types = try sema.arena.alloc(Type, 2); const values = try sema.arena.alloc(Value, 2); @@ -14520,7 +14533,7 @@ fn analyzeArithmetic( const rhs_zig_ty_tag = try rhs_ty.zigTypeTagOrPoison(mod); try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); - if (lhs_zig_ty_tag == .Pointer) switch (lhs_ty.ptrSize()) { + if (lhs_zig_ty_tag == .Pointer) switch (lhs_ty.ptrSize(mod)) { .One, .Slice => {}, .Many, .C => { const air_tag: Air.Inst.Tag = switch (zir_tag) { @@ -14993,9 +15006,9 @@ fn analyzePtrArithmetic( const opt_ptr_val = try sema.resolveMaybeUndefVal(ptr); const opt_off_val = try sema.resolveDefinedValue(block, offset_src, offset); const ptr_ty = sema.typeOf(ptr); - const ptr_info = ptr_ty.ptrInfo().data; + const ptr_info = ptr_ty.ptrInfo(mod); const elem_ty = if (ptr_info.size == .One and ptr_info.pointee_type.zigTypeTag(mod) == .Array) - ptr_info.pointee_type.childType() + ptr_info.pointee_type.childType(mod) else ptr_info.pointee_type; @@ -15466,7 +15479,10 @@ fn cmpSelf( if (rhs_val.isUndef()) return sema.addConstUndef(Type.bool); if (resolved_type.zigTypeTag(mod) == .Vector) { - const result_ty = try Type.vector(sema.arena, resolved_type.vectorLen(), Type.bool); + const result_ty = try mod.vectorType(.{ + .len = resolved_type.vectorLen(mod), + .child = .bool_type, + }); const cmp_val = try sema.compareVector(lhs_val, op, rhs_val, resolved_type); return sema.addConstant(result_ty, cmp_val); } @@ -15767,6 +15783,7 @@ fn zirBuiltinSrc( const tracy = trace(@src()); defer tracy.end(); + const mod = sema.mod; const extra = sema.code.extraData(Zir.Inst.Src, extended.operand).data; const src = LazySrcLoc.nodeOffset(extra.node); const func = sema.func orelse return sema.fail(block, src, "@src outside function", .{}); @@ -15778,7 +15795,7 @@ fn zirBuiltinSrc( const name = std.mem.span(fn_owner_decl.name); const bytes = try anon_decl.arena().dupe(u8, name[0 .. name.len + 1]); const new_decl = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len - 1), + try Type.array(anon_decl.arena(), bytes.len - 1, Value.zero, Type.u8, mod), try Value.Tag.bytes.create(anon_decl.arena(), bytes), 0, // default alignment ); @@ -15791,7 +15808,7 @@ fn zirBuiltinSrc( // The compiler must not call realpath anywhere. const name = try fn_owner_decl.getFileScope().fullPathZ(anon_decl.arena()); const new_decl = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), name.len), + try Type.array(anon_decl.arena(), name.len, Value.zero, Type.u8, mod), try Value.Tag.bytes.create(anon_decl.arena(), name[0 .. name.len + 1]), 0, // default alignment ); @@ -16024,7 +16041,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai ); }, .Pointer => { - const info = ty.ptrInfo().data; + const info = ty.ptrInfo(mod); const alignment = if (info.@"align" != 0) try Value.Tag.int_u64.create(sema.arena, info.@"align") else @@ -16059,7 +16076,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai ); }, .Array => { - const info = ty.arrayInfo(); + const info = ty.arrayInfo(mod); const field_values = try sema.arena.alloc(Value, 3); // len: comptime_int, field_values[0] = try Value.Tag.int_u64.create(sema.arena, info.len); @@ -16077,7 +16094,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai ); }, .Vector => { - const info = ty.arrayInfo(); + const info = ty.arrayInfo(mod); const field_values = try sema.arena.alloc(Value, 2); // len: comptime_int, field_values[0] = try Value.Tag.int_u64.create(sema.arena, info.len); @@ -16095,7 +16112,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai .Optional => { const field_values = try sema.arena.alloc(Value, 1); // child: type, - field_values[0] = try Value.Tag.ty.create(sema.arena, try ty.optionalChildAlloc(sema.arena)); + field_values[0] = try Value.Tag.ty.create(sema.arena, ty.optionalChild(mod)); return sema.addConstant( type_info_ty, @@ -16141,7 +16158,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai defer anon_decl.deinit(); const bytes = try anon_decl.arena().dupeZ(u8, name); const new_decl = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), + try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), 0, // default alignment ); @@ -16250,7 +16267,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai defer anon_decl.deinit(); const bytes = try anon_decl.arena().dupeZ(u8, name); const new_decl = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), + try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), 0, // default alignment ); @@ -16338,7 +16355,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai defer anon_decl.deinit(); const bytes = try anon_decl.arena().dupeZ(u8, name); const new_decl = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), + try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), 0, // default alignment ); @@ -16448,7 +16465,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai else try std.fmt.allocPrintZ(anon_decl.arena(), "{d}", .{i}); const new_decl = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), + try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), 0, // default alignment ); @@ -16490,7 +16507,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai defer anon_decl.deinit(); const bytes = try anon_decl.arena().dupeZ(u8, name); const new_decl = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), + try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), 0, // default alignment ); @@ -16666,14 +16683,15 @@ fn typeInfoNamespaceDecls( decl_vals: *std.ArrayList(Value), seen_namespaces: *std.AutoHashMap(*Namespace, void), ) !void { + const mod = sema.mod; const gop = try seen_namespaces.getOrPut(namespace); if (gop.found_existing) return; const decls = namespace.decls.keys(); for (decls) |decl_index| { - const decl = sema.mod.declPtr(decl_index); + const decl = mod.declPtr(decl_index); if (decl.kind == .@"usingnamespace") { if (decl.analysis == .in_progress) continue; - try sema.mod.ensureDeclAnalyzed(decl_index); + try mod.ensureDeclAnalyzed(decl_index); const new_ns = decl.val.toType().getNamespace().?; try sema.typeInfoNamespaceDecls(block, decls_anon_decl, new_ns, decl_vals, seen_namespaces); continue; @@ -16684,7 +16702,7 @@ fn typeInfoNamespaceDecls( defer anon_decl.deinit(); const bytes = try anon_decl.arena().dupeZ(u8, mem.sliceTo(decl.name, 0)); const new_decl = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), + try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), 0, // default alignment ); @@ -16770,9 +16788,9 @@ fn log2IntType(sema: *Sema, block: *Block, operand: Type, src: LazySrcLoc) Compi .Vector => { const elem_ty = operand.elemType2(mod); const log2_elem_ty = try sema.log2IntType(block, elem_ty, src); - return Type.Tag.vector.create(sema.arena, .{ - .len = operand.vectorLen(), - .elem_type = log2_elem_ty, + return mod.vectorType(.{ + .len = operand.vectorLen(mod), + .child = log2_elem_ty.ip_index, }); }, else => {}, @@ -17207,7 +17225,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr _ = try sema.analyzeBodyInner(&sub_block, body); const operand_ty = sema.typeOf(operand); - const ptr_info = operand_ty.ptrInfo().data; + const ptr_info = operand_ty.ptrInfo(mod); const res_ty = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = err_union_ty.errorUnionPayload(), .@"addrspace" = ptr_info.@"addrspace", @@ -17398,6 +17416,7 @@ fn retWithErrTracing( ret_tag: Air.Inst.Tag, operand: Air.Inst.Ref, ) CompileError!Zir.Inst.Index { + const mod = sema.mod; const need_check = switch (is_non_err) { .bool_true => { _ = try block.addUnOp(ret_tag, operand); @@ -17409,7 +17428,7 @@ fn retWithErrTracing( const gpa = sema.gpa; const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); - const ptr_stack_trace_ty = try Type.Tag.single_mut_pointer.create(sema.arena, stack_trace_ty); + const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); const err_return_trace = try block.addTy(.err_return_trace, ptr_stack_trace_ty); const return_err_fn = try sema.getBuiltin("returnError"); const args: [1]Air.Inst.Ref = .{err_return_trace}; @@ -17755,7 +17774,7 @@ fn structInitEmpty( fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) CompileError!Air.Inst.Ref { const mod = sema.mod; - const arr_len = obj_ty.arrayLen(); + const arr_len = obj_ty.arrayLen(mod); if (arr_len != 0) { if (obj_ty.zigTypeTag(mod) == .Array) { return sema.fail(block, src, "expected {d} array elements; found 0", .{arr_len}); @@ -17763,7 +17782,7 @@ fn arrayInitEmpty(sema: *Sema, block: *Block, src: LazySrcLoc, obj_ty: Type) Com return sema.fail(block, src, "expected {d} vector elements; found 0", .{arr_len}); } } - if (obj_ty.sentinel()) |sentinel| { + if (obj_ty.sentinel(mod)) |sentinel| { const val = try Value.Tag.empty_array_sentinel.create(sema.arena, sentinel); return sema.addConstant(obj_ty, val); } else { @@ -18199,6 +18218,7 @@ fn zirArrayInit( inst: Zir.Inst.Index, is_ref: bool, ) CompileError!Air.Inst.Ref { + const mod = sema.mod; const gpa = sema.gpa; const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const src = inst_data.src(); @@ -18208,8 +18228,7 @@ fn zirArrayInit( assert(args.len >= 2); // array_ty + at least one element const array_ty = try sema.resolveType(block, src, args[0]); - const sentinel_val = array_ty.sentinel(); - const mod = sema.mod; + const sentinel_val = array_ty.sentinel(mod); const resolved_args = try gpa.alloc(Air.Inst.Ref, args.len - 1 + @boolToInt(sentinel_val != null)); defer gpa.free(resolved_args); @@ -18489,14 +18508,16 @@ fn zirErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { } fn getErrorReturnTrace(sema: *Sema, block: *Block) CompileError!Air.Inst.Ref { + const mod = sema.mod; const unresolved_stack_trace_ty = try sema.getBuiltinType("StackTrace"); const stack_trace_ty = try sema.resolveTypeFields(unresolved_stack_trace_ty); - const opt_ptr_stack_trace_ty = try Type.Tag.optional_single_mut_pointer.create(sema.arena, stack_trace_ty); + const ptr_stack_trace_ty = try mod.singleMutPtrType(stack_trace_ty); + const opt_ptr_stack_trace_ty = try Type.optional(sema.arena, ptr_stack_trace_ty, mod); if (sema.owner_func != null and sema.owner_func.?.calls_or_awaits_errorable_fn and - sema.mod.comp.bin_file.options.error_return_tracing and - sema.mod.backendSupportsFeature(.error_return_trace)) + mod.comp.bin_file.options.error_return_tracing and + mod.backendSupportsFeature(.error_return_trace)) { return block.addTy(.err_return_trace, opt_ptr_stack_trace_ty); } @@ -18585,8 +18606,11 @@ fn zirUnaryMath( switch (operand_ty.zigTypeTag(mod)) { .Vector => { const scalar_ty = operand_ty.scalarType(mod); - const vec_len = operand_ty.vectorLen(); - const result_ty = try Type.vector(sema.arena, vec_len, scalar_ty); + const vec_len = operand_ty.vectorLen(mod); + const result_ty = try mod.vectorType(.{ + .len = vec_len, + .child = scalar_ty.ip_index, + }); if (try sema.resolveMaybeUndefVal(operand)) |val| { if (val.isUndef()) return sema.addConstUndef(result_ty); @@ -18730,12 +18754,15 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in const len_val = struct_val[0]; const child_val = struct_val[1]; - const len = len_val.toUnsignedInt(mod); + const len = @intCast(u32, len_val.toUnsignedInt(mod)); const child_ty = child_val.toType(); try sema.checkVectorElemType(block, src, child_ty); - const ty = try Type.vector(sema.arena, len, try child_ty.copy(sema.arena)); + const ty = try mod.vectorType(.{ + .len = len, + .child = child_ty.ip_index, + }); return sema.addType(ty); }, .Float => { @@ -18872,7 +18899,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in const child_ty = try child_val.toType().copy(sema.arena); - const ty = try Type.optional(sema.arena, child_ty); + const ty = try Type.optional(sema.arena, child_ty, mod); return sema.addType(ty); }, .ErrorUnion => { @@ -18912,7 +18939,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in // TODO use reflection instead of magic numbers here // error_set: type, const name_val = struct_val[0]; - const name_str = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, sema.mod); + const name_str = try name_val.toAllocatedBytes(Type.const_slice_u8, sema.arena, sema.mod); const kv = try mod.getErrorValue(name_str); const gop = names.getOrPutAssumeCapacity(kv.key); @@ -19038,7 +19065,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in const value_val = field_struct_val[1]; const field_name = try name_val.toAllocatedBytes( - Type.initTag(.const_slice_u8), + Type.const_slice_u8, new_decl_arena_allocator, sema.mod, ); @@ -19215,7 +19242,7 @@ fn zirReify(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData, in const alignment_val = field_struct_val[2]; const field_name = try name_val.toAllocatedBytes( - Type.initTag(.const_slice_u8), + Type.const_slice_u8, new_decl_arena_allocator, sema.mod, ); @@ -19482,7 +19509,7 @@ fn reifyStruct( } const field_name = try name_val.toAllocatedBytes( - Type.initTag(.const_slice_u8), + Type.const_slice_u8, new_decl_arena_allocator, mod, ); @@ -19626,7 +19653,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst try sema.checkPtrOperand(block, ptr_src, ptr_ty); - var ptr_info = ptr_ty.ptrInfo().data; + var ptr_info = ptr_ty.ptrInfo(mod); const src_addrspace = ptr_info.@"addrspace"; if (!target_util.addrSpaceCastIsValid(sema.mod.getTarget(), src_addrspace, dest_addrspace)) { const msg = msg: { @@ -19641,7 +19668,7 @@ fn zirAddrSpaceCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.Inst ptr_info.@"addrspace" = dest_addrspace; const dest_ptr_ty = try Type.ptr(sema.arena, sema.mod, ptr_info); const dest_ty = if (ptr_ty.zigTypeTag(mod) == .Optional) - try Type.optional(sema.arena, dest_ptr_ty) + try Type.optional(sema.arena, dest_ptr_ty, mod) else dest_ptr_ty; @@ -19731,6 +19758,7 @@ fn zirCVaStart(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) } fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { + const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[inst].un_node; const ty_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const ty = try sema.resolveType(block, ty_src, inst_data.operand); @@ -19738,10 +19766,10 @@ fn zirTypeName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai var anon_decl = try block.startAnonDecl(); defer anon_decl.deinit(); - const bytes = try ty.nameAllocArena(anon_decl.arena(), sema.mod); + const bytes = try ty.nameAllocArena(anon_decl.arena(), mod); const new_decl = try anon_decl.finish( - try Type.Tag.array_u8_sentinel_0.create(anon_decl.arena(), bytes.len), + try Type.array(anon_decl.arena(), bytes.len, Value.zero, Type.u8, mod), try Value.Tag.bytes.create(anon_decl.arena(), bytes[0 .. bytes.len + 1]), 0, // default alignment ); @@ -19842,7 +19870,7 @@ fn zirIntToPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const elem_ty = ptr_ty.elemType2(mod); const ptr_align = try ptr_ty.ptrAlignmentAdvanced(mod, sema); - if (ptr_ty.isSlice()) { + if (ptr_ty.isSlice(mod)) { const msg = msg: { const msg = try sema.errMsg(block, type_src, "integer cannot be converted to slice type '{}'", .{ptr_ty.fmt(sema.mod)}); errdefer msg.destroy(sema.gpa); @@ -19987,8 +20015,8 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air try sema.checkPtrType(block, dest_ty_src, dest_ty); try sema.checkPtrOperand(block, operand_src, operand_ty); - const operand_info = operand_ty.ptrInfo().data; - const dest_info = dest_ty.ptrInfo().data; + const operand_info = operand_ty.ptrInfo(mod); + const dest_info = dest_ty.ptrInfo(mod); if (!operand_info.mutable and dest_info.mutable) { const msg = msg: { const msg = try sema.errMsg(block, src, "cast discards const qualifier", .{}); @@ -20042,12 +20070,11 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air const aligned_dest_ty = if (operand_align <= dest_align) dest_ty else blk: { // Unwrap the pointer (or pointer-like optional) type, set alignment, and re-wrap into result if (dest_ty.zigTypeTag(mod) == .Optional) { - var buf: Type.Payload.ElemType = undefined; - var dest_ptr_info = dest_ty.optionalChild(&buf).ptrInfo().data; + var dest_ptr_info = dest_ty.optionalChild(mod).ptrInfo(mod); dest_ptr_info.@"align" = operand_align; - break :blk try Type.optional(sema.arena, try Type.ptr(sema.arena, sema.mod, dest_ptr_info)); + break :blk try Type.optional(sema.arena, try Type.ptr(sema.arena, sema.mod, dest_ptr_info), mod); } else { - var dest_ptr_info = dest_ty.ptrInfo().data; + var dest_ptr_info = dest_ty.ptrInfo(mod); dest_ptr_info.@"align" = operand_align; break :blk try Type.ptr(sema.arena, sema.mod, dest_ptr_info); } @@ -20110,6 +20137,7 @@ fn zirPtrCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air } fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { + const mod = sema.mod; const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; const src = LazySrcLoc.nodeOffset(extra.node); const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; @@ -20117,7 +20145,7 @@ fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData const operand_ty = sema.typeOf(operand); try sema.checkPtrOperand(block, operand_src, operand_ty); - var ptr_info = operand_ty.ptrInfo().data; + var ptr_info = operand_ty.ptrInfo(mod); ptr_info.mutable = true; const dest_ty = try Type.ptr(sema.arena, sema.mod, ptr_info); @@ -20130,6 +20158,7 @@ fn zirConstCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData } fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref { + const mod = sema.mod; const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data; const src = LazySrcLoc.nodeOffset(extra.node); const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = extra.node }; @@ -20137,7 +20166,7 @@ fn zirVolatileCast(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD const operand_ty = sema.typeOf(operand); try sema.checkPtrOperand(block, operand_src, operand_ty); - var ptr_info = operand_ty.ptrInfo().data; + var ptr_info = operand_ty.ptrInfo(mod); ptr_info.@"volatile" = false; const dest_ty = try Type.ptr(sema.arena, sema.mod, ptr_info); @@ -20163,7 +20192,10 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const operand_scalar_ty = try sema.checkIntOrVectorAllowComptime(block, operand_ty, operand_src); const is_vector = operand_ty.zigTypeTag(mod) == .Vector; const dest_ty = if (is_vector) - try Type.vector(sema.arena, operand_ty.vectorLen(), dest_scalar_ty) + try mod.vectorType(.{ + .len = operand_ty.vectorLen(mod), + .child = dest_scalar_ty.ip_index, + }) else dest_scalar_ty; @@ -20218,7 +20250,7 @@ fn zirTruncate(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai ); } var elem_buf: Value.ElemValueBuffer = undefined; - const elems = try sema.arena.alloc(Value, operand_ty.vectorLen()); + const elems = try sema.arena.alloc(Value, operand_ty.vectorLen(mod)); for (elems, 0..) |*elem, i| { const elem_val = val.elemValueBuffer(sema.mod, i, &elem_buf); elem.* = try elem_val.intTrunc(operand_scalar_ty, sema.arena, dest_info.signedness, dest_info.bits, sema.mod); @@ -20245,7 +20277,7 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A try sema.checkPtrOperand(block, ptr_src, ptr_ty); - var ptr_info = ptr_ty.ptrInfo().data; + var ptr_info = ptr_ty.ptrInfo(mod); ptr_info.@"align" = dest_align; var dest_ty = try Type.ptr(sema.arena, sema.mod, ptr_info); if (ptr_ty.zigTypeTag(mod) == .Optional) { @@ -20314,8 +20346,11 @@ fn zirBitCount( const result_scalar_ty = try mod.smallestUnsignedInt(bits); switch (operand_ty.zigTypeTag(mod)) { .Vector => { - const vec_len = operand_ty.vectorLen(); - const result_ty = try Type.vector(sema.arena, vec_len, result_scalar_ty); + const vec_len = operand_ty.vectorLen(mod); + const result_ty = try mod.vectorType(.{ + .len = vec_len, + .child = result_scalar_ty.ip_index, + }); if (try sema.resolveMaybeUndefVal(operand)) |val| { if (val.isUndef()) return sema.addConstUndef(result_ty); @@ -20388,7 +20423,7 @@ fn zirByteSwap(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai if (val.isUndef()) return sema.addConstUndef(operand_ty); - const vec_len = operand_ty.vectorLen(); + const vec_len = operand_ty.vectorLen(mod); var elem_buf: Value.ElemValueBuffer = undefined; const elems = try sema.arena.alloc(Value, vec_len); for (elems, 0..) |*elem, i| { @@ -20437,7 +20472,7 @@ fn zirBitReverse(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError! if (val.isUndef()) return sema.addConstUndef(operand_ty); - const vec_len = operand_ty.vectorLen(); + const vec_len = operand_ty.vectorLen(mod); var elem_buf: Value.ElemValueBuffer = undefined; const elems = try sema.arena.alloc(Value, vec_len); for (elems, 0..) |*elem, i| { @@ -20546,7 +20581,7 @@ fn checkInvalidPtrArithmetic( ) CompileError!void { const mod = sema.mod; switch (try ty.zigTypeTagOrPoison(mod)) { - .Pointer => switch (ty.ptrSize()) { + .Pointer => switch (ty.ptrSize(mod)) { .One, .Slice => return, .Many, .C => return sema.fail( block, @@ -20676,7 +20711,7 @@ fn checkNumericType( const mod = sema.mod; switch (ty.zigTypeTag(mod)) { .ComptimeFloat, .Float, .ComptimeInt, .Int => {}, - .Vector => switch (ty.childType().zigTypeTag(mod)) { + .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { .ComptimeFloat, .Float, .ComptimeInt, .Int => {}, else => |t| return sema.fail(block, ty_src, "expected number, found '{}'", .{t}), }, @@ -20726,7 +20761,7 @@ fn checkAtomicPtrOperand( const ptr_ty = sema.typeOf(ptr); const ptr_data = switch (try ptr_ty.zigTypeTagOrPoison(mod)) { - .Pointer => ptr_ty.ptrInfo().data, + .Pointer => ptr_ty.ptrInfo(mod), else => { const wanted_ptr_ty = try Type.ptr(sema.arena, sema.mod, wanted_ptr_data); _ = try sema.coerce(block, wanted_ptr_ty, ptr, ptr_src); @@ -20797,7 +20832,7 @@ fn checkIntOrVector( switch (try operand_ty.zigTypeTagOrPoison(mod)) { .Int => return operand_ty, .Vector => { - const elem_ty = operand_ty.childType(); + const elem_ty = operand_ty.childType(mod); switch (try elem_ty.zigTypeTagOrPoison(mod)) { .Int => return elem_ty, else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{ @@ -20821,7 +20856,7 @@ fn checkIntOrVectorAllowComptime( switch (try operand_ty.zigTypeTagOrPoison(mod)) { .Int, .ComptimeInt => return operand_ty, .Vector => { - const elem_ty = operand_ty.childType(); + const elem_ty = operand_ty.childType(mod); switch (try elem_ty.zigTypeTagOrPoison(mod)) { .Int, .ComptimeInt => return elem_ty, else => return sema.fail(block, operand_src, "expected vector of integers; found vector of '{}'", .{ @@ -20870,7 +20905,7 @@ fn checkSimdBinOp( const rhs_ty = sema.typeOf(uncasted_rhs); try sema.checkVectorizableBinaryOperands(block, src, lhs_ty, rhs_ty, lhs_src, rhs_src); - var vec_len: ?usize = if (lhs_ty.zigTypeTag(mod) == .Vector) lhs_ty.vectorLen() else null; + var vec_len: ?usize = if (lhs_ty.zigTypeTag(mod) == .Vector) lhs_ty.vectorLen(mod) else null; const result_ty = try sema.resolvePeerTypes(block, src, &.{ uncasted_lhs, uncasted_rhs }, .{ .override = &[_]?LazySrcLoc{ lhs_src, rhs_src }, }); @@ -20912,8 +20947,8 @@ fn checkVectorizableBinaryOperands( }; if (lhs_is_vector and rhs_is_vector) { - const lhs_len = lhs_ty.arrayLen(); - const rhs_len = rhs_ty.arrayLen(); + const lhs_len = lhs_ty.arrayLen(mod); + const rhs_len = rhs_ty.arrayLen(mod); if (lhs_len != rhs_len) { const msg = msg: { const msg = try sema.errMsg(block, src, "vector length mismatch", .{}); @@ -20966,7 +21001,7 @@ fn resolveExportOptions( const name_operand = try sema.fieldVal(block, src, options, "name", name_src); const name_val = try sema.resolveConstValue(block, name_src, name_operand, "name of exported value must be comptime-known"); - const name_ty = Type.initTag(.const_slice_u8); + const name_ty = Type.const_slice_u8; const name = try name_val.toAllocatedBytes(name_ty, sema.arena, mod); const linkage_operand = try sema.fieldVal(block, src, options, "linkage", linkage_src); @@ -20975,7 +21010,7 @@ fn resolveExportOptions( const section_operand = try sema.fieldVal(block, src, options, "section", section_src); const section_opt_val = try sema.resolveConstValue(block, section_src, section_operand, "linksection of exported value must be comptime-known"); - const section_ty = Type.initTag(.const_slice_u8); + const section_ty = Type.const_slice_u8; const section = if (section_opt_val.optionalValue(mod)) |section_val| try section_val.toAllocatedBytes(section_ty, sema.arena, mod) else @@ -21087,7 +21122,7 @@ fn zirCmpxchg( return sema.fail(block, failure_order_src, "failure atomic ordering must not be Release or AcqRel", .{}); } - const result_ty = try Type.optional(sema.arena, elem_ty); + const result_ty = try Type.optional(sema.arena, elem_ty, mod); // special case zero bit types if ((try sema.typeHasOnePossibleValue(elem_ty)) != null) { @@ -21133,6 +21168,7 @@ fn zirCmpxchg( } fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref { + const mod = sema.mod; const inst_data = sema.code.instructions.items(.data)[inst].pl_node; const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data; const len_src: LazySrcLoc = .{ .node_offset_bin_lhs = inst_data.src_node }; @@ -21141,9 +21177,9 @@ fn zirSplat(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.I const scalar = try sema.resolveInst(extra.rhs); const scalar_ty = sema.typeOf(scalar); try sema.checkVectorElemType(block, scalar_src, scalar_ty); - const vector_ty = try Type.Tag.vector.create(sema.arena, .{ + const vector_ty = try mod.vectorType(.{ .len = len, - .elem_type = scalar_ty, + .child = scalar_ty.ip_index, }); if (try sema.resolveMaybeUndefVal(scalar)) |scalar_val| { if (scalar_val.isUndef()) return sema.addConstUndef(vector_ty); @@ -21172,7 +21208,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. return sema.fail(block, operand_src, "expected vector, found '{}'", .{operand_ty.fmt(mod)}); } - const scalar_ty = operand_ty.childType(); + const scalar_ty = operand_ty.childType(mod); // Type-check depending on operation. switch (operation) { @@ -21190,7 +21226,7 @@ fn zirReduce(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air. }, } - const vec_len = operand_ty.vectorLen(); + const vec_len = operand_ty.vectorLen(mod); if (vec_len == 0) { // TODO re-evaluate if we should introduce a "neutral value" for some operations, // e.g. zero for add and one for mul. @@ -21243,12 +21279,12 @@ fn zirShuffle(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air var mask_ty = sema.typeOf(mask); const mask_len = switch (sema.typeOf(mask).zigTypeTag(mod)) { - .Array, .Vector => sema.typeOf(mask).arrayLen(), + .Array, .Vector => sema.typeOf(mask).arrayLen(mod), else => return sema.fail(block, mask_src, "expected vector or array, found '{}'", .{sema.typeOf(mask).fmt(sema.mod)}), }; - mask_ty = try Type.Tag.vector.create(sema.arena, .{ - .len = mask_len, - .elem_type = Type.i32, + mask_ty = try mod.vectorType(.{ + .len = @intCast(u32, mask_len), + .child = .i32_type, }); mask = try sema.coerce(block, mask_ty, mask, mask_src); const mask_val = try sema.resolveConstMaybeUndefVal(block, mask_src, mask, "shuffle mask must be comptime-known"); @@ -21272,13 +21308,13 @@ fn analyzeShuffle( var a = a_arg; var b = b_arg; - const res_ty = try Type.Tag.vector.create(sema.arena, .{ + const res_ty = try mod.vectorType(.{ .len = mask_len, - .elem_type = elem_ty, + .child = elem_ty.ip_index, }); var maybe_a_len = switch (sema.typeOf(a).zigTypeTag(mod)) { - .Array, .Vector => sema.typeOf(a).arrayLen(), + .Array, .Vector => sema.typeOf(a).arrayLen(mod), .Undefined => null, else => return sema.fail(block, a_src, "expected vector or array with element type '{}', found '{}'", .{ elem_ty.fmt(sema.mod), @@ -21286,7 +21322,7 @@ fn analyzeShuffle( }), }; var maybe_b_len = switch (sema.typeOf(b).zigTypeTag(mod)) { - .Array, .Vector => sema.typeOf(b).arrayLen(), + .Array, .Vector => sema.typeOf(b).arrayLen(mod), .Undefined => null, else => return sema.fail(block, b_src, "expected vector or array with element type '{}', found '{}'", .{ elem_ty.fmt(sema.mod), @@ -21296,16 +21332,16 @@ fn analyzeShuffle( if (maybe_a_len == null and maybe_b_len == null) { return sema.addConstUndef(res_ty); } - const a_len = maybe_a_len orelse maybe_b_len.?; - const b_len = maybe_b_len orelse a_len; + const a_len = @intCast(u32, maybe_a_len orelse maybe_b_len.?); + const b_len = @intCast(u32, maybe_b_len orelse a_len); - const a_ty = try Type.Tag.vector.create(sema.arena, .{ + const a_ty = try mod.vectorType(.{ .len = a_len, - .elem_type = elem_ty, + .child = elem_ty.ip_index, }); - const b_ty = try Type.Tag.vector.create(sema.arena, .{ + const b_ty = try mod.vectorType(.{ .len = b_len, - .elem_type = elem_ty, + .child = elem_ty.ip_index, }); if (maybe_a_len == null) a = try sema.addConstUndef(a_ty) else a = try sema.coerce(block, a_ty, a, a_src); @@ -21437,15 +21473,21 @@ fn zirSelect(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstData) C const pred_ty = sema.typeOf(pred_uncoerced); const vec_len_u64 = switch (try pred_ty.zigTypeTagOrPoison(mod)) { - .Vector, .Array => pred_ty.arrayLen(), + .Vector, .Array => pred_ty.arrayLen(mod), else => return sema.fail(block, pred_src, "expected vector or array, found '{}'", .{pred_ty.fmt(sema.mod)}), }; - const vec_len = try sema.usizeCast(block, pred_src, vec_len_u64); + const vec_len = @intCast(u32, try sema.usizeCast(block, pred_src, vec_len_u64)); - const bool_vec_ty = try Type.vector(sema.arena, vec_len, Type.bool); + const bool_vec_ty = try mod.vectorType(.{ + .len = vec_len, + .child = .bool_type, + }); const pred = try sema.coerce(block, bool_vec_ty, pred_uncoerced, pred_src); - const vec_ty = try Type.vector(sema.arena, vec_len, elem_ty); + const vec_ty = try mod.vectorType(.{ + .len = vec_len, + .child = elem_ty.ip_index, + }); const a = try sema.coerce(block, vec_ty, try sema.resolveInst(extra.a), a_src); const b = try sema.coerce(block, vec_ty, try sema.resolveInst(extra.b), b_src); @@ -21854,7 +21896,7 @@ fn zirFieldParentPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileEr } try sema.checkPtrOperand(block, ptr_src, field_ptr_ty); - const field_ptr_ty_info = field_ptr_ty.ptrInfo().data; + const field_ptr_ty_info = field_ptr_ty.ptrInfo(mod); var ptr_ty_data: Type.Payload.Pointer.Data = .{ .pointee_type = parent_ty.structFieldType(field_index), @@ -22052,8 +22094,8 @@ fn analyzeMinMax( } const refined_ty = if (orig_ty.zigTypeTag(mod) == .Vector) blk: { - const elem_ty = orig_ty.childType(); - const len = orig_ty.vectorLen(); + const elem_ty = orig_ty.childType(mod); + const len = orig_ty.vectorLen(mod); if (len == 0) break :blk orig_ty; if (elem_ty.isAnyFloat()) break :blk orig_ty; // can't refine floats @@ -22068,7 +22110,10 @@ fn analyzeMinMax( } const refined_elem_ty = try mod.intFittingRange(cur_min, cur_max); - break :blk try Type.vector(sema.arena, len, refined_elem_ty); + break :blk try mod.vectorType(.{ + .len = len, + .child = refined_elem_ty.ip_index, + }); } else blk: { if (orig_ty.isAnyFloat()) break :blk orig_ty; // can't refine floats if (val.isUndef()) break :blk orig_ty; // can't refine undef @@ -22129,8 +22174,8 @@ fn analyzeMinMax( if (known_undef) break :refine; // can't refine undef const unrefined_ty = sema.typeOf(cur_minmax.?); const is_vector = unrefined_ty.zigTypeTag(mod) == .Vector; - const comptime_elem_ty = if (is_vector) comptime_ty.childType() else comptime_ty; - const unrefined_elem_ty = if (is_vector) unrefined_ty.childType() else unrefined_ty; + const comptime_elem_ty = if (is_vector) comptime_ty.childType(mod) else comptime_ty; + const unrefined_elem_ty = if (is_vector) unrefined_ty.childType(mod) else unrefined_ty; if (unrefined_elem_ty.isAnyFloat()) break :refine; // we can't refine floats @@ -22150,7 +22195,10 @@ fn analyzeMinMax( const final_elem_ty = try mod.intFittingRange(min_val, max_val); const final_ty = if (is_vector) - try Type.vector(sema.arena, unrefined_ty.vectorLen(), final_elem_ty) + try mod.vectorType(.{ + .len = unrefined_ty.vectorLen(mod), + .child = final_elem_ty.ip_index, + }) else final_elem_ty; @@ -22165,7 +22213,7 @@ fn analyzeMinMax( fn upgradeToArrayPtr(sema: *Sema, block: *Block, ptr: Air.Inst.Ref, len: u64) !Air.Inst.Ref { const mod = sema.mod; - const info = sema.typeOf(ptr).ptrInfo().data; + const info = sema.typeOf(ptr).ptrInfo(mod); if (info.size == .One) { // Already an array pointer. return ptr; @@ -22659,7 +22707,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A const body = sema.code.extra[extra_index..][0..body_len]; extra_index += body.len; - const ty = Type.initTag(.const_slice_u8); + const ty = Type.const_slice_u8; const val = try sema.resolveGenericBody(block, section_src, body, inst, ty, "linksection must be comptime-known"); if (val.isGenericPoison()) { break :blk FuncLinkSection{ .generic = {} }; @@ -22943,7 +22991,7 @@ fn resolveExternOptions( const name_ref = try sema.fieldVal(block, src, options, "name", name_src); const name_val = try sema.resolveConstValue(block, name_src, name_ref, "name of the extern symbol must be comptime-known"); - const name = try name_val.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, mod); + const name = try name_val.toAllocatedBytes(Type.const_slice_u8, sema.arena, mod); const library_name_inst = try sema.fieldVal(block, src, options, "library_name", library_src); const library_name_val = try sema.resolveConstValue(block, library_src, library_name_inst, "library in which extern symbol is must be comptime-known"); @@ -22957,7 +23005,7 @@ fn resolveExternOptions( const library_name = if (!library_name_val.isNull(mod)) blk: { const payload = library_name_val.castTag(.opt_payload).?.data; - const library_name = try payload.toAllocatedBytes(Type.initTag(.const_slice_u8), sema.arena, mod); + const library_name = try payload.toAllocatedBytes(Type.const_slice_u8, sema.arena, mod); if (library_name.len == 0) { return sema.fail(block, library_src, "library name cannot be empty", .{}); } @@ -22994,7 +23042,7 @@ fn zirBuiltinExtern( if (!ty.isPtrAtRuntime(mod)) { return sema.fail(block, ty_src, "expected (optional) pointer", .{}); } - if (!try sema.validateExternType(ty.childType(), .other)) { + if (!try sema.validateExternType(ty.childType(mod), .other)) { const msg = msg: { const msg = try sema.errMsg(block, ty_src, "extern symbol cannot have type '{}'", .{ty.fmt(mod)}); errdefer msg.destroy(sema.gpa); @@ -23014,7 +23062,7 @@ fn zirBuiltinExtern( }; if (options.linkage == .Weak and !ty.ptrAllowsZero(mod)) { - ty = try Type.optional(sema.arena, ty); + ty = try Type.optional(sema.arena, ty, mod); } // TODO check duplicate extern @@ -23194,7 +23242,7 @@ fn validateRunTimeType( => return false, .Pointer => { - const elem_ty = ty.childType(); + const elem_ty = ty.childType(mod); switch (elem_ty.zigTypeTag(mod)) { .Opaque => return true, .Fn => return elem_ty.isFnOrHasRuntimeBits(mod), @@ -23204,11 +23252,10 @@ fn validateRunTimeType( .Opaque => return is_extern, .Optional => { - var buf: Type.Payload.ElemType = undefined; - const child_ty = ty.optionalChild(&buf); + const child_ty = ty.optionalChild(mod); return sema.validateRunTimeType(child_ty, is_extern); }, - .Array, .Vector => ty = ty.elemType(), + .Array, .Vector => ty = ty.childType(mod), .ErrorUnion => ty = ty.errorUnionPayload(), @@ -23277,7 +23324,7 @@ fn explainWhyTypeIsComptimeInner( }, .Array, .Vector => { - try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.elemType(), type_set); + try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.childType(mod), type_set); }, .Pointer => { const elem_ty = ty.elemType2(mod); @@ -23295,12 +23342,11 @@ fn explainWhyTypeIsComptimeInner( } return; } - try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.elemType(), type_set); + try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.childType(mod), type_set); }, .Optional => { - var buf: Type.Payload.ElemType = undefined; - try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.optionalChild(&buf), type_set); + try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.optionalChild(mod), type_set); }, .ErrorUnion => { try sema.explainWhyTypeIsComptimeInner(msg, src_loc, ty.errorUnionPayload(), type_set); @@ -23451,7 +23497,7 @@ fn explainWhyTypeIsNotExtern( if (ty.isSlice(mod)) { try mod.errNoteNonLazy(src_loc, msg, "slices have no guaranteed in-memory representation", .{}); } else { - const pointee_ty = ty.childType(); + const pointee_ty = ty.childType(mod); try mod.errNoteNonLazy(src_loc, msg, "pointer to comptime-only type '{}'", .{pointee_ty.fmt(sema.mod)}); try sema.explainWhyTypeIsComptime(msg, src_loc, pointee_ty); } @@ -23698,7 +23744,7 @@ fn panicWithMsg( .@"addrspace" = target_util.defaultAddressSpace(target, .global_constant), // TODO might need a place that is more dynamic }); const null_stack_trace = try sema.addConstant( - try Type.optional(arena, ptr_stack_trace_ty), + try Type.optional(arena, ptr_stack_trace_ty, mod), Value.null, ); const args: [3]Air.Inst.Ref = .{ msg_inst, null_stack_trace, .null_value }; @@ -23927,7 +23973,7 @@ fn fieldVal( const is_pointer_to = object_ty.isSinglePointer(mod); const inner_ty = if (is_pointer_to) - object_ty.childType() + object_ty.childType(mod) else object_ty; @@ -23936,12 +23982,12 @@ fn fieldVal( if (mem.eql(u8, field_name, "len")) { return sema.addConstant( Type.usize, - try Value.Tag.int_u64.create(arena, inner_ty.arrayLen()), + try Value.Tag.int_u64.create(arena, inner_ty.arrayLen(mod)), ); } else if (mem.eql(u8, field_name, "ptr") and is_pointer_to) { - const ptr_info = object_ty.ptrInfo().data; + const ptr_info = object_ty.ptrInfo(mod); const result_ty = try Type.ptr(sema.arena, sema.mod, .{ - .pointee_type = ptr_info.pointee_type.childType(), + .pointee_type = ptr_info.pointee_type.childType(mod), .sentinel = ptr_info.sentinel, .@"align" = ptr_info.@"align", .@"addrspace" = ptr_info.@"addrspace", @@ -23964,7 +24010,7 @@ fn fieldVal( } }, .Pointer => { - const ptr_info = inner_ty.ptrInfo().data; + const ptr_info = inner_ty.ptrInfo(mod); if (ptr_info.size == .Slice) { if (mem.eql(u8, field_name, "ptr")) { const slice = if (is_pointer_to) @@ -24107,7 +24153,7 @@ fn fieldPtr( const object_ptr_src = src; // TODO better source location const object_ptr_ty = sema.typeOf(object_ptr); const object_ty = switch (object_ptr_ty.zigTypeTag(mod)) { - .Pointer => object_ptr_ty.elemType(), + .Pointer => object_ptr_ty.childType(mod), else => return sema.fail(block, object_ptr_src, "expected pointer, found '{}'", .{object_ptr_ty.fmt(sema.mod)}), }; @@ -24117,7 +24163,7 @@ fn fieldPtr( const is_pointer_to = object_ty.isSinglePointer(mod); const inner_ty = if (is_pointer_to) - object_ty.childType() + object_ty.childType(mod) else object_ty; @@ -24128,7 +24174,7 @@ fn fieldPtr( defer anon_decl.deinit(); return sema.analyzeDeclRef(try anon_decl.finish( Type.usize, - try Value.Tag.int_u64.create(anon_decl.arena(), inner_ty.arrayLen()), + try Value.Tag.int_u64.create(anon_decl.arena(), inner_ty.arrayLen(mod)), 0, // default alignment )); } else { @@ -24154,9 +24200,9 @@ fn fieldPtr( const result_ty = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = slice_ptr_ty, - .mutable = attr_ptr_ty.ptrIsMutable(), + .mutable = attr_ptr_ty.ptrIsMutable(mod), .@"volatile" = attr_ptr_ty.isVolatilePtr(), - .@"addrspace" = attr_ptr_ty.ptrAddressSpace(), + .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod), }); if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { @@ -24175,9 +24221,9 @@ fn fieldPtr( } else if (mem.eql(u8, field_name, "len")) { const result_ty = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = Type.usize, - .mutable = attr_ptr_ty.ptrIsMutable(), + .mutable = attr_ptr_ty.ptrIsMutable(mod), .@"volatile" = attr_ptr_ty.isVolatilePtr(), - .@"addrspace" = attr_ptr_ty.ptrAddressSpace(), + .@"addrspace" = attr_ptr_ty.ptrAddressSpace(mod), }); if (try sema.resolveDefinedValue(block, object_ptr_src, inner_ptr)) |val| { @@ -24329,14 +24375,14 @@ fn fieldCallBind( const mod = sema.mod; const raw_ptr_src = src; // TODO better source location const raw_ptr_ty = sema.typeOf(raw_ptr); - const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize() == .One or raw_ptr_ty.ptrSize() == .C)) - raw_ptr_ty.childType() + const inner_ty = if (raw_ptr_ty.zigTypeTag(mod) == .Pointer and (raw_ptr_ty.ptrSize(mod) == .One or raw_ptr_ty.ptrSize(mod) == .C)) + raw_ptr_ty.childType(mod) else return sema.fail(block, raw_ptr_src, "expected single pointer, found '{}'", .{raw_ptr_ty.fmt(sema.mod)}); // Optionally dereference a second pointer to get the concrete type. - const is_double_ptr = inner_ty.zigTypeTag(mod) == .Pointer and inner_ty.ptrSize() == .One; - const concrete_ty = if (is_double_ptr) inner_ty.childType() else inner_ty; + const is_double_ptr = inner_ty.zigTypeTag(mod) == .Pointer and inner_ty.ptrSize(mod) == .One; + const concrete_ty = if (is_double_ptr) inner_ty.childType(mod) else inner_ty; const ptr_ty = if (is_double_ptr) inner_ty else raw_ptr_ty; const object_ptr = if (is_double_ptr) try sema.analyzeLoad(block, src, raw_ptr, src) @@ -24404,9 +24450,9 @@ fn fieldCallBind( // zig fmt: off if (first_param_type.isGenericPoison() or ( first_param_type.zigTypeTag(mod) == .Pointer and - (first_param_type.ptrSize() == .One or - first_param_type.ptrSize() == .C) and - first_param_type.childType().eql(concrete_ty, sema.mod))) + (first_param_type.ptrSize(mod) == .One or + first_param_type.ptrSize(mod) == .C) and + first_param_type.childType(mod).eql(concrete_ty, sema.mod))) { // zig fmt: on // Note that if the param type is generic poison, we know that it must @@ -24425,8 +24471,7 @@ fn fieldCallBind( .arg0_inst = deref, } }; } else if (first_param_type.zigTypeTag(mod) == .Optional) { - var opt_buf: Type.Payload.ElemType = undefined; - const child = first_param_type.optionalChild(&opt_buf); + const child = first_param_type.optionalChild(mod); if (child.eql(concrete_ty, sema.mod)) { const deref = try sema.analyzeLoad(block, src, object_ptr, src); return .{ .method = .{ @@ -24434,8 +24479,8 @@ fn fieldCallBind( .arg0_inst = deref, } }; } else if (child.zigTypeTag(mod) == .Pointer and - child.ptrSize() == .One and - child.childType().eql(concrete_ty, sema.mod)) + child.ptrSize(mod) == .One and + child.childType(mod).eql(concrete_ty, sema.mod)) { return .{ .method = .{ .func_inst = decl_val, @@ -24482,15 +24527,15 @@ fn finishFieldCallBind( field_index: u32, object_ptr: Air.Inst.Ref, ) CompileError!ResolvedFieldCallee { + const mod = sema.mod; const arena = sema.arena; const ptr_field_ty = try Type.ptr(arena, sema.mod, .{ .pointee_type = field_ty, - .mutable = ptr_ty.ptrIsMutable(), - .@"addrspace" = ptr_ty.ptrAddressSpace(), + .mutable = ptr_ty.ptrIsMutable(mod), + .@"addrspace" = ptr_ty.ptrAddressSpace(mod), }); - const mod = sema.mod; - const container_ty = ptr_ty.childType(); + const container_ty = ptr_ty.childType(mod); if (container_ty.zigTypeTag(mod) == .Struct) { if (container_ty.structFieldValueComptime(mod, field_index)) |default_val| { return .{ .direct = try sema.addConstant(field_ty, default_val) }; @@ -24618,7 +24663,7 @@ fn structFieldPtrByIndex( const struct_obj = struct_ty.castTag(.@"struct").?.data; const field = struct_obj.fields.values()[field_index]; const struct_ptr_ty = sema.typeOf(struct_ptr); - const struct_ptr_ty_info = struct_ptr_ty.ptrInfo().data; + const struct_ptr_ty_info = struct_ptr_ty.ptrInfo(mod); var ptr_ty_data: Type.Payload.Pointer.Data = .{ .pointee_type = field.ty, @@ -24696,7 +24741,7 @@ fn structFieldPtrByIndex( ptr_field_ty, try Value.Tag.field_ptr.create(sema.arena, .{ .container_ptr = struct_ptr_val, - .container_ty = struct_ptr_ty.childType(), + .container_ty = struct_ptr_ty.childType(mod), .field_index = field_index, }), ); @@ -24846,9 +24891,9 @@ fn unionFieldPtr( const field = union_obj.fields.values()[field_index]; const ptr_field_ty = try Type.ptr(arena, sema.mod, .{ .pointee_type = field.ty, - .mutable = union_ptr_ty.ptrIsMutable(), + .mutable = union_ptr_ty.ptrIsMutable(mod), .@"volatile" = union_ptr_ty.isVolatilePtr(), - .@"addrspace" = union_ptr_ty.ptrAddressSpace(), + .@"addrspace" = union_ptr_ty.ptrAddressSpace(mod), }); const enum_field_index = @intCast(u32, union_obj.tag_ty.enumFieldIndex(field_name).?); @@ -25009,7 +25054,7 @@ fn elemPtr( const indexable_ptr_ty = sema.typeOf(indexable_ptr); const indexable_ty = switch (indexable_ptr_ty.zigTypeTag(mod)) { - .Pointer => indexable_ptr_ty.elemType(), + .Pointer => indexable_ptr_ty.childType(mod), else => return sema.fail(block, indexable_ptr_src, "expected pointer, found '{}'", .{indexable_ptr_ty.fmt(sema.mod)}), }; try checkIndexable(sema, block, src, indexable_ty); @@ -25046,7 +25091,7 @@ fn elemPtrOneLayerOnly( try checkIndexable(sema, block, src, indexable_ty); - switch (indexable_ty.ptrSize()) { + switch (indexable_ty.ptrSize(mod)) { .Slice => return sema.elemPtrSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety), .Many, .C => { const maybe_ptr_val = try sema.resolveDefinedValue(block, indexable_src, indexable); @@ -25065,7 +25110,7 @@ fn elemPtrOneLayerOnly( return block.addPtrElemPtr(indexable, elem_index, result_ty); }, .One => { - assert(indexable_ty.childType().zigTypeTag(mod) == .Array); // Guaranteed by checkIndexable + assert(indexable_ty.childType(mod).zigTypeTag(mod) == .Array); // Guaranteed by checkIndexable return sema.elemPtrArray(block, src, indexable_src, indexable, elem_index_src, elem_index, init, oob_safety); }, } @@ -25091,7 +25136,7 @@ fn elemVal( const elem_index = try sema.coerce(block, Type.usize, elem_index_uncasted, elem_index_src); switch (indexable_ty.zigTypeTag(mod)) { - .Pointer => switch (indexable_ty.ptrSize()) { + .Pointer => switch (indexable_ty.ptrSize(mod)) { .Slice => return sema.elemValSlice(block, src, indexable_src, indexable, elem_index_src, elem_index, oob_safety), .Many, .C => { const maybe_indexable_val = try sema.resolveDefinedValue(block, indexable_src, indexable); @@ -25112,7 +25157,7 @@ fn elemVal( return block.addBinOp(.ptr_elem_val, indexable, elem_index); }, .One => { - assert(indexable_ty.childType().zigTypeTag(mod) == .Array); // Guaranteed by checkIndexable + assert(indexable_ty.childType(mod).zigTypeTag(mod) == .Array); // Guaranteed by checkIndexable const elem_ptr = try sema.elemPtr(block, indexable_src, indexable, elem_index, elem_index_src, false, oob_safety); return sema.analyzeLoad(block, indexable_src, elem_ptr, elem_index_src); }, @@ -25171,7 +25216,7 @@ fn tupleFieldPtr( ) CompileError!Air.Inst.Ref { const mod = sema.mod; const tuple_ptr_ty = sema.typeOf(tuple_ptr); - const tuple_ty = tuple_ptr_ty.childType(); + const tuple_ty = tuple_ptr_ty.childType(mod); _ = try sema.resolveTypeFields(tuple_ty); const field_count = tuple_ty.structFieldCount(); @@ -25188,9 +25233,9 @@ fn tupleFieldPtr( const field_ty = tuple_ty.structFieldType(field_index); const ptr_field_ty = try Type.ptr(sema.arena, sema.mod, .{ .pointee_type = field_ty, - .mutable = tuple_ptr_ty.ptrIsMutable(), + .mutable = tuple_ptr_ty.ptrIsMutable(mod), .@"volatile" = tuple_ptr_ty.isVolatilePtr(), - .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(), + .@"addrspace" = tuple_ptr_ty.ptrAddressSpace(mod), }); if (tuple_ty.structFieldValueComptime(mod, field_index)) |default_val| { @@ -25271,10 +25316,10 @@ fn elemValArray( ) CompileError!Air.Inst.Ref { const mod = sema.mod; const array_ty = sema.typeOf(array); - const array_sent = array_ty.sentinel(); - const array_len = array_ty.arrayLen(); + const array_sent = array_ty.sentinel(mod); + const array_len = array_ty.arrayLen(mod); const array_len_s = array_len + @boolToInt(array_sent != null); - const elem_ty = array_ty.childType(); + const elem_ty = array_ty.childType(mod); if (array_len_s == 0) { return sema.fail(block, array_src, "indexing into empty array is not allowed", .{}); @@ -25335,9 +25380,9 @@ fn elemPtrArray( ) CompileError!Air.Inst.Ref { const mod = sema.mod; const array_ptr_ty = sema.typeOf(array_ptr); - const array_ty = array_ptr_ty.childType(); - const array_sent = array_ty.sentinel() != null; - const array_len = array_ty.arrayLen(); + const array_ty = array_ptr_ty.childType(mod); + const array_sent = array_ty.sentinel(mod) != null; + const array_len = array_ty.arrayLen(mod); const array_len_s = array_len + @boolToInt(array_sent); if (array_len_s == 0) { @@ -25396,7 +25441,7 @@ fn elemValSlice( ) CompileError!Air.Inst.Ref { const mod = sema.mod; const slice_ty = sema.typeOf(slice); - const slice_sent = slice_ty.sentinel() != null; + const slice_sent = slice_ty.sentinel(mod) != null; const elem_ty = slice_ty.elemType2(mod); var runtime_src = slice_src; @@ -25453,7 +25498,7 @@ fn elemPtrSlice( ) CompileError!Air.Inst.Ref { const mod = sema.mod; const slice_ty = sema.typeOf(slice); - const slice_sent = slice_ty.sentinel() != null; + const slice_sent = slice_ty.sentinel(mod) != null; const maybe_undef_slice_val = try sema.resolveMaybeUndefVal(slice); // The index must not be undefined since it can be out of bounds. @@ -25614,7 +25659,7 @@ fn coerceExtra( } // T to ?T - const child_type = try dest_ty.optionalChildAlloc(sema.arena); + const child_type = dest_ty.optionalChild(mod); const intermediate = sema.coerceExtra(block, child_type, inst, inst_src, .{ .report_err = false }) catch |err| switch (err) { error.NotCoercible => { if (in_memory_result == .no_match) { @@ -25628,7 +25673,7 @@ fn coerceExtra( return try sema.wrapOptional(block, dest_ty, intermediate, inst_src); }, .Pointer => pointer: { - const dest_info = dest_ty.ptrInfo().data; + const dest_info = dest_ty.ptrInfo(mod); // Function body to function pointer. if (inst_ty.zigTypeTag(mod) == .Fn) { @@ -25643,11 +25688,11 @@ fn coerceExtra( if (dest_info.size != .One) break :single_item; if (!inst_ty.isSinglePointer(mod)) break :single_item; if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer; - const ptr_elem_ty = inst_ty.childType(); + const ptr_elem_ty = inst_ty.childType(mod); const array_ty = dest_info.pointee_type; if (array_ty.zigTypeTag(mod) != .Array) break :single_item; - const array_elem_ty = array_ty.childType(); - if (array_ty.arrayLen() != 1) break :single_item; + const array_elem_ty = array_ty.childType(mod); + if (array_ty.arrayLen(mod) != 1) break :single_item; const dest_is_mut = dest_info.mutable; switch (try sema.coerceInMemoryAllowed(block, array_elem_ty, ptr_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) { .ok => {}, @@ -25660,9 +25705,9 @@ fn coerceExtra( src_array_ptr: { if (!inst_ty.isSinglePointer(mod)) break :src_array_ptr; if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :pointer; - const array_ty = inst_ty.childType(); + const array_ty = inst_ty.childType(mod); if (array_ty.zigTypeTag(mod) != .Array) break :src_array_ptr; - const array_elem_type = array_ty.childType(); + const array_elem_type = array_ty.childType(mod); const dest_is_mut = dest_info.mutable; const dst_elem_type = dest_info.pointee_type; @@ -25680,7 +25725,7 @@ fn coerceExtra( } if (dest_info.sentinel) |dest_sent| { - if (array_ty.sentinel()) |inst_sent| { + if (array_ty.sentinel(mod)) |inst_sent| { if (!dest_sent.eql(inst_sent, dst_elem_type, sema.mod)) { in_memory_result = .{ .ptr_sentinel = .{ .actual = inst_sent, @@ -25721,7 +25766,7 @@ fn coerceExtra( if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :src_c_ptr; // In this case we must add a safety check because the C pointer // could be null. - const src_elem_ty = inst_ty.childType(); + const src_elem_ty = inst_ty.childType(mod); const dest_is_mut = dest_info.mutable; const dst_elem_type = dest_info.pointee_type; switch (try sema.coerceInMemoryAllowed(block, dst_elem_type, src_elem_ty, dest_is_mut, target, dest_ty_src, inst_src)) { @@ -25784,7 +25829,7 @@ fn coerceExtra( }, .Pointer => p: { if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :p; - const inst_info = inst_ty.ptrInfo().data; + const inst_info = inst_ty.ptrInfo(mod); switch (try sema.coerceInMemoryAllowed( block, dest_info.pointee_type, @@ -25814,7 +25859,7 @@ fn coerceExtra( .Union => { // pointer to anonymous struct to pointer to union if (inst_ty.isSinglePointer(mod) and - inst_ty.childType().isAnonStruct() and + inst_ty.childType(mod).isAnonStruct() and sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) { return sema.coerceAnonStructToUnionPtrs(block, dest_ty, dest_ty_src, inst, inst_src); @@ -25823,7 +25868,7 @@ fn coerceExtra( .Struct => { // pointer to anonymous struct to pointer to struct if (inst_ty.isSinglePointer(mod) and - inst_ty.childType().isAnonStruct() and + inst_ty.childType(mod).isAnonStruct() and sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) { return sema.coerceAnonStructToStructPtrs(block, dest_ty, dest_ty_src, inst, inst_src) catch |err| switch (err) { @@ -25835,7 +25880,7 @@ fn coerceExtra( .Array => { // pointer to tuple to pointer to array if (inst_ty.isSinglePointer(mod) and - inst_ty.childType().isTuple() and + inst_ty.childType(mod).isTuple() and sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) { return sema.coerceTupleToArrayPtrs(block, dest_ty, dest_ty_src, inst, inst_src); @@ -25854,7 +25899,7 @@ fn coerceExtra( } if (!inst_ty.isSinglePointer(mod)) break :to_slice; - const inst_child_ty = inst_ty.childType(); + const inst_child_ty = inst_ty.childType(mod); if (!inst_child_ty.isTuple()) break :to_slice; // empty tuple to zero-length slice @@ -25887,7 +25932,7 @@ fn coerceExtra( .Many => p: { if (!inst_ty.isSlice(mod)) break :p; if (!sema.checkPtrAttributes(dest_ty, inst_ty, &in_memory_result)) break :p; - const inst_info = inst_ty.ptrInfo().data; + const inst_info = inst_ty.ptrInfo(mod); switch (try sema.coerceInMemoryAllowed( block, @@ -26196,9 +26241,8 @@ fn coerceExtra( } // ?T to T - var buf: Type.Payload.ElemType = undefined; if (inst_ty.zigTypeTag(mod) == .Optional and - (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(&buf), dest_ty, false, target, dest_ty_src, inst_src)) == .ok) + (try sema.coerceInMemoryAllowed(block, inst_ty.optionalChild(mod), dest_ty, false, target, dest_ty_src, inst_src)) == .ok) { try sema.errNote(block, inst_src, msg, "cannot convert optional to payload type", .{}); try sema.errNote(block, inst_src, msg, "consider using '.?', 'orelse', or 'if'", .{}); @@ -26399,10 +26443,8 @@ const InMemoryCoercionResult = union(enum) { cur = pair.child; }, .optional_shape => |pair| { - var buf_actual: Type.Payload.ElemType = undefined; - var buf_wanted: Type.Payload.ElemType = undefined; try sema.errNote(block, src, msg, "optional type child '{}' cannot cast into optional type child '{}'", .{ - pair.actual.optionalChild(&buf_actual).fmt(sema.mod), pair.wanted.optionalChild(&buf_wanted).fmt(sema.mod), + pair.actual.optionalChild(mod).fmt(sema.mod), pair.wanted.optionalChild(mod).fmt(sema.mod), }); break; }, @@ -26640,10 +26682,8 @@ fn coerceInMemoryAllowed( } // Pointers / Pointer-like Optionals - var dest_buf: Type.Payload.ElemType = undefined; - var src_buf: Type.Payload.ElemType = undefined; - const maybe_dest_ptr_ty = try sema.typePtrOrOptionalPtrTy(dest_ty, &dest_buf); - const maybe_src_ptr_ty = try sema.typePtrOrOptionalPtrTy(src_ty, &src_buf); + const maybe_dest_ptr_ty = try sema.typePtrOrOptionalPtrTy(dest_ty); + const maybe_src_ptr_ty = try sema.typePtrOrOptionalPtrTy(src_ty); if (maybe_dest_ptr_ty) |dest_ptr_ty| { if (maybe_src_ptr_ty) |src_ptr_ty| { return try sema.coerceInMemoryAllowedPtrs(block, dest_ty, src_ty, dest_ptr_ty, src_ptr_ty, dest_is_mut, target, dest_src, src_src); @@ -26685,8 +26725,8 @@ fn coerceInMemoryAllowed( // Arrays if (dest_tag == .Array and src_tag == .Array) { - const dest_info = dest_ty.arrayInfo(); - const src_info = src_ty.arrayInfo(); + const dest_info = dest_ty.arrayInfo(mod); + const src_info = src_ty.arrayInfo(mod); if (dest_info.len != src_info.len) { return InMemoryCoercionResult{ .array_len = .{ .actual = src_info.len, @@ -26717,8 +26757,8 @@ fn coerceInMemoryAllowed( // Vectors if (dest_tag == .Vector and src_tag == .Vector) { - const dest_len = dest_ty.vectorLen(); - const src_len = src_ty.vectorLen(); + const dest_len = dest_ty.vectorLen(mod); + const src_len = src_ty.vectorLen(mod); if (dest_len != src_len) { return InMemoryCoercionResult{ .vector_len = .{ .actual = src_len, @@ -26748,8 +26788,8 @@ fn coerceInMemoryAllowed( .wanted = dest_ty, } }; } - const dest_child_type = dest_ty.optionalChild(&dest_buf); - const src_child_type = src_ty.optionalChild(&src_buf); + const dest_child_type = dest_ty.optionalChild(mod); + const src_child_type = src_ty.optionalChild(mod); const child = try sema.coerceInMemoryAllowed(block, dest_child_type, src_child_type, dest_is_mut, target, dest_src, src_src); if (child != .ok) { @@ -27019,8 +27059,8 @@ fn coerceInMemoryAllowedPtrs( src_src: LazySrcLoc, ) !InMemoryCoercionResult { const mod = sema.mod; - const dest_info = dest_ptr_ty.ptrInfo().data; - const src_info = src_ptr_ty.ptrInfo().data; + const dest_info = dest_ptr_ty.ptrInfo(mod); + const src_info = src_ptr_ty.ptrInfo(mod); const ok_ptr_size = src_info.size == dest_info.size or src_info.size == .C or dest_info.size == .C; @@ -27206,11 +27246,12 @@ fn storePtr2( operand_src: LazySrcLoc, air_tag: Air.Inst.Tag, ) CompileError!void { + const mod = sema.mod; const ptr_ty = sema.typeOf(ptr); if (ptr_ty.isConstPtr()) return sema.fail(block, ptr_src, "cannot assign to constant", .{}); - const elem_ty = ptr_ty.childType(); + const elem_ty = ptr_ty.childType(mod); // To generate better code for tuples, we detect a tuple operand here, and // analyze field loads and stores directly. This avoids an extra allocation + memcpy @@ -27221,7 +27262,6 @@ fn storePtr2( // this code does not handle tuple-to-struct coercion which requires dealing with missing // fields. const operand_ty = sema.typeOf(uncasted_operand); - const mod = sema.mod; if (operand_ty.isTuple() and elem_ty.zigTypeTag(mod) == .Array) { const field_count = operand_ty.structFieldCount(); var i: u32 = 0; @@ -27247,7 +27287,7 @@ fn storePtr2( // as well as working around an LLVM bug: // https://github.com/ziglang/zig/issues/11154 if (sema.obtainBitCastedVectorPtr(ptr)) |vector_ptr| { - const vector_ty = sema.typeOf(vector_ptr).childType(); + const vector_ty = sema.typeOf(vector_ptr).childType(mod); const vector = sema.coerceExtra(block, vector_ty, uncasted_operand, operand_src, .{ .is_ret = is_ret }) catch |err| switch (err) { error.NotCoercible => unreachable, else => |e| return e, @@ -27288,7 +27328,7 @@ fn storePtr2( try sema.requireRuntimeBlock(block, src, runtime_src); try sema.queueFullTypeResolution(elem_ty); - if (ptr_ty.ptrInfo().data.vector_index == .runtime) { + if (ptr_ty.ptrInfo(mod).vector_index == .runtime) { const ptr_inst = Air.refToIndex(ptr).?; const air_tags = sema.air_instructions.items(.tag); if (air_tags[ptr_inst] == .ptr_elem_ptr) { @@ -27322,8 +27362,8 @@ fn storePtr2( /// pointer. Only if the final element type matches the vector element type, and the /// lengths match. fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { - const array_ty = sema.typeOf(ptr).childType(); const mod = sema.mod; + const array_ty = sema.typeOf(ptr).childType(mod); if (array_ty.zigTypeTag(mod) != .Array) return null; var ptr_inst = Air.refToIndex(ptr) orelse return null; const air_datas = sema.air_instructions.items(.data); @@ -27332,7 +27372,6 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { const prev_ptr = air_datas[ptr_inst].ty_op.operand; const prev_ptr_ty = sema.typeOf(prev_ptr); const prev_ptr_child_ty = switch (prev_ptr_ty.tag()) { - .single_mut_pointer => prev_ptr_ty.castTag(.single_mut_pointer).?.data, .pointer => prev_ptr_ty.castTag(.pointer).?.data.pointee_type, else => return null, }; @@ -27342,9 +27381,9 @@ fn obtainBitCastedVectorPtr(sema: *Sema, ptr: Air.Inst.Ref) ?Air.Inst.Ref { // We have a pointer-to-array and a pointer-to-vector. If the elements and // lengths match, return the result. - const vector_ty = sema.typeOf(prev_ptr).childType(); - if (array_ty.childType().eql(vector_ty.childType(), sema.mod) and - array_ty.arrayLen() == vector_ty.vectorLen()) + const vector_ty = sema.typeOf(prev_ptr).childType(mod); + if (array_ty.childType(mod).eql(vector_ty.childType(mod), sema.mod) and + array_ty.arrayLen(mod) == vector_ty.vectorLen(mod)) { return prev_ptr; } else { @@ -27476,14 +27515,14 @@ fn beginComptimePtrMutation( switch (parent.pointee) { .direct => |val_ptr| switch (parent.ty.zigTypeTag(mod)) { .Array, .Vector => { - const check_len = parent.ty.arrayLenIncludingSentinel(); + const check_len = parent.ty.arrayLenIncludingSentinel(mod); if (elem_ptr.index >= check_len) { // TODO have the parent include the decl so we can say "declared here" return sema.fail(block, src, "comptime store of index {d} out of bounds of array length {d}", .{ elem_ptr.index, check_len, }); } - const elem_ty = parent.ty.childType(); + const elem_ty = parent.ty.childType(mod); // We might have a pointer to multiple elements of the array (e.g. a pointer // to a sub-array). In this case, we just have to reinterpret the relevant @@ -27510,7 +27549,7 @@ fn beginComptimePtrMutation( defer parent.finishArena(sema.mod); const array_len_including_sentinel = - try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel()); + try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod)); const elems = try arena.alloc(Value, array_len_including_sentinel); @memset(elems, Value.undef); @@ -27536,7 +27575,7 @@ fn beginComptimePtrMutation( defer parent.finishArena(sema.mod); const bytes = val_ptr.castTag(.bytes).?.data; - const dest_len = parent.ty.arrayLenIncludingSentinel(); + const dest_len = parent.ty.arrayLenIncludingSentinel(mod); // bytes.len may be one greater than dest_len because of the case when // assigning `[N:S]T` to `[N]T`. This is allowed; the sentinel is omitted. assert(bytes.len >= dest_len); @@ -27567,13 +27606,13 @@ fn beginComptimePtrMutation( defer parent.finishArena(sema.mod); const str_lit = val_ptr.castTag(.str_lit).?.data; - const dest_len = parent.ty.arrayLenIncludingSentinel(); + const dest_len = parent.ty.arrayLenIncludingSentinel(mod); const bytes = sema.mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; const elems = try arena.alloc(Value, @intCast(usize, dest_len)); for (bytes, 0..) |byte, i| { elems[i] = try Value.Tag.int_u64.create(arena, byte); } - if (parent.ty.sentinel()) |sent_val| { + if (parent.ty.sentinel(mod)) |sent_val| { assert(elems.len == bytes.len + 1); elems[bytes.len] = sent_val; } @@ -27603,7 +27642,7 @@ fn beginComptimePtrMutation( const repeated_val = try val_ptr.castTag(.repeated).?.data.copy(arena); const array_len_including_sentinel = - try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel()); + try sema.usizeCast(block, src, parent.ty.arrayLenIncludingSentinel(mod)); const elems = try arena.alloc(Value, array_len_including_sentinel); if (elems.len > 0) elems[0] = repeated_val; for (elems[1..]) |*elem| { @@ -27906,12 +27945,12 @@ fn beginComptimePtrMutation( }, .opt_payload_ptr => { const opt_ptr = if (ptr_val.castTag(.opt_payload_ptr)) |some| some.data else { - return sema.beginComptimePtrMutation(block, src, ptr_val, try ptr_elem_ty.optionalChildAlloc(sema.arena)); + return sema.beginComptimePtrMutation(block, src, ptr_val, ptr_elem_ty.optionalChild(mod)); }; var parent = try sema.beginComptimePtrMutation(block, src, opt_ptr.container_ptr, opt_ptr.container_ty); switch (parent.pointee) { .direct => |val_ptr| { - const payload_ty = try parent.ty.optionalChildAlloc(sema.arena); + const payload_ty = parent.ty.optionalChild(mod); switch (val_ptr.tag()) { .undef, .null_value => { // An optional has been initialized to undefined at comptime and now we @@ -27984,7 +28023,7 @@ fn beginComptimePtrMutationInner( // Handle the case that the decl is an array and we're actually trying to point to an element. if (decl_ty.isArrayOrVector(mod)) { - const decl_elem_ty = decl_ty.childType(); + const decl_elem_ty = decl_ty.childType(mod); if ((try sema.coerceInMemoryAllowed(block, ptr_elem_ty, decl_elem_ty, true, target, src, src)) == .ok) { return ComptimePtrMutationKit{ .decl_ref_mut = decl_ref_mut, @@ -28105,7 +28144,7 @@ fn beginComptimePtrLoad( // If we're loading an elem_ptr that was derived from a different type // than the true type of the underlying decl, we cannot deref directly const ty_matches = if (deref.pointee != null and deref.pointee.?.ty.isArrayOrVector(mod)) x: { - const deref_elem_ty = deref.pointee.?.ty.childType(); + const deref_elem_ty = deref.pointee.?.ty.childType(mod); break :x (try sema.coerceInMemoryAllowed(block, deref_elem_ty, elem_ty, false, target, src, src)) == .ok or (try sema.coerceInMemoryAllowed(block, elem_ty, deref_elem_ty, false, target, src, src)) == .ok; } else false; @@ -28115,12 +28154,12 @@ fn beginComptimePtrLoad( } var array_tv = deref.pointee.?; - const check_len = array_tv.ty.arrayLenIncludingSentinel(); + const check_len = array_tv.ty.arrayLenIncludingSentinel(mod); if (maybe_array_ty) |load_ty| { // It's possible that we're loading a [N]T, in which case we'd like to slice // the pointee array directly from our parent array. - if (load_ty.isArrayOrVector(mod) and load_ty.childType().eql(elem_ty, sema.mod)) { - const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel()); + if (load_ty.isArrayOrVector(mod) and load_ty.childType(mod).eql(elem_ty, sema.mod)) { + const N = try sema.usizeCast(block, src, load_ty.arrayLenIncludingSentinel(mod)); deref.pointee = if (elem_ptr.index + N <= check_len) TypedValue{ .ty = try Type.array(sema.arena, N, null, elem_ty, sema.mod), .val = try array_tv.val.sliceArray(sema.mod, sema.arena, elem_ptr.index, elem_ptr.index + N), @@ -28134,7 +28173,7 @@ fn beginComptimePtrLoad( break :blk deref; } if (elem_ptr.index == check_len - 1) { - if (array_tv.ty.sentinel()) |sent| { + if (array_tv.ty.sentinel(mod)) |sent| { deref.pointee = TypedValue{ .ty = elem_ty, .val = sent, @@ -28226,7 +28265,7 @@ fn beginComptimePtrLoad( const payload_ptr = ptr_val.cast(Value.Payload.PayloadPtr).?.data; const payload_ty = switch (ptr_val.tag()) { .eu_payload_ptr => payload_ptr.container_ty.errorUnionPayload(), - .opt_payload_ptr => try payload_ptr.container_ty.optionalChildAlloc(sema.arena), + .opt_payload_ptr => payload_ptr.container_ty.optionalChild(mod), else => unreachable, }; var deref = try sema.beginComptimePtrLoad(block, src, payload_ptr.container_ptr, payload_ptr.container_ty); @@ -28357,12 +28396,13 @@ fn coerceArrayPtrToSlice( inst: Air.Inst.Ref, inst_src: LazySrcLoc, ) CompileError!Air.Inst.Ref { + const mod = sema.mod; if (try sema.resolveMaybeUndefVal(inst)) |val| { const ptr_array_ty = sema.typeOf(inst); - const array_ty = ptr_array_ty.childType(); + const array_ty = ptr_array_ty.childType(mod); const slice_val = try Value.Tag.slice.create(sema.arena, .{ .ptr = val, - .len = try Value.Tag.int_u64.create(sema.arena, array_ty.arrayLen()), + .len = try Value.Tag.int_u64.create(sema.arena, array_ty.arrayLen(mod)), }); return sema.addConstant(dest_ty, slice_val); } @@ -28371,11 +28411,11 @@ fn coerceArrayPtrToSlice( } fn checkPtrAttributes(sema: *Sema, dest_ty: Type, inst_ty: Type, in_memory_result: *InMemoryCoercionResult) bool { - const dest_info = dest_ty.ptrInfo().data; - const inst_info = inst_ty.ptrInfo().data; const mod = sema.mod; - const len0 = (inst_info.pointee_type.zigTypeTag(mod) == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel() == 0 or - (inst_info.pointee_type.arrayLen() == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or + const dest_info = dest_ty.ptrInfo(mod); + const inst_info = inst_ty.ptrInfo(mod); + const len0 = (inst_info.pointee_type.zigTypeTag(mod) == .Array and (inst_info.pointee_type.arrayLenIncludingSentinel(mod) == 0 or + (inst_info.pointee_type.arrayLen(mod) == 0 and dest_info.sentinel == null and dest_info.size != .C and dest_info.size != .Many))) or (inst_info.pointee_type.isTuple() and inst_info.pointee_type.structFieldCount() == 0); const ok_cv_qualifiers = @@ -28647,7 +28687,8 @@ fn coerceAnonStructToUnionPtrs( ptr_anon_struct: Air.Inst.Ref, anon_struct_src: LazySrcLoc, ) !Air.Inst.Ref { - const union_ty = ptr_union_ty.childType(); + const mod = sema.mod; + const union_ty = ptr_union_ty.childType(mod); const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src); const union_inst = try sema.coerceAnonStructToUnion(block, union_ty, union_ty_src, anon_struct, anon_struct_src); return sema.analyzeRef(block, union_ty_src, union_inst); @@ -28661,7 +28702,8 @@ fn coerceAnonStructToStructPtrs( ptr_anon_struct: Air.Inst.Ref, anon_struct_src: LazySrcLoc, ) !Air.Inst.Ref { - const struct_ty = ptr_struct_ty.childType(); + const mod = sema.mod; + const struct_ty = ptr_struct_ty.childType(mod); const anon_struct = try sema.analyzeLoad(block, anon_struct_src, ptr_anon_struct, anon_struct_src); const struct_inst = try sema.coerceTupleToStruct(block, struct_ty, anon_struct, anon_struct_src); return sema.analyzeRef(block, struct_ty_src, struct_inst); @@ -28676,15 +28718,16 @@ fn coerceArrayLike( inst: Air.Inst.Ref, inst_src: LazySrcLoc, ) !Air.Inst.Ref { + const mod = sema.mod; const inst_ty = sema.typeOf(inst); - const inst_len = inst_ty.arrayLen(); - const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen()); - const target = sema.mod.getTarget(); + const inst_len = inst_ty.arrayLen(mod); + const dest_len = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLen(mod)); + const target = mod.getTarget(); if (dest_len != inst_len) { const msg = msg: { const msg = try sema.errMsg(block, inst_src, "expected type '{}', found '{}'", .{ - dest_ty.fmt(sema.mod), inst_ty.fmt(sema.mod), + dest_ty.fmt(mod), inst_ty.fmt(mod), }); errdefer msg.destroy(sema.gpa); try sema.errNote(block, dest_ty_src, msg, "destination has length {d}", .{dest_len}); @@ -28694,8 +28737,8 @@ fn coerceArrayLike( return sema.failWithOwnedErrorMsg(msg); } - const dest_elem_ty = dest_ty.childType(); - const inst_elem_ty = inst_ty.childType(); + const dest_elem_ty = dest_ty.childType(mod); + const inst_elem_ty = inst_ty.childType(mod); const in_memory_result = try sema.coerceInMemoryAllowed(block, dest_elem_ty, inst_elem_ty, false, target, dest_ty_src, inst_src); if (in_memory_result == .ok) { if (try sema.resolveMaybeUndefVal(inst)) |inst_val| { @@ -28749,9 +28792,10 @@ fn coerceTupleToArray( inst: Air.Inst.Ref, inst_src: LazySrcLoc, ) !Air.Inst.Ref { + const mod = sema.mod; const inst_ty = sema.typeOf(inst); - const inst_len = inst_ty.arrayLen(); - const dest_len = dest_ty.arrayLen(); + const inst_len = inst_ty.arrayLen(mod); + const dest_len = dest_ty.arrayLen(mod); if (dest_len != inst_len) { const msg = msg: { @@ -28766,16 +28810,16 @@ fn coerceTupleToArray( return sema.failWithOwnedErrorMsg(msg); } - const dest_elems = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLenIncludingSentinel()); + const dest_elems = try sema.usizeCast(block, dest_ty_src, dest_ty.arrayLenIncludingSentinel(mod)); const element_vals = try sema.arena.alloc(Value, dest_elems); const element_refs = try sema.arena.alloc(Air.Inst.Ref, dest_elems); - const dest_elem_ty = dest_ty.childType(); + const dest_elem_ty = dest_ty.childType(mod); var runtime_src: ?LazySrcLoc = null; for (element_vals, 0..) |*elem, i_usize| { const i = @intCast(u32, i_usize); if (i_usize == inst_len) { - elem.* = dest_ty.sentinel().?; + elem.* = dest_ty.sentinel(mod).?; element_refs[i] = try sema.addConstant(dest_elem_ty, elem.*); break; } @@ -28812,9 +28856,10 @@ fn coerceTupleToSlicePtrs( ptr_tuple: Air.Inst.Ref, tuple_src: LazySrcLoc, ) !Air.Inst.Ref { - const tuple_ty = sema.typeOf(ptr_tuple).childType(); + const mod = sema.mod; + const tuple_ty = sema.typeOf(ptr_tuple).childType(mod); const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); - const slice_info = slice_ty.ptrInfo().data; + const slice_info = slice_ty.ptrInfo(mod); const array_ty = try Type.array(sema.arena, tuple_ty.structFieldCount(), slice_info.sentinel, slice_info.pointee_type, sema.mod); const array_inst = try sema.coerceTupleToArray(block, array_ty, slice_ty_src, tuple, tuple_src); if (slice_info.@"align" != 0) { @@ -28833,8 +28878,9 @@ fn coerceTupleToArrayPtrs( ptr_tuple: Air.Inst.Ref, tuple_src: LazySrcLoc, ) !Air.Inst.Ref { + const mod = sema.mod; const tuple = try sema.analyzeLoad(block, tuple_src, ptr_tuple, tuple_src); - const ptr_info = ptr_array_ty.ptrInfo().data; + const ptr_info = ptr_array_ty.ptrInfo(mod); const array_ty = ptr_info.pointee_type; const array_inst = try sema.coerceTupleToArray(block, array_ty, array_ty_src, tuple, tuple_src); if (ptr_info.@"align" != 0) { @@ -29231,7 +29277,7 @@ fn analyzeLoad( const mod = sema.mod; const ptr_ty = sema.typeOf(ptr); const elem_ty = switch (ptr_ty.zigTypeTag(mod)) { - .Pointer => ptr_ty.childType(), + .Pointer => ptr_ty.childType(mod), else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ty.fmt(sema.mod)}), }; @@ -29245,7 +29291,7 @@ fn analyzeLoad( } } - if (ptr_ty.ptrInfo().data.vector_index == .runtime) { + if (ptr_ty.ptrInfo(mod).vector_index == .runtime) { const ptr_inst = Air.refToIndex(ptr).?; const air_tags = sema.air_instructions.items(.tag); if (air_tags[ptr_inst] == .ptr_elem_ptr) { @@ -29318,8 +29364,7 @@ fn analyzeIsNull( const inverted_non_null_res = if (invert_logic) Air.Inst.Ref.bool_true else Air.Inst.Ref.bool_false; const operand_ty = sema.typeOf(operand); - var buf: Type.Payload.ElemType = undefined; - if (operand_ty.zigTypeTag(mod) == .Optional and operand_ty.optionalChild(&buf).zigTypeTag(mod) == .NoReturn) { + if (operand_ty.zigTypeTag(mod) == .Optional and operand_ty.optionalChild(mod).zigTypeTag(mod) == .NoReturn) { return inverted_non_null_res; } if (operand_ty.zigTypeTag(mod) != .Optional and !operand_ty.isPtrLikeOptional(mod)) { @@ -29339,7 +29384,7 @@ fn analyzePtrIsNonErrComptimeOnly( const mod = sema.mod; const ptr_ty = sema.typeOf(operand); assert(ptr_ty.zigTypeTag(mod) == .Pointer); - const child_ty = ptr_ty.childType(); + const child_ty = ptr_ty.childType(mod); const child_tag = child_ty.zigTypeTag(mod); if (child_tag != .ErrorSet and child_tag != .ErrorUnion) return Air.Inst.Ref.bool_true; @@ -29495,7 +29540,7 @@ fn analyzeSlice( // the slice operand to be a pointer. In the case of a non-array, it will be a double pointer. const ptr_ptr_ty = sema.typeOf(ptr_ptr); const ptr_ptr_child_ty = switch (ptr_ptr_ty.zigTypeTag(mod)) { - .Pointer => ptr_ptr_ty.elemType(), + .Pointer => ptr_ptr_ty.childType(mod), else => return sema.fail(block, ptr_src, "expected pointer, found '{}'", .{ptr_ptr_ty.fmt(sema.mod)}), }; @@ -29506,30 +29551,30 @@ fn analyzeSlice( var ptr_sentinel: ?Value = null; switch (ptr_ptr_child_ty.zigTypeTag(mod)) { .Array => { - ptr_sentinel = ptr_ptr_child_ty.sentinel(); - elem_ty = ptr_ptr_child_ty.childType(); + ptr_sentinel = ptr_ptr_child_ty.sentinel(mod); + elem_ty = ptr_ptr_child_ty.childType(mod); }, - .Pointer => switch (ptr_ptr_child_ty.ptrSize()) { + .Pointer => switch (ptr_ptr_child_ty.ptrSize(mod)) { .One => { - const double_child_ty = ptr_ptr_child_ty.childType(); + const double_child_ty = ptr_ptr_child_ty.childType(mod); if (double_child_ty.zigTypeTag(mod) == .Array) { - ptr_sentinel = double_child_ty.sentinel(); + ptr_sentinel = double_child_ty.sentinel(mod); ptr_or_slice = try sema.analyzeLoad(block, src, ptr_ptr, ptr_src); slice_ty = ptr_ptr_child_ty; array_ty = double_child_ty; - elem_ty = double_child_ty.childType(); + elem_ty = double_child_ty.childType(mod); } else { return sema.fail(block, src, "slice of single-item pointer", .{}); } }, .Many, .C => { - ptr_sentinel = ptr_ptr_child_ty.sentinel(); + ptr_sentinel = ptr_ptr_child_ty.sentinel(mod); ptr_or_slice = try sema.analyzeLoad(block, src, ptr_ptr, ptr_src); slice_ty = ptr_ptr_child_ty; array_ty = ptr_ptr_child_ty; - elem_ty = ptr_ptr_child_ty.childType(); + elem_ty = ptr_ptr_child_ty.childType(mod); - if (ptr_ptr_child_ty.ptrSize() == .C) { + if (ptr_ptr_child_ty.ptrSize(mod) == .C) { if (try sema.resolveDefinedValue(block, ptr_src, ptr_or_slice)) |ptr_val| { if (ptr_val.isNull(mod)) { return sema.fail(block, src, "slice of null pointer", .{}); @@ -29538,11 +29583,11 @@ fn analyzeSlice( } }, .Slice => { - ptr_sentinel = ptr_ptr_child_ty.sentinel(); + ptr_sentinel = ptr_ptr_child_ty.sentinel(mod); ptr_or_slice = try sema.analyzeLoad(block, src, ptr_ptr, ptr_src); slice_ty = ptr_ptr_child_ty; array_ty = ptr_ptr_child_ty; - elem_ty = ptr_ptr_child_ty.childType(); + elem_ty = ptr_ptr_child_ty.childType(mod); }, }, else => return sema.fail(block, src, "slice of non-array type '{}'", .{ptr_ptr_child_ty.fmt(mod)}), @@ -29563,7 +29608,7 @@ fn analyzeSlice( var end_is_len = uncasted_end_opt == .none; const end = e: { if (array_ty.zigTypeTag(mod) == .Array) { - const len_val = try Value.Tag.int_u64.create(sema.arena, array_ty.arrayLen()); + const len_val = try Value.Tag.int_u64.create(sema.arena, array_ty.arrayLen(mod)); if (!end_is_len) { const end = if (by_length) end: { @@ -29574,10 +29619,10 @@ fn analyzeSlice( if (try sema.resolveMaybeUndefVal(end)) |end_val| { const len_s_val = try Value.Tag.int_u64.create( sema.arena, - array_ty.arrayLenIncludingSentinel(), + array_ty.arrayLenIncludingSentinel(mod), ); if (!(try sema.compareAll(end_val, .lte, len_s_val, Type.usize))) { - const sentinel_label: []const u8 = if (array_ty.sentinel() != null) + const sentinel_label: []const u8 = if (array_ty.sentinel(mod) != null) " +1 (sentinel)" else ""; @@ -29617,7 +29662,7 @@ fn analyzeSlice( if (slice_val.isUndef()) { return sema.fail(block, src, "slice of undefined", .{}); } - const has_sentinel = slice_ty.sentinel() != null; + const has_sentinel = slice_ty.sentinel(mod) != null; var int_payload: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = slice_val.sliceLen(mod) + @boolToInt(has_sentinel), @@ -29751,8 +29796,8 @@ fn analyzeSlice( try sema.analyzeArithmetic(block, .sub, end, start, src, end_src, start_src, false); const opt_new_len_val = try sema.resolveDefinedValue(block, src, new_len); - const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo().data; - const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize() != .C; + const new_ptr_ty_info = sema.typeOf(new_ptr).ptrInfo(mod); + const new_allowzero = new_ptr_ty_info.@"allowzero" and sema.typeOf(ptr).ptrSize(mod) != .C; if (opt_new_len_val) |new_len_val| { const new_len_int = new_len_val.toUnsignedInt(mod); @@ -29780,7 +29825,7 @@ fn analyzeSlice( if (slice_ty.isSlice(mod)) { const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); - const actual_len = if (slice_ty.sentinel() == null) + const actual_len = if (slice_ty.sentinel(mod) == null) slice_len_inst else try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true); @@ -29839,7 +29884,7 @@ fn analyzeSlice( // requirement: end <= len const opt_len_inst = if (array_ty.zigTypeTag(mod) == .Array) - try sema.addIntUnsigned(Type.usize, array_ty.arrayLenIncludingSentinel()) + try sema.addIntUnsigned(Type.usize, array_ty.arrayLenIncludingSentinel(mod)) else if (slice_ty.isSlice(mod)) blk: { if (try sema.resolveDefinedValue(block, src, ptr_or_slice)) |slice_val| { // we don't need to add one for sentinels because the @@ -29848,7 +29893,7 @@ fn analyzeSlice( } const slice_len_inst = try block.addTyOp(.slice_len, Type.usize, ptr_or_slice); - if (slice_ty.sentinel() == null) break :blk slice_len_inst; + if (slice_ty.sentinel(mod) == null) break :blk slice_len_inst; // we have to add one because slice lengths don't include the sentinel break :blk try sema.analyzeArithmetic(block, .add, slice_len_inst, .one, src, end_src, end_src, true); @@ -30284,7 +30329,10 @@ fn cmpVector( const casted_lhs = try sema.coerce(block, resolved_ty, lhs, lhs_src); const casted_rhs = try sema.coerce(block, resolved_ty, rhs, rhs_src); - const result_ty = try Type.vector(sema.arena, lhs_ty.vectorLen(), Type.bool); + const result_ty = try mod.vectorType(.{ + .len = lhs_ty.vectorLen(mod), + .child = .bool_type, + }); const runtime_src: LazySrcLoc = src: { if (try sema.resolveMaybeUndefVal(casted_lhs)) |lhs_val| { @@ -30484,12 +30532,12 @@ fn resolvePeerTypes( } continue; }, - .Pointer => if (chosen_ty.ptrSize() == .C) continue, + .Pointer => if (chosen_ty.ptrSize(mod) == .C) continue, else => {}, }, .ComptimeInt => switch (chosen_ty_tag) { .Int, .Float, .ComptimeFloat => continue, - .Pointer => if (chosen_ty.ptrSize() == .C) continue, + .Pointer => if (chosen_ty.ptrSize(mod) == .C) continue, else => {}, }, .Float => switch (chosen_ty_tag) { @@ -30654,10 +30702,10 @@ fn resolvePeerTypes( }, }, .Pointer => { - const cand_info = candidate_ty.ptrInfo().data; + const cand_info = candidate_ty.ptrInfo(mod); switch (chosen_ty_tag) { .Pointer => { - const chosen_info = chosen_ty.ptrInfo().data; + const chosen_info = chosen_ty.ptrInfo(mod); seen_const = seen_const or !chosen_info.mutable or !cand_info.mutable; @@ -30690,8 +30738,8 @@ fn resolvePeerTypes( chosen_info.pointee_type.zigTypeTag(mod) == .Array and cand_info.pointee_type.zigTypeTag(mod) == .Array) { - const chosen_elem_ty = chosen_info.pointee_type.childType(); - const cand_elem_ty = cand_info.pointee_type.childType(); + const chosen_elem_ty = chosen_info.pointee_type.childType(mod); + const cand_elem_ty = cand_info.pointee_type.childType(mod); const chosen_ok = .ok == try sema.coerceInMemoryAllowed(block, chosen_elem_ty, cand_elem_ty, chosen_info.mutable, target, src, src); if (chosen_ok) { @@ -30757,10 +30805,9 @@ fn resolvePeerTypes( } }, .Optional => { - var opt_child_buf: Type.Payload.ElemType = undefined; - const chosen_ptr_ty = chosen_ty.optionalChild(&opt_child_buf); + const chosen_ptr_ty = chosen_ty.optionalChild(mod); if (chosen_ptr_ty.zigTypeTag(mod) == .Pointer) { - const chosen_info = chosen_ptr_ty.ptrInfo().data; + const chosen_info = chosen_ptr_ty.ptrInfo(mod); seen_const = seen_const or !chosen_info.mutable or !cand_info.mutable; @@ -30777,7 +30824,7 @@ fn resolvePeerTypes( .ErrorUnion => { const chosen_ptr_ty = chosen_ty.errorUnionPayload(); if (chosen_ptr_ty.zigTypeTag(mod) == .Pointer) { - const chosen_info = chosen_ptr_ty.ptrInfo().data; + const chosen_info = chosen_ptr_ty.ptrInfo(mod); seen_const = seen_const or !chosen_info.mutable or !cand_info.mutable; @@ -30802,8 +30849,7 @@ fn resolvePeerTypes( } }, .Optional => { - var opt_child_buf: Type.Payload.ElemType = undefined; - const opt_child_ty = candidate_ty.optionalChild(&opt_child_buf); + const opt_child_ty = candidate_ty.optionalChild(mod); if ((try sema.coerceInMemoryAllowed(block, chosen_ty, opt_child_ty, false, target, src, src)) == .ok) { seen_const = seen_const or opt_child_ty.isConstPtr(); any_are_null = true; @@ -30818,13 +30864,13 @@ fn resolvePeerTypes( }, .Vector => switch (chosen_ty_tag) { .Vector => { - const chosen_len = chosen_ty.vectorLen(); - const candidate_len = candidate_ty.vectorLen(); + const chosen_len = chosen_ty.vectorLen(mod); + const candidate_len = candidate_ty.vectorLen(mod); if (chosen_len != candidate_len) continue; - const chosen_child_ty = chosen_ty.childType(); - const candidate_child_ty = candidate_ty.childType(); + const chosen_child_ty = chosen_ty.childType(mod); + const candidate_child_ty = candidate_ty.childType(mod); if (chosen_child_ty.zigTypeTag(mod) == .Int and candidate_child_ty.zigTypeTag(mod) == .Int) { const chosen_info = chosen_child_ty.intInfo(mod); const candidate_info = candidate_child_ty.intInfo(mod); @@ -30853,8 +30899,8 @@ fn resolvePeerTypes( .Vector => continue, else => {}, }, - .Fn => if (chosen_ty.isSinglePointer(mod) and chosen_ty.isConstPtr() and chosen_ty.childType().zigTypeTag(mod) == .Fn) { - if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(), candidate_ty, target, src, src)) { + .Fn => if (chosen_ty.isSinglePointer(mod) and chosen_ty.isConstPtr() and chosen_ty.childType(mod).zigTypeTag(mod) == .Fn) { + if (.ok == try sema.coerceInMemoryAllowedFns(block, chosen_ty.childType(mod), candidate_ty, target, src, src)) { continue; } }, @@ -30874,8 +30920,7 @@ fn resolvePeerTypes( continue; }, .Optional => { - var opt_child_buf: Type.Payload.ElemType = undefined; - const opt_child_ty = chosen_ty.optionalChild(&opt_child_buf); + const opt_child_ty = chosen_ty.optionalChild(mod); if ((try sema.coerceInMemoryAllowed(block, opt_child_ty, candidate_ty, false, target, src, src)) == .ok) { continue; } @@ -30949,16 +30994,16 @@ fn resolvePeerTypes( if (convert_to_slice) { // turn *[N]T => []T - const chosen_child_ty = chosen_ty.childType(); - var info = chosen_ty.ptrInfo(); - info.data.sentinel = chosen_child_ty.sentinel(); - info.data.size = .Slice; - info.data.mutable = !(seen_const or chosen_child_ty.isConstPtr()); - info.data.pointee_type = chosen_child_ty.elemType2(mod); + const chosen_child_ty = chosen_ty.childType(mod); + var info = chosen_ty.ptrInfo(mod); + info.sentinel = chosen_child_ty.sentinel(mod); + info.size = .Slice; + info.mutable = !(seen_const or chosen_child_ty.isConstPtr()); + info.pointee_type = chosen_child_ty.elemType2(mod); - const new_ptr_ty = try Type.ptr(sema.arena, mod, info.data); + const new_ptr_ty = try Type.ptr(sema.arena, mod, info); const opt_ptr_ty = if (any_are_null) - try Type.optional(sema.arena, new_ptr_ty) + try Type.optional(sema.arena, new_ptr_ty, mod) else new_ptr_ty; const set_ty = err_set_ty orelse return opt_ptr_ty; @@ -30970,22 +31015,22 @@ fn resolvePeerTypes( switch (chosen_ty.zigTypeTag(mod)) { .ErrorUnion => { const ptr_ty = chosen_ty.errorUnionPayload(); - var info = ptr_ty.ptrInfo(); - info.data.mutable = false; - const new_ptr_ty = try Type.ptr(sema.arena, mod, info.data); + var info = ptr_ty.ptrInfo(mod); + info.mutable = false; + const new_ptr_ty = try Type.ptr(sema.arena, mod, info); const opt_ptr_ty = if (any_are_null) - try Type.optional(sema.arena, new_ptr_ty) + try Type.optional(sema.arena, new_ptr_ty, mod) else new_ptr_ty; const set_ty = err_set_ty orelse chosen_ty.errorUnionSet(); return try Type.errorUnion(sema.arena, set_ty, opt_ptr_ty, mod); }, .Pointer => { - var info = chosen_ty.ptrInfo(); - info.data.mutable = false; - const new_ptr_ty = try Type.ptr(sema.arena, mod, info.data); + var info = chosen_ty.ptrInfo(mod); + info.mutable = false; + const new_ptr_ty = try Type.ptr(sema.arena, mod, info); const opt_ptr_ty = if (any_are_null) - try Type.optional(sema.arena, new_ptr_ty) + try Type.optional(sema.arena, new_ptr_ty, mod) else new_ptr_ty; const set_ty = err_set_ty orelse return opt_ptr_ty; @@ -30998,7 +31043,7 @@ fn resolvePeerTypes( if (any_are_null) { const opt_ty = switch (chosen_ty.zigTypeTag(mod)) { .Null, .Optional => chosen_ty, - else => try Type.optional(sema.arena, chosen_ty), + else => try Type.optional(sema.arena, chosen_ty, mod), }; const set_ty = err_set_ty orelse return opt_ty; return try Type.errorUnion(sema.arena, set_ty, opt_ty, mod); @@ -31077,13 +31122,12 @@ pub fn resolveTypeLayout(sema: *Sema, ty: Type) CompileError!void { .Struct => return sema.resolveStructLayout(ty), .Union => return sema.resolveUnionLayout(ty), .Array => { - if (ty.arrayLenIncludingSentinel() == 0) return; - const elem_ty = ty.childType(); + if (ty.arrayLenIncludingSentinel(mod) == 0) return; + const elem_ty = ty.childType(mod); return sema.resolveTypeLayout(elem_ty); }, .Optional => { - var buf: Type.Payload.ElemType = undefined; - const payload_ty = ty.optionalChild(&buf); + const payload_ty = ty.optionalChild(mod); // In case of querying the ABI alignment of this optional, we will ask // for hasRuntimeBits() of the payload type, so we need "requires comptime" // to be known already before this function returns. @@ -31343,10 +31387,10 @@ fn checkIndexable(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { fn checkMemOperand(sema: *Sema, block: *Block, src: LazySrcLoc, ty: Type) !void { const mod = sema.mod; if (ty.zigTypeTag(mod) == .Pointer) { - switch (ty.ptrSize()) { + switch (ty.ptrSize(mod)) { .Slice, .Many, .C => return, .One => { - const elem_ty = ty.childType(); + const elem_ty = ty.childType(mod); if (elem_ty.zigTypeTag(mod) == .Array) return; // TODO https://github.com/ziglang/zig/issues/15479 // if (elem_ty.isTuple()) return; @@ -31418,8 +31462,8 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { .int_type => false, .ptr_type => @panic("TODO"), .array_type => @panic("TODO"), - .vector_type => @panic("TODO"), - .optional_type => @panic("TODO"), + .vector_type => |vector_type| return sema.resolveTypeRequiresComptime(vector_type.child.toType()), + .opt_type => @panic("TODO"), .error_union_type => @panic("TODO"), .simple_type => |t| switch (t) { .f16, @@ -31478,12 +31522,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { }; return switch (ty.tag()) { - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .anyerror_void_error_union, .empty_struct_literal, .empty_struct, .error_set, @@ -31491,34 +31529,20 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { .error_set_inferred, .error_set_merged, .@"opaque", - .array_u8, - .array_u8_sentinel_0, .enum_simple, => false, - .single_const_pointer_to_comptime_int, - .function, - => true, + .function => true, .inferred_alloc_mut => unreachable, .inferred_alloc_const => unreachable, .array, .array_sentinel, - .vector, - => return sema.resolveTypeRequiresComptime(ty.childType()), + => return sema.resolveTypeRequiresComptime(ty.childType(mod)), - .pointer, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, - => { - const child_ty = ty.childType(); + .pointer => { + const child_ty = ty.childType(mod); if (child_ty.zigTypeTag(mod) == .Fn) { return child_ty.fnInfo().is_generic; } else { @@ -31526,12 +31550,8 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { } }, - .optional, - .optional_single_mut_pointer, - .optional_single_const_pointer, - => { - var buf: Type.Payload.ElemType = undefined; - return sema.resolveTypeRequiresComptime(ty.optionalChild(&buf)); + .optional => { + return sema.resolveTypeRequiresComptime(ty.optionalChild(mod)); }, .tuple, .anon_struct => { @@ -31609,7 +31629,7 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void { const mod = sema.mod; switch (ty.zigTypeTag(mod)) { .Pointer => { - const child_ty = try sema.resolveTypeFields(ty.childType()); + const child_ty = try sema.resolveTypeFields(ty.childType(mod)); return sema.resolveTypeFully(child_ty); }, .Struct => switch (ty.tag()) { @@ -31624,10 +31644,9 @@ pub fn resolveTypeFully(sema: *Sema, ty: Type) CompileError!void { else => {}, }, .Union => return sema.resolveUnionFully(ty), - .Array => return sema.resolveTypeFully(ty.childType()), + .Array => return sema.resolveTypeFully(ty.childType(mod)), .Optional => { - var buf: Type.Payload.ElemType = undefined; - return sema.resolveTypeFully(ty.optionalChild(&buf)); + return sema.resolveTypeFully(ty.optionalChild(mod)); }, .ErrorUnion => return sema.resolveTypeFully(ty.errorUnionPayload()), .Fn => { @@ -32897,10 +32916,14 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { return null; } }, - .ptr_type => @panic("TODO"), + .ptr_type => return null, .array_type => @panic("TODO"), - .vector_type => @panic("TODO"), - .optional_type => @panic("TODO"), + .vector_type => |vector_type| { + if (vector_type.len == 0) return Value.initTag(.empty_array); + if (try sema.typeHasOnePossibleValue(vector_type.child.toType())) |v| return v; + return null; + }, + .opt_type => @panic("TODO"), .error_union_type => @panic("TODO"), .simple_type => |t| switch (t) { .f16, @@ -32963,34 +32986,15 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { .error_set_merged, .error_union, .function, - .single_const_pointer_to_comptime_int, .array_sentinel, - .array_u8_sentinel_0, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .const_slice, - .mut_slice, - .optional_single_mut_pointer, - .optional_single_const_pointer, - .anyerror_void_error_union, .error_set_inferred, .@"opaque", - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, .anyframe_T, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .single_const_pointer, - .single_mut_pointer, .pointer, => return null, .optional => { - var buf: Type.Payload.ElemType = undefined; - const child_ty = ty.optionalChild(&buf); + const child_ty = ty.optionalChild(mod); if (child_ty.isNoReturn()) { return Value.null; } else { @@ -33111,10 +33115,10 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value { .empty_struct, .empty_struct_literal => return Value.initTag(.empty_struct_value), - .vector, .array, .array_u8 => { - if (ty.arrayLen() == 0) + .array => { + if (ty.arrayLen(mod) == 0) return Value.initTag(.empty_array); - if ((try sema.typeHasOnePossibleValue(ty.elemType())) != null) { + if ((try sema.typeHasOnePossibleValue(ty.childType(mod))) != null) { return Value.initTag(.the_only_possible_value); } return null; @@ -33147,20 +33151,13 @@ pub fn addType(sema: *Sema, ty: Type) !Air.Inst.Ref { .data = .{ .interned = ty.ip_index }, }); return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1)); + } else { + try sema.air_instructions.append(sema.gpa, .{ + .tag = .const_ty, + .data = .{ .ty = ty }, + }); + return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1)); } - switch (ty.tag()) { - .manyptr_u8 => return .manyptr_u8_type, - .manyptr_const_u8 => return .manyptr_const_u8_type, - .single_const_pointer_to_comptime_int => return .single_const_pointer_to_comptime_int_type, - .const_slice_u8 => return .const_slice_u8_type, - .anyerror_void_error_union => return .anyerror_void_error_union_type, - else => {}, - } - try sema.air_instructions.append(sema.gpa, .{ - .tag = .const_ty, - .data = .{ .ty = ty }, - }); - return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1)); } fn addIntUnsigned(sema: *Sema, ty: Type, int: u64) CompileError!Air.Inst.Ref { @@ -33173,6 +33170,15 @@ fn addConstUndef(sema: *Sema, ty: Type) CompileError!Air.Inst.Ref { pub fn addConstant(sema: *Sema, ty: Type, val: Value) SemaError!Air.Inst.Ref { const gpa = sema.gpa; + if (val.ip_index != .none) { + if (@enumToInt(val.ip_index) < Air.ref_start_index) + return @intToEnum(Air.Inst.Ref, @enumToInt(val.ip_index)); + try sema.air_instructions.append(gpa, .{ + .tag = .interned, + .data = .{ .interned = val.ip_index }, + }); + return Air.indexToRef(@intCast(u32, sema.air_instructions.len - 1)); + } const ty_inst = try sema.addType(ty); try sema.air_values.append(gpa, val); try sema.air_instructions.append(gpa, .{ @@ -33331,7 +33337,8 @@ pub fn analyzeAddressSpace( /// Asserts the value is a pointer and dereferences it. /// Returns `null` if the pointer contents cannot be loaded at comptime. fn pointerDeref(sema: *Sema, block: *Block, src: LazySrcLoc, ptr_val: Value, ptr_ty: Type) CompileError!?Value { - const load_ty = ptr_ty.childType(); + const mod = sema.mod; + const load_ty = ptr_ty.childType(mod); const res = try sema.pointerDerefExtra(block, src, ptr_val, load_ty, true); switch (res) { .runtime_load => return null, @@ -33422,11 +33429,7 @@ fn usizeCast(sema: *Sema, block: *Block, src: LazySrcLoc, int: u64) CompileError /// This can return `error.AnalysisFail` because it sometimes requires resolving whether /// a type has zero bits, which can cause a "foo depends on itself" compile error. /// This logic must be kept in sync with `Type.isPtrLikeOptional`. -fn typePtrOrOptionalPtrTy( - sema: *Sema, - ty: Type, - buf: *Type.Payload.ElemType, -) !?Type { +fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type { const mod = sema.mod; if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) { @@ -33435,14 +33438,14 @@ fn typePtrOrOptionalPtrTy( .C => return ptr_type.elem_type.toType(), .One, .Many => return ty, }, - .optional_type => |o| switch (mod.intern_pool.indexToKey(o.payload_type)) { + .opt_type => |opt_child| switch (mod.intern_pool.indexToKey(opt_child)) { .ptr_type => |ptr_type| switch (ptr_type.size) { .Slice, .C => return null, .Many, .One => { if (ptr_type.is_allowzero) return null; // optionals of zero sized types behave like bools, not pointers - const payload_ty = o.payload_type.toType(); + const payload_ty = opt_child.toType(); if ((try sema.typeHasOnePossibleValue(payload_ty)) != null) { return null; } @@ -33456,25 +33459,9 @@ fn typePtrOrOptionalPtrTy( }; switch (ty.tag()) { - .optional_single_const_pointer, - .optional_single_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - => return ty.optionalChild(buf), - - .single_const_pointer_to_comptime_int, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - => return ty, - - .pointer => switch (ty.ptrSize()) { + .pointer => switch (ty.ptrSize(mod)) { .Slice => return null, - .C => return ty.optionalChild(buf), + .C => return ty.optionalChild(mod), else => return ty, }, @@ -33482,10 +33469,10 @@ fn typePtrOrOptionalPtrTy( .inferred_alloc_mut => unreachable, .optional => { - const child_type = ty.optionalChild(buf); + const child_type = ty.optionalChild(mod); if (child_type.zigTypeTag(mod) != .Pointer) return null; - const info = child_type.ptrInfo().data; + const info = child_type.ptrInfo(mod); switch (info.size) { .Slice, .C => return null, .Many, .One => { @@ -33518,8 +33505,8 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { .int_type => return false, .ptr_type => @panic("TODO"), .array_type => @panic("TODO"), - .vector_type => @panic("TODO"), - .optional_type => @panic("TODO"), + .vector_type => |vector_type| return sema.typeRequiresComptime(vector_type.child.toType()), + .opt_type => @panic("TODO"), .error_union_type => @panic("TODO"), .simple_type => |t| return switch (t) { .f16, @@ -33578,12 +33565,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { } } return switch (ty.tag()) { - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .anyerror_void_error_union, .empty_struct_literal, .empty_struct, .error_set, @@ -33591,34 +33572,20 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { .error_set_inferred, .error_set_merged, .@"opaque", - .array_u8, - .array_u8_sentinel_0, .enum_simple, => false, - .single_const_pointer_to_comptime_int, - .function, - => true, + .function => true, .inferred_alloc_mut => unreachable, .inferred_alloc_const => unreachable, .array, .array_sentinel, - .vector, - => return sema.typeRequiresComptime(ty.childType()), + => return sema.typeRequiresComptime(ty.childType(mod)), - .pointer, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, - => { - const child_ty = ty.childType(); + .pointer => { + const child_ty = ty.childType(mod); if (child_ty.zigTypeTag(mod) == .Fn) { return child_ty.fnInfo().is_generic; } else { @@ -33626,12 +33593,8 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool { } }, - .optional, - .optional_single_mut_pointer, - .optional_single_const_pointer, - => { - var buf: Type.Payload.ElemType = undefined; - return sema.typeRequiresComptime(ty.optionalChild(&buf)); + .optional => { + return sema.typeRequiresComptime(ty.optionalChild(mod)); }, .tuple, .anon_struct => { @@ -33814,7 +33777,7 @@ fn queueFullTypeResolution(sema: *Sema, ty: Type) !void { fn intAdd(sema: *Sema, lhs: Value, rhs: Value, ty: Type) !Value { const mod = sema.mod; if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try sema.arena.alloc(Value, ty.vectorLen()); + const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -33874,7 +33837,7 @@ fn intSub( ) !Value { const mod = sema.mod; if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try sema.arena.alloc(Value, ty.vectorLen()); + const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -33934,7 +33897,7 @@ fn floatAdd( ) !Value { const mod = sema.mod; if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try sema.arena.alloc(Value, float_type.vectorLen()); + const result_data = try sema.arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -33992,7 +33955,7 @@ fn floatSub( ) !Value { const mod = sema.mod; if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try sema.arena.alloc(Value, float_type.vectorLen()); + const result_data = try sema.arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -34050,8 +34013,8 @@ fn intSubWithOverflow( ) !Value.OverflowArithmeticResult { const mod = sema.mod; if (ty.zigTypeTag(mod) == .Vector) { - const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen()); - const result_data = try sema.arena.alloc(Value, ty.vectorLen()); + const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen(mod)); + const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -34105,8 +34068,8 @@ fn floatToInt( ) CompileError!Value { const mod = sema.mod; if (float_ty.zigTypeTag(mod) == .Vector) { - const elem_ty = float_ty.childType(); - const result_data = try sema.arena.alloc(Value, float_ty.vectorLen()); + const elem_ty = float_ty.childType(mod); + const result_data = try sema.arena.alloc(Value, float_ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(sema.mod, i, &buf); @@ -34383,8 +34346,8 @@ fn intAddWithOverflow( ) !Value.OverflowArithmeticResult { const mod = sema.mod; if (ty.zigTypeTag(mod) == .Vector) { - const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen()); - const result_data = try sema.arena.alloc(Value, ty.vectorLen()); + const overflowed_data = try sema.arena.alloc(Value, ty.vectorLen(mod)); + const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -34442,7 +34405,7 @@ fn compareAll( const mod = sema.mod; if (ty.zigTypeTag(mod) == .Vector) { var i: usize = 0; - while (i < ty.vectorLen()) : (i += 1) { + while (i < ty.vectorLen(mod)) : (i += 1) { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; const lhs_elem = lhs.elemValueBuffer(sema.mod, i, &lhs_buf); @@ -34490,7 +34453,7 @@ fn compareVector( ) !Value { const mod = sema.mod; assert(ty.zigTypeTag(mod) == .Vector); - const result_data = try sema.arena.alloc(Value, ty.vectorLen()); + const result_data = try sema.arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -34511,10 +34474,10 @@ fn compareVector( /// This code is duplicated in `analyzePtrArithmetic`. fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type { const mod = sema.mod; - const ptr_info = ptr_ty.ptrInfo().data; + const ptr_info = ptr_ty.ptrInfo(mod); const elem_ty = ptr_ty.elemType2(mod); const allow_zero = ptr_info.@"allowzero" and (offset orelse 0) == 0; - const parent_ty = ptr_ty.childType(); + const parent_ty = ptr_ty.childType(mod); const VI = Type.Payload.Pointer.Data.VectorIndex; @@ -34522,14 +34485,14 @@ fn elemPtrType(sema: *Sema, ptr_ty: Type, offset: ?usize) !Type { host_size: u16 = 0, alignment: u32 = 0, vector_index: VI = .none, - } = if (parent_ty.tag() == .vector and ptr_info.size == .One) blk: { + } = if (parent_ty.isVector(mod) and ptr_info.size == .One) blk: { const elem_bits = elem_ty.bitSize(mod); if (elem_bits == 0) break :blk .{}; const is_packed = elem_bits < 8 or !std.math.isPowerOfTwo(elem_bits); if (!is_packed) break :blk .{}; break :blk .{ - .host_size = @intCast(u16, parent_ty.arrayLen()), + .host_size = @intCast(u16, parent_ty.arrayLen(mod)), .alignment = @intCast(u16, parent_ty.abiAlignment(mod)), .vector_index = if (offset) |some| @intToEnum(VI, some) else .runtime, }; diff --git a/src/TypedValue.zig b/src/TypedValue.zig index 877a8f5f4c..7f599caafb 100644 --- a/src/TypedValue.zig +++ b/src/TypedValue.zig @@ -77,15 +77,6 @@ pub fn print( return writer.writeAll("(variable)"); while (true) switch (val.tag()) { - .single_const_pointer_to_comptime_int_type => return writer.writeAll("*const comptime_int"), - .const_slice_u8_type => return writer.writeAll("[]const u8"), - .const_slice_u8_sentinel_0_type => return writer.writeAll("[:0]const u8"), - .anyerror_void_error_union_type => return writer.writeAll("anyerror!void"), - - .manyptr_u8_type => return writer.writeAll("[*]u8"), - .manyptr_const_u8_type => return writer.writeAll("[*]const u8"), - .manyptr_const_u8_sentinel_0_type => return writer.writeAll("[*:0]const u8"), - .empty_struct_value, .aggregate => { if (level == 0) { return writer.writeAll(".{ ... }"); @@ -112,7 +103,7 @@ pub fn print( return writer.writeAll("}"); } else { const elem_ty = ty.elemType2(mod); - const len = ty.arrayLen(); + const len = ty.arrayLen(mod); if (elem_ty.eql(Type.u8, mod)) str: { const max_len = @intCast(usize, std.math.min(len, max_string_len)); @@ -288,7 +279,7 @@ pub fn print( .ty = ty.elemType2(mod), .val = val.castTag(.repeated).?.data, }; - const len = ty.arrayLen(); + const len = ty.arrayLen(mod); const max_len = std.math.min(len, max_aggregate_items); while (i < max_len) : (i += 1) { if (i != 0) try writer.writeAll(", "); @@ -306,7 +297,7 @@ pub fn print( try writer.writeAll(".{ "); try print(.{ .ty = ty.elemType2(mod), - .val = ty.sentinel().?, + .val = ty.sentinel(mod).?, }, writer, level - 1, mod); return writer.writeAll(" }"); }, @@ -364,8 +355,7 @@ pub fn print( }, .opt_payload => { val = val.castTag(.opt_payload).?.data; - var buf: Type.Payload.ElemType = undefined; - ty = ty.optionalChild(&buf); + ty = ty.optionalChild(mod); return print(.{ .ty = ty, .val = val }, writer, level, mod); }, .eu_payload_ptr => { @@ -386,13 +376,8 @@ pub fn print( try writer.writeAll(", &(payload of "); - var ptr_ty: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = data.container_ty, - }; - try print(.{ - .ty = Type.initPayload(&ptr_ty.base), + .ty = mod.singleMutPtrType(data.container_ty) catch @panic("OOM"), .val = data.container_ptr, }, writer, level - 1, mod); @@ -415,13 +400,8 @@ pub fn print( try writer.writeAll(", &(payload of "); - var ptr_ty: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = data.container_ty, - }; - try print(.{ - .ty = Type.initPayload(&ptr_ty.base), + .ty = mod.singleMutPtrType(data.container_ty) catch @panic("OOM"), .val = data.container_ptr, }, writer, level - 1, mod); diff --git a/src/arch/aarch64/CodeGen.zig b/src/arch/aarch64/CodeGen.zig index 503bbdbb02..81169750c1 100644 --- a/src/arch/aarch64/CodeGen.zig +++ b/src/arch/aarch64/CodeGen.zig @@ -1030,7 +1030,7 @@ fn allocMem( /// Use a pointer instruction as the basis for allocating stack memory. fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { const mod = self.bin_file.options.module.?; - const elem_ty = self.typeOfIndex(inst).elemType(); + const elem_ty = self.typeOfIndex(inst).childType(mod); if (!elem_ty.hasRuntimeBits(mod)) { // return the stack offset 0. Stack offset 0 will be where all @@ -1140,17 +1140,14 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { } fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const result: MCValue = switch (self.ret_mcv) { .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) }, .stack_offset => blk: { // self.ret_mcv is an address to where this function // should store its result into const ret_ty = self.fn_type.fnReturnType(); - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ret_ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ret_ty); // addr_reg will contain the address of where to store the // result into @@ -2406,9 +2403,9 @@ fn ptrArithmetic( assert(rhs_ty.eql(Type.usize, mod)); const ptr_ty = lhs_ty; - const elem_ty = switch (ptr_ty.ptrSize()) { - .One => ptr_ty.childType().childType(), // ptr to array, so get array element type - else => ptr_ty.childType(), + const elem_ty = switch (ptr_ty.ptrSize(mod)) { + .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type + else => ptr_ty.childType(mod), }; const elem_size = elem_ty.abiSize(mod); @@ -3024,8 +3021,7 @@ fn airOptionalPayload(self: *Self, inst: Air.Inst.Index) !void { fn optionalPayload(self: *Self, inst: Air.Inst.Index, mcv: MCValue, optional_ty: Type) !MCValue { const mod = self.bin_file.options.module.?; - var opt_buf: Type.Payload.ElemType = undefined; - const payload_ty = optional_ty.optionalChild(&opt_buf); + const payload_ty = optional_ty.optionalChild(mod); if (!payload_ty.hasRuntimeBits(mod)) return MCValue.none; if (optional_ty.isPtrLikeOptional(mod)) { // TODO should we reuse the operand here? @@ -3459,7 +3455,7 @@ fn ptrElemVal( maybe_inst: ?Air.Inst.Index, ) !MCValue { const mod = self.bin_file.options.module.?; - const elem_ty = ptr_ty.childType(); + const elem_ty = ptr_ty.childType(mod); const elem_size = @intCast(u32, elem_ty.abiSize(mod)); // TODO optimize for elem_sizes of 1, 2, 4, 8 @@ -3617,7 +3613,7 @@ fn reuseOperand( fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { const mod = self.bin_file.options.module.?; - const elem_ty = ptr_ty.elemType(); + const elem_ty = ptr_ty.childType(mod); const elem_size = elem_ty.abiSize(mod); switch (ptr) { @@ -3773,7 +3769,7 @@ fn genInlineMemset( ) !void { const dst_reg = switch (dst) { .register => |r| r, - else => try self.copyToTmpRegister(Type.initTag(.manyptr_u8), dst), + else => try self.copyToTmpRegister(Type.manyptr_u8, dst), }; const dst_reg_lock = self.register_manager.lockReg(dst_reg); defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock); @@ -4096,7 +4092,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde const mod = self.bin_file.options.module.?; const mcv = try self.resolveInst(operand); const ptr_ty = self.typeOf(operand); - const struct_ty = ptr_ty.childType(); + const struct_ty = ptr_ty.childType(mod); const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod)); switch (mcv) { .ptr_stack_offset => |off| { @@ -4173,7 +4169,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const field_ptr = try self.resolveInst(extra.field_ptr); - const struct_ty = self.air.getRefType(ty_pl.ty).childType(); + const struct_ty = self.air.getRefType(ty_pl.ty).childType(mod); const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(extra.field_index, mod)); switch (field_ptr) { .ptr_stack_offset => |off| { @@ -4254,7 +4250,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier const fn_ty = switch (ty.zigTypeTag(mod)) { .Fn => ty, - .Pointer => ty.childType(), + .Pointer => ty.childType(mod), else => unreachable, }; @@ -4280,11 +4276,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier const ret_ptr_reg = self.registerAlias(.x0, Type.usize); - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ret_ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ret_ty); try self.register_manager.getReg(ret_ptr_reg, null); try self.genSetReg(ptr_ty, ret_ptr_reg, .{ .ptr_stack_offset = stack_offset }); @@ -4453,11 +4445,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { // // self.ret_mcv is an address to where this function // should store its result into - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ret_ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ret_ty); try self.store(self.ret_mcv, operand, ptr_ty, ret_ty); }, else => unreachable, @@ -4533,8 +4521,7 @@ fn cmp( const mod = self.bin_file.options.module.?; const int_ty = switch (lhs_ty.zigTypeTag(mod)) { .Optional => blk: { - var opt_buffer: Type.Payload.ElemType = undefined; - const payload_ty = lhs_ty.optionalChild(&opt_buffer); + const payload_ty = lhs_ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { break :blk Type.u1; } else if (lhs_ty.isPtrLikeOptional(mod)) { @@ -4850,8 +4837,7 @@ fn airCondBr(self: *Self, inst: Air.Inst.Index) !void { fn isNull(self: *Self, operand_bind: ReadArg.Bind, operand_ty: Type) !MCValue { const mod = self.bin_file.options.module.?; const sentinel: struct { ty: Type, bind: ReadArg.Bind } = if (!operand_ty.isPtrLikeOptional(mod)) blk: { - var buf: Type.Payload.ElemType = undefined; - const payload_ty = operand_ty.optionalChild(&buf); + const payload_ty = operand_ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) break :blk .{ .ty = operand_ty, .bind = operand_bind }; @@ -4947,11 +4933,12 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { } fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const un_op = self.air.instructions.items(.data)[inst].un_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const operand_ptr = try self.resolveInst(un_op); const ptr_ty = self.typeOf(un_op); - const elem_ty = ptr_ty.elemType(); + const elem_ty = ptr_ty.childType(mod); const operand = try self.allocRegOrMem(elem_ty, true, null); try self.load(operand, operand_ptr, ptr_ty); @@ -4973,11 +4960,12 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { } fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const un_op = self.air.instructions.items(.data)[inst].un_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const operand_ptr = try self.resolveInst(un_op); const ptr_ty = self.typeOf(un_op); - const elem_ty = ptr_ty.elemType(); + const elem_ty = ptr_ty.childType(mod); const operand = try self.allocRegOrMem(elem_ty, true, null); try self.load(operand, operand_ptr, ptr_ty); @@ -4999,11 +4987,12 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { } fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const un_op = self.air.instructions.items(.data)[inst].un_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const operand_ptr = try self.resolveInst(un_op); const ptr_ty = self.typeOf(un_op); - const elem_ty = ptr_ty.elemType(); + const elem_ty = ptr_ty.childType(mod); const operand = try self.allocRegOrMem(elem_ty, true, null); try self.load(operand, operand_ptr, ptr_ty); @@ -5025,11 +5014,12 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { } fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const un_op = self.air.instructions.items(.data)[inst].un_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const operand_ptr = try self.resolveInst(un_op); const ptr_ty = self.typeOf(un_op); - const elem_ty = ptr_ty.elemType(); + const elem_ty = ptr_ty.childType(mod); const operand = try self.allocRegOrMem(elem_ty, true, null); try self.load(operand, operand_ptr, ptr_ty); @@ -5511,11 +5501,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro const reg = try self.copyToTmpRegister(ty, mcv); return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); } else { - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ty); // TODO call extern memcpy const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); @@ -5833,11 +5819,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I const reg = try self.copyToTmpRegister(ty, mcv); return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg }); } else { - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ty); // TODO call extern memcpy const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); @@ -5957,12 +5939,13 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { } fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const ptr_ty = self.typeOf(ty_op.operand); const ptr = try self.resolveInst(ty_op.operand); - const array_ty = ptr_ty.childType(); - const array_len = @intCast(u32, array_ty.arrayLen()); + const array_ty = ptr_ty.childType(mod); + const array_len = @intCast(u32, array_ty.arrayLen(mod)); const ptr_bits = self.target.ptrBitWidth(); const ptr_bytes = @divExact(ptr_bits, 8); @@ -6079,8 +6062,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { } fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const vector_ty = self.typeOfIndex(inst); - const len = vector_ty.vectorLen(); + const len = vector_ty.vectorLen(mod); const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]); const result: MCValue = res: { diff --git a/src/arch/arm/CodeGen.zig b/src/arch/arm/CodeGen.zig index 55ec0d4125..c08cb58c48 100644 --- a/src/arch/arm/CodeGen.zig +++ b/src/arch/arm/CodeGen.zig @@ -1010,7 +1010,7 @@ fn allocMem( /// Use a pointer instruction as the basis for allocating stack memory. fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { const mod = self.bin_file.options.module.?; - const elem_ty = self.typeOfIndex(inst).elemType(); + const elem_ty = self.typeOfIndex(inst).childType(mod); if (!elem_ty.hasRuntimeBits(mod)) { // As this stack item will never be dereferenced at runtime, @@ -1117,17 +1117,14 @@ fn airAlloc(self: *Self, inst: Air.Inst.Index) !void { } fn airRetPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const result: MCValue = switch (self.ret_mcv) { .none, .register => .{ .ptr_stack_offset = try self.allocMemPtr(inst) }, .stack_offset => blk: { // self.ret_mcv is an address to where this function // should store its result into const ret_ty = self.fn_type.fnReturnType(); - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ret_ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ret_ty); // addr_reg will contain the address of where to store the // result into @@ -2372,8 +2369,8 @@ fn ptrElemVal( ptr_ty: Type, maybe_inst: ?Air.Inst.Index, ) !MCValue { - const elem_ty = ptr_ty.childType(); const mod = self.bin_file.options.module.?; + const elem_ty = ptr_ty.childType(mod); const elem_size = @intCast(u32, elem_ty.abiSize(mod)); switch (elem_size) { @@ -2474,7 +2471,8 @@ fn arrayElemVal( array_ty: Type, maybe_inst: ?Air.Inst.Index, ) InnerError!MCValue { - const elem_ty = array_ty.childType(); + const mod = self.bin_file.options.module.?; + const elem_ty = array_ty.childType(mod); const mcv = try array_bind.resolveToMcv(self); switch (mcv) { @@ -2508,11 +2506,7 @@ fn arrayElemVal( const base_bind: ReadArg.Bind = .{ .mcv = ptr_to_mcv }; - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = elem_ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(elem_ty); return try self.ptrElemVal(base_bind, index_bind, ptr_ty, maybe_inst); }, @@ -2659,8 +2653,8 @@ fn reuseOperand( } fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { - const elem_ty = ptr_ty.elemType(); const mod = self.bin_file.options.module.?; + const elem_ty = ptr_ty.childType(mod); const elem_size = @intCast(u32, elem_ty.abiSize(mod)); switch (ptr) { @@ -2888,7 +2882,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde const mod = self.bin_file.options.module.?; const mcv = try self.resolveInst(operand); const ptr_ty = self.typeOf(operand); - const struct_ty = ptr_ty.childType(); + const struct_ty = ptr_ty.childType(mod); const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod)); switch (mcv) { .ptr_stack_offset => |off| { @@ -3004,7 +2998,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const field_ptr = try self.resolveInst(extra.field_ptr); - const struct_ty = self.air.getRefType(ty_pl.ty).childType(); + const struct_ty = self.air.getRefType(ty_pl.ty).childType(mod); if (struct_ty.zigTypeTag(mod) == .Union) { return self.fail("TODO implement @fieldParentPtr codegen for unions", .{}); @@ -3898,9 +3892,9 @@ fn ptrArithmetic( assert(rhs_ty.eql(Type.usize, mod)); const ptr_ty = lhs_ty; - const elem_ty = switch (ptr_ty.ptrSize()) { - .One => ptr_ty.childType().childType(), // ptr to array, so get array element type - else => ptr_ty.childType(), + const elem_ty = switch (ptr_ty.ptrSize(mod)) { + .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type + else => ptr_ty.childType(mod), }; const elem_size = @intCast(u32, elem_ty.abiSize(mod)); @@ -4079,7 +4073,7 @@ fn genInlineMemset( ) !void { const dst_reg = switch (dst) { .register => |r| r, - else => try self.copyToTmpRegister(Type.initTag(.manyptr_u8), dst), + else => try self.copyToTmpRegister(Type.manyptr_u8, dst), }; const dst_reg_lock = self.register_manager.lockReg(dst_reg); defer if (dst_reg_lock) |lock| self.register_manager.unlockReg(lock); @@ -4229,7 +4223,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier const fn_ty = switch (ty.zigTypeTag(mod)) { .Fn => ty, - .Pointer => ty.childType(), + .Pointer => ty.childType(mod), else => unreachable, }; @@ -4259,11 +4253,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier const ret_abi_align = @intCast(u32, ret_ty.abiAlignment(mod)); const stack_offset = try self.allocMem(ret_abi_size, ret_abi_align, inst); - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ret_ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ret_ty); try self.register_manager.getReg(.r0, null); try self.genSetReg(ptr_ty, .r0, .{ .ptr_stack_offset = stack_offset }); @@ -4401,11 +4391,7 @@ fn airRet(self: *Self, inst: Air.Inst.Index) !void { // // self.ret_mcv is an address to where this function // should store its result into - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ret_ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ret_ty); try self.store(self.ret_mcv, operand, ptr_ty, ret_ty); }, else => unreachable, // invalid return result @@ -4482,8 +4468,7 @@ fn cmp( const mod = self.bin_file.options.module.?; const int_ty = switch (lhs_ty.zigTypeTag(mod)) { .Optional => blk: { - var opt_buffer: Type.Payload.ElemType = undefined; - const payload_ty = lhs_ty.optionalChild(&opt_buffer); + const payload_ty = lhs_ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { break :blk Type.u1; } else if (lhs_ty.isPtrLikeOptional(mod)) { @@ -4837,11 +4822,12 @@ fn airIsNull(self: *Self, inst: Air.Inst.Index) !void { } fn airIsNullPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const un_op = self.air.instructions.items(.data)[inst].un_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const operand_ptr = try self.resolveInst(un_op); const ptr_ty = self.typeOf(un_op); - const elem_ty = ptr_ty.elemType(); + const elem_ty = ptr_ty.childType(mod); const operand = try self.allocRegOrMem(elem_ty, true, null); try self.load(operand, operand_ptr, ptr_ty); @@ -4863,11 +4849,12 @@ fn airIsNonNull(self: *Self, inst: Air.Inst.Index) !void { } fn airIsNonNullPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const un_op = self.air.instructions.items(.data)[inst].un_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const operand_ptr = try self.resolveInst(un_op); const ptr_ty = self.typeOf(un_op); - const elem_ty = ptr_ty.elemType(); + const elem_ty = ptr_ty.childType(mod); const operand = try self.allocRegOrMem(elem_ty, true, null); try self.load(operand, operand_ptr, ptr_ty); @@ -4924,11 +4911,12 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { } fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const un_op = self.air.instructions.items(.data)[inst].un_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const operand_ptr = try self.resolveInst(un_op); const ptr_ty = self.typeOf(un_op); - const elem_ty = ptr_ty.elemType(); + const elem_ty = ptr_ty.childType(mod); const operand = try self.allocRegOrMem(elem_ty, true, null); try self.load(operand, operand_ptr, ptr_ty); @@ -4950,11 +4938,12 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { } fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const un_op = self.air.instructions.items(.data)[inst].un_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const operand_ptr = try self.resolveInst(un_op); const ptr_ty = self.typeOf(un_op); - const elem_ty = ptr_ty.elemType(); + const elem_ty = ptr_ty.childType(mod); const operand = try self.allocRegOrMem(elem_ty, true, null); try self.load(operand, operand_ptr, ptr_ty); @@ -5455,11 +5444,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro const reg = try self.copyToTmpRegister(ty, mcv); return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); } else { - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ty); // TODO call extern memcpy const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); @@ -5816,11 +5801,7 @@ fn genSetStackArgument(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) I const reg = try self.copyToTmpRegister(ty, mcv); return self.genSetStackArgument(ty, stack_offset, MCValue{ .register = reg }); } else { - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ty); // TODO call extern memcpy const regs = try self.register_manager.allocRegs(5, .{ null, null, null, null, null }, gp); @@ -5908,12 +5889,13 @@ fn airBitCast(self: *Self, inst: Air.Inst.Index) !void { } fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const ptr_ty = self.typeOf(ty_op.operand); const ptr = try self.resolveInst(ty_op.operand); - const array_ty = ptr_ty.childType(); - const array_len = @intCast(u32, array_ty.arrayLen()); + const array_ty = ptr_ty.childType(mod); + const array_len = @intCast(u32, array_ty.arrayLen(mod)); const stack_offset = try self.allocMem(8, 8, inst); try self.genSetStack(ptr_ty, stack_offset, ptr); @@ -6026,8 +6008,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { } fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const vector_ty = self.typeOfIndex(inst); - const len = vector_ty.vectorLen(); + const len = vector_ty.vectorLen(mod); const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]); const result: MCValue = res: { diff --git a/src/arch/riscv64/CodeGen.zig b/src/arch/riscv64/CodeGen.zig index 488b937141..1e5858a948 100644 --- a/src/arch/riscv64/CodeGen.zig +++ b/src/arch/riscv64/CodeGen.zig @@ -807,7 +807,7 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u /// Use a pointer instruction as the basis for allocating stack memory. fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { const mod = self.bin_file.options.module.?; - const elem_ty = self.typeOfIndex(inst).elemType(); + const elem_ty = self.typeOfIndex(inst).childType(mod); const abi_size = math.cast(u32, elem_ty.abiSize(mod)) orelse { return self.fail("type '{}' too big to fit into stack frame", .{elem_ty.fmt(mod)}); }; @@ -1099,9 +1099,9 @@ fn binOp( switch (lhs_ty.zigTypeTag(mod)) { .Pointer => { const ptr_ty = lhs_ty; - const elem_ty = switch (ptr_ty.ptrSize()) { - .One => ptr_ty.childType().childType(), // ptr to array, so get array element type - else => ptr_ty.childType(), + const elem_ty = switch (ptr_ty.ptrSize(mod)) { + .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type + else => ptr_ty.childType(mod), }; const elem_size = elem_ty.abiSize(mod); @@ -1502,7 +1502,8 @@ fn reuseOperand(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, op_ind } fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { - const elem_ty = ptr_ty.elemType(); + const mod = self.bin_file.options.module.?; + const elem_ty = ptr_ty.childType(mod); switch (ptr) { .none => unreachable, .undef => unreachable, @@ -2496,8 +2497,9 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { } fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const vector_ty = self.typeOfIndex(inst); - const len = vector_ty.vectorLen(); + const len = vector_ty.vectorLen(mod); const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]); const result: MCValue = res: { diff --git a/src/arch/sparc64/CodeGen.zig b/src/arch/sparc64/CodeGen.zig index c565b6dc23..f8a62f9798 100644 --- a/src/arch/sparc64/CodeGen.zig +++ b/src/arch/sparc64/CodeGen.zig @@ -838,8 +838,9 @@ fn airAddSubWithOverflow(self: *Self, inst: Air.Inst.Index) !void { } fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const vector_ty = self.typeOfIndex(inst); - const len = vector_ty.vectorLen(); + const len = vector_ty.vectorLen(mod); const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]); const result: MCValue = res: { @@ -871,12 +872,13 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { } fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const result: MCValue = if (self.liveness.isUnused(inst)) .dead else result: { const ptr_ty = self.typeOf(ty_op.operand); const ptr = try self.resolveInst(ty_op.operand); - const array_ty = ptr_ty.childType(); - const array_len = @intCast(u32, array_ty.arrayLen()); + const array_ty = ptr_ty.childType(mod); + const array_len = @intCast(u32, array_ty.arrayLen(mod)); const ptr_bits = self.target.ptrBitWidth(); const ptr_bytes = @divExact(ptr_bits, 8); @@ -1300,7 +1302,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier const mod = self.bin_file.options.module.?; const fn_ty = switch (ty.zigTypeTag(mod)) { .Fn => ty, - .Pointer => ty.childType(), + .Pointer => ty.childType(mod), else => unreachable, }; @@ -1440,8 +1442,7 @@ fn airCmp(self: *Self, inst: Air.Inst.Index, op: math.CompareOperator) !void { .Pointer => Type.usize, .ErrorSet => Type.u16, .Optional => blk: { - var opt_buffer: Type.Payload.ElemType = undefined; - const payload_ty = lhs_ty.optionalChild(&opt_buffer); + const payload_ty = lhs_ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { break :blk Type.u1; } else if (lhs_ty.isPtrLikeOptional(mod)) { @@ -2447,6 +2448,7 @@ fn airSlice(self: *Self, inst: Air.Inst.Index) !void { } fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const is_volatile = false; // TODO const bin_op = self.air.instructions.items(.data)[inst].bin_op; @@ -2456,8 +2458,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void { const index_mcv = try self.resolveInst(bin_op.rhs); const slice_ty = self.typeOf(bin_op.lhs); - const elem_ty = slice_ty.childType(); - const mod = self.bin_file.options.module.?; + const elem_ty = slice_ty.childType(mod); const elem_size = elem_ty.abiSize(mod); var buf: Type.SlicePtrFieldTypeBuffer = undefined; @@ -2797,7 +2798,7 @@ fn allocMem(self: *Self, inst: Air.Inst.Index, abi_size: u32, abi_align: u32) !u /// Use a pointer instruction as the basis for allocating stack memory. fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !u32 { const mod = self.bin_file.options.module.?; - const elem_ty = self.typeOfIndex(inst).elemType(); + const elem_ty = self.typeOfIndex(inst).childType(mod); if (!elem_ty.hasRuntimeBits(mod)) { // As this stack item will never be dereferenced at runtime, @@ -3001,9 +3002,9 @@ fn binOp( switch (lhs_ty.zigTypeTag(mod)) { .Pointer => { const ptr_ty = lhs_ty; - const elem_ty = switch (ptr_ty.ptrSize()) { - .One => ptr_ty.childType().childType(), // ptr to array, so get array element type - else => ptr_ty.childType(), + const elem_ty = switch (ptr_ty.ptrSize(mod)) { + .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type + else => ptr_ty.childType(mod), }; const elem_size = elem_ty.abiSize(mod); @@ -3019,7 +3020,7 @@ fn binOp( // multiplying it with elem_size const offset = try self.binOp(.mul, rhs, .{ .immediate = elem_size }, Type.usize, Type.usize, null); - const addr = try self.binOp(tag, lhs, offset, Type.initTag(.manyptr_u8), Type.usize, null); + const addr = try self.binOp(tag, lhs, offset, Type.manyptr_u8, Type.usize, null); return addr; } }, @@ -4042,11 +4043,7 @@ fn genSetStack(self: *Self, ty: Type, stack_offset: u32, mcv: MCValue) InnerErro const reg = try self.copyToTmpRegister(ty, mcv); return self.genSetStack(ty, stack_offset, MCValue{ .register = reg }); } else { - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ty); const regs = try self.register_manager.allocRegs(4, .{ null, null, null, null }, gp); const regs_locks = self.register_manager.lockRegsAssumeUnused(4, regs); @@ -4269,7 +4266,7 @@ fn jump(self: *Self, inst: Mir.Inst.Index) !void { fn load(self: *Self, dst_mcv: MCValue, ptr: MCValue, ptr_ty: Type) InnerError!void { const mod = self.bin_file.options.module.?; - const elem_ty = ptr_ty.elemType(); + const elem_ty = ptr_ty.childType(mod); const elem_size = elem_ty.abiSize(mod); switch (ptr) { @@ -4729,7 +4726,7 @@ fn structFieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, inde const mod = self.bin_file.options.module.?; const mcv = try self.resolveInst(operand); const ptr_ty = self.typeOf(operand); - const struct_ty = ptr_ty.childType(); + const struct_ty = ptr_ty.childType(mod); const struct_field_offset = @intCast(u32, struct_ty.structFieldOffset(index, mod)); switch (mcv) { .ptr_stack_offset => |off| { diff --git a/src/arch/wasm/CodeGen.zig b/src/arch/wasm/CodeGen.zig index 7fc5dbc825..96304628e9 100644 --- a/src/arch/wasm/CodeGen.zig +++ b/src/arch/wasm/CodeGen.zig @@ -1542,7 +1542,7 @@ fn allocStack(func: *CodeGen, ty: Type) !WValue { fn allocStackPtr(func: *CodeGen, inst: Air.Inst.Index) !WValue { const mod = func.bin_file.base.options.module.?; const ptr_ty = func.typeOfIndex(inst); - const pointee_ty = ptr_ty.childType(); + const pointee_ty = ptr_ty.childType(mod); if (func.initial_stack_value == .none) { try func.initializeStack(); @@ -1766,8 +1766,7 @@ fn isByRef(ty: Type, mod: *const Module) bool { }, .Optional => { if (ty.isPtrLikeOptional(mod)) return false; - var buf: Type.Payload.ElemType = undefined; - const pl_type = ty.optionalChild(&buf); + const pl_type = ty.optionalChild(mod); if (pl_type.zigTypeTag(mod) == .ErrorSet) return false; return pl_type.hasRuntimeBitsIgnoreComptime(mod); }, @@ -2139,7 +2138,7 @@ fn airRet(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { fn airRetPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const mod = func.bin_file.base.options.module.?; - const child_type = func.typeOfIndex(inst).childType(); + const child_type = func.typeOfIndex(inst).childType(mod); var result = result: { if (!child_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { @@ -2161,7 +2160,7 @@ fn airRetLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const mod = func.bin_file.base.options.module.?; const un_op = func.air.instructions.items(.data)[inst].un_op; const operand = try func.resolveInst(un_op); - const ret_ty = func.typeOf(un_op).childType(); + const ret_ty = func.typeOf(un_op).childType(mod); const fn_info = func.decl.ty.fnInfo(); if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { @@ -2188,7 +2187,7 @@ fn airCall(func: *CodeGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif const mod = func.bin_file.base.options.module.?; const fn_ty = switch (ty.zigTypeTag(mod)) { .Fn => ty, - .Pointer => ty.childType(), + .Pointer => ty.childType(mod), else => unreachable, }; const ret_ty = fn_ty.fnReturnType(); @@ -2301,8 +2300,8 @@ fn airStore(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void const lhs = try func.resolveInst(bin_op.lhs); const rhs = try func.resolveInst(bin_op.rhs); const ptr_ty = func.typeOf(bin_op.lhs); - const ptr_info = ptr_ty.ptrInfo().data; - const ty = ptr_ty.childType(); + const ptr_info = ptr_ty.ptrInfo(mod); + const ty = ptr_ty.childType(mod); if (ptr_info.host_size == 0) { try func.store(lhs, rhs, ty, 0); @@ -2360,8 +2359,7 @@ fn store(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, offset: u32) InnerE if (ty.isPtrLikeOptional(mod)) { return func.store(lhs, rhs, Type.usize, 0); } - var buf: Type.Payload.ElemType = undefined; - const pl_ty = ty.optionalChild(&buf); + const pl_ty = ty.optionalChild(mod); if (!pl_ty.hasRuntimeBitsIgnoreComptime(mod)) { return func.store(lhs, rhs, Type.u8, 0); } @@ -2454,7 +2452,7 @@ fn airLoad(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const operand = try func.resolveInst(ty_op.operand); const ty = func.air.getRefType(ty_op.ty); const ptr_ty = func.typeOf(ty_op.operand); - const ptr_info = ptr_ty.ptrInfo().data; + const ptr_info = ptr_ty.ptrInfo(mod); if (!ty.hasRuntimeBitsIgnoreComptime(mod)) return func.finishAir(inst, .none, &.{ty_op.operand}); @@ -2971,7 +2969,7 @@ fn lowerParentPtr(func: *CodeGen, ptr_val: Value, offset: u32) InnerError!WValue break :blk field_offset; }, }, - .Pointer => switch (parent_ty.ptrSize()) { + .Pointer => switch (parent_ty.ptrSize(mod)) { .Slice => switch (field_ptr.field_index) { 0 => 0, 1 => func.ptrSize(), @@ -3001,11 +2999,7 @@ fn lowerParentPtrDecl(func: *CodeGen, ptr_val: Value, decl_index: Module.Decl.In const mod = func.bin_file.base.options.module.?; const decl = mod.declPtr(decl_index); mod.markDeclAlive(decl); - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = decl.ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(decl.ty); return func.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index, offset); } @@ -3145,8 +3139,7 @@ fn lowerConstant(func: *CodeGen, arg_val: Value, ty: Type) InnerError!WValue { return func.fail("Wasm TODO: lowerConstant error union with non-zero-bit payload type", .{}); }, .Optional => if (ty.optionalReprIsPayload(mod)) { - var buf: Type.Payload.ElemType = undefined; - const pl_ty = ty.optionalChild(&buf); + const pl_ty = ty.optionalChild(mod); if (val.castTag(.opt_payload)) |payload| { return func.lowerConstant(payload.data, pl_ty); } else if (val.isNull(mod)) { @@ -3217,8 +3210,7 @@ fn emitUndefined(func: *CodeGen, ty: Type) InnerError!WValue { else => unreachable, }, .Optional => { - var buf: Type.Payload.ElemType = undefined; - const pl_ty = ty.optionalChild(&buf); + const pl_ty = ty.optionalChild(mod); if (ty.optionalReprIsPayload(mod)) { return func.emitUndefined(pl_ty); } @@ -3403,8 +3395,7 @@ fn cmp(func: *CodeGen, lhs: WValue, rhs: WValue, ty: Type, op: std.math.CompareO assert(!(lhs != .stack and rhs == .stack)); const mod = func.bin_file.base.options.module.?; if (ty.zigTypeTag(mod) == .Optional and !ty.optionalReprIsPayload(mod)) { - var buf: Type.Payload.ElemType = undefined; - const payload_ty = ty.optionalChild(&buf); + const payload_ty = ty.optionalChild(mod); if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { // When we hit this case, we must check the value of optionals // that are not pointers. This means first checking against non-null for @@ -3609,19 +3600,21 @@ fn bitcast(func: *CodeGen, wanted_ty: Type, given_ty: Type, operand: WValue) Inn } fn airStructFieldPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { + const mod = func.bin_file.base.options.module.?; const ty_pl = func.air.instructions.items(.data)[inst].ty_pl; const extra = func.air.extraData(Air.StructField, ty_pl.payload); const struct_ptr = try func.resolveInst(extra.data.struct_operand); - const struct_ty = func.typeOf(extra.data.struct_operand).childType(); + const struct_ty = func.typeOf(extra.data.struct_operand).childType(mod); const result = try func.structFieldPtr(inst, extra.data.struct_operand, struct_ptr, struct_ty, extra.data.field_index); func.finishAir(inst, result, &.{extra.data.struct_operand}); } fn airStructFieldPtrIndex(func: *CodeGen, inst: Air.Inst.Index, index: u32) InnerError!void { + const mod = func.bin_file.base.options.module.?; const ty_op = func.air.instructions.items(.data)[inst].ty_op; const struct_ptr = try func.resolveInst(ty_op.operand); - const struct_ty = func.typeOf(ty_op.operand).childType(); + const struct_ty = func.typeOf(ty_op.operand).childType(mod); const result = try func.structFieldPtr(inst, ty_op.operand, struct_ptr, struct_ty, index); func.finishAir(inst, result, &.{ty_op.operand}); @@ -3640,7 +3633,7 @@ fn structFieldPtr( const offset = switch (struct_ty.containerLayout()) { .Packed => switch (struct_ty.zigTypeTag(mod)) { .Struct => offset: { - if (result_ty.ptrInfo().data.host_size != 0) { + if (result_ty.ptrInfo(mod).host_size != 0) { break :offset @as(u32, 0); } break :offset struct_ty.packedStructFieldByteOffset(index, mod); @@ -3981,7 +3974,7 @@ fn airUnwrapErrUnionPayload(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: boo const operand = try func.resolveInst(ty_op.operand); const op_ty = func.typeOf(ty_op.operand); - const err_ty = if (op_is_ptr) op_ty.childType() else op_ty; + const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty; const payload_ty = err_ty.errorUnionPayload(); const result = result: { @@ -4009,7 +4002,7 @@ fn airUnwrapErrUnionError(func: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) const operand = try func.resolveInst(ty_op.operand); const op_ty = func.typeOf(ty_op.operand); - const err_ty = if (op_is_ptr) op_ty.childType() else op_ty; + const err_ty = if (op_is_ptr) op_ty.childType(mod) else op_ty; const payload_ty = err_ty.errorUnionPayload(); const result = result: { @@ -4156,11 +4149,12 @@ fn intcast(func: *CodeGen, operand: WValue, given: Type, wanted: Type) InnerErro } fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: enum { value, ptr }) InnerError!void { + const mod = func.bin_file.base.options.module.?; const un_op = func.air.instructions.items(.data)[inst].un_op; const operand = try func.resolveInst(un_op); const op_ty = func.typeOf(un_op); - const optional_ty = if (op_kind == .ptr) op_ty.childType() else op_ty; + const optional_ty = if (op_kind == .ptr) op_ty.childType(mod) else op_ty; const is_null = try func.isNull(operand, optional_ty, opcode); const result = try is_null.toLocal(func, optional_ty); func.finishAir(inst, result, &.{un_op}); @@ -4171,8 +4165,7 @@ fn airIsNull(func: *CodeGen, inst: Air.Inst.Index, opcode: wasm.Opcode, op_kind: fn isNull(func: *CodeGen, operand: WValue, optional_ty: Type, opcode: wasm.Opcode) InnerError!WValue { const mod = func.bin_file.base.options.module.?; try func.emitWValue(operand); - var buf: Type.Payload.ElemType = undefined; - const payload_ty = optional_ty.optionalChild(&buf); + const payload_ty = optional_ty.optionalChild(mod); if (!optional_ty.optionalReprIsPayload(mod)) { // When payload is zero-bits, we can treat operand as a value, rather than // a pointer to the stack value @@ -4221,14 +4214,13 @@ fn airOptionalPayload(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { } fn airOptionalPayloadPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { + const mod = func.bin_file.base.options.module.?; const ty_op = func.air.instructions.items(.data)[inst].ty_op; const operand = try func.resolveInst(ty_op.operand); - const opt_ty = func.typeOf(ty_op.operand).childType(); + const opt_ty = func.typeOf(ty_op.operand).childType(mod); - const mod = func.bin_file.base.options.module.?; const result = result: { - var buf: Type.Payload.ElemType = undefined; - const payload_ty = opt_ty.optionalChild(&buf); + const payload_ty = opt_ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or opt_ty.optionalReprIsPayload(mod)) { break :result func.reuseOperand(ty_op.operand, operand); } @@ -4242,9 +4234,8 @@ fn airOptionalPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi const mod = func.bin_file.base.options.module.?; const ty_op = func.air.instructions.items(.data)[inst].ty_op; const operand = try func.resolveInst(ty_op.operand); - const opt_ty = func.typeOf(ty_op.operand).childType(); - var buf: Type.Payload.ElemType = undefined; - const payload_ty = opt_ty.optionalChild(&buf); + const opt_ty = func.typeOf(ty_op.operand).childType(mod); + const payload_ty = opt_ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { return func.fail("TODO: Implement OptionalPayloadPtrSet for optional with zero-sized type {}", .{payload_ty.fmtDebug()}); } @@ -4325,13 +4316,13 @@ fn airSliceLen(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { } fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { + const mod = func.bin_file.base.options.module.?; const bin_op = func.air.instructions.items(.data)[inst].bin_op; const slice_ty = func.typeOf(bin_op.lhs); const slice = try func.resolveInst(bin_op.lhs); const index = try func.resolveInst(bin_op.rhs); - const elem_ty = slice_ty.childType(); - const mod = func.bin_file.base.options.module.?; + const elem_ty = slice_ty.childType(mod); const elem_size = elem_ty.abiSize(mod); // load pointer onto stack @@ -4355,11 +4346,11 @@ fn airSliceElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { } fn airSliceElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { + const mod = func.bin_file.base.options.module.?; const ty_pl = func.air.instructions.items(.data)[inst].ty_pl; const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; - const elem_ty = func.air.getRefType(ty_pl.ty).childType(); - const mod = func.bin_file.base.options.module.?; + const elem_ty = func.air.getRefType(ty_pl.ty).childType(mod); const elem_size = elem_ty.abiSize(mod); const slice = try func.resolveInst(bin_op.lhs); @@ -4436,7 +4427,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const ty_op = func.air.instructions.items(.data)[inst].ty_op; const operand = try func.resolveInst(ty_op.operand); - const array_ty = func.typeOf(ty_op.operand).childType(); + const array_ty = func.typeOf(ty_op.operand).childType(mod); const slice_ty = func.air.getRefType(ty_op.ty); // create a slice on the stack @@ -4448,7 +4439,7 @@ fn airArrayToSlice(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { } // store the length of the array in the slice - const len = WValue{ .imm32 = @intCast(u32, array_ty.arrayLen()) }; + const len = WValue{ .imm32 = @intCast(u32, array_ty.arrayLen(mod)) }; try func.store(slice_local, len, Type.usize, func.ptrSize()); func.finishAir(inst, slice_local, &.{ty_op.operand}); @@ -4470,13 +4461,13 @@ fn airPtrToInt(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { } fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { + const mod = func.bin_file.base.options.module.?; const bin_op = func.air.instructions.items(.data)[inst].bin_op; const ptr_ty = func.typeOf(bin_op.lhs); const ptr = try func.resolveInst(bin_op.lhs); const index = try func.resolveInst(bin_op.rhs); - const elem_ty = ptr_ty.childType(); - const mod = func.bin_file.base.options.module.?; + const elem_ty = ptr_ty.childType(mod); const elem_size = elem_ty.abiSize(mod); // load pointer onto the stack @@ -4507,12 +4498,12 @@ fn airPtrElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { } fn airPtrElemPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { + const mod = func.bin_file.base.options.module.?; const ty_pl = func.air.instructions.items(.data)[inst].ty_pl; const bin_op = func.air.extraData(Air.Bin, ty_pl.payload).data; const ptr_ty = func.typeOf(bin_op.lhs); - const elem_ty = func.air.getRefType(ty_pl.ty).childType(); - const mod = func.bin_file.base.options.module.?; + const elem_ty = func.air.getRefType(ty_pl.ty).childType(mod); const elem_size = elem_ty.abiSize(mod); const ptr = try func.resolveInst(bin_op.lhs); @@ -4544,9 +4535,9 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { const ptr = try func.resolveInst(bin_op.lhs); const offset = try func.resolveInst(bin_op.rhs); const ptr_ty = func.typeOf(bin_op.lhs); - const pointee_ty = switch (ptr_ty.ptrSize()) { - .One => ptr_ty.childType().childType(), // ptr to array, so get array element type - else => ptr_ty.childType(), + const pointee_ty = switch (ptr_ty.ptrSize(mod)) { + .One => ptr_ty.childType(mod).childType(mod), // ptr to array, so get array element type + else => ptr_ty.childType(mod), }; const valtype = typeToValtype(Type.usize, mod); @@ -4565,6 +4556,7 @@ fn airPtrBinOp(func: *CodeGen, inst: Air.Inst.Index, op: Op) InnerError!void { } fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void { + const mod = func.bin_file.base.options.module.?; if (safety) { // TODO if the value is undef, write 0xaa bytes to dest } else { @@ -4575,16 +4567,16 @@ fn airMemset(func: *CodeGen, inst: Air.Inst.Index, safety: bool) InnerError!void const ptr = try func.resolveInst(bin_op.lhs); const ptr_ty = func.typeOf(bin_op.lhs); const value = try func.resolveInst(bin_op.rhs); - const len = switch (ptr_ty.ptrSize()) { + const len = switch (ptr_ty.ptrSize(mod)) { .Slice => try func.sliceLen(ptr), - .One => @as(WValue, .{ .imm32 = @intCast(u32, ptr_ty.childType().arrayLen()) }), + .One => @as(WValue, .{ .imm32 = @intCast(u32, ptr_ty.childType(mod).arrayLen(mod)) }), .C, .Many => unreachable, }; - const elem_ty = if (ptr_ty.ptrSize() == .One) - ptr_ty.childType().childType() + const elem_ty = if (ptr_ty.ptrSize(mod) == .One) + ptr_ty.childType(mod).childType(mod) else - ptr_ty.childType(); + ptr_ty.childType(mod); const dst_ptr = try func.sliceOrArrayPtr(ptr, ptr_ty); try func.memset(elem_ty, dst_ptr, len, value); @@ -4686,13 +4678,13 @@ fn memset(func: *CodeGen, elem_ty: Type, ptr: WValue, len: WValue, value: WValue } fn airArrayElemVal(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { + const mod = func.bin_file.base.options.module.?; const bin_op = func.air.instructions.items(.data)[inst].bin_op; const array_ty = func.typeOf(bin_op.lhs); const array = try func.resolveInst(bin_op.lhs); const index = try func.resolveInst(bin_op.rhs); - const elem_ty = array_ty.childType(); - const mod = func.bin_file.base.options.module.?; + const elem_ty = array_ty.childType(mod); const elem_size = elem_ty.abiSize(mod); if (isByRef(array_ty, mod)) { @@ -4810,7 +4802,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const ty_op = func.air.instructions.items(.data)[inst].ty_op; const operand = try func.resolveInst(ty_op.operand); const ty = func.typeOfIndex(inst); - const elem_ty = ty.childType(); + const elem_ty = ty.childType(mod); if (determineSimdStoreStrategy(ty, mod) == .direct) blk: { switch (operand) { @@ -4859,7 +4851,7 @@ fn airSplat(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { } } const elem_size = elem_ty.bitSize(mod); - const vector_len = @intCast(usize, ty.vectorLen()); + const vector_len = @intCast(usize, ty.vectorLen(mod)); if ((!std.math.isPowerOfTwo(elem_size) or elem_size % 8 != 0) and vector_len > 1) { return func.fail("TODO: WebAssembly `@splat` for arbitrary element bitsize {d}", .{elem_size}); } @@ -4895,7 +4887,7 @@ fn airShuffle(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const mask = func.air.values[extra.mask]; const mask_len = extra.mask_len; - const child_ty = inst_ty.childType(); + const child_ty = inst_ty.childType(mod); const elem_size = child_ty.abiSize(mod); // TODO: One of them could be by ref; handle in loop @@ -4959,16 +4951,16 @@ fn airAggregateInit(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const mod = func.bin_file.base.options.module.?; const ty_pl = func.air.instructions.items(.data)[inst].ty_pl; const result_ty = func.typeOfIndex(inst); - const len = @intCast(usize, result_ty.arrayLen()); + const len = @intCast(usize, result_ty.arrayLen(mod)); const elements = @ptrCast([]const Air.Inst.Ref, func.air.extra[ty_pl.payload..][0..len]); const result: WValue = result_value: { switch (result_ty.zigTypeTag(mod)) { .Array => { const result = try func.allocStack(result_ty); - const elem_ty = result_ty.childType(); + const elem_ty = result_ty.childType(mod); const elem_size = @intCast(u32, elem_ty.abiSize(mod)); - const sentinel = if (result_ty.sentinel()) |sent| blk: { + const sentinel = if (result_ty.sentinel(mod)) |sent| blk: { break :blk try func.lowerConstant(sent, elem_ty); } else null; @@ -5190,8 +5182,7 @@ fn cmpOptionals(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: const mod = func.bin_file.base.options.module.?; assert(operand_ty.hasRuntimeBitsIgnoreComptime(mod)); assert(op == .eq or op == .neq); - var buf: Type.Payload.ElemType = undefined; - const payload_ty = operand_ty.optionalChild(&buf); + const payload_ty = operand_ty.optionalChild(mod); // We store the final result in here that will be validated // if the optional is truly equal. @@ -5268,7 +5259,7 @@ fn cmpBigInt(func: *CodeGen, lhs: WValue, rhs: WValue, operand_ty: Type, op: std fn airSetUnionTag(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const mod = func.bin_file.base.options.module.?; const bin_op = func.air.instructions.items(.data)[inst].bin_op; - const un_ty = func.typeOf(bin_op.lhs).childType(); + const un_ty = func.typeOf(bin_op.lhs).childType(mod); const tag_ty = func.typeOf(bin_op.rhs); const layout = un_ty.unionGetLayout(mod); if (layout.tag_size == 0) return func.finishAir(inst, .none, &.{ bin_op.lhs, bin_op.rhs }); @@ -5398,7 +5389,7 @@ fn airErrUnionPayloadPtrSet(func: *CodeGen, inst: Air.Inst.Index) InnerError!voi const mod = func.bin_file.base.options.module.?; const ty_op = func.air.instructions.items(.data)[inst].ty_op; - const err_set_ty = func.typeOf(ty_op.operand).childType(); + const err_set_ty = func.typeOf(ty_op.operand).childType(mod); const payload_ty = err_set_ty.errorUnionPayload(); const operand = try func.resolveInst(ty_op.operand); @@ -5426,7 +5417,7 @@ fn airFieldParentPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const extra = func.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; const field_ptr = try func.resolveInst(extra.field_ptr); - const parent_ty = func.air.getRefType(ty_pl.ty).childType(); + const parent_ty = func.air.getRefType(ty_pl.ty).childType(mod); const field_offset = parent_ty.structFieldOffset(extra.field_index, mod); const result = if (field_offset != 0) result: { @@ -5455,10 +5446,10 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const bin_op = func.air.instructions.items(.data)[inst].bin_op; const dst = try func.resolveInst(bin_op.lhs); const dst_ty = func.typeOf(bin_op.lhs); - const ptr_elem_ty = dst_ty.childType(); + const ptr_elem_ty = dst_ty.childType(mod); const src = try func.resolveInst(bin_op.rhs); const src_ty = func.typeOf(bin_op.rhs); - const len = switch (dst_ty.ptrSize()) { + const len = switch (dst_ty.ptrSize(mod)) { .Slice => blk: { const slice_len = try func.sliceLen(dst); if (ptr_elem_ty.abiSize(mod) != 1) { @@ -5470,7 +5461,7 @@ fn airMemcpy(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { break :blk slice_len; }, .One => @as(WValue, .{ - .imm32 = @intCast(u32, ptr_elem_ty.arrayLen() * ptr_elem_ty.childType().abiSize(mod)), + .imm32 = @intCast(u32, ptr_elem_ty.arrayLen(mod) * ptr_elem_ty.childType(mod).abiSize(mod)), }), .C, .Many => unreachable, }; @@ -5551,7 +5542,7 @@ fn airErrorName(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { // As the names are global and the slice elements are constant, we do not have // to make a copy of the ptr+value but can point towards them directly. const error_table_symbol = try func.bin_file.getErrorTableSymbol(); - const name_ty = Type.initTag(.const_slice_u8_sentinel_0); + const name_ty = Type.const_slice_u8_sentinel_0; const mod = func.bin_file.base.options.module.?; const abi_size = name_ty.abiSize(mod); @@ -5857,7 +5848,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { try func.addLabel(.local_set, overflow_bit.local.value); break :blk try func.wrapOperand(bin_op, lhs_ty); } else if (int_info.bits == 64 and int_info.signedness == .unsigned) blk: { - const new_ty = Type.initTag(.u128); + const new_ty = Type.u128; var lhs_upcast = try (try func.intcast(lhs, lhs_ty, new_ty)).toLocal(func, lhs_ty); defer lhs_upcast.free(func); var rhs_upcast = try (try func.intcast(rhs, lhs_ty, new_ty)).toLocal(func, lhs_ty); @@ -5878,7 +5869,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const bin_op = try func.callIntrinsic( "__multi3", &[_]Type{Type.i64} ** 4, - Type.initTag(.i128), + Type.i128, &.{ lhs, lhs_shifted, rhs, rhs_shifted }, ); const res = try func.allocLocal(lhs_ty); @@ -5902,19 +5893,19 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const mul1 = try func.callIntrinsic( "__multi3", &[_]Type{Type.i64} ** 4, - Type.initTag(.i128), + Type.i128, &.{ lhs_lsb, zero, rhs_msb, zero }, ); const mul2 = try func.callIntrinsic( "__multi3", &[_]Type{Type.i64} ** 4, - Type.initTag(.i128), + Type.i128, &.{ rhs_lsb, zero, lhs_msb, zero }, ); const mul3 = try func.callIntrinsic( "__multi3", &[_]Type{Type.i64} ** 4, - Type.initTag(.i128), + Type.i128, &.{ lhs_msb, zero, rhs_msb, zero }, ); @@ -5942,7 +5933,7 @@ fn airMulWithOverflow(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { _ = try func.binOp(lsb_or, mul_add_lt, Type.bool, .@"or"); try func.addLabel(.local_set, overflow_bit.local.value); - const tmp_result = try func.allocStack(Type.initTag(.u128)); + const tmp_result = try func.allocStack(Type.u128); try func.emitWValue(tmp_result); const mul3_msb = try func.load(mul3, Type.u64, 0); try func.store(.stack, mul3_msb, Type.u64, tmp_result.offset()); @@ -6191,11 +6182,12 @@ fn airTry(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { } fn airTryPtr(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { + const mod = func.bin_file.base.options.module.?; const ty_pl = func.air.instructions.items(.data)[inst].ty_pl; const extra = func.air.extraData(Air.TryPtr, ty_pl.payload); const err_union_ptr = try func.resolveInst(extra.data.ptr); const body = func.air.extra[extra.end..][0..extra.data.body_len]; - const err_union_ty = func.typeOf(extra.data.ptr).childType(); + const err_union_ty = func.typeOf(extra.data.ptr).childType(mod); const result = try lowerTry(func, inst, err_union_ptr, body, err_union_ty, true); func.finishAir(inst, result, &.{extra.data.ptr}); } @@ -6845,11 +6837,11 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { for (enum_ty.enumFields().keys(), 0..) |tag_name, field_index| { // for each tag name, create an unnamed const, // and then get a pointer to its value. - var name_ty_payload: Type.Payload.Len = .{ - .base = .{ .tag = .array_u8_sentinel_0 }, - .data = @intCast(u64, tag_name.len), - }; - const name_ty = Type.initPayload(&name_ty_payload.base); + const name_ty = try mod.arrayType(.{ + .len = tag_name.len, + .child = .u8_type, + .sentinel = .zero_u8, + }); const string_bytes = &mod.string_literal_bytes; try string_bytes.ensureUnusedCapacity(mod.gpa, tag_name.len); const gop = try mod.string_literal_table.getOrPutContextAdapted(mod.gpa, tag_name, Module.StringLiteralAdapter{ @@ -6972,7 +6964,7 @@ fn getTagNameFunction(func: *CodeGen, enum_ty: Type) InnerError!u32 { // finish function body try writer.writeByte(std.wasm.opcode(.end)); - const slice_ty = Type.initTag(.const_slice_u8_sentinel_0); + const slice_ty = Type.const_slice_u8_sentinel_0; const func_type = try genFunctype(arena, .Unspecified, &.{int_tag_ty}, slice_ty, mod); return func.bin_file.createFunction(func_name, func_type, &body_list, &relocs); } @@ -7068,7 +7060,7 @@ fn airCmpxchg(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const extra = func.air.extraData(Air.Cmpxchg, ty_pl.payload).data; const ptr_ty = func.typeOf(extra.ptr); - const ty = ptr_ty.childType(); + const ty = ptr_ty.childType(mod); const result_ty = func.typeOfIndex(inst); const ptr_operand = try func.resolveInst(extra.ptr); @@ -7355,7 +7347,7 @@ fn airAtomicStore(func: *CodeGen, inst: Air.Inst.Index) InnerError!void { const ptr = try func.resolveInst(bin_op.lhs); const operand = try func.resolveInst(bin_op.rhs); const ptr_ty = func.typeOf(bin_op.lhs); - const ty = ptr_ty.childType(); + const ty = ptr_ty.childType(mod); if (func.useAtomicFeature()) { const tag: wasm.AtomicsOpcode = switch (ty.abiSize(mod)) { diff --git a/src/arch/x86_64/CodeGen.zig b/src/arch/x86_64/CodeGen.zig index ad67a0db3d..f6304a0ff3 100644 --- a/src/arch/x86_64/CodeGen.zig +++ b/src/arch/x86_64/CodeGen.zig @@ -2259,7 +2259,7 @@ fn allocFrameIndex(self: *Self, alloc: FrameAlloc) !FrameIndex { fn allocMemPtr(self: *Self, inst: Air.Inst.Index) !FrameIndex { const mod = self.bin_file.options.module.?; const ptr_ty = self.typeOfIndex(inst); - const val_ty = ptr_ty.childType(); + const val_ty = ptr_ty.childType(mod); return self.allocFrameIndex(FrameAlloc.init(.{ .size = math.cast(u32, val_ty.abiSize(mod)) orelse { return self.fail("type '{}' too big to fit into stack frame", .{val_ty.fmt(mod)}); @@ -2289,8 +2289,8 @@ fn allocRegOrMemAdvanced(self: *Self, ty: Type, inst: ?Air.Inst.Index, reg_ok: b 80 => break :need_mem, else => unreachable, }, - .Vector => switch (ty.childType().zigTypeTag(mod)) { - .Float => switch (ty.childType().floatBits(self.target.*)) { + .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (ty.childType(mod).floatBits(self.target.*)) { 16, 32, 64, 128 => if (self.hasFeature(.avx)) 32 else 16, 80 => break :need_mem, else => unreachable, @@ -2727,12 +2727,12 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); if (dst_ty.zigTypeTag(mod) == .Vector) { - assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen() == src_ty.vectorLen()); - const dst_info = dst_ty.childType().intInfo(mod); - const src_info = src_ty.childType().intInfo(mod); + assert(src_ty.zigTypeTag(mod) == .Vector and dst_ty.vectorLen(mod) == src_ty.vectorLen(mod)); + const dst_info = dst_ty.childType(mod).intInfo(mod); + const src_info = src_ty.childType(mod).intInfo(mod); const mir_tag = if (@as(?Mir.Inst.FixedTag, switch (dst_info.bits) { 8 => switch (src_info.bits) { - 16 => switch (dst_ty.vectorLen()) { + 16 => switch (dst_ty.vectorLen(mod)) { 1...8 => if (self.hasFeature(.avx)) .{ .vp_b, .ackusw } else .{ .p_b, .ackusw }, 9...16 => if (self.hasFeature(.avx2)) .{ .vp_b, .ackusw } else null, else => null, @@ -2740,7 +2740,7 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { else => null, }, 16 => switch (src_info.bits) { - 32 => switch (dst_ty.vectorLen()) { + 32 => switch (dst_ty.vectorLen(mod)) { 1...4 => if (self.hasFeature(.avx)) .{ .vp_w, .ackusd } else if (self.hasFeature(.sse4_1)) @@ -2769,14 +2769,10 @@ fn airTrunc(self: *Self, inst: Air.Inst.Index) !void { }; const splat_val = Value.initPayload(&splat_pl.base); - var full_pl = Type.Payload.Array{ - .base = .{ .tag = .vector }, - .data = .{ - .len = @divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits), - .elem_type = src_ty.childType(), - }, - }; - const full_ty = Type.initPayload(&full_pl.base); + const full_ty = try mod.vectorType(.{ + .len = @intCast(u32, @divExact(@as(u64, if (src_abi_size > 16) 256 else 128), src_info.bits)), + .child = src_ty.childType(mod).ip_index, + }); const full_abi_size = @intCast(u32, full_ty.abiSize(mod)); const splat_mcv = try self.genTypedValue(.{ .ty = full_ty, .val = splat_val }); @@ -3587,7 +3583,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { const result = result: { const dst_ty = self.typeOfIndex(inst); const src_ty = self.typeOf(ty_op.operand); - const opt_ty = src_ty.childType(); + const opt_ty = src_ty.childType(mod); const src_mcv = try self.resolveInst(ty_op.operand); if (opt_ty.optionalReprIsPayload(mod)) { @@ -3607,7 +3603,7 @@ fn airOptionalPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { else try self.copyToRegisterWithInstTracking(inst, dst_ty, src_mcv); - const pl_ty = dst_ty.childType(); + const pl_ty = dst_ty.childType(mod); const pl_abi_size = @intCast(i32, pl_ty.abiSize(mod)); try self.genSetMem(.{ .reg = dst_mcv.getReg().? }, pl_abi_size, Type.bool, .{ .immediate = 1 }); break :result if (self.liveness.isUnused(inst)) .unreach else dst_mcv; @@ -3737,7 +3733,7 @@ fn airUnwrapErrUnionErrPtr(self: *Self, inst: Air.Inst.Index) !void { const dst_lock = self.register_manager.lockRegAssumeUnused(dst_reg); defer self.register_manager.unlockReg(dst_lock); - const eu_ty = src_ty.childType(); + const eu_ty = src_ty.childType(mod); const pl_ty = eu_ty.errorUnionPayload(); const err_ty = eu_ty.errorUnionSet(); const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod)); @@ -3777,7 +3773,7 @@ fn airUnwrapErrUnionPayloadPtr(self: *Self, inst: Air.Inst.Index) !void { const dst_lock = self.register_manager.lockReg(dst_reg); defer if (dst_lock) |lock| self.register_manager.unlockReg(lock); - const eu_ty = src_ty.childType(); + const eu_ty = src_ty.childType(mod); const pl_ty = eu_ty.errorUnionPayload(); const pl_off = @intCast(i32, errUnionPayloadOffset(pl_ty, mod)); const dst_abi_size = @intCast(u32, dst_ty.abiSize(mod)); @@ -3803,7 +3799,7 @@ fn airErrUnionPayloadPtrSet(self: *Self, inst: Air.Inst.Index) !void { const src_lock = self.register_manager.lockRegAssumeUnused(src_reg); defer self.register_manager.unlockReg(src_lock); - const eu_ty = src_ty.childType(); + const eu_ty = src_ty.childType(mod); const pl_ty = eu_ty.errorUnionPayload(); const err_ty = eu_ty.errorUnionSet(); const err_off = @intCast(i32, errUnionErrorOffset(pl_ty, mod)); @@ -4057,7 +4053,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue { }; defer if (slice_mcv_lock) |lock| self.register_manager.unlockReg(lock); - const elem_ty = slice_ty.childType(); + const elem_ty = slice_ty.childType(mod); const elem_size = elem_ty.abiSize(mod); var buf: Type.SlicePtrFieldTypeBuffer = undefined; const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf); @@ -4116,7 +4112,7 @@ fn airArrayElemVal(self: *Self, inst: Air.Inst.Index) !void { }; defer if (array_lock) |lock| self.register_manager.unlockReg(lock); - const elem_ty = array_ty.childType(); + const elem_ty = array_ty.childType(mod); const elem_abi_size = elem_ty.abiSize(mod); const index_ty = self.typeOf(bin_op.rhs); @@ -4253,7 +4249,7 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { const mod = self.bin_file.options.module.?; const bin_op = self.air.instructions.items(.data)[inst].bin_op; const ptr_union_ty = self.typeOf(bin_op.lhs); - const union_ty = ptr_union_ty.childType(); + const union_ty = ptr_union_ty.childType(mod); const tag_ty = self.typeOf(bin_op.rhs); const layout = union_ty.unionGetLayout(mod); @@ -4287,7 +4283,9 @@ fn airSetUnionTag(self: *Self, inst: Air.Inst.Index) !void { break :blk MCValue{ .register = reg }; } else ptr; - var ptr_tag_pl = ptr_union_ty.ptrInfo(); + var ptr_tag_pl: Type.Payload.Pointer = .{ + .data = ptr_union_ty.ptrInfo(mod), + }; ptr_tag_pl.data.pointee_type = tag_ty; const ptr_tag_ty = Type.initPayload(&ptr_tag_pl.base); try self.store(ptr_tag_ty, adjusted_ptr, tag); @@ -4924,14 +4922,11 @@ fn airFloatSign(self: *Self, inst: Air.Inst.Index) !void { var stack align(@alignOf(ExpectedContents)) = std.heap.stackFallback(@sizeOf(ExpectedContents), arena.allocator()); - var vec_pl = Type.Payload.Array{ - .base = .{ .tag = .vector }, - .data = .{ - .len = @divExact(abi_size * 8, scalar_bits), - .elem_type = try mod.intType(.signed, scalar_bits), - }, - }; - const vec_ty = Type.initPayload(&vec_pl.base); + const vec_ty = try mod.vectorType(.{ + .len = @divExact(abi_size * 8, scalar_bits), + .child = (try mod.intType(.signed, scalar_bits)).ip_index, + }); + const sign_val = switch (tag) { .neg => try vec_ty.minInt(stack.get(), mod), .fabs => try vec_ty.maxInt(stack.get(), mod), @@ -5034,15 +5029,15 @@ fn genRound(self: *Self, ty: Type, dst_reg: Register, src_mcv: MCValue, mode: u4 16, 80, 128 => null, else => unreachable, }, - .Vector => switch (ty.childType().zigTypeTag(mod)) { - .Float => switch (ty.childType().floatBits(self.target.*)) { - 32 => switch (ty.vectorLen()) { + .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (ty.childType(mod).floatBits(self.target.*)) { + 32 => switch (ty.vectorLen(mod)) { 1 => if (self.hasFeature(.avx)) .{ .v_ss, .round } else .{ ._ss, .round }, 2...4 => if (self.hasFeature(.avx)) .{ .v_ps, .round } else .{ ._ps, .round }, 5...8 => if (self.hasFeature(.avx)) .{ .v_ps, .round } else null, else => null, }, - 64 => switch (ty.vectorLen()) { + 64 => switch (ty.vectorLen(mod)) { 1 => if (self.hasFeature(.avx)) .{ .v_sd, .round } else .{ ._sd, .round }, 2 => if (self.hasFeature(.avx)) .{ .v_pd, .round } else .{ ._pd, .round }, 3...4 => if (self.hasFeature(.avx)) .{ .v_pd, .round } else null, @@ -5131,9 +5126,9 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { 80, 128 => null, else => unreachable, }, - .Vector => switch (ty.childType().zigTypeTag(mod)) { - .Float => switch (ty.childType().floatBits(self.target.*)) { - 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen()) { + .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (ty.childType(mod).floatBits(self.target.*)) { + 16 => if (self.hasFeature(.f16c)) switch (ty.vectorLen(mod)) { 1 => { try self.asmRegisterRegister( .{ .v_ps, .cvtph2 }, @@ -5184,13 +5179,13 @@ fn airSqrt(self: *Self, inst: Air.Inst.Index) !void { }, else => null, } else null, - 32 => switch (ty.vectorLen()) { + 32 => switch (ty.vectorLen(mod)) { 1 => if (self.hasFeature(.avx)) .{ .v_ss, .sqrt } else .{ ._ss, .sqrt }, 2...4 => if (self.hasFeature(.avx)) .{ .v_ps, .sqrt } else .{ ._ps, .sqrt }, 5...8 => if (self.hasFeature(.avx)) .{ .v_ps, .sqrt } else null, else => null, }, - 64 => switch (ty.vectorLen()) { + 64 => switch (ty.vectorLen(mod)) { 1 => if (self.hasFeature(.avx)) .{ .v_sd, .sqrt } else .{ ._sd, .sqrt }, 2 => if (self.hasFeature(.avx)) .{ .v_pd, .sqrt } else .{ ._pd, .sqrt }, 3...4 => if (self.hasFeature(.avx)) .{ .v_pd, .sqrt } else null, @@ -5292,7 +5287,7 @@ fn reuseOperandAdvanced( fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { const mod = self.bin_file.options.module.?; - const ptr_info = ptr_ty.ptrInfo().data; + const ptr_info = ptr_ty.ptrInfo(mod); const val_ty = ptr_info.pointee_type; const val_abi_size = @intCast(u32, val_ty.abiSize(mod)); @@ -5365,7 +5360,8 @@ fn packedLoad(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) Inn } fn load(self: *Self, dst_mcv: MCValue, ptr_ty: Type, ptr_mcv: MCValue) InnerError!void { - const dst_ty = ptr_ty.childType(); + const mod = self.bin_file.options.module.?; + const dst_ty = ptr_ty.childType(mod); switch (ptr_mcv) { .none, .unreach, @@ -5424,7 +5420,7 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { else try self.allocRegOrMem(inst, true); - if (ptr_ty.ptrInfo().data.host_size > 0) { + if (ptr_ty.ptrInfo(mod).host_size > 0) { try self.packedLoad(dst_mcv, ptr_ty, ptr_mcv); } else { try self.load(dst_mcv, ptr_ty, ptr_mcv); @@ -5436,8 +5432,8 @@ fn airLoad(self: *Self, inst: Air.Inst.Index) !void { fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void { const mod = self.bin_file.options.module.?; - const ptr_info = ptr_ty.ptrInfo().data; - const src_ty = ptr_ty.childType(); + const ptr_info = ptr_ty.ptrInfo(mod); + const src_ty = ptr_ty.childType(mod); const limb_abi_size: u16 = @min(ptr_info.host_size, 8); const limb_abi_bits = limb_abi_size * 8; @@ -5509,7 +5505,8 @@ fn packedStore(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) In } fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerError!void { - const src_ty = ptr_ty.childType(); + const mod = self.bin_file.options.module.?; + const src_ty = ptr_ty.childType(mod); switch (ptr_mcv) { .none, .unreach, @@ -5544,6 +5541,7 @@ fn store(self: *Self, ptr_ty: Type, ptr_mcv: MCValue, src_mcv: MCValue) InnerErr } fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void { + const mod = self.bin_file.options.module.?; if (safety) { // TODO if the value is undef, write 0xaa bytes to dest } else { @@ -5553,7 +5551,7 @@ fn airStore(self: *Self, inst: Air.Inst.Index, safety: bool) !void { const ptr_mcv = try self.resolveInst(bin_op.lhs); const ptr_ty = self.typeOf(bin_op.lhs); const src_mcv = try self.resolveInst(bin_op.rhs); - if (ptr_ty.ptrInfo().data.host_size > 0) { + if (ptr_ty.ptrInfo(mod).host_size > 0) { try self.packedStore(ptr_ty, ptr_mcv, src_mcv); } else { try self.store(ptr_ty, ptr_mcv, src_mcv); @@ -5578,11 +5576,11 @@ fn fieldPtr(self: *Self, inst: Air.Inst.Index, operand: Air.Inst.Ref, index: u32 const mod = self.bin_file.options.module.?; const ptr_field_ty = self.typeOfIndex(inst); const ptr_container_ty = self.typeOf(operand); - const container_ty = ptr_container_ty.childType(); + const container_ty = ptr_container_ty.childType(mod); const field_offset = @intCast(i32, switch (container_ty.containerLayout()) { .Auto, .Extern => container_ty.structFieldOffset(index, mod), .Packed => if (container_ty.zigTypeTag(mod) == .Struct and - ptr_field_ty.ptrInfo().data.host_size == 0) + ptr_field_ty.ptrInfo(mod).host_size == 0) container_ty.packedStructFieldByteOffset(index, mod) else 0, @@ -5760,7 +5758,7 @@ fn airFieldParentPtr(self: *Self, inst: Air.Inst.Index) !void { const extra = self.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; const inst_ty = self.typeOfIndex(inst); - const parent_ty = inst_ty.childType(); + const parent_ty = inst_ty.childType(mod); const field_offset = @intCast(i32, parent_ty.structFieldOffset(extra.field_index, mod)); const src_mcv = try self.resolveInst(extra.field_ptr); @@ -6680,10 +6678,10 @@ fn genBinOp( 80, 128 => null, else => unreachable, }, - .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) { + .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { else => null, - .Int => switch (lhs_ty.childType().intInfo(mod).bits) { - 8 => switch (lhs_ty.vectorLen()) { + .Int => switch (lhs_ty.childType(mod).intInfo(mod).bits) { + 8 => switch (lhs_ty.vectorLen(mod)) { 1...16 => switch (air_tag) { .add, .addwrap, @@ -6694,7 +6692,7 @@ fn genBinOp( .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" }, .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" }, .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor }, - .min => switch (lhs_ty.childType().intInfo(mod).signedness) { + .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx)) .{ .vp_b, .mins } else if (self.hasFeature(.sse4_1)) @@ -6708,7 +6706,7 @@ fn genBinOp( else null, }, - .max => switch (lhs_ty.childType().intInfo(mod).signedness) { + .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx)) .{ .vp_b, .maxs } else if (self.hasFeature(.sse4_1)) @@ -6734,11 +6732,11 @@ fn genBinOp( .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null, .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null, .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null, - .min => switch (lhs_ty.childType().intInfo(mod).signedness) { + .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .mins } else null, .unsigned => if (self.hasFeature(.avx)) .{ .vp_b, .minu } else null, }, - .max => switch (lhs_ty.childType().intInfo(mod).signedness) { + .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx2)) .{ .vp_b, .maxs } else null, .unsigned => if (self.hasFeature(.avx2)) .{ .vp_b, .maxu } else null, }, @@ -6746,7 +6744,7 @@ fn genBinOp( }, else => null, }, - 16 => switch (lhs_ty.vectorLen()) { + 16 => switch (lhs_ty.vectorLen(mod)) { 1...8 => switch (air_tag) { .add, .addwrap, @@ -6760,7 +6758,7 @@ fn genBinOp( .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" }, .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" }, .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor }, - .min => switch (lhs_ty.childType().intInfo(mod).signedness) { + .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx)) .{ .vp_w, .mins } else @@ -6770,7 +6768,7 @@ fn genBinOp( else .{ .p_w, .minu }, }, - .max => switch (lhs_ty.childType().intInfo(mod).signedness) { + .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx)) .{ .vp_w, .maxs } else @@ -6795,11 +6793,11 @@ fn genBinOp( .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null, .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null, .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null, - .min => switch (lhs_ty.childType().intInfo(mod).signedness) { + .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .mins } else null, .unsigned => if (self.hasFeature(.avx)) .{ .vp_w, .minu } else null, }, - .max => switch (lhs_ty.childType().intInfo(mod).signedness) { + .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx2)) .{ .vp_w, .maxs } else null, .unsigned => if (self.hasFeature(.avx2)) .{ .vp_w, .maxu } else null, }, @@ -6807,7 +6805,7 @@ fn genBinOp( }, else => null, }, - 32 => switch (lhs_ty.vectorLen()) { + 32 => switch (lhs_ty.vectorLen(mod)) { 1...4 => switch (air_tag) { .add, .addwrap, @@ -6826,7 +6824,7 @@ fn genBinOp( .bit_and => if (self.hasFeature(.avx)) .{ .vp_, .@"and" } else .{ .p_, .@"and" }, .bit_or => if (self.hasFeature(.avx)) .{ .vp_, .@"or" } else .{ .p_, .@"or" }, .xor => if (self.hasFeature(.avx)) .{ .vp_, .xor } else .{ .p_, .xor }, - .min => switch (lhs_ty.childType().intInfo(mod).signedness) { + .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx)) .{ .vp_d, .mins } else if (self.hasFeature(.sse4_1)) @@ -6840,7 +6838,7 @@ fn genBinOp( else null, }, - .max => switch (lhs_ty.childType().intInfo(mod).signedness) { + .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx)) .{ .vp_d, .maxs } else if (self.hasFeature(.sse4_1)) @@ -6869,11 +6867,11 @@ fn genBinOp( .bit_and => if (self.hasFeature(.avx2)) .{ .vp_, .@"and" } else null, .bit_or => if (self.hasFeature(.avx2)) .{ .vp_, .@"or" } else null, .xor => if (self.hasFeature(.avx2)) .{ .vp_, .xor } else null, - .min => switch (lhs_ty.childType().intInfo(mod).signedness) { + .min => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .mins } else null, .unsigned => if (self.hasFeature(.avx)) .{ .vp_d, .minu } else null, }, - .max => switch (lhs_ty.childType().intInfo(mod).signedness) { + .max => switch (lhs_ty.childType(mod).intInfo(mod).signedness) { .signed => if (self.hasFeature(.avx2)) .{ .vp_d, .maxs } else null, .unsigned => if (self.hasFeature(.avx2)) .{ .vp_d, .maxu } else null, }, @@ -6881,7 +6879,7 @@ fn genBinOp( }, else => null, }, - 64 => switch (lhs_ty.vectorLen()) { + 64 => switch (lhs_ty.vectorLen(mod)) { 1...2 => switch (air_tag) { .add, .addwrap, @@ -6910,8 +6908,8 @@ fn genBinOp( }, else => null, }, - .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { - 16 => if (self.hasFeature(.f16c)) switch (lhs_ty.vectorLen()) { + .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { + 16 => if (self.hasFeature(.f16c)) switch (lhs_ty.vectorLen(mod)) { 1 => { const tmp_reg = (try self.register_manager.allocReg(null, sse)).to128(); const tmp_lock = self.register_manager.lockRegAssumeUnused(tmp_reg); @@ -7086,7 +7084,7 @@ fn genBinOp( }, else => null, } else null, - 32 => switch (lhs_ty.vectorLen()) { + 32 => switch (lhs_ty.vectorLen(mod)) { 1 => switch (air_tag) { .add => if (self.hasFeature(.avx)) .{ .v_ss, .add } else .{ ._ss, .add }, .sub => if (self.hasFeature(.avx)) .{ .v_ss, .sub } else .{ ._ss, .sub }, @@ -7124,7 +7122,7 @@ fn genBinOp( } else null, else => null, }, - 64 => switch (lhs_ty.vectorLen()) { + 64 => switch (lhs_ty.vectorLen(mod)) { 1 => switch (air_tag) { .add => if (self.hasFeature(.avx)) .{ .v_sd, .add } else .{ ._sd, .add }, .sub => if (self.hasFeature(.avx)) .{ .v_sd, .sub } else .{ ._sd, .sub }, @@ -7236,14 +7234,14 @@ fn genBinOp( 16, 80, 128 => null, else => unreachable, }, - .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) { - .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { - 32 => switch (lhs_ty.vectorLen()) { + .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { + 32 => switch (lhs_ty.vectorLen(mod)) { 1 => .{ .v_ss, .cmp }, 2...8 => .{ .v_ps, .cmp }, else => null, }, - 64 => switch (lhs_ty.vectorLen()) { + 64 => switch (lhs_ty.vectorLen(mod)) { 1 => .{ .v_sd, .cmp }, 2...4 => .{ .v_pd, .cmp }, else => null, @@ -7270,13 +7268,13 @@ fn genBinOp( 16, 80, 128 => null, else => unreachable, }, - .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) { - .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { - 32 => switch (lhs_ty.vectorLen()) { + .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { + 32 => switch (lhs_ty.vectorLen(mod)) { 1...8 => .{ .v_ps, .blendv }, else => null, }, - 64 => switch (lhs_ty.vectorLen()) { + 64 => switch (lhs_ty.vectorLen(mod)) { 1...4 => .{ .v_pd, .blendv }, else => null, }, @@ -7304,14 +7302,14 @@ fn genBinOp( 16, 80, 128 => null, else => unreachable, }, - .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) { - .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { - 32 => switch (lhs_ty.vectorLen()) { + .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { + 32 => switch (lhs_ty.vectorLen(mod)) { 1 => .{ ._ss, .cmp }, 2...4 => .{ ._ps, .cmp }, else => null, }, - 64 => switch (lhs_ty.vectorLen()) { + 64 => switch (lhs_ty.vectorLen(mod)) { 1 => .{ ._sd, .cmp }, 2 => .{ ._pd, .cmp }, else => null, @@ -7337,13 +7335,13 @@ fn genBinOp( 16, 80, 128 => null, else => unreachable, }, - .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) { - .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { - 32 => switch (lhs_ty.vectorLen()) { + .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { + 32 => switch (lhs_ty.vectorLen(mod)) { 1...4 => .{ ._ps, .blendv }, else => null, }, - 64 => switch (lhs_ty.vectorLen()) { + 64 => switch (lhs_ty.vectorLen(mod)) { 1...2 => .{ ._pd, .blendv }, else => null, }, @@ -7368,13 +7366,13 @@ fn genBinOp( 16, 80, 128 => null, else => unreachable, }, - .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) { - .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { - 32 => switch (lhs_ty.vectorLen()) { + .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { + 32 => switch (lhs_ty.vectorLen(mod)) { 1...4 => .{ ._ps, .@"and" }, else => null, }, - 64 => switch (lhs_ty.vectorLen()) { + 64 => switch (lhs_ty.vectorLen(mod)) { 1...2 => .{ ._pd, .@"and" }, else => null, }, @@ -7398,13 +7396,13 @@ fn genBinOp( 16, 80, 128 => null, else => unreachable, }, - .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) { - .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { - 32 => switch (lhs_ty.vectorLen()) { + .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { + 32 => switch (lhs_ty.vectorLen(mod)) { 1...4 => .{ ._ps, .andn }, else => null, }, - 64 => switch (lhs_ty.vectorLen()) { + 64 => switch (lhs_ty.vectorLen(mod)) { 1...2 => .{ ._pd, .andn }, else => null, }, @@ -7428,13 +7426,13 @@ fn genBinOp( 16, 80, 128 => null, else => unreachable, }, - .Vector => switch (lhs_ty.childType().zigTypeTag(mod)) { - .Float => switch (lhs_ty.childType().floatBits(self.target.*)) { - 32 => switch (lhs_ty.vectorLen()) { + .Vector => switch (lhs_ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (lhs_ty.childType(mod).floatBits(self.target.*)) { + 32 => switch (lhs_ty.vectorLen(mod)) { 1...4 => .{ ._ps, .@"or" }, else => null, }, - 64 => switch (lhs_ty.vectorLen()) { + 64 => switch (lhs_ty.vectorLen(mod)) { 1...2 => .{ ._pd, .@"or" }, else => null, }, @@ -7586,11 +7584,7 @@ fn genBinOpMir( .load_got, .load_tlv, => { - var ptr_pl = Type.Payload.ElemType{ - .base = .{ .tag = .single_const_pointer }, - .data = ty, - }; - const ptr_ty = Type.initPayload(&ptr_pl.base); + const ptr_ty = try mod.singleConstPtrType(ty); const addr_reg = try self.copyToTmpRegister(ptr_ty, src_mcv.address()); return self.genBinOpMir(mir_tag, ty, dst_mcv, .{ .indirect = .{ .reg = addr_reg }, @@ -8058,7 +8052,7 @@ fn airCall(self: *Self, inst: Air.Inst.Index, modifier: std.builtin.CallModifier const fn_ty = switch (ty.zigTypeTag(mod)) { .Fn => ty, - .Pointer => ty.childType(), + .Pointer => ty.childType(mod), else => unreachable, }; @@ -8506,10 +8500,11 @@ fn airTry(self: *Self, inst: Air.Inst.Index) !void { } fn airTryPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.TryPtr, ty_pl.payload); const body = self.air.extra[extra.end..][0..extra.data.body_len]; - const err_union_ty = self.typeOf(extra.data.ptr).childType(); + const err_union_ty = self.typeOf(extra.data.ptr).childType(mod); const result = try self.genTry(inst, extra.data.ptr, body, err_union_ty, true); return self.finishAir(inst, result, .{ .none, .none, .none }); } @@ -8683,8 +8678,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC try self.spillEflagsIfOccupied(); self.eflags_inst = inst; - var pl_buf: Type.Payload.ElemType = undefined; - const pl_ty = opt_ty.optionalChild(&pl_buf); + const pl_ty = opt_ty.optionalChild(mod); var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) @@ -8775,9 +8769,8 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue) try self.spillEflagsIfOccupied(); self.eflags_inst = inst; - const opt_ty = ptr_ty.childType(); - var pl_buf: Type.Payload.ElemType = undefined; - const pl_ty = opt_ty.optionalChild(&pl_buf); + const opt_ty = ptr_ty.childType(mod); + const pl_ty = opt_ty.optionalChild(mod); var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod)) @@ -8919,6 +8912,7 @@ fn airIsErr(self: *Self, inst: Air.Inst.Index) !void { } fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const un_op = self.air.instructions.items(.data)[inst].un_op; const operand_ptr = try self.resolveInst(un_op); @@ -8939,7 +8933,7 @@ fn airIsErrPtr(self: *Self, inst: Air.Inst.Index) !void { const ptr_ty = self.typeOf(un_op); try self.load(operand, ptr_ty, operand_ptr); - const result = try self.isErr(inst, ptr_ty.childType(), operand); + const result = try self.isErr(inst, ptr_ty.childType(mod), operand); return self.finishAir(inst, result, .{ un_op, .none, .none }); } @@ -8953,6 +8947,7 @@ fn airIsNonErr(self: *Self, inst: Air.Inst.Index) !void { } fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const un_op = self.air.instructions.items(.data)[inst].un_op; const operand_ptr = try self.resolveInst(un_op); @@ -8973,7 +8968,7 @@ fn airIsNonErrPtr(self: *Self, inst: Air.Inst.Index) !void { const ptr_ty = self.typeOf(un_op); try self.load(operand, ptr_ty, operand_ptr); - const result = try self.isNonErr(inst, ptr_ty.childType(), operand); + const result = try self.isNonErr(inst, ptr_ty.childType(mod), operand); return self.finishAir(inst, result, .{ un_op, .none, .none }); } @@ -9452,9 +9447,9 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, else => {}, }, - .Vector => switch (ty.childType().zigTypeTag(mod)) { - .Int => switch (ty.childType().intInfo(mod).bits) { - 8 => switch (ty.vectorLen()) { + .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { + .Int => switch (ty.childType(mod).intInfo(mod).bits) { + 8 => switch (ty.vectorLen(mod)) { 1 => if (self.hasFeature(.avx)) return .{ .vex_insert_extract = .{ .insert = .{ .vp_b, .insr }, .extract = .{ .vp_b, .extr }, @@ -9484,7 +9479,7 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, else => {}, }, - 16 => switch (ty.vectorLen()) { + 16 => switch (ty.vectorLen(mod)) { 1 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{ .insert = .{ .vp_w, .insr }, .extract = .{ .vp_w, .extr }, @@ -9507,7 +9502,7 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, else => {}, }, - 32 => switch (ty.vectorLen()) { + 32 => switch (ty.vectorLen(mod)) { 1 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_d, .mov } else @@ -9523,7 +9518,7 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, else => {}, }, - 64 => switch (ty.vectorLen()) { + 64 => switch (ty.vectorLen(mod)) { 1 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_q, .mov } else @@ -9535,7 +9530,7 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, else => {}, }, - 128 => switch (ty.vectorLen()) { + 128 => switch (ty.vectorLen(mod)) { 1 => return .{ .move = if (self.hasFeature(.avx)) if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, @@ -9543,15 +9538,15 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, else => {}, }, - 256 => switch (ty.vectorLen()) { + 256 => switch (ty.vectorLen(mod)) { 1 => if (self.hasFeature(.avx)) return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, else => {}, }, else => {}, }, - .Float => switch (ty.childType().floatBits(self.target.*)) { - 16 => switch (ty.vectorLen()) { + .Float => switch (ty.childType(mod).floatBits(self.target.*)) { + 16 => switch (ty.vectorLen(mod)) { 1 => return if (self.hasFeature(.avx)) .{ .vex_insert_extract = .{ .insert = .{ .vp_w, .insr }, .extract = .{ .vp_w, .extr }, @@ -9574,7 +9569,7 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { return .{ .move = if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } }, else => {}, }, - 32 => switch (ty.vectorLen()) { + 32 => switch (ty.vectorLen(mod)) { 1 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_ss, .mov } else @@ -9590,7 +9585,7 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { return .{ .move = if (aligned) .{ .v_ps, .mova } else .{ .v_ps, .movu } }, else => {}, }, - 64 => switch (ty.vectorLen()) { + 64 => switch (ty.vectorLen(mod)) { 1 => return .{ .move = if (self.hasFeature(.avx)) .{ .v_sd, .mov } else @@ -9602,7 +9597,7 @@ fn moveStrategy(self: *Self, ty: Type, aligned: bool) !MoveStrategy { return .{ .move = if (aligned) .{ .v_pd, .mova } else .{ .v_pd, .movu } }, else => {}, }, - 128 => switch (ty.vectorLen()) { + 128 => switch (ty.vectorLen(mod)) { 1 => return .{ .move = if (self.hasFeature(.avx)) if (aligned) .{ .v_, .movdqa } else .{ .v_, .movdqu } else if (aligned) .{ ._, .movdqa } else .{ ._, .movdqu } }, @@ -10248,8 +10243,8 @@ fn airArrayToSlice(self: *Self, inst: Air.Inst.Index) !void { const slice_ty = self.typeOfIndex(inst); const ptr_ty = self.typeOf(ty_op.operand); const ptr = try self.resolveInst(ty_op.operand); - const array_ty = ptr_ty.childType(); - const array_len = array_ty.arrayLen(); + const array_ty = ptr_ty.childType(mod); + const array_len = array_ty.arrayLen(mod); const frame_index = try self.allocFrameIndex(FrameAlloc.initType(slice_ty, mod)); try self.genSetMem(.{ .frame = frame_index }, 0, ptr_ty, ptr); @@ -10790,16 +10785,16 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { const elem_abi_size = @intCast(u31, elem_ty.abiSize(mod)); if (elem_abi_size == 1) { - const ptr: MCValue = switch (dst_ptr_ty.ptrSize()) { + const ptr: MCValue = switch (dst_ptr_ty.ptrSize(mod)) { // TODO: this only handles slices stored in the stack .Slice => dst_ptr, .One => dst_ptr, .C, .Many => unreachable, }; - const len: MCValue = switch (dst_ptr_ty.ptrSize()) { + const len: MCValue = switch (dst_ptr_ty.ptrSize(mod)) { // TODO: this only handles slices stored in the stack .Slice => dst_ptr.address().offset(8).deref(), - .One => .{ .immediate = dst_ptr_ty.childType().arrayLen() }, + .One => .{ .immediate = dst_ptr_ty.childType(mod).arrayLen(mod) }, .C, .Many => unreachable, }; const len_lock: ?RegisterLock = switch (len) { @@ -10815,7 +10810,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { // Store the first element, and then rely on memcpy copying forwards. // Length zero requires a runtime check - so we handle arrays specially // here to elide it. - switch (dst_ptr_ty.ptrSize()) { + switch (dst_ptr_ty.ptrSize(mod)) { .Slice => { var buf: Type.SlicePtrFieldTypeBuffer = undefined; const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(&buf); @@ -10858,13 +10853,9 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { try self.performReloc(skip_reloc); }, .One => { - var elem_ptr_pl = Type.Payload.ElemType{ - .base = .{ .tag = .single_mut_pointer }, - .data = elem_ty, - }; - const elem_ptr_ty = Type.initPayload(&elem_ptr_pl.base); + const elem_ptr_ty = try mod.singleMutPtrType(elem_ty); - const len = dst_ptr_ty.childType().arrayLen(); + const len = dst_ptr_ty.childType(mod).arrayLen(mod); assert(len != 0); // prevented by Sema try self.store(elem_ptr_ty, dst_ptr, src_val); @@ -10889,6 +10880,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void { } fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { + const mod = self.bin_file.options.module.?; const bin_op = self.air.instructions.items(.data)[inst].bin_op; const dst_ptr = try self.resolveInst(bin_op.lhs); @@ -10906,9 +10898,9 @@ fn airMemcpy(self: *Self, inst: Air.Inst.Index) !void { }; defer if (src_ptr_lock) |lock| self.register_manager.unlockReg(lock); - const len: MCValue = switch (dst_ptr_ty.ptrSize()) { + const len: MCValue = switch (dst_ptr_ty.ptrSize(mod)) { .Slice => dst_ptr.address().offset(8).deref(), - .One => .{ .immediate = dst_ptr_ty.childType().arrayLen() }, + .One => .{ .immediate = dst_ptr_ty.childType(mod).arrayLen(mod) }, .C, .Many => unreachable, }; const len_lock: ?RegisterLock = switch (len) { @@ -11059,7 +11051,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { switch (scalar_ty.zigTypeTag(mod)) { else => {}, .Float => switch (scalar_ty.floatBits(self.target.*)) { - 32 => switch (vector_ty.vectorLen()) { + 32 => switch (vector_ty.vectorLen(mod)) { 1 => { if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; const dst_reg = try self.register_manager.allocReg(inst, dst_rc); @@ -11139,7 +11131,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { }, else => {}, }, - 64 => switch (vector_ty.vectorLen()) { + 64 => switch (vector_ty.vectorLen(mod)) { 1 => { if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; const dst_reg = try self.register_manager.allocReg(inst, dst_rc); @@ -11205,7 +11197,7 @@ fn airSplat(self: *Self, inst: Air.Inst.Index) !void { }, else => {}, }, - 128 => switch (vector_ty.vectorLen()) { + 128 => switch (vector_ty.vectorLen(mod)) { 1 => { if (self.reuseOperand(inst, ty_op.operand, 0, src_mcv)) break :result src_mcv; const dst_reg = try self.register_manager.allocReg(inst, dst_rc); @@ -11271,7 +11263,7 @@ fn airReduce(self: *Self, inst: Air.Inst.Index) !void { fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { const mod = self.bin_file.options.module.?; const result_ty = self.typeOfIndex(inst); - const len = @intCast(usize, result_ty.arrayLen()); + const len = @intCast(usize, result_ty.arrayLen(mod)); const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]); const result: MCValue = result: { @@ -11375,7 +11367,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { .Array => { const frame_index = try self.allocFrameIndex(FrameAlloc.initType(result_ty, mod)); - const elem_ty = result_ty.childType(); + const elem_ty = result_ty.childType(mod); const elem_size = @intCast(u32, elem_ty.abiSize(mod)); for (elements, 0..) |elem, elem_i| { @@ -11387,7 +11379,7 @@ fn airAggregateInit(self: *Self, inst: Air.Inst.Index) !void { const elem_off = @intCast(i32, elem_size * elem_i); try self.genSetMem(.{ .frame = frame_index }, elem_off, elem_ty, mat_elem_mcv); } - if (result_ty.sentinel()) |sentinel| try self.genSetMem( + if (result_ty.sentinel(mod)) |sentinel| try self.genSetMem( .{ .frame = frame_index }, @intCast(i32, elem_size * elements.len), elem_ty, @@ -11512,14 +11504,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { 16, 80, 128 => null, else => unreachable, }, - .Vector => switch (ty.childType().zigTypeTag(mod)) { - .Float => switch (ty.childType().floatBits(self.target.*)) { - 32 => switch (ty.vectorLen()) { + .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (ty.childType(mod).floatBits(self.target.*)) { + 32 => switch (ty.vectorLen(mod)) { 1 => .{ .v_ss, .fmadd132 }, 2...8 => .{ .v_ps, .fmadd132 }, else => null, }, - 64 => switch (ty.vectorLen()) { + 64 => switch (ty.vectorLen(mod)) { 1 => .{ .v_sd, .fmadd132 }, 2...4 => .{ .v_pd, .fmadd132 }, else => null, @@ -11539,14 +11531,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { 16, 80, 128 => null, else => unreachable, }, - .Vector => switch (ty.childType().zigTypeTag(mod)) { - .Float => switch (ty.childType().floatBits(self.target.*)) { - 32 => switch (ty.vectorLen()) { + .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (ty.childType(mod).floatBits(self.target.*)) { + 32 => switch (ty.vectorLen(mod)) { 1 => .{ .v_ss, .fmadd213 }, 2...8 => .{ .v_ps, .fmadd213 }, else => null, }, - 64 => switch (ty.vectorLen()) { + 64 => switch (ty.vectorLen(mod)) { 1 => .{ .v_sd, .fmadd213 }, 2...4 => .{ .v_pd, .fmadd213 }, else => null, @@ -11566,14 +11558,14 @@ fn airMulAdd(self: *Self, inst: Air.Inst.Index) !void { 16, 80, 128 => null, else => unreachable, }, - .Vector => switch (ty.childType().zigTypeTag(mod)) { - .Float => switch (ty.childType().floatBits(self.target.*)) { - 32 => switch (ty.vectorLen()) { + .Vector => switch (ty.childType(mod).zigTypeTag(mod)) { + .Float => switch (ty.childType(mod).floatBits(self.target.*)) { + 32 => switch (ty.vectorLen(mod)) { 1 => .{ .v_ss, .fmadd231 }, 2...8 => .{ .v_ps, .fmadd231 }, else => null, }, - 64 => switch (ty.vectorLen()) { + 64 => switch (ty.vectorLen(mod)) { 1 => .{ .v_sd, .fmadd231 }, 2...4 => .{ .v_pd, .fmadd231 }, else => null, diff --git a/src/arch/x86_64/abi.zig b/src/arch/x86_64/abi.zig index c8d20c73fa..ea75a1f4d2 100644 --- a/src/arch/x86_64/abi.zig +++ b/src/arch/x86_64/abi.zig @@ -76,7 +76,7 @@ pub fn classifySystemV(ty: Type, mod: *const Module, ctx: Context) [8]Class { }; var result = [1]Class{.none} ** 8; switch (ty.zigTypeTag(mod)) { - .Pointer => switch (ty.ptrSize()) { + .Pointer => switch (ty.ptrSize(mod)) { .Slice => { result[0] = .integer; result[1] = .integer; @@ -158,8 +158,8 @@ pub fn classifySystemV(ty: Type, mod: *const Module, ctx: Context) [8]Class { else => unreachable, }, .Vector => { - const elem_ty = ty.childType(); - const bits = elem_ty.bitSize(mod) * ty.arrayLen(); + const elem_ty = ty.childType(mod); + const bits = elem_ty.bitSize(mod) * ty.arrayLen(mod); if (bits <= 64) return .{ .sse, .none, .none, .none, .none, .none, .none, .none, diff --git a/src/codegen.zig b/src/codegen.zig index c9e2c6c265..a807400502 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -230,7 +230,7 @@ pub fn generateSymbol( .Array => switch (typed_value.val.tag()) { .bytes => { const bytes = typed_value.val.castTag(.bytes).?.data; - const len = @intCast(usize, typed_value.ty.arrayLenIncludingSentinel()); + const len = @intCast(usize, typed_value.ty.arrayLenIncludingSentinel(mod)); // The bytes payload already includes the sentinel, if any try code.ensureUnusedCapacity(len); code.appendSliceAssumeCapacity(bytes[0..len]); @@ -241,7 +241,7 @@ pub fn generateSymbol( const bytes = mod.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; try code.ensureUnusedCapacity(bytes.len + 1); code.appendSliceAssumeCapacity(bytes); - if (typed_value.ty.sentinel()) |sent_val| { + if (typed_value.ty.sentinel(mod)) |sent_val| { const byte = @intCast(u8, sent_val.toUnsignedInt(mod)); code.appendAssumeCapacity(byte); } @@ -249,8 +249,8 @@ pub fn generateSymbol( }, .aggregate => { const elem_vals = typed_value.val.castTag(.aggregate).?.data; - const elem_ty = typed_value.ty.elemType(); - const len = @intCast(usize, typed_value.ty.arrayLenIncludingSentinel()); + const elem_ty = typed_value.ty.childType(mod); + const len = @intCast(usize, typed_value.ty.arrayLenIncludingSentinel(mod)); for (elem_vals[0..len]) |elem_val| { switch (try generateSymbol(bin_file, src_loc, .{ .ty = elem_ty, @@ -264,9 +264,9 @@ pub fn generateSymbol( }, .repeated => { const array = typed_value.val.castTag(.repeated).?.data; - const elem_ty = typed_value.ty.childType(); - const sentinel = typed_value.ty.sentinel(); - const len = typed_value.ty.arrayLen(); + const elem_ty = typed_value.ty.childType(mod); + const sentinel = typed_value.ty.sentinel(mod); + const len = typed_value.ty.arrayLen(mod); var index: u64 = 0; while (index < len) : (index += 1) { @@ -292,8 +292,8 @@ pub fn generateSymbol( return Result.ok; }, .empty_array_sentinel => { - const elem_ty = typed_value.ty.childType(); - const sentinel_val = typed_value.ty.sentinel().?; + const elem_ty = typed_value.ty.childType(mod); + const sentinel_val = typed_value.ty.sentinel(mod).?; switch (try generateSymbol(bin_file, src_loc, .{ .ty = elem_ty, .val = sentinel_val, @@ -618,8 +618,7 @@ pub fn generateSymbol( return Result.ok; }, .Optional => { - var opt_buf: Type.Payload.ElemType = undefined; - const payload_type = typed_value.ty.optionalChild(&opt_buf); + const payload_type = typed_value.ty.optionalChild(mod); const is_pl = !typed_value.val.isNull(mod); const abi_size = math.cast(usize, typed_value.ty.abiSize(mod)) orelse return error.Overflow; @@ -751,7 +750,7 @@ pub fn generateSymbol( .Vector => switch (typed_value.val.tag()) { .bytes => { const bytes = typed_value.val.castTag(.bytes).?.data; - const len = math.cast(usize, typed_value.ty.arrayLen()) orelse return error.Overflow; + const len = math.cast(usize, typed_value.ty.arrayLen(mod)) orelse return error.Overflow; const padding = math.cast(usize, typed_value.ty.abiSize(mod) - len) orelse return error.Overflow; try code.ensureUnusedCapacity(len + padding); @@ -761,8 +760,8 @@ pub fn generateSymbol( }, .aggregate => { const elem_vals = typed_value.val.castTag(.aggregate).?.data; - const elem_ty = typed_value.ty.elemType(); - const len = math.cast(usize, typed_value.ty.arrayLen()) orelse return error.Overflow; + const elem_ty = typed_value.ty.childType(mod); + const len = math.cast(usize, typed_value.ty.arrayLen(mod)) orelse return error.Overflow; const padding = math.cast(usize, typed_value.ty.abiSize(mod) - (math.divCeil(u64, elem_ty.bitSize(mod) * len, 8) catch |err| switch (err) { error.DivisionByZero => unreachable, @@ -782,8 +781,8 @@ pub fn generateSymbol( }, .repeated => { const array = typed_value.val.castTag(.repeated).?.data; - const elem_ty = typed_value.ty.childType(); - const len = typed_value.ty.arrayLen(); + const elem_ty = typed_value.ty.childType(mod); + const len = typed_value.ty.arrayLen(mod); const padding = math.cast(usize, typed_value.ty.abiSize(mod) - (math.divCeil(u64, elem_ty.bitSize(mod) * len, 8) catch |err| switch (err) { error.DivisionByZero => unreachable, @@ -1188,7 +1187,7 @@ pub fn genTypedValue( switch (typed_value.ty.zigTypeTag(mod)) { .Void => return GenResult.mcv(.none), - .Pointer => switch (typed_value.ty.ptrSize()) { + .Pointer => switch (typed_value.ty.ptrSize(mod)) { .Slice => {}, else => { switch (typed_value.val.tag()) { @@ -1219,9 +1218,8 @@ pub fn genTypedValue( if (typed_value.ty.isPtrLikeOptional(mod)) { if (typed_value.val.tag() == .null_value) return GenResult.mcv(.{ .immediate = 0 }); - var buf: Type.Payload.ElemType = undefined; return genTypedValue(bin_file, src_loc, .{ - .ty = typed_value.ty.optionalChild(&buf), + .ty = typed_value.ty.optionalChild(mod), .val = if (typed_value.val.castTag(.opt_payload)) |pl| pl.data else typed_value.val, }, owner_decl_index); } else if (typed_value.ty.abiSize(mod) == 1) { diff --git a/src/codegen/c.zig b/src/codegen/c.zig index cd4f36e574..e6ec461e43 100644 --- a/src/codegen/c.zig +++ b/src/codegen/c.zig @@ -625,7 +625,9 @@ pub const DeclGen = struct { // Ensure complete type definition is visible before accessing fields. _ = try dg.typeToIndex(field_ptr.container_ty, .complete); - var container_ptr_pl = ptr_ty.ptrInfo(); + var container_ptr_pl: Type.Payload.Pointer = .{ + .data = ptr_ty.ptrInfo(mod), + }; container_ptr_pl.data.pointee_type = field_ptr.container_ty; const container_ptr_ty = Type.initPayload(&container_ptr_pl.base); @@ -653,7 +655,9 @@ pub const DeclGen = struct { try dg.writeCValue(writer, field); }, .byte_offset => |byte_offset| { - var u8_ptr_pl = ptr_ty.ptrInfo(); + var u8_ptr_pl: Type.Payload.Pointer = .{ + .data = ptr_ty.ptrInfo(mod), + }; u8_ptr_pl.data.pointee_type = Type.u8; const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); @@ -692,11 +696,10 @@ pub const DeclGen = struct { }, .elem_ptr => { const elem_ptr = ptr_val.castTag(.elem_ptr).?.data; - var elem_ptr_ty_pl: Type.Payload.ElemType = .{ - .base = .{ .tag = .c_mut_pointer }, - .data = elem_ptr.elem_ty, - }; - const elem_ptr_ty = Type.initPayload(&elem_ptr_ty_pl.base); + const elem_ptr_ty = try mod.ptrType(.{ + .size = .C, + .elem_type = elem_ptr.elem_ty.ip_index, + }); try writer.writeAll("&("); try dg.renderParentPtr(writer, elem_ptr.array_ptr, elem_ptr_ty, location); @@ -704,11 +707,10 @@ pub const DeclGen = struct { }, .opt_payload_ptr, .eu_payload_ptr => { const payload_ptr = ptr_val.cast(Value.Payload.PayloadPtr).?.data; - var container_ptr_ty_pl: Type.Payload.ElemType = .{ - .base = .{ .tag = .c_mut_pointer }, - .data = payload_ptr.container_ty, - }; - const container_ptr_ty = Type.initPayload(&container_ptr_ty_pl.base); + const container_ptr_ty = try mod.ptrType(.{ + .elem_type = payload_ptr.container_ty.ip_index, + .size = .C, + }); // Ensure complete type definition is visible before accessing fields. _ = try dg.typeToIndex(payload_ptr.container_ty, .complete); @@ -794,8 +796,7 @@ pub const DeclGen = struct { return writer.print("){x})", .{try dg.fmtIntLiteral(Type.usize, val, .Other)}); }, .Optional => { - var opt_buf: Type.Payload.ElemType = undefined; - const payload_ty = ty.optionalChild(&opt_buf); + const payload_ty = ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { return dg.renderValue(writer, Type.bool, val, location); @@ -889,11 +890,11 @@ pub const DeclGen = struct { return writer.writeAll(" }"); }, .Array, .Vector => { - const ai = ty.arrayInfo(); + const ai = ty.arrayInfo(mod); if (ai.elem_type.eql(Type.u8, dg.module)) { var literal = stringLiteral(writer); try literal.start(); - const c_len = ty.arrayLenIncludingSentinel(); + const c_len = ty.arrayLenIncludingSentinel(mod); var index: u64 = 0; while (index < c_len) : (index += 1) try literal.writeChar(0xaa); @@ -906,11 +907,11 @@ pub const DeclGen = struct { } try writer.writeByte('{'); - const c_len = ty.arrayLenIncludingSentinel(); + const c_len = ty.arrayLenIncludingSentinel(mod); var index: u64 = 0; while (index < c_len) : (index += 1) { if (index > 0) try writer.writeAll(", "); - try dg.renderValue(writer, ty.childType(), val, initializer_type); + try dg.renderValue(writer, ty.childType(mod), val, initializer_type); } return writer.writeByte('}'); } @@ -1110,7 +1111,7 @@ pub const DeclGen = struct { // First try specific tag representations for more efficiency. switch (val.tag()) { .undef, .empty_struct_value, .empty_array => { - const ai = ty.arrayInfo(); + const ai = ty.arrayInfo(mod); try writer.writeByte('{'); if (ai.sentinel) |s| { try dg.renderValue(writer, ai.elem_type, s, initializer_type); @@ -1128,9 +1129,9 @@ pub const DeclGen = struct { }, else => unreachable, }; - const sentinel = if (ty.sentinel()) |sentinel| @intCast(u8, sentinel.toUnsignedInt(mod)) else null; + const sentinel = if (ty.sentinel(mod)) |sentinel| @intCast(u8, sentinel.toUnsignedInt(mod)) else null; try writer.print("{s}", .{ - fmtStringLiteral(bytes[0..@intCast(usize, ty.arrayLen())], sentinel), + fmtStringLiteral(bytes[0..@intCast(usize, ty.arrayLen(mod))], sentinel), }); }, else => { @@ -1142,7 +1143,7 @@ pub const DeclGen = struct { // MSVC throws C2078 if an array of size 65536 or greater is initialized with a string literal const max_string_initializer_len = 65535; - const ai = ty.arrayInfo(); + const ai = ty.arrayInfo(mod); if (ai.elem_type.eql(Type.u8, dg.module)) { if (ai.len <= max_string_initializer_len) { var literal = stringLiteral(writer); @@ -1198,8 +1199,7 @@ pub const DeclGen = struct { } }, .Optional => { - var opt_buf: Type.Payload.ElemType = undefined; - const payload_ty = ty.optionalChild(&opt_buf); + const payload_ty = ty.optionalChild(mod); const is_null_val = Value.makeBool(val.tag() == .null_value); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) @@ -2410,12 +2410,13 @@ pub fn genGlobalAsm(mod: *Module, writer: anytype) !void { } pub fn genErrDecls(o: *Object) !void { + const mod = o.dg.module; const writer = o.writer(); try writer.writeAll("enum {\n"); o.indent_writer.pushIndent(); var max_name_len: usize = 0; - for (o.dg.module.error_name_list.items, 0..) |name, value| { + for (mod.error_name_list.items, 0..) |name, value| { max_name_len = std.math.max(name.len, max_name_len); var err_pl = Value.Payload.Error{ .data = .{ .name = name } }; try o.dg.renderValue(writer, Type.anyerror, Value.initPayload(&err_pl.base), .Other); @@ -2430,12 +2431,15 @@ pub fn genErrDecls(o: *Object) !void { defer o.dg.gpa.free(name_buf); @memcpy(name_buf[0..name_prefix.len], name_prefix); - for (o.dg.module.error_name_list.items) |name| { + for (mod.error_name_list.items) |name| { @memcpy(name_buf[name_prefix.len..][0..name.len], name); const identifier = name_buf[0 .. name_prefix.len + name.len]; - var name_ty_pl = Type.Payload.Len{ .base = .{ .tag = .array_u8_sentinel_0 }, .data = name.len }; - const name_ty = Type.initPayload(&name_ty_pl.base); + const name_ty = try mod.arrayType(.{ + .len = name.len, + .child = .u8_type, + .sentinel = .zero_u8, + }); var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name }; const name_val = Value.initPayload(&name_pl.base); @@ -2448,15 +2452,15 @@ pub fn genErrDecls(o: *Object) !void { } var name_array_ty_pl = Type.Payload.Array{ .base = .{ .tag = .array }, .data = .{ - .len = o.dg.module.error_name_list.items.len, - .elem_type = Type.initTag(.const_slice_u8_sentinel_0), + .len = mod.error_name_list.items.len, + .elem_type = Type.const_slice_u8_sentinel_0, } }; const name_array_ty = Type.initPayload(&name_array_ty_pl.base); try writer.writeAll("static "); try o.dg.renderTypeAndName(writer, name_array_ty, .{ .identifier = array_identifier }, Const, 0, .complete); try writer.writeAll(" = {"); - for (o.dg.module.error_name_list.items, 0..) |name, value| { + for (mod.error_name_list.items, 0..) |name, value| { if (value != 0) try writer.writeByte(','); var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = name.len }; @@ -2487,6 +2491,7 @@ fn genExports(o: *Object) !void { } pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { + const mod = o.dg.module; const w = o.writer(); const key = lazy_fn.key_ptr.*; const val = lazy_fn.value_ptr; @@ -2495,7 +2500,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { .tag_name => { const enum_ty = val.data.tag_name; - const name_slice_ty = Type.initTag(.const_slice_u8_sentinel_0); + const name_slice_ty = Type.const_slice_u8_sentinel_0; try w.writeAll("static "); try o.dg.renderType(w, name_slice_ty); @@ -2514,11 +2519,11 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { var int_pl: Value.Payload.U64 = undefined; const int_val = tag_val.enumToInt(enum_ty, &int_pl); - var name_ty_pl = Type.Payload.Len{ - .base = .{ .tag = .array_u8_sentinel_0 }, - .data = name.len, - }; - const name_ty = Type.initPayload(&name_ty_pl.base); + const name_ty = try mod.arrayType(.{ + .len = name.len, + .child = .u8_type, + .sentinel = .zero_u8, + }); var name_pl = Value.Payload.Bytes{ .base = .{ .tag = .bytes }, .data = name }; const name_val = Value.initPayload(&name_pl.base); @@ -2547,7 +2552,7 @@ pub fn genLazyFn(o: *Object, lazy_fn: LazyFnMap.Entry) !void { try w.writeAll("}\n"); }, .never_tail, .never_inline => |fn_decl_index| { - const fn_decl = o.dg.module.declPtr(fn_decl_index); + const fn_decl = mod.declPtr(fn_decl_index); const fn_cty = try o.dg.typeToCType(fn_decl.ty, .complete); const fn_info = fn_cty.cast(CType.Payload.Function).?.data; @@ -3150,7 +3155,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { const inst_ty = f.typeOfIndex(inst); const ptr_ty = f.typeOf(bin_op.lhs); - const elem_ty = ptr_ty.childType(); + const elem_ty = ptr_ty.childType(mod); const elem_has_bits = elem_ty.hasRuntimeBitsIgnoreComptime(mod); const ptr = try f.resolveInst(bin_op.lhs); @@ -3166,7 +3171,7 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { try f.renderType(writer, inst_ty); try writer.writeByte(')'); if (elem_has_bits) try writer.writeByte('&'); - if (elem_has_bits and ptr_ty.ptrSize() == .One) { + if (elem_has_bits and ptr_ty.ptrSize(mod) == .One) { // It's a pointer to an array, so we need to de-reference. try f.writeCValueDeref(writer, ptr); } else try f.writeCValue(writer, ptr, .Other); @@ -3264,7 +3269,7 @@ fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { const mod = f.object.dg.module; const inst_ty = f.typeOfIndex(inst); - const elem_type = inst_ty.elemType(); + const elem_type = inst_ty.childType(mod); if (!elem_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty }; const local = try f.allocLocalValue( @@ -3280,7 +3285,7 @@ fn airAlloc(f: *Function, inst: Air.Inst.Index) !CValue { fn airRetPtr(f: *Function, inst: Air.Inst.Index) !CValue { const mod = f.object.dg.module; const inst_ty = f.typeOfIndex(inst); - const elem_ty = inst_ty.elemType(); + const elem_ty = inst_ty.childType(mod); if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return .{ .undef = inst_ty }; const local = try f.allocLocalValue( @@ -3323,7 +3328,7 @@ fn airLoad(f: *Function, inst: Air.Inst.Index) !CValue { const ptr_ty = f.typeOf(ty_op.operand); const ptr_scalar_ty = ptr_ty.scalarType(mod); - const ptr_info = ptr_scalar_ty.ptrInfo().data; + const ptr_info = ptr_scalar_ty.ptrInfo(mod); const src_ty = ptr_info.pointee_type; if (!src_ty.hasRuntimeBitsIgnoreComptime(mod)) { @@ -3412,7 +3417,7 @@ fn airRet(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValue { const writer = f.object.writer(); const op_inst = Air.refToIndex(un_op); const op_ty = f.typeOf(un_op); - const ret_ty = if (is_ptr) op_ty.childType() else op_ty; + const ret_ty = if (is_ptr) op_ty.childType(mod) else op_ty; var lowered_ret_buf: LowerFnRetTyBuffer = undefined; const lowered_ret_ty = lowerFnRetTy(ret_ty, &lowered_ret_buf, mod); @@ -3601,7 +3606,7 @@ fn airStore(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { const ptr_ty = f.typeOf(bin_op.lhs); const ptr_scalar_ty = ptr_ty.scalarType(mod); - const ptr_info = ptr_scalar_ty.ptrInfo().data; + const ptr_info = ptr_scalar_ty.ptrInfo(mod); const ptr_val = try f.resolveInst(bin_op.lhs); const src_ty = f.typeOf(bin_op.rhs); @@ -4156,7 +4161,7 @@ fn airCall( const callee_ty = f.typeOf(pl_op.operand); const fn_ty = switch (callee_ty.zigTypeTag(mod)) { .Fn => callee_ty, - .Pointer => callee_ty.childType(), + .Pointer => callee_ty.childType(mod), else => unreachable, }; @@ -4331,10 +4336,11 @@ fn airTry(f: *Function, inst: Air.Inst.Index) !CValue { } fn airTryPtr(f: *Function, inst: Air.Inst.Index) !CValue { + const mod = f.object.dg.module; const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; const extra = f.air.extraData(Air.TryPtr, ty_pl.payload); const body = f.air.extra[extra.end..][0..extra.data.body_len]; - const err_union_ty = f.typeOf(extra.data.ptr).childType(); + const err_union_ty = f.typeOf(extra.data.ptr).childType(mod); return lowerTry(f, inst, extra.data.ptr, body, err_union_ty, true); } @@ -4826,7 +4832,7 @@ fn airAsm(f: *Function, inst: Air.Inst.Index) !CValue { const is_reg = constraint[1] == '{'; if (is_reg) { - const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType(); + const output_ty = if (output == .none) inst_ty else f.typeOf(output).childType(mod); try writer.writeAll("register "); const alignment = 0; const local_value = try f.allocLocalValue(output_ty, alignment); @@ -5061,9 +5067,8 @@ fn airIsNull( } const operand_ty = f.typeOf(un_op); - const optional_ty = if (is_ptr) operand_ty.childType() else operand_ty; - var payload_buf: Type.Payload.ElemType = undefined; - const payload_ty = optional_ty.optionalChild(&payload_buf); + const optional_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty; + const payload_ty = optional_ty.optionalChild(mod); var slice_ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; const rhs = if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) @@ -5097,8 +5102,7 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { try reap(f, inst, &.{ty_op.operand}); const opt_ty = f.typeOf(ty_op.operand); - var buf: Type.Payload.ElemType = undefined; - const payload_ty = opt_ty.optionalChild(&buf); + const payload_ty = opt_ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { return .none; @@ -5132,10 +5136,10 @@ fn airOptionalPayloadPtr(f: *Function, inst: Air.Inst.Index) !CValue { const operand = try f.resolveInst(ty_op.operand); try reap(f, inst, &.{ty_op.operand}); const ptr_ty = f.typeOf(ty_op.operand); - const opt_ty = ptr_ty.childType(); + const opt_ty = ptr_ty.childType(mod); const inst_ty = f.typeOfIndex(inst); - if (!inst_ty.childType().hasRuntimeBitsIgnoreComptime(mod)) { + if (!inst_ty.childType(mod).hasRuntimeBitsIgnoreComptime(mod)) { return .{ .undef = inst_ty }; } @@ -5163,7 +5167,7 @@ fn airOptionalPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { try reap(f, inst, &.{ty_op.operand}); const operand_ty = f.typeOf(ty_op.operand); - const opt_ty = operand_ty.elemType(); + const opt_ty = operand_ty.childType(mod); const inst_ty = f.typeOfIndex(inst); @@ -5221,7 +5225,7 @@ fn fieldLocation( else .{ .identifier = container_ty.structFieldName(next_field_index) } }; } else if (container_ty.hasRuntimeBitsIgnoreComptime(mod)) .end else .begin, - .Packed => if (field_ptr_ty.ptrInfo().data.host_size == 0) + .Packed => if (field_ptr_ty.ptrInfo(mod).host_size == 0) .{ .byte_offset = container_ty.packedStructFieldByteOffset(field_index, mod) } else .begin, @@ -5243,7 +5247,7 @@ fn fieldLocation( }, .Packed => .begin, }, - .Pointer => switch (container_ty.ptrSize()) { + .Pointer => switch (container_ty.ptrSize(mod)) { .Slice => switch (field_index) { 0 => .{ .field = .{ .identifier = "ptr" } }, 1 => .{ .field = .{ .identifier = "len" } }, @@ -5280,7 +5284,7 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { const extra = f.air.extraData(Air.FieldParentPtr, ty_pl.payload).data; const container_ptr_ty = f.typeOfIndex(inst); - const container_ty = container_ptr_ty.childType(); + const container_ty = container_ptr_ty.childType(mod); const field_ptr_ty = f.typeOf(extra.field_ptr); const field_ptr_val = try f.resolveInst(extra.field_ptr); @@ -5296,7 +5300,9 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { switch (fieldLocation(container_ty, field_ptr_ty, extra.field_index, mod)) { .begin => try f.writeCValue(writer, field_ptr_val, .Initializer), .field => |field| { - var u8_ptr_pl = field_ptr_ty.ptrInfo(); + var u8_ptr_pl: Type.Payload.Pointer = .{ + .data = field_ptr_ty.ptrInfo(mod), + }; u8_ptr_pl.data.pointee_type = Type.u8; const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); @@ -5311,7 +5317,9 @@ fn airFieldParentPtr(f: *Function, inst: Air.Inst.Index) !CValue { try writer.writeAll("))"); }, .byte_offset => |byte_offset| { - var u8_ptr_pl = field_ptr_ty.ptrInfo(); + var u8_ptr_pl: Type.Payload.Pointer = .{ + .data = field_ptr_ty.ptrInfo(mod), + }; u8_ptr_pl.data.pointee_type = Type.u8; const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); @@ -5345,7 +5353,7 @@ fn fieldPtr( field_index: u32, ) !CValue { const mod = f.object.dg.module; - const container_ty = container_ptr_ty.elemType(); + const container_ty = container_ptr_ty.childType(mod); const field_ptr_ty = f.typeOfIndex(inst); // Ensure complete type definition is visible before accessing fields. @@ -5365,7 +5373,9 @@ fn fieldPtr( try f.writeCValueDerefMember(writer, container_ptr_val, field); }, .byte_offset => |byte_offset| { - var u8_ptr_pl = field_ptr_ty.ptrInfo(); + var u8_ptr_pl: Type.Payload.Pointer = .{ + .data = field_ptr_ty.ptrInfo(mod), + }; u8_ptr_pl.data.pointee_type = Type.u8; const u8_ptr_ty = Type.initPayload(&u8_ptr_pl.base); @@ -5532,7 +5542,7 @@ fn airUnwrapErrUnionErr(f: *Function, inst: Air.Inst.Index) !CValue { try reap(f, inst, &.{ty_op.operand}); const operand_is_ptr = operand_ty.zigTypeTag(mod) == .Pointer; - const error_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; + const error_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; const error_ty = error_union_ty.errorUnionSet(); const payload_ty = error_union_ty.errorUnionPayload(); const local = try f.allocLocal(inst, inst_ty); @@ -5569,7 +5579,7 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu const operand = try f.resolveInst(ty_op.operand); try reap(f, inst, &.{ty_op.operand}); const operand_ty = f.typeOf(ty_op.operand); - const error_union_ty = if (is_ptr) operand_ty.childType() else operand_ty; + const error_union_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty; const writer = f.object.writer(); if (!error_union_ty.errorUnionPayload().hasRuntimeBits(mod)) { @@ -5673,7 +5683,7 @@ fn airErrUnionPayloadPtrSet(f: *Function, inst: Air.Inst.Index) !CValue { const writer = f.object.writer(); const ty_op = f.air.instructions.items(.data)[inst].ty_op; const operand = try f.resolveInst(ty_op.operand); - const error_union_ty = f.typeOf(ty_op.operand).childType(); + const error_union_ty = f.typeOf(ty_op.operand).childType(mod); const error_ty = error_union_ty.errorUnionSet(); const payload_ty = error_union_ty.errorUnionPayload(); @@ -5761,7 +5771,7 @@ fn airIsErr(f: *Function, inst: Air.Inst.Index, is_ptr: bool, operator: []const try reap(f, inst, &.{un_op}); const operand_ty = f.typeOf(un_op); const local = try f.allocLocal(inst, Type.bool); - const err_union_ty = if (is_ptr) operand_ty.childType() else operand_ty; + const err_union_ty = if (is_ptr) operand_ty.childType(mod) else operand_ty; const payload_ty = err_union_ty.errorUnionPayload(); const error_ty = err_union_ty.errorUnionSet(); @@ -5795,7 +5805,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { const inst_ty = f.typeOfIndex(inst); const writer = f.object.writer(); const local = try f.allocLocal(inst, inst_ty); - const array_ty = f.typeOf(ty_op.operand).childType(); + const array_ty = f.typeOf(ty_op.operand).childType(mod); try f.writeCValueMember(writer, local, .{ .identifier = "ptr" }); try writer.writeAll(" = "); @@ -5811,7 +5821,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue { } else try f.writeCValue(writer, operand, .Initializer); try writer.writeAll("; "); - const array_len = array_ty.arrayLen(); + const array_len = array_ty.arrayLen(mod); var len_pl: Value.Payload.U64 = .{ .base = .{ .tag = .int_u64 }, .data = array_len }; const len_val = Value.initPayload(&len_pl.base); try f.writeCValueMember(writer, local, .{ .identifier = "len" }); @@ -6050,7 +6060,7 @@ fn airCmpxchg(f: *Function, inst: Air.Inst.Index, flavor: [*:0]const u8) !CValue const expected_value = try f.resolveInst(extra.expected_value); const new_value = try f.resolveInst(extra.new_value); const ptr_ty = f.typeOf(extra.ptr); - const ty = ptr_ty.childType(); + const ty = ptr_ty.childType(mod); const writer = f.object.writer(); const new_value_mat = try Materialize.start(f, inst, writer, ty, new_value); @@ -6152,7 +6162,7 @@ fn airAtomicRmw(f: *Function, inst: Air.Inst.Index) !CValue { const extra = f.air.extraData(Air.AtomicRmw, pl_op.payload).data; const inst_ty = f.typeOfIndex(inst); const ptr_ty = f.typeOf(pl_op.operand); - const ty = ptr_ty.childType(); + const ty = ptr_ty.childType(mod); const ptr = try f.resolveInst(pl_op.operand); const operand = try f.resolveInst(extra.operand); @@ -6207,7 +6217,7 @@ fn airAtomicLoad(f: *Function, inst: Air.Inst.Index) !CValue { const ptr = try f.resolveInst(atomic_load.ptr); try reap(f, inst, &.{atomic_load.ptr}); const ptr_ty = f.typeOf(atomic_load.ptr); - const ty = ptr_ty.childType(); + const ty = ptr_ty.childType(mod); const repr_ty = if (ty.isRuntimeFloat()) mod.intType(.unsigned, @intCast(u16, ty.abiSize(mod) * 8)) catch unreachable @@ -6241,7 +6251,7 @@ fn airAtomicStore(f: *Function, inst: Air.Inst.Index, order: [*:0]const u8) !CVa const mod = f.object.dg.module; const bin_op = f.air.instructions.items(.data)[inst].bin_op; const ptr_ty = f.typeOf(bin_op.lhs); - const ty = ptr_ty.childType(); + const ty = ptr_ty.childType(mod); const ptr = try f.resolveInst(bin_op.lhs); const element = try f.resolveInst(bin_op.rhs); @@ -6299,7 +6309,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { } try writer.writeAll("memset("); - switch (dest_ty.ptrSize()) { + switch (dest_ty.ptrSize(mod)) { .Slice => { try f.writeCValueMember(writer, dest_slice, .{ .identifier = "ptr" }); try writer.writeAll(", 0xaa, "); @@ -6311,8 +6321,8 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { } }, .One => { - const array_ty = dest_ty.childType(); - const len = array_ty.arrayLen() * elem_abi_size; + const array_ty = dest_ty.childType(mod); + const len = array_ty.arrayLen(mod) * elem_abi_size; try f.writeCValue(writer, dest_slice, .FunctionArgument); try writer.print(", 0xaa, {d});\n", .{len}); @@ -6327,11 +6337,10 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { // For the assignment in this loop, the array pointer needs to get // casted to a regular pointer, otherwise an error like this occurs: // error: array type 'uint32_t[20]' (aka 'unsigned int[20]') is not assignable - var elem_ptr_ty_pl: Type.Payload.ElemType = .{ - .base = .{ .tag = .c_mut_pointer }, - .data = elem_ty, - }; - const elem_ptr_ty = Type.initPayload(&elem_ptr_ty_pl.base); + const elem_ptr_ty = try mod.ptrType(.{ + .size = .C, + .elem_type = elem_ty.ip_index, + }); const index = try f.allocLocal(inst, Type.usize); @@ -6342,13 +6351,13 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { try writer.writeAll("; "); try f.writeCValue(writer, index, .Other); try writer.writeAll(" != "); - switch (dest_ty.ptrSize()) { + switch (dest_ty.ptrSize(mod)) { .Slice => { try f.writeCValueMember(writer, dest_slice, .{ .identifier = "len" }); }, .One => { - const array_ty = dest_ty.childType(); - try writer.print("{d}", .{array_ty.arrayLen()}); + const array_ty = dest_ty.childType(mod); + try writer.print("{d}", .{array_ty.arrayLen(mod)}); }, .Many, .C => unreachable, } @@ -6377,7 +6386,7 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { const bitcasted = try bitcast(f, Type.u8, value, elem_ty); try writer.writeAll("memset("); - switch (dest_ty.ptrSize()) { + switch (dest_ty.ptrSize(mod)) { .Slice => { try f.writeCValueMember(writer, dest_slice, .{ .identifier = "ptr" }); try writer.writeAll(", "); @@ -6387,8 +6396,8 @@ fn airMemset(f: *Function, inst: Air.Inst.Index, safety: bool) !CValue { try writer.writeAll(");\n"); }, .One => { - const array_ty = dest_ty.childType(); - const len = array_ty.arrayLen() * elem_abi_size; + const array_ty = dest_ty.childType(mod); + const len = array_ty.arrayLen(mod) * elem_abi_size; try f.writeCValue(writer, dest_slice, .FunctionArgument); try writer.writeAll(", "); @@ -6416,9 +6425,9 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue { try writer.writeAll(", "); try writeSliceOrPtr(f, writer, src_ptr, src_ty); try writer.writeAll(", "); - switch (dest_ty.ptrSize()) { + switch (dest_ty.ptrSize(mod)) { .Slice => { - const elem_ty = dest_ty.childType(); + const elem_ty = dest_ty.childType(mod); const elem_abi_size = elem_ty.abiSize(mod); try f.writeCValueMember(writer, dest_ptr, .{ .identifier = "len" }); if (elem_abi_size > 1) { @@ -6428,10 +6437,10 @@ fn airMemcpy(f: *Function, inst: Air.Inst.Index) !CValue { } }, .One => { - const array_ty = dest_ty.childType(); - const elem_ty = array_ty.childType(); + const array_ty = dest_ty.childType(mod); + const elem_ty = array_ty.childType(mod); const elem_abi_size = elem_ty.abiSize(mod); - const len = array_ty.arrayLen() * elem_abi_size; + const len = array_ty.arrayLen(mod) * elem_abi_size; try writer.print("{d});\n", .{len}); }, .Many, .C => unreachable, @@ -6448,7 +6457,7 @@ fn airSetUnionTag(f: *Function, inst: Air.Inst.Index) !CValue { const new_tag = try f.resolveInst(bin_op.rhs); try reap(f, inst, &.{ bin_op.lhs, bin_op.rhs }); - const union_ty = f.typeOf(bin_op.lhs).childType(); + const union_ty = f.typeOf(bin_op.lhs).childType(mod); const layout = union_ty.unionGetLayout(mod); if (layout.tag_size == 0) return .none; const tag_ty = union_ty.unionTagTypeSafety().?; @@ -6777,7 +6786,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { const mod = f.object.dg.module; const ty_pl = f.air.instructions.items(.data)[inst].ty_pl; const inst_ty = f.typeOfIndex(inst); - const len = @intCast(usize, inst_ty.arrayLen()); + const len = @intCast(usize, inst_ty.arrayLen(mod)); const elements = @ptrCast([]const Air.Inst.Ref, f.air.extra[ty_pl.payload..][0..len]); const gpa = f.object.dg.gpa; const resolved_elements = try gpa.alloc(CValue, elements.len); @@ -6796,7 +6805,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { const local = try f.allocLocal(inst, inst_ty); switch (inst_ty.zigTypeTag(mod)) { .Array, .Vector => { - const elem_ty = inst_ty.childType(); + const elem_ty = inst_ty.childType(mod); const a = try Assignment.init(f, elem_ty); for (resolved_elements, 0..) |element, i| { try a.restart(f, writer); @@ -6806,7 +6815,7 @@ fn airAggregateInit(f: *Function, inst: Air.Inst.Index) !CValue { try f.writeCValue(writer, element, .Other); try a.end(f, writer); } - if (inst_ty.sentinel()) |sentinel| { + if (inst_ty.sentinel(mod)) |sentinel| { try a.restart(f, writer); try f.writeCValue(writer, local, .Other); try writer.print("[{d}]", .{resolved_elements.len}); @@ -7708,7 +7717,7 @@ const Vectorize = struct { pub fn start(f: *Function, inst: Air.Inst.Index, writer: anytype, ty: Type) !Vectorize { const mod = f.object.dg.module; return if (ty.zigTypeTag(mod) == .Vector) index: { - var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen() }; + var len_pl = Value.Payload.U64{ .base = .{ .tag = .int_u64 }, .data = ty.vectorLen(mod) }; const local = try f.allocLocal(inst, Type.usize); diff --git a/src/codegen/c/type.zig b/src/codegen/c/type.zig index 27fa997fd3..9e6de6cb21 100644 --- a/src/codegen/c/type.zig +++ b/src/codegen/c/type.zig @@ -1423,7 +1423,7 @@ pub const CType = extern union { }), .Pointer => { - const info = ty.ptrInfo().data; + const info = ty.ptrInfo(mod); switch (info.size) { .Slice => { if (switch (kind) { @@ -1625,9 +1625,9 @@ pub const CType = extern union { .Vector => .vector, else => unreachable, }; - if (try lookup.typeToIndex(ty.childType(), kind)) |child_idx| { + if (try lookup.typeToIndex(ty.childType(mod), kind)) |child_idx| { self.storage = .{ .seq = .{ .base = .{ .tag = t }, .data = .{ - .len = ty.arrayLenIncludingSentinel(), + .len = ty.arrayLenIncludingSentinel(mod), .elem_type = child_idx, } } }; self.value = .{ .cty = initPayload(&self.storage.seq) }; @@ -1639,8 +1639,7 @@ pub const CType = extern union { }, .Optional => { - var buf: Type.Payload.ElemType = undefined; - const payload_ty = ty.optionalChild(&buf); + const payload_ty = ty.optionalChild(mod); if (payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { if (ty.optionalReprIsPayload(mod)) { try self.initType(payload_ty, kind, lookup); diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index 5d9345c84f..f45a63df72 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -597,7 +597,7 @@ pub const Object = struct { llvm_usize_ty, }; const llvm_slice_ty = self.context.structType(&type_fields, type_fields.len, .False); - const slice_ty = Type.initTag(.const_slice_u8_sentinel_0); + const slice_ty = Type.const_slice_u8_sentinel_0; const slice_alignment = slice_ty.abiAlignment(mod); const error_name_list = mod.error_name_list.items; @@ -1071,7 +1071,7 @@ pub const Object = struct { .slice => { assert(!it.byval_attr); const param_ty = fn_info.param_types[it.zig_index - 1]; - const ptr_info = param_ty.ptrInfo().data; + const ptr_info = param_ty.ptrInfo(mod); if (math.cast(u5, it.zig_index - 1)) |i| { if (@truncate(u1, fn_info.noalias_bits >> i) != 0) { @@ -1596,7 +1596,7 @@ pub const Object = struct { }, .Pointer => { // Normalize everything that the debug info does not represent. - const ptr_info = ty.ptrInfo().data; + const ptr_info = ty.ptrInfo(mod); if (ptr_info.sentinel != null or ptr_info.@"addrspace" != .generic or @@ -1755,8 +1755,8 @@ pub const Object = struct { const array_di_ty = dib.createArrayType( ty.abiSize(mod) * 8, ty.abiAlignment(mod) * 8, - try o.lowerDebugType(ty.childType(), .full), - @intCast(c_int, ty.arrayLen()), + try o.lowerDebugType(ty.childType(mod), .full), + @intCast(c_int, ty.arrayLen(mod)), ); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(array_di_ty), .{ .mod = o.module }); @@ -1781,14 +1781,14 @@ pub const Object = struct { break :blk dib.createBasicType(name, info.bits, dwarf_encoding); }, .Bool => dib.createBasicType("bool", 1, DW.ATE.boolean), - else => try o.lowerDebugType(ty.childType(), .full), + else => try o.lowerDebugType(ty.childType(mod), .full), }; const vector_di_ty = dib.createVectorType( ty.abiSize(mod) * 8, ty.abiAlignment(mod) * 8, elem_di_type, - ty.vectorLen(), + ty.vectorLen(mod), ); // The recursive call to `lowerDebugType` means we can't use `gop` anymore. try o.di_type_map.putContext(gpa, ty, AnnotatedDITypePtr.initFull(vector_di_ty), .{ .mod = o.module }); @@ -1797,8 +1797,7 @@ pub const Object = struct { .Optional => { const name = try ty.nameAlloc(gpa, o.module); defer gpa.free(name); - var buf: Type.Payload.ElemType = undefined; - const child_ty = ty.optionalChild(&buf); + const child_ty = ty.optionalChild(mod); if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) { const di_bits = 8; // lldb cannot handle non-byte sized types const di_ty = dib.createBasicType(name, di_bits, DW.ATE.boolean); @@ -2350,11 +2349,7 @@ pub const Object = struct { try param_di_types.append(try o.lowerDebugType(di_ret_ty, .full)); if (sret) { - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = fn_info.return_type, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(fn_info.return_type); try param_di_types.append(try o.lowerDebugType(ptr_ty, .full)); } } else { @@ -2364,11 +2359,7 @@ pub const Object = struct { if (fn_info.return_type.isError(mod) and o.module.comp.bin_file.options.error_return_tracing) { - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = o.getStackTraceType(), - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(o.getStackTraceType()); try param_di_types.append(try o.lowerDebugType(ptr_ty, .full)); } @@ -2376,11 +2367,7 @@ pub const Object = struct { if (!param_ty.hasRuntimeBitsIgnoreComptime(mod)) continue; if (isByRef(param_ty, mod)) { - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = param_ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(param_ty); try param_di_types.append(try o.lowerDebugType(ptr_ty, .full)); } else { try param_di_types.append(try o.lowerDebugType(param_ty, .full)); @@ -2843,7 +2830,7 @@ pub const DeclGen = struct { }; return dg.context.structType(&fields, fields.len, .False); } - const ptr_info = t.ptrInfo().data; + const ptr_info = t.ptrInfo(mod); const llvm_addrspace = toLlvmAddressSpace(ptr_info.@"addrspace", target); return dg.context.pointerType(llvm_addrspace); }, @@ -2866,19 +2853,18 @@ pub const DeclGen = struct { return llvm_struct_ty; }, .Array => { - const elem_ty = t.childType(); + const elem_ty = t.childType(mod); assert(elem_ty.onePossibleValue(mod) == null); const elem_llvm_ty = try dg.lowerType(elem_ty); - const total_len = t.arrayLen() + @boolToInt(t.sentinel() != null); + const total_len = t.arrayLen(mod) + @boolToInt(t.sentinel(mod) != null); return elem_llvm_ty.arrayType(@intCast(c_uint, total_len)); }, .Vector => { - const elem_type = try dg.lowerType(t.childType()); - return elem_type.vectorType(t.vectorLen()); + const elem_type = try dg.lowerType(t.childType(mod)); + return elem_type.vectorType(t.vectorLen(mod)); }, .Optional => { - var buf: Type.Payload.ElemType = undefined; - const child_ty = t.optionalChild(&buf); + const child_ty = t.optionalChild(mod); if (!child_ty.hasRuntimeBitsIgnoreComptime(mod)) { return dg.context.intType(8); } @@ -3173,11 +3159,7 @@ pub const DeclGen = struct { if (fn_info.return_type.isError(mod) and mod.comp.bin_file.options.error_return_tracing) { - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = dg.object.getStackTraceType(), - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(dg.object.getStackTraceType()); try llvm_params.append(try dg.lowerType(ptr_ty)); } @@ -3199,9 +3181,8 @@ pub const DeclGen = struct { .slice => { const param_ty = fn_info.param_types[it.zig_index - 1]; var buf: Type.SlicePtrFieldTypeBuffer = undefined; - var opt_buf: Type.Payload.ElemType = undefined; const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional) - param_ty.optionalChild(&opt_buf).slicePtrFieldType(&buf) + param_ty.optionalChild(mod).slicePtrFieldType(&buf) else param_ty.slicePtrFieldType(&buf); const ptr_llvm_ty = try dg.lowerType(ptr_ty); @@ -3247,7 +3228,7 @@ pub const DeclGen = struct { const lower_elem_ty = switch (elem_ty.zigTypeTag(mod)) { .Opaque => true, .Fn => !elem_ty.fnInfo().is_generic, - .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(mod), + .Array => elem_ty.childType(mod).hasRuntimeBitsIgnoreComptime(mod), else => elem_ty.hasRuntimeBitsIgnoreComptime(mod), }; const llvm_elem_ty = if (lower_elem_ty) @@ -3417,7 +3398,7 @@ pub const DeclGen = struct { return llvm_int.constIntToPtr(try dg.lowerType(tv.ty)); }, .field_ptr, .opt_payload_ptr, .eu_payload_ptr, .elem_ptr => { - return dg.lowerParentPtr(tv.val, tv.ty.ptrInfo().data.bit_offset % 8 == 0); + return dg.lowerParentPtr(tv.val, tv.ty.ptrInfo(mod).bit_offset % 8 == 0); }, .null_value, .zero => { const llvm_type = try dg.lowerType(tv.ty); @@ -3425,7 +3406,7 @@ pub const DeclGen = struct { }, .opt_payload => { const payload = tv.val.castTag(.opt_payload).?.data; - return dg.lowerParentPtr(payload, tv.ty.ptrInfo().data.bit_offset % 8 == 0); + return dg.lowerParentPtr(payload, tv.ty.ptrInfo(mod).bit_offset % 8 == 0); }, else => |tag| return dg.todo("implement const of pointer type '{}' ({})", .{ tv.ty.fmtDebug(), tag, @@ -3436,14 +3417,14 @@ pub const DeclGen = struct { const bytes = tv.val.castTag(.bytes).?.data; return dg.context.constString( bytes.ptr, - @intCast(c_uint, tv.ty.arrayLenIncludingSentinel()), + @intCast(c_uint, tv.ty.arrayLenIncludingSentinel(mod)), .True, // Don't null terminate. Bytes has the sentinel, if any. ); }, .str_lit => { const str_lit = tv.val.castTag(.str_lit).?.data; const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; - if (tv.ty.sentinel()) |sent_val| { + if (tv.ty.sentinel(mod)) |sent_val| { const byte = @intCast(u8, sent_val.toUnsignedInt(mod)); if (byte == 0 and bytes.len > 0) { return dg.context.constString( @@ -3472,9 +3453,9 @@ pub const DeclGen = struct { }, .aggregate => { const elem_vals = tv.val.castTag(.aggregate).?.data; - const elem_ty = tv.ty.elemType(); + const elem_ty = tv.ty.childType(mod); const gpa = dg.gpa; - const len = @intCast(usize, tv.ty.arrayLenIncludingSentinel()); + const len = @intCast(usize, tv.ty.arrayLenIncludingSentinel(mod)); const llvm_elems = try gpa.alloc(*llvm.Value, len); defer gpa.free(llvm_elems); var need_unnamed = false; @@ -3498,9 +3479,9 @@ pub const DeclGen = struct { }, .repeated => { const val = tv.val.castTag(.repeated).?.data; - const elem_ty = tv.ty.elemType(); - const sentinel = tv.ty.sentinel(); - const len = @intCast(usize, tv.ty.arrayLen()); + const elem_ty = tv.ty.childType(mod); + const sentinel = tv.ty.sentinel(mod); + const len = @intCast(usize, tv.ty.arrayLen(mod)); const len_including_sent = len + @boolToInt(sentinel != null); const gpa = dg.gpa; const llvm_elems = try gpa.alloc(*llvm.Value, len_including_sent); @@ -3534,8 +3515,8 @@ pub const DeclGen = struct { } }, .empty_array_sentinel => { - const elem_ty = tv.ty.elemType(); - const sent_val = tv.ty.sentinel().?; + const elem_ty = tv.ty.childType(mod); + const sent_val = tv.ty.sentinel(mod).?; const sentinel = try dg.lowerValue(.{ .ty = elem_ty, .val = sent_val }); const llvm_elems: [1]*llvm.Value = .{sentinel}; const need_unnamed = dg.isUnnamedType(elem_ty, llvm_elems[0]); @@ -3550,8 +3531,7 @@ pub const DeclGen = struct { }, .Optional => { comptime assert(optional_layout_version == 3); - var buf: Type.Payload.ElemType = undefined; - const payload_ty = tv.ty.optionalChild(&buf); + const payload_ty = tv.ty.optionalChild(mod); const llvm_i8 = dg.context.intType(8); const is_pl = !tv.val.isNull(mod); @@ -3897,10 +3877,10 @@ pub const DeclGen = struct { .bytes => { // Note, sentinel is not stored even if the type has a sentinel. const bytes = tv.val.castTag(.bytes).?.data; - const vector_len = @intCast(usize, tv.ty.arrayLen()); + const vector_len = @intCast(usize, tv.ty.arrayLen(mod)); assert(vector_len == bytes.len or vector_len + 1 == bytes.len); - const elem_ty = tv.ty.elemType(); + const elem_ty = tv.ty.childType(mod); const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_len); defer dg.gpa.free(llvm_elems); for (llvm_elems, 0..) |*elem, i| { @@ -3923,9 +3903,9 @@ pub const DeclGen = struct { // Note, sentinel is not stored even if the type has a sentinel. // The value includes the sentinel in those cases. const elem_vals = tv.val.castTag(.aggregate).?.data; - const vector_len = @intCast(usize, tv.ty.arrayLen()); + const vector_len = @intCast(usize, tv.ty.arrayLen(mod)); assert(vector_len == elem_vals.len or vector_len + 1 == elem_vals.len); - const elem_ty = tv.ty.elemType(); + const elem_ty = tv.ty.childType(mod); const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_len); defer dg.gpa.free(llvm_elems); for (llvm_elems, 0..) |*elem, i| { @@ -3939,8 +3919,8 @@ pub const DeclGen = struct { .repeated => { // Note, sentinel is not stored even if the type has a sentinel. const val = tv.val.castTag(.repeated).?.data; - const elem_ty = tv.ty.elemType(); - const len = @intCast(usize, tv.ty.arrayLen()); + const elem_ty = tv.ty.childType(mod); + const len = @intCast(usize, tv.ty.arrayLen(mod)); const llvm_elems = try dg.gpa.alloc(*llvm.Value, len); defer dg.gpa.free(llvm_elems); for (llvm_elems) |*elem| { @@ -3955,10 +3935,10 @@ pub const DeclGen = struct { // Note, sentinel is not stored const str_lit = tv.val.castTag(.str_lit).?.data; const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; - const vector_len = @intCast(usize, tv.ty.arrayLen()); + const vector_len = @intCast(usize, tv.ty.arrayLen(mod)); assert(vector_len == bytes.len); - const elem_ty = tv.ty.elemType(); + const elem_ty = tv.ty.childType(mod); const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_len); defer dg.gpa.free(llvm_elems); for (llvm_elems, 0..) |*elem, i| { @@ -4006,13 +3986,10 @@ pub const DeclGen = struct { ptr_val: Value, decl_index: Module.Decl.Index, ) Error!*llvm.Value { - const decl = dg.module.declPtr(decl_index); - dg.module.markDeclAlive(decl); - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = decl.ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const mod = dg.module; + const decl = mod.declPtr(decl_index); + mod.markDeclAlive(decl); + const ptr_ty = try mod.singleMutPtrType(decl.ty); return try dg.lowerDeclRefValue(.{ .ty = ptr_ty, .val = ptr_val }, decl_index); } @@ -4135,9 +4112,8 @@ pub const DeclGen = struct { .opt_payload_ptr => { const opt_payload_ptr = ptr_val.castTag(.opt_payload_ptr).?.data; const parent_llvm_ptr = try dg.lowerParentPtr(opt_payload_ptr.container_ptr, true); - var buf: Type.Payload.ElemType = undefined; - const payload_ty = opt_payload_ptr.container_ty.optionalChild(&buf); + const payload_ty = opt_payload_ptr.container_ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or payload_ty.optionalReprIsPayload(mod)) { @@ -4251,7 +4227,8 @@ pub const DeclGen = struct { } fn lowerPtrToVoid(dg: *DeclGen, ptr_ty: Type) !*llvm.Value { - const alignment = ptr_ty.ptrInfo().data.@"align"; + const mod = dg.module; + const alignment = ptr_ty.ptrInfo(mod).@"align"; // Even though we are pointing at something which has zero bits (e.g. `void`), // Pointers are defined to have bits. So we must return something here. // The value cannot be undefined, because we use the `nonnull` annotation @@ -4374,7 +4351,7 @@ pub const DeclGen = struct { ) void { const mod = dg.module; if (param_ty.isPtrAtRuntime(mod)) { - const ptr_info = param_ty.ptrInfo().data; + const ptr_info = param_ty.ptrInfo(mod); if (math.cast(u5, param_index)) |i| { if (@truncate(u1, fn_info.noalias_bits >> i) != 0) { dg.addArgAttr(llvm_fn, llvm_arg_i, "noalias"); @@ -4786,7 +4763,7 @@ pub const FuncGen = struct { const mod = self.dg.module; const zig_fn_ty = switch (callee_ty.zigTypeTag(mod)) { .Fn => callee_ty, - .Pointer => callee_ty.childType(), + .Pointer => callee_ty.childType(mod), else => unreachable, }; const fn_info = zig_fn_ty.fnInfo(); @@ -5014,7 +4991,7 @@ pub const FuncGen = struct { .slice => { assert(!it.byval_attr); const param_ty = fn_info.param_types[it.zig_index - 1]; - const ptr_info = param_ty.ptrInfo().data; + const ptr_info = param_ty.ptrInfo(mod); const llvm_arg_i = it.llvm_index - 2; if (math.cast(u5, it.zig_index - 1)) |i| { @@ -5098,11 +5075,7 @@ pub const FuncGen = struct { const ret_ty = self.typeOf(un_op); if (self.ret_ptr) |ret_ptr| { const operand = try self.resolveInst(un_op); - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ret_ty, - }; - const ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const ptr_ty = try mod.singleMutPtrType(ret_ty); try self.store(ret_ptr, ptr_ty, operand, .NotAtomic); _ = self.builder.buildRetVoid(); return null; @@ -5150,11 +5123,11 @@ pub const FuncGen = struct { } fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { + const mod = self.dg.module; const un_op = self.air.instructions.items(.data)[inst].un_op; const ptr_ty = self.typeOf(un_op); - const ret_ty = ptr_ty.childType(); + const ret_ty = ptr_ty.childType(mod); const fn_info = self.dg.decl.ty.fnInfo(); - const mod = self.dg.module; if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { if (fn_info.return_type.isError(mod)) { // Functions with an empty error set are emitted with an error code @@ -5301,15 +5274,13 @@ pub const FuncGen = struct { operand_ty: Type, op: math.CompareOperator, ) Allocator.Error!*llvm.Value { - var opt_buffer: Type.Payload.ElemType = undefined; - const mod = self.dg.module; const scalar_ty = operand_ty.scalarType(mod); const int_ty = switch (scalar_ty.zigTypeTag(mod)) { .Enum => scalar_ty.intTagType(), .Int, .Bool, .Pointer, .ErrorSet => scalar_ty, .Optional => blk: { - const payload_ty = operand_ty.optionalChild(&opt_buffer); + const payload_ty = operand_ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod) or operand_ty.optionalReprIsPayload(mod)) { @@ -5506,11 +5477,12 @@ pub const FuncGen = struct { } fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { + const mod = self.dg.module; const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const extra = self.air.extraData(Air.TryPtr, ty_pl.payload); const err_union_ptr = try self.resolveInst(extra.data.ptr); const body = self.air.extra[extra.end..][0..extra.data.body_len]; - const err_union_ty = self.typeOf(extra.data.ptr).childType(); + const err_union_ty = self.typeOf(extra.data.ptr).childType(mod); const is_unused = self.liveness.isUnused(inst); return lowerTry(self, err_union_ptr, body, err_union_ty, true, true, is_unused); } @@ -5661,9 +5633,9 @@ pub const FuncGen = struct { const mod = self.dg.module; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const operand_ty = self.typeOf(ty_op.operand); - const array_ty = operand_ty.childType(); + const array_ty = operand_ty.childType(mod); const llvm_usize = try self.dg.lowerType(Type.usize); - const len = llvm_usize.constInt(array_ty.arrayLen(), .False); + const len = llvm_usize.constInt(array_ty.arrayLen(mod), .False); const slice_llvm_ty = try self.dg.lowerType(self.typeOfIndex(inst)); const operand = try self.resolveInst(ty_op.operand); if (!array_ty.hasRuntimeBitsIgnoreComptime(mod)) { @@ -5806,20 +5778,20 @@ pub const FuncGen = struct { const mod = fg.dg.module; const target = mod.getTarget(); const llvm_usize_ty = fg.context.intType(target.ptrBitWidth()); - switch (ty.ptrSize()) { + switch (ty.ptrSize(mod)) { .Slice => { const len = fg.builder.buildExtractValue(ptr, 1, ""); - const elem_ty = ty.childType(); + const elem_ty = ty.childType(mod); const abi_size = elem_ty.abiSize(mod); if (abi_size == 1) return len; const abi_size_llvm_val = llvm_usize_ty.constInt(abi_size, .False); return fg.builder.buildMul(len, abi_size_llvm_val, ""); }, .One => { - const array_ty = ty.childType(); - const elem_ty = array_ty.childType(); + const array_ty = ty.childType(mod); + const elem_ty = array_ty.childType(mod); const abi_size = elem_ty.abiSize(mod); - return llvm_usize_ty.constInt(array_ty.arrayLen() * abi_size, .False); + return llvm_usize_ty.constInt(array_ty.arrayLen(mod) * abi_size, .False); }, .Many, .C => unreachable, } @@ -5832,10 +5804,11 @@ pub const FuncGen = struct { } fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*llvm.Value { + const mod = self.dg.module; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const slice_ptr = try self.resolveInst(ty_op.operand); const slice_ptr_ty = self.typeOf(ty_op.operand); - const slice_llvm_ty = try self.dg.lowerPtrElemTy(slice_ptr_ty.childType()); + const slice_llvm_ty = try self.dg.lowerPtrElemTy(slice_ptr_ty.childType(mod)); return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, ""); } @@ -5847,7 +5820,7 @@ pub const FuncGen = struct { const slice_ty = self.typeOf(bin_op.lhs); const slice = try self.resolveInst(bin_op.lhs); const index = try self.resolveInst(bin_op.rhs); - const elem_ty = slice_ty.childType(); + const elem_ty = slice_ty.childType(mod); const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty); const base_ptr = self.builder.buildExtractValue(slice, 0, ""); const indices: [1]*llvm.Value = .{index}; @@ -5863,13 +5836,14 @@ pub const FuncGen = struct { } fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { + const mod = self.dg.module; const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; const slice_ty = self.typeOf(bin_op.lhs); const slice = try self.resolveInst(bin_op.lhs); const index = try self.resolveInst(bin_op.rhs); - const llvm_elem_ty = try self.dg.lowerPtrElemTy(slice_ty.childType()); + const llvm_elem_ty = try self.dg.lowerPtrElemTy(slice_ty.childType(mod)); const base_ptr = self.builder.buildExtractValue(slice, 0, ""); const indices: [1]*llvm.Value = .{index}; return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); @@ -5884,7 +5858,7 @@ pub const FuncGen = struct { const array_llvm_val = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); const array_llvm_ty = try self.dg.lowerType(array_ty); - const elem_ty = array_ty.childType(); + const elem_ty = array_ty.childType(mod); if (isByRef(array_ty, mod)) { const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs }; if (isByRef(elem_ty, mod)) { @@ -5923,7 +5897,7 @@ pub const FuncGen = struct { const inst = body_tail[0]; const bin_op = self.air.instructions.items(.data)[inst].bin_op; const ptr_ty = self.typeOf(bin_op.lhs); - const elem_ty = ptr_ty.childType(); + const elem_ty = ptr_ty.childType(mod); const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty); const base_ptr = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); @@ -5951,14 +5925,14 @@ pub const FuncGen = struct { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; const ptr_ty = self.typeOf(bin_op.lhs); - const elem_ty = ptr_ty.childType(); + const elem_ty = ptr_ty.childType(mod); if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty); const base_ptr = try self.resolveInst(bin_op.lhs); const rhs = try self.resolveInst(bin_op.rhs); const elem_ptr = self.air.getRefType(ty_pl.ty); - if (elem_ptr.ptrInfo().data.vector_index != .none) return base_ptr; + if (elem_ptr.ptrInfo(mod).vector_index != .none) return base_ptr; const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty); if (ptr_ty.isSinglePointer(mod)) { @@ -6098,7 +6072,7 @@ pub const FuncGen = struct { const field_ptr = try self.resolveInst(extra.field_ptr); const target = self.dg.module.getTarget(); - const parent_ty = self.air.getRefType(ty_pl.ty).childType(); + const parent_ty = self.air.getRefType(ty_pl.ty).childType(mod); const field_offset = parent_ty.structFieldOffset(extra.field_index, mod); const res_ty = try self.dg.lowerType(self.air.getRefType(ty_pl.ty)); @@ -6232,6 +6206,7 @@ pub const FuncGen = struct { } fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { + const mod = self.dg.module; const dib = self.dg.object.di_builder orelse return null; const pl_op = self.air.instructions.items(.data)[inst].pl_op; const operand = try self.resolveInst(pl_op.operand); @@ -6243,7 +6218,7 @@ pub const FuncGen = struct { name.ptr, self.di_file.?, self.prev_dbg_line, - try self.dg.object.lowerDebugType(ptr_ty.childType(), .full), + try self.dg.object.lowerDebugType(ptr_ty.childType(mod), .full), true, // always preserve 0, // flags ); @@ -6365,7 +6340,7 @@ pub const FuncGen = struct { const output_inst = try self.resolveInst(output); const output_ty = self.typeOf(output); assert(output_ty.zigTypeTag(mod) == .Pointer); - const elem_llvm_ty = try self.dg.lowerPtrElemTy(output_ty.childType()); + const elem_llvm_ty = try self.dg.lowerPtrElemTy(output_ty.childType(mod)); if (llvm_ret_indirect[i]) { // Pass the result by reference as an indirect output (e.g. "=*m") @@ -6466,7 +6441,7 @@ pub const FuncGen = struct { // an elementtype() attribute. if (constraint[0] == '*') { llvm_param_attrs[llvm_param_i] = llvm_elem_ty orelse - try self.dg.lowerPtrElemTy(arg_ty.childType()); + try self.dg.lowerPtrElemTy(arg_ty.childType(mod)); } else { llvm_param_attrs[llvm_param_i] = null; } @@ -6657,14 +6632,13 @@ pub const FuncGen = struct { operand_is_ptr: bool, pred: llvm.IntPredicate, ) !?*llvm.Value { + const mod = self.dg.module; const un_op = self.air.instructions.items(.data)[inst].un_op; const operand = try self.resolveInst(un_op); const operand_ty = self.typeOf(un_op); - const optional_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; + const optional_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; const optional_llvm_ty = try self.dg.lowerType(optional_ty); - var buf: Type.Payload.ElemType = undefined; - const payload_ty = optional_ty.optionalChild(&buf); - const mod = self.dg.module; + const payload_ty = optional_ty.optionalChild(mod); if (optional_ty.optionalReprIsPayload(mod)) { const loaded = if (operand_is_ptr) self.builder.buildLoad(optional_llvm_ty, operand, "") @@ -6709,7 +6683,7 @@ pub const FuncGen = struct { const un_op = self.air.instructions.items(.data)[inst].un_op; const operand = try self.resolveInst(un_op); const operand_ty = self.typeOf(un_op); - const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; + const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; const payload_ty = err_union_ty.errorUnionPayload(); const err_set_ty = try self.dg.lowerType(Type.anyerror); const zero = err_set_ty.constNull(); @@ -6748,9 +6722,8 @@ pub const FuncGen = struct { const mod = self.dg.module; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const operand = try self.resolveInst(ty_op.operand); - const optional_ty = self.typeOf(ty_op.operand).childType(); - var buf: Type.Payload.ElemType = undefined; - const payload_ty = optional_ty.optionalChild(&buf); + const optional_ty = self.typeOf(ty_op.operand).childType(mod); + const payload_ty = optional_ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { // We have a pointer to a zero-bit value and we need to return // a pointer to a zero-bit value. @@ -6770,9 +6743,8 @@ pub const FuncGen = struct { const mod = self.dg.module; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const operand = try self.resolveInst(ty_op.operand); - const optional_ty = self.typeOf(ty_op.operand).childType(); - var buf: Type.Payload.ElemType = undefined; - const payload_ty = optional_ty.optionalChild(&buf); + const optional_ty = self.typeOf(ty_op.operand).childType(mod); + const payload_ty = optional_ty.optionalChild(mod); const non_null_bit = self.context.intType(8).constInt(1, .False); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { // We have a pointer to a i8. We need to set it to 1 and then return the same pointer. @@ -6827,9 +6799,9 @@ pub const FuncGen = struct { const ty_op = self.air.instructions.items(.data)[inst].ty_op; const operand = try self.resolveInst(ty_op.operand); const operand_ty = self.typeOf(ty_op.operand); - const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; + const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; const result_ty = self.typeOfIndex(inst); - const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty; + const payload_ty = if (operand_is_ptr) result_ty.childType(mod) else result_ty; if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { return if (operand_is_ptr) operand else null; @@ -6862,7 +6834,7 @@ pub const FuncGen = struct { const ty_op = self.air.instructions.items(.data)[inst].ty_op; const operand = try self.resolveInst(ty_op.operand); const operand_ty = self.typeOf(ty_op.operand); - const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty; + const err_union_ty = if (operand_is_ptr) operand_ty.childType(mod) else operand_ty; if (err_union_ty.errorUnionSet().errorSetIsEmpty(mod)) { const err_llvm_ty = try self.dg.lowerType(Type.anyerror); if (operand_is_ptr) { @@ -6895,7 +6867,7 @@ pub const FuncGen = struct { const mod = self.dg.module; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const operand = try self.resolveInst(ty_op.operand); - const err_union_ty = self.typeOf(ty_op.operand).childType(); + const err_union_ty = self.typeOf(ty_op.operand).childType(mod); const payload_ty = err_union_ty.errorUnionPayload(); const non_error_val = try self.dg.lowerValue(.{ .ty = Type.anyerror, .val = Value.zero }); @@ -6961,11 +6933,7 @@ pub const FuncGen = struct { if (isByRef(optional_ty, mod)) { const optional_ptr = self.buildAlloca(llvm_optional_ty, optional_ty.abiAlignment(mod)); const payload_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 0, ""); - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = payload_ty, - }; - const payload_ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const payload_ptr_ty = try mod.singleMutPtrType(payload_ty); try self.store(payload_ptr, payload_ptr_ty, operand, .NotAtomic); const non_null_ptr = self.builder.buildStructGEP(llvm_optional_ty, optional_ptr, 1, ""); _ = self.builder.buildStore(non_null_bit, non_null_ptr); @@ -6995,11 +6963,7 @@ pub const FuncGen = struct { const store_inst = self.builder.buildStore(ok_err_code, err_ptr); store_inst.setAlignment(Type.anyerror.abiAlignment(mod)); const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, ""); - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = payload_ty, - }; - const payload_ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const payload_ptr_ty = try mod.singleMutPtrType(payload_ty); try self.store(payload_ptr, payload_ptr_ty, operand, .NotAtomic); return result_ptr; } @@ -7027,11 +6991,7 @@ pub const FuncGen = struct { const store_inst = self.builder.buildStore(operand, err_ptr); store_inst.setAlignment(Type.anyerror.abiAlignment(mod)); const payload_ptr = self.builder.buildStructGEP(err_un_llvm_ty, result_ptr, payload_offset, ""); - var ptr_ty_payload: Type.Payload.ElemType = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = payload_ty, - }; - const payload_ptr_ty = Type.initPayload(&ptr_ty_payload.base); + const payload_ptr_ty = try mod.singleMutPtrType(payload_ty); // TODO store undef to payload_ptr _ = payload_ptr; _ = payload_ptr_ty; @@ -7076,7 +7036,7 @@ pub const FuncGen = struct { const operand = try self.resolveInst(extra.rhs); const loaded_vector = blk: { - const elem_llvm_ty = try self.dg.lowerType(vector_ptr_ty.childType()); + const elem_llvm_ty = try self.dg.lowerType(vector_ptr_ty.childType(mod)); const load_inst = self.builder.buildLoad(elem_llvm_ty, vector_ptr, ""); load_inst.setAlignment(vector_ptr_ty.ptrAlignment(mod)); load_inst.setVolatile(llvm.Bool.fromBool(vector_ptr_ty.isVolatilePtr())); @@ -7287,7 +7247,7 @@ pub const FuncGen = struct { const inst_llvm_ty = try self.dg.lowerType(inst_ty); const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { - const vec_len = inst_ty.vectorLen(); + const vec_len = inst_ty.vectorLen(mod); const scalar_llvm_ty = try self.dg.lowerType(scalar_ty); const shifts = try self.gpa.alloc(*llvm.Value, vec_len); @@ -7361,7 +7321,7 @@ pub const FuncGen = struct { if (scalar_ty.isSignedInt(mod)) { const scalar_bit_size_minus_one = scalar_ty.bitSize(mod) - 1; const bit_size_minus_one = if (inst_ty.zigTypeTag(mod) == .Vector) const_vector: { - const vec_len = inst_ty.vectorLen(); + const vec_len = inst_ty.vectorLen(mod); const scalar_llvm_ty = try self.dg.lowerType(scalar_ty); const shifts = try self.gpa.alloc(*llvm.Value, vec_len); @@ -7384,13 +7344,14 @@ pub const FuncGen = struct { } fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { + const mod = self.dg.module; const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; const ptr = try self.resolveInst(bin_op.lhs); const offset = try self.resolveInst(bin_op.rhs); const ptr_ty = self.typeOf(bin_op.lhs); - const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType()); - switch (ptr_ty.ptrSize()) { + const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType(mod)); + switch (ptr_ty.ptrSize(mod)) { .One => { // It's a pointer to an array, so according to LLVM we need an extra GEP index. const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), offset }; @@ -7409,14 +7370,15 @@ pub const FuncGen = struct { } fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { + const mod = self.dg.module; const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; const ptr = try self.resolveInst(bin_op.lhs); const offset = try self.resolveInst(bin_op.rhs); const negative_offset = self.builder.buildNeg(offset, ""); const ptr_ty = self.typeOf(bin_op.lhs); - const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType()); - switch (ptr_ty.ptrSize()) { + const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType(mod)); + switch (ptr_ty.ptrSize(mod)) { .One => { // It's a pointer to an array, so according to LLVM we need an extra GEP index. const indices: [2]*llvm.Value = .{ @@ -7587,7 +7549,7 @@ pub const FuncGen = struct { }; if (ty.zigTypeTag(mod) == .Vector) { - const vec_len = ty.vectorLen(); + const vec_len = ty.vectorLen(mod); const vector_result_ty = llvm_i32.vectorType(vec_len); var result = vector_result_ty.getUndef(); @@ -7672,8 +7634,8 @@ pub const FuncGen = struct { const shift_amt = int_llvm_ty.constInt(float_bits - 1, .False); const sign_mask = one.constShl(shift_amt); const result = if (ty.zigTypeTag(mod) == .Vector) blk: { - const splat_sign_mask = self.builder.buildVectorSplat(ty.vectorLen(), sign_mask, ""); - const cast_ty = int_llvm_ty.vectorType(ty.vectorLen()); + const splat_sign_mask = self.builder.buildVectorSplat(ty.vectorLen(mod), sign_mask, ""); + const cast_ty = int_llvm_ty.vectorType(ty.vectorLen(mod)); const bitcasted_operand = self.builder.buildBitCast(params[0], cast_ty, ""); break :blk self.builder.buildXor(bitcasted_operand, splat_sign_mask, ""); } else blk: { @@ -7720,7 +7682,7 @@ pub const FuncGen = struct { const libc_fn = self.getLibcFunction(fn_name, param_types[0..params.len], scalar_llvm_ty); if (ty.zigTypeTag(mod) == .Vector) { const result = llvm_ty.getUndef(); - return self.buildElementwiseCall(libc_fn, ¶ms, result, ty.vectorLen()); + return self.buildElementwiseCall(libc_fn, ¶ms, result, ty.vectorLen(mod)); } break :b libc_fn; @@ -7887,7 +7849,7 @@ pub const FuncGen = struct { const bits = lhs_scalar_llvm_ty.constInt(lhs_bits, .False); const lhs_max = lhs_scalar_llvm_ty.constAllOnes(); if (rhs_ty.zigTypeTag(mod) == .Vector) { - const vec_len = rhs_ty.vectorLen(); + const vec_len = rhs_ty.vectorLen(mod); const bits_vec = self.builder.buildVectorSplat(vec_len, bits, ""); const lhs_max_vec = self.builder.buildVectorSplat(vec_len, lhs_max, ""); const in_range = self.builder.buildICmp(.ULT, rhs, bits_vec, ""); @@ -8059,7 +8021,7 @@ pub const FuncGen = struct { } if (operand_ty.zigTypeTag(mod) == .Vector and inst_ty.zigTypeTag(mod) == .Array) { - const elem_ty = operand_ty.childType(); + const elem_ty = operand_ty.childType(mod); if (!result_is_ref) { return self.dg.todo("implement bitcast vector to non-ref array", .{}); } @@ -8074,7 +8036,7 @@ pub const FuncGen = struct { const llvm_usize = try self.dg.lowerType(Type.usize); const llvm_u32 = self.context.intType(32); const zero = llvm_usize.constNull(); - const vector_len = operand_ty.arrayLen(); + const vector_len = operand_ty.arrayLen(mod); var i: u64 = 0; while (i < vector_len) : (i += 1) { const index_usize = llvm_usize.constInt(i, .False); @@ -8087,7 +8049,7 @@ pub const FuncGen = struct { } return array_ptr; } else if (operand_ty.zigTypeTag(mod) == .Array and inst_ty.zigTypeTag(mod) == .Vector) { - const elem_ty = operand_ty.childType(); + const elem_ty = operand_ty.childType(mod); const llvm_vector_ty = try self.dg.lowerType(inst_ty); if (!operand_is_ref) { return self.dg.todo("implement bitcast non-ref array to vector", .{}); @@ -8108,7 +8070,7 @@ pub const FuncGen = struct { const llvm_usize = try self.dg.lowerType(Type.usize); const llvm_u32 = self.context.intType(32); const zero = llvm_usize.constNull(); - const vector_len = operand_ty.arrayLen(); + const vector_len = operand_ty.arrayLen(mod); var vector = llvm_vector_ty.getUndef(); var i: u64 = 0; while (i < vector_len) : (i += 1) { @@ -8207,7 +8169,7 @@ pub const FuncGen = struct { fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { const mod = self.dg.module; const ptr_ty = self.typeOfIndex(inst); - const pointee_type = ptr_ty.childType(); + const pointee_type = ptr_ty.childType(mod); if (!pointee_type.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty); const pointee_llvm_ty = try self.dg.lowerType(pointee_type); @@ -8218,7 +8180,7 @@ pub const FuncGen = struct { fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { const mod = self.dg.module; const ptr_ty = self.typeOfIndex(inst); - const ret_ty = ptr_ty.childType(); + const ret_ty = ptr_ty.childType(mod); if (!ret_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return self.dg.lowerPtrToVoid(ptr_ty); if (self.ret_ptr) |ret_ptr| return ret_ptr; const ret_llvm_ty = try self.dg.lowerType(ret_ty); @@ -8232,11 +8194,11 @@ pub const FuncGen = struct { } fn airStore(self: *FuncGen, inst: Air.Inst.Index, safety: bool) !?*llvm.Value { + const mod = self.dg.module; const bin_op = self.air.instructions.items(.data)[inst].bin_op; const dest_ptr = try self.resolveInst(bin_op.lhs); const ptr_ty = self.typeOf(bin_op.lhs); - const operand_ty = ptr_ty.childType(); - const mod = self.dg.module; + const operand_ty = ptr_ty.childType(mod); const val_is_undef = if (self.air.value(bin_op.rhs, mod)) |val| val.isUndefDeep() else false; if (val_is_undef) { @@ -8271,8 +8233,10 @@ pub const FuncGen = struct { /// /// The first instruction of `body_tail` is the one whose copy we want to elide. fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool { + const mod = fg.dg.module; + const ip = &mod.intern_pool; for (body_tail[1..]) |body_inst| { - switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0])) { + switch (fg.liveness.categorizeOperand(fg.air, body_inst, body_tail[0], ip.*)) { .none => continue, .write, .noret, .complex => return false, .tomb => return true, @@ -8288,7 +8252,7 @@ pub const FuncGen = struct { const inst = body_tail[0]; const ty_op = fg.air.instructions.items(.data)[inst].ty_op; const ptr_ty = fg.typeOf(ty_op.operand); - const ptr_info = ptr_ty.ptrInfo().data; + const ptr_info = ptr_ty.ptrInfo(mod); const ptr = try fg.resolveInst(ty_op.operand); elide: { @@ -8363,7 +8327,7 @@ pub const FuncGen = struct { const ptr = try self.resolveInst(extra.ptr); var expected_value = try self.resolveInst(extra.expected_value); var new_value = try self.resolveInst(extra.new_value); - const operand_ty = self.typeOf(extra.ptr).elemType(); + const operand_ty = self.typeOf(extra.ptr).childType(mod); const opt_abi_ty = self.dg.getAtomicAbiType(operand_ty, false); if (opt_abi_ty) |abi_ty| { // operand needs widening and truncating @@ -8409,7 +8373,7 @@ pub const FuncGen = struct { const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data; const ptr = try self.resolveInst(pl_op.operand); const ptr_ty = self.typeOf(pl_op.operand); - const operand_ty = ptr_ty.elemType(); + const operand_ty = ptr_ty.childType(mod); const operand = try self.resolveInst(extra.operand); const is_signed_int = operand_ty.isSignedInt(mod); const is_float = operand_ty.isRuntimeFloat(); @@ -8464,7 +8428,7 @@ pub const FuncGen = struct { const atomic_load = self.air.instructions.items(.data)[inst].atomic_load; const ptr = try self.resolveInst(atomic_load.ptr); const ptr_ty = self.typeOf(atomic_load.ptr); - const ptr_info = ptr_ty.ptrInfo().data; + const ptr_info = ptr_ty.ptrInfo(mod); const elem_ty = ptr_info.pointee_type; if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null; @@ -8497,7 +8461,7 @@ pub const FuncGen = struct { const mod = self.dg.module; const bin_op = self.air.instructions.items(.data)[inst].bin_op; const ptr_ty = self.typeOf(bin_op.lhs); - const operand_ty = ptr_ty.childType(); + const operand_ty = ptr_ty.childType(mod); if (!operand_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) return null; const ptr = try self.resolveInst(bin_op.lhs); var element = try self.resolveInst(bin_op.rhs); @@ -8595,9 +8559,9 @@ pub const FuncGen = struct { const end_block = self.context.appendBasicBlock(self.llvm_func, "InlineMemsetEnd"); const llvm_usize_ty = self.context.intType(target.ptrBitWidth()); - const len = switch (ptr_ty.ptrSize()) { + const len = switch (ptr_ty.ptrSize(mod)) { .Slice => self.builder.buildExtractValue(dest_slice, 1, ""), - .One => llvm_usize_ty.constInt(ptr_ty.childType().arrayLen(), .False), + .One => llvm_usize_ty.constInt(ptr_ty.childType(mod).arrayLen(mod), .False), .Many, .C => unreachable, }; const elem_llvm_ty = try self.dg.lowerType(elem_ty); @@ -8665,7 +8629,7 @@ pub const FuncGen = struct { fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { const mod = self.dg.module; const bin_op = self.air.instructions.items(.data)[inst].bin_op; - const un_ty = self.typeOf(bin_op.lhs).childType(); + const un_ty = self.typeOf(bin_op.lhs).childType(mod); const layout = un_ty.unionGetLayout(mod); if (layout.tag_size == 0) return null; const union_ptr = try self.resolveInst(bin_op.lhs); @@ -8791,7 +8755,7 @@ pub const FuncGen = struct { // The truncated result at the end will be the correct bswap const scalar_llvm_ty = self.context.intType(bits + 8); if (operand_ty.zigTypeTag(mod) == .Vector) { - const vec_len = operand_ty.vectorLen(); + const vec_len = operand_ty.vectorLen(mod); operand_llvm_ty = scalar_llvm_ty.vectorType(vec_len); const shifts = try self.gpa.alloc(*llvm.Value, vec_len); @@ -8980,7 +8944,7 @@ pub const FuncGen = struct { defer self.gpa.free(fqn); const llvm_fn_name = try std.fmt.allocPrintZ(arena, "__zig_tag_name_{s}", .{fqn}); - const slice_ty = Type.initTag(.const_slice_u8_sentinel_0); + const slice_ty = Type.const_slice_u8_sentinel_0; const llvm_ret_ty = try self.dg.lowerType(slice_ty); const usize_llvm_ty = try self.dg.lowerType(Type.usize); const slice_alignment = slice_ty.abiAlignment(mod); @@ -9097,10 +9061,11 @@ pub const FuncGen = struct { } fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { + const mod = self.dg.module; const ty_op = self.air.instructions.items(.data)[inst].ty_op; const scalar = try self.resolveInst(ty_op.operand); const vector_ty = self.typeOfIndex(inst); - const len = vector_ty.vectorLen(); + const len = vector_ty.vectorLen(mod); return self.builder.buildVectorSplat(len, scalar, ""); } @@ -9122,7 +9087,7 @@ pub const FuncGen = struct { const b = try self.resolveInst(extra.b); const mask = self.air.values[extra.mask]; const mask_len = extra.mask_len; - const a_len = self.typeOf(extra.a).vectorLen(); + const a_len = self.typeOf(extra.a).vectorLen(mod); // LLVM uses integers larger than the length of the first array to // index into the second array. This was deemed unnecessarily fragile @@ -9298,14 +9263,14 @@ pub const FuncGen = struct { .ty = scalar_ty, .val = Value.initPayload(&init_value_payload.base), }); - return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(), init_value); + return self.buildReducedCall(libc_fn, operand, operand_ty.vectorLen(mod), init_value); } fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { const mod = self.dg.module; const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const result_ty = self.typeOfIndex(inst); - const len = @intCast(usize, result_ty.arrayLen()); + const len = @intCast(usize, result_ty.arrayLen(mod)); const elements = @ptrCast([]const Air.Inst.Ref, self.air.extra[ty_pl.payload..][0..len]); const llvm_result_ty = try self.dg.lowerType(result_ty); @@ -9400,7 +9365,7 @@ pub const FuncGen = struct { const llvm_usize = try self.dg.lowerType(Type.usize); const alloca_inst = self.buildAlloca(llvm_result_ty, result_ty.abiAlignment(mod)); - const array_info = result_ty.arrayInfo(); + const array_info = result_ty.arrayInfo(mod); var elem_ptr_payload: Type.Payload.Pointer = .{ .data = .{ .pointee_type = array_info.elem_type, @@ -9720,7 +9685,7 @@ pub const FuncGen = struct { } const mod = self.dg.module; - const slice_ty = Type.initTag(.const_slice_u8_sentinel_0); + const slice_ty = Type.const_slice_u8_sentinel_0; const slice_alignment = slice_ty.abiAlignment(mod); const llvm_slice_ptr_ty = self.context.pointerType(0); // TODO: Address space @@ -9763,9 +9728,8 @@ pub const FuncGen = struct { opt_ty: Type, can_elide_load: bool, ) !*llvm.Value { - var buf: Type.Payload.ElemType = undefined; - const payload_ty = opt_ty.optionalChild(&buf); const mod = fg.dg.module; + const payload_ty = opt_ty.optionalChild(mod); if (isByRef(opt_ty, mod)) { // We have a pointer and we need to return a pointer to the first field. @@ -9827,13 +9791,13 @@ pub const FuncGen = struct { struct_ptr_ty: Type, field_index: u32, ) !?*llvm.Value { - const struct_ty = struct_ptr_ty.childType(); const mod = self.dg.module; + const struct_ty = struct_ptr_ty.childType(mod); switch (struct_ty.zigTypeTag(mod)) { .Struct => switch (struct_ty.containerLayout()) { .Packed => { const result_ty = self.typeOfIndex(inst); - const result_ty_info = result_ty.ptrInfo().data; + const result_ty_info = result_ty.ptrInfo(mod); if (result_ty_info.host_size != 0) { // From LLVM's perspective, a pointer to a packed struct and a pointer @@ -9919,7 +9883,7 @@ pub const FuncGen = struct { /// For isByRef=false types, it creates a load instruction and returns it. fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value { const mod = self.dg.module; - const info = ptr_ty.ptrInfo().data; + const info = ptr_ty.ptrInfo(mod); if (!info.pointee_type.hasRuntimeBitsIgnoreComptime(mod)) return null; const ptr_alignment = info.alignment(mod); @@ -9954,7 +9918,7 @@ pub const FuncGen = struct { containing_int.setAlignment(ptr_alignment); containing_int.setVolatile(ptr_volatile); - const elem_bits = @intCast(c_uint, ptr_ty.elemType().bitSize(mod)); + const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod)); const shift_amt = containing_int.typeOf().constInt(info.bit_offset, .False); const shifted_value = self.builder.buildLShr(containing_int, shift_amt, ""); const elem_llvm_ty = try self.dg.lowerType(info.pointee_type); @@ -9992,9 +9956,9 @@ pub const FuncGen = struct { elem: *llvm.Value, ordering: llvm.AtomicOrdering, ) !void { - const info = ptr_ty.ptrInfo().data; - const elem_ty = info.pointee_type; const mod = self.dg.module; + const info = ptr_ty.ptrInfo(mod); + const elem_ty = info.pointee_type; if (!elem_ty.isFnOrHasRuntimeBitsIgnoreComptime(mod)) { return; } @@ -10026,7 +9990,7 @@ pub const FuncGen = struct { assert(ordering == .NotAtomic); containing_int.setAlignment(ptr_alignment); containing_int.setVolatile(ptr_volatile); - const elem_bits = @intCast(c_uint, ptr_ty.elemType().bitSize(mod)); + const elem_bits = @intCast(c_uint, ptr_ty.childType(mod).bitSize(mod)); const containing_int_ty = containing_int.typeOf(); const shift_amt = containing_int_ty.constInt(info.bit_offset, .False); // Convert to equally-sized integer type in order to perform the bit @@ -10864,8 +10828,7 @@ const ParamTypeIterator = struct { .Unspecified, .Inline => { it.zig_index += 1; it.llvm_index += 1; - var buf: Type.Payload.ElemType = undefined; - if (ty.isSlice(mod) or (ty.zigTypeTag(mod) == .Optional and ty.optionalChild(&buf).isSlice(mod))) { + if (ty.isSlice(mod) or (ty.zigTypeTag(mod) == .Optional and ty.optionalChild(mod).isSlice(mod))) { it.llvm_index += 1; return .slice; } else if (isByRef(ty, mod)) { @@ -11185,8 +11148,7 @@ fn isByRef(ty: Type, mod: *const Module) bool { return true; }, .Optional => { - var buf: Type.Payload.ElemType = undefined; - const payload_ty = ty.optionalChild(&buf); + const payload_ty = ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { return false; } diff --git a/src/codegen/spirv.zig b/src/codegen/spirv.zig index f69c6cb317..9de2c03142 100644 --- a/src/codegen/spirv.zig +++ b/src/codegen/spirv.zig @@ -625,20 +625,20 @@ pub const DeclGen = struct { .Array => switch (val.tag()) { .aggregate => { const elem_vals = val.castTag(.aggregate).?.data; - const elem_ty = ty.elemType(); - const len = @intCast(u32, ty.arrayLenIncludingSentinel()); // TODO: limit spir-v to 32 bit arrays in a more elegant way. + const elem_ty = ty.childType(mod); + const len = @intCast(u32, ty.arrayLenIncludingSentinel(mod)); // TODO: limit spir-v to 32 bit arrays in a more elegant way. for (elem_vals[0..len]) |elem_val| { try self.lower(elem_ty, elem_val); } }, .repeated => { const elem_val = val.castTag(.repeated).?.data; - const elem_ty = ty.elemType(); - const len = @intCast(u32, ty.arrayLen()); + const elem_ty = ty.childType(mod); + const len = @intCast(u32, ty.arrayLen(mod)); for (0..len) |_| { try self.lower(elem_ty, elem_val); } - if (ty.sentinel()) |sentinel| { + if (ty.sentinel(mod)) |sentinel| { try self.lower(elem_ty, sentinel); } }, @@ -646,7 +646,7 @@ pub const DeclGen = struct { const str_lit = val.castTag(.str_lit).?.data; const bytes = dg.module.string_literal_bytes.items[str_lit.index..][0..str_lit.len]; try self.addBytes(bytes); - if (ty.sentinel()) |sentinel| { + if (ty.sentinel(mod)) |sentinel| { try self.addByte(@intCast(u8, sentinel.toUnsignedInt(mod))); } }, @@ -706,8 +706,7 @@ pub const DeclGen = struct { } }, .Optional => { - var opt_buf: Type.Payload.ElemType = undefined; - const payload_ty = ty.optionalChild(&opt_buf); + const payload_ty = ty.optionalChild(mod); const has_payload = !val.isNull(mod); const abi_size = ty.abiSize(mod); @@ -1216,10 +1215,10 @@ pub const DeclGen = struct { return try self.spv.resolve(.{ .float_type = .{ .bits = bits } }); }, .Array => { - const elem_ty = ty.childType(); + const elem_ty = ty.childType(mod); const elem_ty_ref = try self.resolveType(elem_ty, .direct); - const total_len = std.math.cast(u32, ty.arrayLenIncludingSentinel()) orelse { - return self.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel()}); + const total_len = std.math.cast(u32, ty.arrayLenIncludingSentinel(mod)) orelse { + return self.fail("array type of {} elements is too large", .{ty.arrayLenIncludingSentinel(mod)}); }; return self.spv.arrayType(total_len, elem_ty_ref); }, @@ -1248,7 +1247,7 @@ pub const DeclGen = struct { }, }, .Pointer => { - const ptr_info = ty.ptrInfo().data; + const ptr_info = ty.ptrInfo(mod); const storage_class = spvStorageClass(ptr_info.@"addrspace"); const child_ty_ref = try self.resolveType(ptr_info.pointee_type, .indirect); @@ -1280,8 +1279,8 @@ pub const DeclGen = struct { // TODO: Properly verify sizes and child type. return try self.spv.resolve(.{ .vector_type = .{ - .component_type = try self.resolveType(ty.elemType(), repr), - .component_count = @intCast(u32, ty.vectorLen()), + .component_type = try self.resolveType(ty.childType(mod), repr), + .component_count = @intCast(u32, ty.vectorLen(mod)), } }); }, .Struct => { @@ -1335,8 +1334,7 @@ pub const DeclGen = struct { } }); }, .Optional => { - var buf: Type.Payload.ElemType = undefined; - const payload_ty = ty.optionalChild(&buf); + const payload_ty = ty.optionalChild(mod); if (!payload_ty.hasRuntimeBitsIgnoreComptime(mod)) { // Just use a bool. // Note: Always generate the bool with indirect format, to save on some sanity @@ -1685,7 +1683,8 @@ pub const DeclGen = struct { } fn load(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef) !IdRef { - const value_ty = ptr_ty.childType(); + const mod = self.module; + const value_ty = ptr_ty.childType(mod); const indirect_value_ty_ref = try self.resolveType(value_ty, .indirect); const result_id = self.spv.allocId(); const access = spec.MemoryAccess.Extended{ @@ -1701,7 +1700,8 @@ pub const DeclGen = struct { } fn store(self: *DeclGen, ptr_ty: Type, ptr_id: IdRef, value_id: IdRef) !void { - const value_ty = ptr_ty.childType(); + const mod = self.module; + const value_ty = ptr_ty.childType(mod); const indirect_value_id = try self.convertToIndirect(value_ty, value_id); const access = spec.MemoryAccess.Extended{ .Volatile = ptr_ty.isVolatilePtr(), @@ -2072,7 +2072,7 @@ pub const DeclGen = struct { const b = try self.resolve(extra.b); const mask = self.air.values[extra.mask]; const mask_len = extra.mask_len; - const a_len = self.typeOf(extra.a).vectorLen(); + const a_len = self.typeOf(extra.a).vectorLen(mod); const result_id = self.spv.allocId(); const result_type_id = try self.resolveTypeId(ty); @@ -2138,9 +2138,10 @@ pub const DeclGen = struct { } fn ptrAdd(self: *DeclGen, result_ty: Type, ptr_ty: Type, ptr_id: IdRef, offset_id: IdRef) !IdRef { + const mod = self.module; const result_ty_ref = try self.resolveType(result_ty, .direct); - switch (ptr_ty.ptrSize()) { + switch (ptr_ty.ptrSize(mod)) { .One => { // Pointer to array // TODO: Is this correct? @@ -2498,7 +2499,7 @@ pub const DeclGen = struct { // Construct new pointer type for the resulting pointer const elem_ty = ptr_ty.elemType2(mod); // use elemType() so that we get T for *[N]T. const elem_ty_ref = try self.resolveType(elem_ty, .direct); - const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, spvStorageClass(ptr_ty.ptrAddressSpace())); + const elem_ptr_ty_ref = try self.spv.ptrType(elem_ty_ref, spvStorageClass(ptr_ty.ptrAddressSpace(mod))); if (ptr_ty.isSinglePointer(mod)) { // Pointer-to-array. In this case, the resulting pointer is not of the same type // as the ptr_ty (we want a *T, not a *[N]T), and hence we need to use accessChain. @@ -2516,7 +2517,7 @@ pub const DeclGen = struct { const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; const ptr_ty = self.typeOf(bin_op.lhs); - const elem_ty = ptr_ty.childType(); + const elem_ty = ptr_ty.childType(mod); // TODO: Make this return a null ptr or something if (!elem_ty.hasRuntimeBitsIgnoreComptime(mod)) return null; @@ -2526,6 +2527,7 @@ pub const DeclGen = struct { } fn airPtrElemVal(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { + const mod = self.module; const bin_op = self.air.instructions.items(.data)[inst].bin_op; const ptr_ty = self.typeOf(bin_op.lhs); const ptr_id = try self.resolve(bin_op.lhs); @@ -2536,9 +2538,9 @@ pub const DeclGen = struct { // If we have a pointer-to-array, construct an element pointer to use with load() // If we pass ptr_ty directly, it will attempt to load the entire array rather than // just an element. - var elem_ptr_info = ptr_ty.ptrInfo(); - elem_ptr_info.data.size = .One; - const elem_ptr_ty = Type.initPayload(&elem_ptr_info.base); + var elem_ptr_info = ptr_ty.ptrInfo(mod); + elem_ptr_info.size = .One; + const elem_ptr_ty = try Type.ptr(undefined, mod, elem_ptr_info); return try self.load(elem_ptr_ty, elem_ptr_id); } @@ -2586,7 +2588,7 @@ pub const DeclGen = struct { field_index: u32, ) !?IdRef { const mod = self.module; - const object_ty = object_ptr_ty.childType(); + const object_ty = object_ptr_ty.childType(mod); switch (object_ty.zigTypeTag(mod)) { .Struct => switch (object_ty.containerLayout()) { .Packed => unreachable, // TODO @@ -2662,9 +2664,10 @@ pub const DeclGen = struct { fn airAlloc(self: *DeclGen, inst: Air.Inst.Index) !?IdRef { if (self.liveness.isUnused(inst)) return null; + const mod = self.module; const ptr_ty = self.typeOfIndex(inst); - assert(ptr_ty.ptrAddressSpace() == .generic); - const child_ty = ptr_ty.childType(); + assert(ptr_ty.ptrAddressSpace(mod) == .generic); + const child_ty = ptr_ty.childType(mod); const child_ty_ref = try self.resolveType(child_ty, .indirect); return try self.alloc(child_ty_ref, null); } @@ -2834,7 +2837,7 @@ pub const DeclGen = struct { const mod = self.module; const un_op = self.air.instructions.items(.data)[inst].un_op; const ptr_ty = self.typeOf(un_op); - const ret_ty = ptr_ty.childType(); + const ret_ty = ptr_ty.childType(mod); if (!ret_ty.hasRuntimeBitsIgnoreComptime(mod)) { try self.func.body.emit(self.spv.gpa, .OpReturn, {}); @@ -2971,8 +2974,7 @@ pub const DeclGen = struct { const operand_id = try self.resolve(un_op); const optional_ty = self.typeOf(un_op); - var buf: Type.Payload.ElemType = undefined; - const payload_ty = optional_ty.optionalChild(&buf); + const payload_ty = optional_ty.optionalChild(mod); const bool_ty_ref = try self.resolveType(Type.bool, .direct); diff --git a/src/codegen/spirv/Module.zig b/src/codegen/spirv/Module.zig index 1d4840aeb7..c5ba429ec9 100644 --- a/src/codegen/spirv/Module.zig +++ b/src/codegen/spirv/Module.zig @@ -11,7 +11,8 @@ const std = @import("std"); const Allocator = std.mem.Allocator; const assert = std.debug.assert; -const ZigDecl = @import("../../Module.zig").Decl; +const ZigModule = @import("../../Module.zig"); +const ZigDecl = ZigModule.Decl; const spec = @import("spec.zig"); const Word = spec.Word; diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index 682431203e..178f9fa64c 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -219,8 +219,7 @@ pub const DeclState = struct { try dbg_info_buffer.writer().print("{}\x00", .{ty.fmt(mod)}); } else { // Non-pointer optionals are structs: struct { .maybe = *, .val = * } - var buf = try arena.create(Type.Payload.ElemType); - const payload_ty = ty.optionalChild(buf); + const payload_ty = ty.optionalChild(mod); // DW.AT.structure_type try dbg_info_buffer.append(@enumToInt(AbbrevKind.struct_type)); // DW.AT.byte_size, DW.FORM.udata @@ -304,7 +303,7 @@ pub const DeclState = struct { // DW.AT.type, DW.FORM.ref4 const index = dbg_info_buffer.items.len; try dbg_info_buffer.resize(index + 4); - try self.addTypeRelocGlobal(atom_index, ty.childType(), @intCast(u32, index)); + try self.addTypeRelocGlobal(atom_index, ty.childType(mod), @intCast(u32, index)); } }, .Array => { @@ -315,7 +314,7 @@ pub const DeclState = struct { // DW.AT.type, DW.FORM.ref4 var index = dbg_info_buffer.items.len; try dbg_info_buffer.resize(index + 4); - try self.addTypeRelocGlobal(atom_index, ty.childType(), @intCast(u32, index)); + try self.addTypeRelocGlobal(atom_index, ty.childType(mod), @intCast(u32, index)); // DW.AT.subrange_type try dbg_info_buffer.append(@enumToInt(AbbrevKind.array_dim)); // DW.AT.type, DW.FORM.ref4 @@ -323,7 +322,7 @@ pub const DeclState = struct { try dbg_info_buffer.resize(index + 4); try self.addTypeRelocGlobal(atom_index, Type.usize, @intCast(u32, index)); // DW.AT.count, DW.FORM.udata - const len = ty.arrayLenIncludingSentinel(); + const len = ty.arrayLenIncludingSentinel(mod); try leb128.writeULEB128(dbg_info_buffer.writer(), len); // DW.AT.array_type delimit children try dbg_info_buffer.append(0); @@ -688,7 +687,7 @@ pub const DeclState = struct { const mod = self.mod; const target = mod.getTarget(); const endian = target.cpu.arch.endian(); - const child_ty = if (is_ptr) ty.childType() else ty; + const child_ty = if (is_ptr) ty.childType(mod) else ty; switch (loc) { .register => |reg| { diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 0154207368..fb7ca3a87f 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -2931,7 +2931,7 @@ pub fn getErrorTableSymbol(wasm: *Wasm) !u32 { const atom_index = try wasm.createAtom(); const atom = wasm.getAtomPtr(atom_index); - const slice_ty = Type.initTag(.const_slice_u8_sentinel_0); + const slice_ty = Type.const_slice_u8_sentinel_0; const mod = wasm.base.options.module.?; atom.alignment = slice_ty.abiAlignment(mod); const sym_index = atom.sym_index; @@ -2988,7 +2988,7 @@ fn populateErrorNameTable(wasm: *Wasm) !void { for (mod.error_name_list.items) |error_name| { const len = @intCast(u32, error_name.len + 1); // names are 0-termianted - const slice_ty = Type.initTag(.const_slice_u8_sentinel_0); + const slice_ty = Type.const_slice_u8_sentinel_0; const offset = @intCast(u32, atom.code.items.len); // first we create the data for the slice of the name try atom.code.appendNTimes(wasm.base.allocator, 0, 4); // ptr to name, will be relocated diff --git a/src/print_air.zig b/src/print_air.zig index f4a1aeae32..8717bdc6bf 100644 --- a/src/print_air.zig +++ b/src/print_air.zig @@ -433,9 +433,10 @@ const Writer = struct { } fn writeAggregateInit(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + const mod = w.module; const ty_pl = w.air.instructions.items(.data)[inst].ty_pl; const vector_ty = w.air.getRefType(ty_pl.ty); - const len = @intCast(usize, vector_ty.arrayLen()); + const len = @intCast(usize, vector_ty.arrayLen(mod)); const elements = @ptrCast([]const Air.Inst.Ref, w.air.extra[ty_pl.payload..][0..len]); try w.writeType(s, vector_ty); @@ -512,10 +513,11 @@ const Writer = struct { } fn writeSelect(w: *Writer, s: anytype, inst: Air.Inst.Index) @TypeOf(s).Error!void { + const mod = w.module; const pl_op = w.air.instructions.items(.data)[inst].pl_op; const extra = w.air.extraData(Air.Bin, pl_op.payload).data; - const elem_ty = w.typeOfIndex(inst).childType(); + const elem_ty = w.typeOfIndex(inst).childType(mod); try w.writeType(s, elem_ty); try s.writeAll(", "); try w.writeOperand(s, inst, 0, pl_op.operand); diff --git a/src/type.zig b/src/type.zig index 868ae4231b..1f970919c9 100644 --- a/src/type.zig +++ b/src/type.zig @@ -40,7 +40,7 @@ pub const Type = struct { .ptr_type => return .Pointer, .array_type => return .Array, .vector_type => return .Vector, - .optional_type => return .Optional, + .opt_type => return .Optional, .error_union_type => return .ErrorUnion, .struct_type => return .Struct, .union_type => return .Union, @@ -118,38 +118,17 @@ pub const Type = struct { .function => return .Fn, .array, - .array_u8_sentinel_0, - .array_u8, .array_sentinel, => return .Array, - .vector => return .Vector, - - .single_const_pointer_to_comptime_int, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, .pointer, .inferred_alloc_const, .inferred_alloc_mut, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, => return .Pointer, - .optional, - .optional_single_const_pointer, - .optional_single_mut_pointer, - => return .Optional, + .optional => return .Optional, - .anyerror_void_error_union, .error_union => return .ErrorUnion, + .error_union => return .ErrorUnion, .anyframe_T => return .AnyFrame, @@ -177,8 +156,7 @@ pub const Type = struct { return switch (self.zigTypeTag(mod)) { .ErrorUnion => self.errorUnionPayload().baseZigTypeTag(mod), .Optional => { - var buf: Payload.ElemType = undefined; - return self.optionalChild(&buf).baseZigTypeTag(mod); + return self.optionalChild(mod).baseZigTypeTag(mod); }, else => |t| t, }; @@ -218,8 +196,7 @@ pub const Type = struct { .Pointer => !ty.isSlice(mod) and (is_equality_cmp or ty.isCPtr()), .Optional => { if (!is_equality_cmp) return false; - var buf: Payload.ElemType = undefined; - return ty.optionalChild(&buf).isSelfComparable(mod, is_equality_cmp); + return ty.optionalChild(mod).isSelfComparable(mod, is_equality_cmp); }, }; } @@ -275,9 +252,8 @@ pub const Type = struct { } pub fn castTag(self: Type, comptime t: Tag) ?*t.Type() { - if (self.ip_index != .none) { - return null; - } + assert(self.ip_index == .none); + if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) return null; @@ -287,281 +263,61 @@ pub const Type = struct { return null; } - pub fn castPointer(self: Type) ?*Payload.ElemType { - return switch (self.tag()) { - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, - .optional_single_const_pointer, - .optional_single_mut_pointer, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - => self.cast(Payload.ElemType), - - .inferred_alloc_const => unreachable, - .inferred_alloc_mut => unreachable, - - else => null, - }; - } - /// If it is a function pointer, returns the function type. Otherwise returns null. pub fn castPtrToFn(ty: Type, mod: *const Module) ?Type { if (ty.zigTypeTag(mod) != .Pointer) return null; - const elem_ty = ty.childType(); + const elem_ty = ty.childType(mod); if (elem_ty.zigTypeTag(mod) != .Fn) return null; return elem_ty; } - pub fn ptrIsMutable(ty: Type) bool { - return switch (ty.tag()) { - .single_const_pointer_to_comptime_int, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .single_const_pointer, - .many_const_pointer, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - .c_const_pointer, - .const_slice, - => false, - - .single_mut_pointer, - .many_mut_pointer, - .manyptr_u8, - .c_mut_pointer, - .mut_slice, - => true, - - .pointer => ty.castTag(.pointer).?.data.mutable, - - else => unreachable, + pub fn ptrIsMutable(ty: Type, mod: *const Module) bool { + return switch (ty.ip_index) { + .none => switch (ty.tag()) { + .pointer => ty.castTag(.pointer).?.data.mutable, + else => unreachable, + }, + else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { + .ptr_type => |ptr_type| !ptr_type.is_const, + else => unreachable, + }, }; } - pub const ArrayInfo = struct { elem_type: Type, sentinel: ?Value = null, len: u64 }; - pub fn arrayInfo(self: Type) ArrayInfo { + pub const ArrayInfo = struct { + elem_type: Type, + sentinel: ?Value = null, + len: u64, + }; + + pub fn arrayInfo(self: Type, mod: *const Module) ArrayInfo { return .{ - .len = self.arrayLen(), - .sentinel = self.sentinel(), - .elem_type = self.elemType(), + .len = self.arrayLen(mod), + .sentinel = self.sentinel(mod), + .elem_type = self.childType(mod), }; } - pub fn ptrInfo(self: Type) Payload.Pointer { - switch (self.ip_index) { - .none => switch (self.tag()) { - .single_const_pointer_to_comptime_int => return .{ .data = .{ - .pointee_type = Type.comptime_int, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = false, - .@"volatile" = false, - .size = .One, - } }, - .const_slice_u8 => return .{ .data = .{ - .pointee_type = Type.u8, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = false, - .@"volatile" = false, - .size = .Slice, - } }, - .const_slice_u8_sentinel_0 => return .{ .data = .{ - .pointee_type = Type.u8, - .sentinel = Value.zero, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = false, - .@"volatile" = false, - .size = .Slice, - } }, - .single_const_pointer => return .{ .data = .{ - .pointee_type = self.castPointer().?.data, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = false, - .@"volatile" = false, - .size = .One, - } }, - .single_mut_pointer => return .{ .data = .{ - .pointee_type = self.castPointer().?.data, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = true, - .@"volatile" = false, - .size = .One, - } }, - .many_const_pointer => return .{ .data = .{ - .pointee_type = self.castPointer().?.data, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = false, - .@"volatile" = false, - .size = .Many, - } }, - .manyptr_const_u8 => return .{ .data = .{ - .pointee_type = Type.u8, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = false, - .@"volatile" = false, - .size = .Many, - } }, - .manyptr_const_u8_sentinel_0 => return .{ .data = .{ - .pointee_type = Type.u8, - .sentinel = Value.zero, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = false, - .@"volatile" = false, - .size = .Many, - } }, - .many_mut_pointer => return .{ .data = .{ - .pointee_type = self.castPointer().?.data, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = true, - .@"volatile" = false, - .size = .Many, - } }, - .manyptr_u8 => return .{ .data = .{ - .pointee_type = Type.u8, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = true, - .@"volatile" = false, - .size = .Many, - } }, - .c_const_pointer => return .{ .data = .{ - .pointee_type = self.castPointer().?.data, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = true, - .mutable = false, - .@"volatile" = false, - .size = .C, - } }, - .c_mut_pointer => return .{ .data = .{ - .pointee_type = self.castPointer().?.data, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = true, - .mutable = true, - .@"volatile" = false, - .size = .C, - } }, - .const_slice => return .{ .data = .{ - .pointee_type = self.castPointer().?.data, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = false, - .@"volatile" = false, - .size = .Slice, - } }, - .mut_slice => return .{ .data = .{ - .pointee_type = self.castPointer().?.data, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = true, - .@"volatile" = false, - .size = .Slice, - } }, - - .pointer => return self.castTag(.pointer).?.*, - - .optional_single_mut_pointer => return .{ .data = .{ - .pointee_type = self.castPointer().?.data, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = true, - .@"volatile" = false, - .size = .One, - } }, - .optional_single_const_pointer => return .{ .data = .{ - .pointee_type = self.castPointer().?.data, - .sentinel = null, - .@"align" = 0, - .@"addrspace" = .generic, - .bit_offset = 0, - .host_size = 0, - .@"allowzero" = false, - .mutable = false, - .@"volatile" = false, - .size = .One, - } }, - .optional => { - var buf: Payload.ElemType = undefined; - const child_type = self.optionalChild(&buf); - return child_type.ptrInfo(); + pub fn ptrInfo(ty: Type, mod: *const Module) Payload.Pointer.Data { + return switch (ty.ip_index) { + .none => switch (ty.tag()) { + .pointer => ty.castTag(.pointer).?.data, + .optional => b: { + const child_type = ty.optionalChild(mod); + break :b child_type.ptrInfo(mod); }, else => unreachable, }, - else => @panic("TODO"), - } + else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { + .ptr_type => |p| Payload.Pointer.Data.fromKey(p), + .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { + .ptr_type => |p| Payload.Pointer.Data.fromKey(p), + else => unreachable, + }, + else => unreachable, + }, + }; } pub fn eql(a: Type, b: Type, mod: *Module) bool { @@ -658,20 +414,17 @@ pub const Type = struct { }, .array, - .array_u8_sentinel_0, - .array_u8, .array_sentinel, - .vector, => { if (a.zigTypeTag(mod) != b.zigTypeTag(mod)) return false; - if (a.arrayLen() != b.arrayLen()) + if (a.arrayLen(mod) != b.arrayLen(mod)) return false; - const elem_ty = a.elemType(); - if (!elem_ty.eql(b.elemType(), mod)) + const elem_ty = a.childType(mod); + if (!elem_ty.eql(b.childType(mod), mod)) return false; - const sentinel_a = a.sentinel(); - const sentinel_b = b.sentinel(); + const sentinel_a = a.sentinel(mod); + const sentinel_b = b.sentinel(mod); if (sentinel_a) |sa| { if (sentinel_b) |sb| { return sa.eql(sb, elem_ty, mod); @@ -683,28 +436,14 @@ pub const Type = struct { } }, - .single_const_pointer_to_comptime_int, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, .pointer, .inferred_alloc_const, .inferred_alloc_mut, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, => { if (b.zigTypeTag(mod) != .Pointer) return false; - const info_a = a.ptrInfo().data; - const info_b = b.ptrInfo().data; + const info_a = a.ptrInfo(mod); + const info_b = b.ptrInfo(mod); if (!info_a.pointee_type.eql(info_b.pointee_type, mod)) return false; if (info_a.@"align" != info_b.@"align") @@ -743,18 +482,13 @@ pub const Type = struct { return true; }, - .optional, - .optional_single_const_pointer, - .optional_single_mut_pointer, - => { + .optional => { if (b.zigTypeTag(mod) != .Optional) return false; - var buf_a: Payload.ElemType = undefined; - var buf_b: Payload.ElemType = undefined; - return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b), mod); + return a.optionalChild(mod).eql(b.optionalChild(mod), mod); }, - .anyerror_void_error_union, .error_union => { + .error_union => { if (b.zigTypeTag(mod) != .ErrorUnion) return false; const a_set = a.errorUnionSet(); @@ -947,47 +681,23 @@ pub const Type = struct { }, .array, - .array_u8_sentinel_0, - .array_u8, .array_sentinel, => { std.hash.autoHash(hasher, std.builtin.TypeId.Array); - const elem_ty = ty.elemType(); - std.hash.autoHash(hasher, ty.arrayLen()); + const elem_ty = ty.childType(mod); + std.hash.autoHash(hasher, ty.arrayLen(mod)); hashWithHasher(elem_ty, hasher, mod); - hashSentinel(ty.sentinel(), elem_ty, hasher, mod); + hashSentinel(ty.sentinel(mod), elem_ty, hasher, mod); }, - .vector => { - std.hash.autoHash(hasher, std.builtin.TypeId.Vector); - - const elem_ty = ty.elemType(); - std.hash.autoHash(hasher, ty.vectorLen()); - hashWithHasher(elem_ty, hasher, mod); - }, - - .single_const_pointer_to_comptime_int, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, .pointer, .inferred_alloc_const, .inferred_alloc_mut, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, => { std.hash.autoHash(hasher, std.builtin.TypeId.Pointer); - const info = ty.ptrInfo().data; + const info = ty.ptrInfo(mod); hashWithHasher(info.pointee_type, hasher, mod); hashSentinel(info.sentinel, info.pointee_type, hasher, mod); std.hash.autoHash(hasher, info.@"align"); @@ -1001,17 +711,13 @@ pub const Type = struct { std.hash.autoHash(hasher, info.size); }, - .optional, - .optional_single_const_pointer, - .optional_single_mut_pointer, - => { + .optional => { std.hash.autoHash(hasher, std.builtin.TypeId.Optional); - var buf: Payload.ElemType = undefined; - hashWithHasher(ty.optionalChild(&buf), hasher, mod); + hashWithHasher(ty.optionalChild(mod), hasher, mod); }, - .anyerror_void_error_union, .error_union => { + .error_union => { std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion); const set_ty = ty.errorUnionSet(); @@ -1023,7 +729,7 @@ pub const Type = struct { .anyframe_T => { std.hash.autoHash(hasher, std.builtin.TypeId.AnyFrame); - hashWithHasher(ty.childType(), hasher, mod); + hashWithHasher(ty.childType(mod), hasher, mod); }, .empty_struct => { @@ -1129,33 +835,12 @@ pub const Type = struct { .legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough }, }; } else switch (self.legacy.ptr_otherwise.tag) { - .single_const_pointer_to_comptime_int, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .anyerror_void_error_union, .inferred_alloc_const, .inferred_alloc_mut, .empty_struct_literal, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, => unreachable, - .array_u8, - .array_u8_sentinel_0, - => return self.copyPayloadShallow(allocator, Payload.Len), - - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, .optional, - .optional_single_mut_pointer, - .optional_single_const_pointer, .anyframe_T, => { const payload = self.cast(Payload.ElemType).?; @@ -1170,13 +855,6 @@ pub const Type = struct { }; }, - .vector => { - const payload = self.castTag(.vector).?.data; - return Tag.vector.create(allocator, .{ - .len = payload.len, - .elem_type = try payload.elem_type.copy(allocator), - }); - }, .array => { const payload = self.castTag(.array).?.data; return Tag.array.create(allocator, .{ @@ -1408,13 +1086,6 @@ pub const Type = struct { }); }, - .anyerror_void_error_union => return writer.writeAll("anyerror!void"), - .const_slice_u8 => return writer.writeAll("[]const u8"), - .const_slice_u8_sentinel_0 => return writer.writeAll("[:0]const u8"), - .single_const_pointer_to_comptime_int => return writer.writeAll("*const comptime_int"), - .manyptr_u8 => return writer.writeAll("[*]u8"), - .manyptr_const_u8 => return writer.writeAll("[*]const u8"), - .manyptr_const_u8_sentinel_0 => return writer.writeAll("[*:0]const u8"), .function => { const payload = ty.castTag(.function).?.data; try writer.writeAll("fn("); @@ -1447,20 +1118,6 @@ pub const Type = struct { ty = return_type; continue; }, - .array_u8 => { - const len = ty.castTag(.array_u8).?.data; - return writer.print("[{d}]u8", .{len}); - }, - .array_u8_sentinel_0 => { - const len = ty.castTag(.array_u8_sentinel_0).?.data; - return writer.print("[{d}:0]u8", .{len}); - }, - .vector => { - const payload = ty.castTag(.vector).?.data; - try writer.print("@Vector({d}, ", .{payload.len}); - try payload.elem_type.dump("", .{}, writer); - return writer.writeAll(")"); - }, .array => { const payload = ty.castTag(.array).?.data; try writer.print("[{d}]", .{payload.len}); @@ -1512,72 +1169,12 @@ pub const Type = struct { try writer.writeAll("}"); return; }, - .single_const_pointer => { - const pointee_type = ty.castTag(.single_const_pointer).?.data; - try writer.writeAll("*const "); - ty = pointee_type; - continue; - }, - .single_mut_pointer => { - const pointee_type = ty.castTag(.single_mut_pointer).?.data; - try writer.writeAll("*"); - ty = pointee_type; - continue; - }, - .many_const_pointer => { - const pointee_type = ty.castTag(.many_const_pointer).?.data; - try writer.writeAll("[*]const "); - ty = pointee_type; - continue; - }, - .many_mut_pointer => { - const pointee_type = ty.castTag(.many_mut_pointer).?.data; - try writer.writeAll("[*]"); - ty = pointee_type; - continue; - }, - .c_const_pointer => { - const pointee_type = ty.castTag(.c_const_pointer).?.data; - try writer.writeAll("[*c]const "); - ty = pointee_type; - continue; - }, - .c_mut_pointer => { - const pointee_type = ty.castTag(.c_mut_pointer).?.data; - try writer.writeAll("[*c]"); - ty = pointee_type; - continue; - }, - .const_slice => { - const pointee_type = ty.castTag(.const_slice).?.data; - try writer.writeAll("[]const "); - ty = pointee_type; - continue; - }, - .mut_slice => { - const pointee_type = ty.castTag(.mut_slice).?.data; - try writer.writeAll("[]"); - ty = pointee_type; - continue; - }, .optional => { const child_type = ty.castTag(.optional).?.data; try writer.writeByte('?'); ty = child_type; continue; }, - .optional_single_const_pointer => { - const pointee_type = ty.castTag(.optional_single_const_pointer).?.data; - try writer.writeAll("?*const "); - ty = pointee_type; - continue; - }, - .optional_single_mut_pointer => { - const pointee_type = ty.castTag(.optional_single_mut_pointer).?.data; - try writer.writeAll("?*"); - ty = pointee_type; - continue; - }, .pointer => { const payload = ty.castTag(.pointer).?.data; @@ -1680,7 +1277,7 @@ pub const Type = struct { .ptr_type => @panic("TODO"), .array_type => @panic("TODO"), .vector_type => @panic("TODO"), - .optional_type => @panic("TODO"), + .opt_type => @panic("TODO"), .error_union_type => @panic("TODO"), .simple_type => |s| return writer.writeAll(@tagName(s)), .struct_type => @panic("TODO"), @@ -1733,14 +1330,6 @@ pub const Type = struct { try decl.renderFullyQualifiedName(mod, writer); }, - .anyerror_void_error_union => try writer.writeAll("anyerror!void"), - .const_slice_u8 => try writer.writeAll("[]const u8"), - .const_slice_u8_sentinel_0 => try writer.writeAll("[:0]const u8"), - .single_const_pointer_to_comptime_int => try writer.writeAll("*const comptime_int"), - .manyptr_u8 => try writer.writeAll("[*]u8"), - .manyptr_const_u8 => try writer.writeAll("[*]const u8"), - .manyptr_const_u8_sentinel_0 => try writer.writeAll("[*:0]const u8"), - .error_set_inferred => { const func = ty.castTag(.error_set_inferred).?.data.func; @@ -1799,20 +1388,6 @@ pub const Type = struct { try print(error_union.payload, writer, mod); }, - .array_u8 => { - const len = ty.castTag(.array_u8).?.data; - try writer.print("[{d}]u8", .{len}); - }, - .array_u8_sentinel_0 => { - const len = ty.castTag(.array_u8_sentinel_0).?.data; - try writer.print("[{d}:0]u8", .{len}); - }, - .vector => { - const payload = ty.castTag(.vector).?.data; - try writer.print("@Vector({d}, ", .{payload.len}); - try print(payload.elem_type, writer, mod); - try writer.writeAll(")"); - }, .array => { const payload = ty.castTag(.array).?.data; try writer.print("[{d}]", .{payload.len}); @@ -1865,17 +1440,8 @@ pub const Type = struct { try writer.writeAll("}"); }, - .pointer, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, - => { - const info = ty.ptrInfo().data; + .pointer => { + const info = ty.ptrInfo(mod); if (info.sentinel) |s| switch (info.size) { .One, .C => unreachable, @@ -1920,16 +1486,6 @@ pub const Type = struct { try writer.writeByte('?'); try print(child_type, writer, mod); }, - .optional_single_mut_pointer => { - const pointee_type = ty.castTag(.optional_single_mut_pointer).?.data; - try writer.writeAll("?*"); - try print(pointee_type, writer, mod); - }, - .optional_single_const_pointer => { - const pointee_type = ty.castTag(.optional_single_const_pointer).?.data; - try writer.writeAll("?*const "); - try print(pointee_type, writer, mod); - }, .anyframe_T => { const return_type = ty.castTag(.anyframe_T).?.data; try writer.print("anyframe->", .{}); @@ -1963,12 +1519,6 @@ pub const Type = struct { pub fn toValue(self: Type, allocator: Allocator) Allocator.Error!Value { if (self.ip_index != .none) return self.ip_index.toValue(); switch (self.tag()) { - .single_const_pointer_to_comptime_int => return Value{ .ip_index = .single_const_pointer_to_comptime_int_type, .legacy = undefined }, - .const_slice_u8 => return Value{ .ip_index = .const_slice_u8_type, .legacy = undefined }, - .const_slice_u8_sentinel_0 => return Value{ .ip_index = .const_slice_u8_sentinel_0_type, .legacy = undefined }, - .manyptr_u8 => return Value{ .ip_index = .manyptr_u8_type, .legacy = undefined }, - .manyptr_const_u8 => return Value{ .ip_index = .manyptr_const_u8_type, .legacy = undefined }, - .manyptr_const_u8_sentinel_0 => return Value{ .ip_index = .manyptr_const_u8_sentinel_0_type, .legacy = undefined }, .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, else => return Value.Tag.ty.create(allocator, self), @@ -1996,10 +1546,41 @@ pub const Type = struct { ) RuntimeBitsError!bool { if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) { .int_type => |int_type| return int_type.bits != 0, - .ptr_type => @panic("TODO"), - .array_type => @panic("TODO"), - .vector_type => @panic("TODO"), - .optional_type => @panic("TODO"), + .ptr_type => |ptr_type| { + // Pointers to zero-bit types still have a runtime address; however, pointers + // to comptime-only types do not, with the exception of function pointers. + if (ignore_comptime_only) return true; + const child_ty = ptr_type.elem_type.toType(); + if (child_ty.zigTypeTag(mod) == .Fn) return !child_ty.fnInfo().is_generic; + if (strat == .sema) return !(try strat.sema.typeRequiresComptime(ty)); + return !comptimeOnly(ty, mod); + }, + .array_type => |array_type| { + if (array_type.sentinel != .none) { + return array_type.child.toType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat); + } else { + return array_type.len > 0 and + try array_type.child.toType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat); + } + }, + .vector_type => |vector_type| { + return vector_type.len > 0 and + try vector_type.child.toType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat); + }, + .opt_type => |child| { + const child_ty = child.toType(); + if (child_ty.isNoReturn()) { + // Then the optional is comptime-known to be null. + return false; + } + if (ignore_comptime_only) { + return true; + } else if (strat == .sema) { + return !(try strat.sema.typeRequiresComptime(child_ty)); + } else { + return !comptimeOnly(child_ty, mod); + } + }, .error_union_type => @panic("TODO"), .simple_type => |t| return switch (t) { .f16, @@ -2058,14 +1639,7 @@ pub const Type = struct { .enum_tag => unreachable, // it's a value, not a type }; switch (ty.tag()) { - .const_slice_u8, - .const_slice_u8_sentinel_0, - .array_u8_sentinel_0, - .anyerror_void_error_union, .error_set_inferred, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, .@"opaque", .error_set_single, @@ -2077,22 +1651,12 @@ pub const Type = struct { // Pointers to zero-bit types still have a runtime address; however, pointers // to comptime-only types do not, with the exception of function pointers. .anyframe_T, - .optional_single_mut_pointer, - .optional_single_const_pointer, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, .pointer, => { if (ignore_comptime_only) { return true; - } else if (ty.childType().zigTypeTag(mod) == .Fn) { - return !ty.childType().fnInfo().is_generic; + } else if (ty.childType(mod).zigTypeTag(mod) == .Fn) { + return !ty.childType(mod).fnInfo().is_generic; } else if (strat == .sema) { return !(try strat.sema.typeRequiresComptime(ty)); } else { @@ -2101,7 +1665,6 @@ pub const Type = struct { }, // These are false because they are comptime-only types. - .single_const_pointer_to_comptime_int, .empty_struct, .empty_struct_literal, // These are function *bodies*, not pointers. @@ -2111,8 +1674,7 @@ pub const Type = struct { => return false, .optional => { - var buf: Payload.ElemType = undefined; - const child_ty = ty.optionalChild(&buf); + const child_ty = ty.optionalChild(mod); if (child_ty.isNoReturn()) { // Then the optional is comptime-known to be null. return false; @@ -2200,10 +1762,9 @@ pub const Type = struct { } }, - .array, .vector => return ty.arrayLen() != 0 and - try ty.elemType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat), - .array_u8 => return ty.arrayLen() != 0, - .array_sentinel => return ty.childType().hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat), + .array => return ty.arrayLen(mod) != 0 and + try ty.childType(mod).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat), + .array_sentinel => return ty.childType(mod).hasRuntimeBitsAdvanced(mod, ignore_comptime_only, strat), .tuple, .anon_struct => { const tuple = ty.tupleFields(); @@ -2224,14 +1785,14 @@ pub const Type = struct { /// readFrom/writeToMemory are supported only for types with a well- /// defined memory layout pub fn hasWellDefinedLayout(ty: Type, mod: *const Module) bool { - if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) { - .int_type => return true, - .ptr_type => @panic("TODO"), - .array_type => @panic("TODO"), - .vector_type => @panic("TODO"), - .optional_type => @panic("TODO"), - .error_union_type => @panic("TODO"), - .simple_type => |t| return switch (t) { + if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) { + .int_type => true, + .ptr_type => true, + .array_type => |array_type| array_type.child.toType().hasWellDefinedLayout(mod), + .vector_type => true, + .opt_type => |child| child.toType().isPtrLikeOptional(mod), + .error_union_type => false, + .simple_type => |t| switch (t) { .f16, .f32, .f64, @@ -2287,23 +1848,8 @@ pub const Type = struct { .enum_tag => unreachable, // it's a value, not a type }; return switch (ty.tag()) { - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - .array_u8, - .array_u8_sentinel_0, .pointer, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .single_const_pointer_to_comptime_int, .enum_numbered, - .vector, - .optional_single_mut_pointer, - .optional_single_const_pointer, => true, .error_set, @@ -2313,13 +1859,8 @@ pub const Type = struct { .@"opaque", // These are function bodies, not function pointers. .function, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .const_slice, - .mut_slice, .enum_simple, .error_union, - .anyerror_void_error_union, .anyframe_T, .tuple, .anon_struct, @@ -2336,7 +1877,7 @@ pub const Type = struct { .array, .array_sentinel, - => ty.childType().hasWellDefinedLayout(mod), + => ty.childType(mod).hasWellDefinedLayout(mod), .optional => ty.isPtrLikeOptional(mod), .@"struct" => ty.castTag(.@"struct").?.data.layout != .Auto, @@ -2417,76 +1958,36 @@ pub const Type = struct { } pub fn ptrAlignmentAdvanced(ty: Type, mod: *const Module, opt_sema: ?*Sema) !u32 { - switch (ty.tag()) { - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, - .optional_single_const_pointer, - .optional_single_mut_pointer, - => { - const child_type = ty.cast(Payload.ElemType).?.data; - if (opt_sema) |sema| { - const res = try child_type.abiAlignmentAdvanced(mod, .{ .sema = sema }); - return res.scalar; - } - return (child_type.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; + switch (ty.ip_index) { + .none => switch (ty.tag()) { + .pointer => { + const ptr_info = ty.castTag(.pointer).?.data; + if (ptr_info.@"align" != 0) { + return ptr_info.@"align"; + } else if (opt_sema) |sema| { + const res = try ptr_info.pointee_type.abiAlignmentAdvanced(mod, .{ .sema = sema }); + return res.scalar; + } else { + return (ptr_info.pointee_type.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; + } + }, + .optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(mod, opt_sema), + + else => unreachable, }, - - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - .const_slice_u8, - .const_slice_u8_sentinel_0, - => return 1, - - .pointer => { - const ptr_info = ty.castTag(.pointer).?.data; - if (ptr_info.@"align" != 0) { - return ptr_info.@"align"; - } else if (opt_sema) |sema| { - const res = try ptr_info.pointee_type.abiAlignmentAdvanced(mod, .{ .sema = sema }); - return res.scalar; - } else { - return (ptr_info.pointee_type.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar; - } + else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { + else => @panic("TODO"), }, - .optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(mod, opt_sema), - - else => unreachable, } } - pub fn ptrAddressSpace(self: Type) std.builtin.AddressSpace { + pub fn ptrAddressSpace(self: Type, mod: *const Module) std.builtin.AddressSpace { return switch (self.tag()) { - .single_const_pointer_to_comptime_int, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, - .inferred_alloc_const, - .inferred_alloc_mut, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - => .generic, - .pointer => self.castTag(.pointer).?.data.@"addrspace", .optional => { - var buf: Payload.ElemType = undefined; - const child_type = self.optionalChild(&buf); - return child_type.ptrAddressSpace(); + const child_type = self.optionalChild(mod); + return child_type.ptrAddressSpace(mod); }, else => unreachable, @@ -2530,15 +2031,31 @@ pub const Type = struct { ) Module.CompileError!AbiAlignmentAdvanced { const target = mod.getTarget(); + const opt_sema = switch (strat) { + .sema => |sema| sema, + else => null, + }; + if (ty.ip_index != .none) switch (mod.intern_pool.indexToKey(ty.ip_index)) { .int_type => |int_type| { if (int_type.bits == 0) return AbiAlignmentAdvanced{ .scalar = 0 }; return AbiAlignmentAdvanced{ .scalar = intAbiAlignment(int_type.bits, target) }; }, - .ptr_type => @panic("TODO"), - .array_type => @panic("TODO"), - .vector_type => @panic("TODO"), - .optional_type => @panic("TODO"), + .ptr_type => { + return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }; + }, + .array_type => |array_type| { + return array_type.child.toType().abiAlignmentAdvanced(mod, strat); + }, + .vector_type => |vector_type| { + const bits_u64 = try bitSizeAdvanced(vector_type.child.toType(), mod, opt_sema); + const bits = @intCast(u32, bits_u64); + const bytes = ((bits * vector_type.len) + 7) / 8; + const alignment = std.math.ceilPowerOfTwoAssert(u32, bytes); + return AbiAlignmentAdvanced{ .scalar = alignment }; + }, + + .opt_type => @panic("TODO"), .error_union_type => @panic("TODO"), .simple_type => |t| switch (t) { .bool, @@ -2617,15 +2134,8 @@ pub const Type = struct { .enum_tag => unreachable, // it's a value, not a type }; - const opt_sema = switch (strat) { - .sema => |sema| sema, - else => null, - }; switch (ty.tag()) { - .array_u8_sentinel_0, - .array_u8, - .@"opaque", - => return AbiAlignmentAdvanced{ .scalar = 1 }, + .@"opaque" => return AbiAlignmentAdvanced{ .scalar = 1 }, // represents machine code; not a pointer .function => { @@ -2634,47 +2144,21 @@ pub const Type = struct { return AbiAlignmentAdvanced{ .scalar = target_util.defaultFunctionAlignment(target) }; }, - .single_const_pointer_to_comptime_int, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, - .optional_single_const_pointer, - .optional_single_mut_pointer, .pointer, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, .anyframe_T, => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, // TODO revisit this when we have the concept of the error tag type - .anyerror_void_error_union, .error_set_inferred, .error_set_single, .error_set, .error_set_merged, => return AbiAlignmentAdvanced{ .scalar = 2 }, - .array, .array_sentinel => return ty.elemType().abiAlignmentAdvanced(mod, strat), - - .vector => { - const len = ty.arrayLen(); - const bits = try bitSizeAdvanced(ty.elemType(), mod, opt_sema); - const bytes = ((bits * len) + 7) / 8; - const alignment = std.math.ceilPowerOfTwoAssert(u64, bytes); - return AbiAlignmentAdvanced{ .scalar = @intCast(u32, alignment) }; - }, + .array, .array_sentinel => return ty.childType(mod).abiAlignmentAdvanced(mod, strat), .optional => { - var buf: Payload.ElemType = undefined; - const child_type = ty.optionalChild(&buf); + const child_type = ty.optionalChild(mod); switch (child_type.zigTypeTag(mod)) { .Pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, @@ -2933,8 +2417,29 @@ pub const Type = struct { }, .ptr_type => @panic("TODO"), .array_type => @panic("TODO"), - .vector_type => @panic("TODO"), - .optional_type => @panic("TODO"), + .vector_type => |vector_type| { + const opt_sema = switch (strat) { + .sema => |sema| sema, + .eager => null, + .lazy => |arena| return AbiSizeAdvanced{ + .val = try Value.Tag.lazy_size.create(arena, ty), + }, + }; + const elem_bits_u64 = try vector_type.child.toType().bitSizeAdvanced(mod, opt_sema); + const elem_bits = @intCast(u32, elem_bits_u64); + const total_bits = elem_bits * vector_type.len; + const total_bytes = (total_bits + 7) / 8; + const alignment = switch (try ty.abiAlignmentAdvanced(mod, strat)) { + .scalar => |x| x, + .val => return AbiSizeAdvanced{ + .val = try Value.Tag.lazy_size.create(strat.lazy, ty), + }, + }; + const result = std.mem.alignForwardGeneric(u32, total_bytes, alignment); + return AbiSizeAdvanced{ .scalar = result }; + }, + + .opt_type => @panic("TODO"), .error_union_type => @panic("TODO"), .simple_type => |t| switch (t) { .bool, @@ -3014,7 +2519,6 @@ pub const Type = struct { .inferred_alloc_const => unreachable, .inferred_alloc_mut => unreachable, - .single_const_pointer_to_comptime_int, .empty_struct_literal, .empty_struct, => return AbiSizeAdvanced{ .scalar = 0 }, @@ -3068,8 +2572,6 @@ pub const Type = struct { return abiSizeAdvancedUnion(ty, mod, strat, union_obj, true); }, - .array_u8 => return AbiSizeAdvanced{ .scalar = ty.castTag(.array_u8).?.data }, - .array_u8_sentinel_0 => return AbiSizeAdvanced{ .scalar = ty.castTag(.array_u8_sentinel_0).?.data + 1 }, .array => { const payload = ty.castTag(.array).?.data; switch (try payload.elem_type.abiSizeAdvanced(mod, strat)) { @@ -3093,47 +2595,7 @@ pub const Type = struct { } }, - .vector => { - const payload = ty.castTag(.vector).?.data; - const opt_sema = switch (strat) { - .sema => |sema| sema, - .eager => null, - .lazy => |arena| return AbiSizeAdvanced{ - .val = try Value.Tag.lazy_size.create(arena, ty), - }, - }; - const elem_bits = try payload.elem_type.bitSizeAdvanced(mod, opt_sema); - const total_bits = elem_bits * payload.len; - const total_bytes = (total_bits + 7) / 8; - const alignment = switch (try ty.abiAlignmentAdvanced(mod, strat)) { - .scalar => |x| x, - .val => return AbiSizeAdvanced{ - .val = try Value.Tag.lazy_size.create(strat.lazy, ty), - }, - }; - const result = std.mem.alignForwardGeneric(u64, total_bytes, alignment); - return AbiSizeAdvanced{ .scalar = result }; - }, - - .anyframe_T, - .optional_single_const_pointer, - .optional_single_mut_pointer, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, - - .const_slice, - .mut_slice, - .const_slice_u8, - .const_slice_u8_sentinel_0, - => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 }, + .anyframe_T => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) }, .pointer => switch (ty.castTag(.pointer).?.data.size) { .Slice => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 }, @@ -3141,7 +2603,6 @@ pub const Type = struct { }, // TODO revisit this when we have the concept of the error tag type - .anyerror_void_error_union, .error_set_inferred, .error_set, .error_set_merged, @@ -3149,8 +2610,7 @@ pub const Type = struct { => return AbiSizeAdvanced{ .scalar = 2 }, .optional => { - var buf: Payload.ElemType = undefined; - const child_type = ty.optionalChild(&buf); + const child_type = ty.optionalChild(mod); if (child_type.isNoReturn()) { return AbiSizeAdvanced{ .scalar = 0 }; @@ -3272,8 +2732,12 @@ pub const Type = struct { .int_type => |int_type| return int_type.bits, .ptr_type => @panic("TODO"), .array_type => @panic("TODO"), - .vector_type => @panic("TODO"), - .optional_type => @panic("TODO"), + .vector_type => |vector_type| { + const child_ty = vector_type.child.toType(); + const elem_bit_size = try bitSizeAdvanced(child_ty, mod, opt_sema); + return elem_bit_size * vector_type.len; + }, + .opt_type => @panic("TODO"), .error_union_type => @panic("TODO"), .simple_type => |t| switch (t) { .f16 => return 16, @@ -3339,7 +2803,6 @@ pub const Type = struct { switch (ty.tag()) { .function => unreachable, // represents machine code; not a pointer - .single_const_pointer_to_comptime_int => unreachable, .empty_struct => unreachable, .empty_struct_literal => unreachable, .inferred_alloc_const => unreachable, @@ -3388,13 +2851,6 @@ pub const Type = struct { return size; }, - .vector => { - const payload = ty.castTag(.vector).?.data; - const elem_bit_size = try bitSizeAdvanced(payload.elem_type, mod, opt_sema); - return elem_bit_size * payload.len; - }, - .array_u8 => return 8 * ty.castTag(.array_u8).?.data, - .array_u8_sentinel_0 => return 8 * (ty.castTag(.array_u8_sentinel_0).?.data + 1), .array => { const payload = ty.castTag(.array).?.data; const elem_size = std.math.max(payload.elem_type.abiAlignment(mod), payload.elem_type.abiSize(mod)); @@ -3415,43 +2871,13 @@ pub const Type = struct { .anyframe_T => return target.ptrBitWidth(), - .const_slice, - .mut_slice, - => return target.ptrBitWidth() * 2, - - .const_slice_u8, - .const_slice_u8_sentinel_0, - => return target.ptrBitWidth() * 2, - - .optional_single_const_pointer, - .optional_single_mut_pointer, - => { - return target.ptrBitWidth(); - }, - - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - => { - return target.ptrBitWidth(); - }, - .pointer => switch (ty.castTag(.pointer).?.data.size) { .Slice => return target.ptrBitWidth() * 2, else => return target.ptrBitWidth(), }, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - => return target.ptrBitWidth(), - .error_set, .error_set_single, - .anyerror_void_error_union, .error_set_inferred, .error_set_merged, => return 16, // TODO revisit this when we have the concept of the error tag type @@ -3481,12 +2907,11 @@ pub const Type = struct { return true; }, .Array => { - if (ty.arrayLenIncludingSentinel() == 0) return true; - return ty.childType().layoutIsResolved(mod); + if (ty.arrayLenIncludingSentinel(mod) == 0) return true; + return ty.childType(mod).layoutIsResolved(mod); }, .Optional => { - var buf: Type.Payload.ElemType = undefined; - const payload_ty = ty.optionalChild(&buf); + const payload_ty = ty.optionalChild(mod); return payload_ty.layoutIsResolved(mod); }, .ErrorUnion => { @@ -3500,9 +2925,6 @@ pub const Type = struct { pub fn isSinglePointer(ty: Type, mod: *const Module) bool { switch (ty.ip_index) { .none => return switch (ty.tag()) { - .single_const_pointer, - .single_mut_pointer, - .single_const_pointer_to_comptime_int, .inferred_alloc_const, .inferred_alloc_mut, => true, @@ -3519,54 +2941,33 @@ pub const Type = struct { } /// Asserts `ty` is a pointer. - pub fn ptrSize(ty: Type) std.builtin.Type.Pointer.Size { - return ptrSizeOrNull(ty).?; + pub fn ptrSize(ty: Type, mod: *const Module) std.builtin.Type.Pointer.Size { + return ptrSizeOrNull(ty, mod).?; } /// Returns `null` if `ty` is not a pointer. - pub fn ptrSizeOrNull(ty: Type) ?std.builtin.Type.Pointer.Size { - return switch (ty.tag()) { - .const_slice, - .mut_slice, - .const_slice_u8, - .const_slice_u8_sentinel_0, - => .Slice, + pub fn ptrSizeOrNull(ty: Type, mod: *const Module) ?std.builtin.Type.Pointer.Size { + return switch (ty.ip_index) { + .none => switch (ty.tag()) { + .inferred_alloc_const, + .inferred_alloc_mut, + => .One, - .many_const_pointer, - .many_mut_pointer, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - => .Many, + .pointer => ty.castTag(.pointer).?.data.size, - .c_const_pointer, - .c_mut_pointer, - => .C, - - .single_const_pointer, - .single_mut_pointer, - .single_const_pointer_to_comptime_int, - .inferred_alloc_const, - .inferred_alloc_mut, - => .One, - - .pointer => ty.castTag(.pointer).?.data.size, - - else => null, + else => null, + }, + else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { + .ptr_type => |ptr_info| ptr_info.size, + else => null, + }, }; } pub fn isSlice(ty: Type, mod: *const Module) bool { return switch (ty.ip_index) { .none => switch (ty.tag()) { - .const_slice, - .mut_slice, - .const_slice_u8, - .const_slice_u8_sentinel_0, - => true, - .pointer => ty.castTag(.pointer).?.data.size == .Slice, - else => false, }, else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { @@ -3583,78 +2984,28 @@ pub const Type = struct { pub fn slicePtrFieldType(self: Type, buffer: *SlicePtrFieldTypeBuffer) Type { switch (self.tag()) { - .const_slice_u8 => return Type.initTag(.manyptr_const_u8), - .const_slice_u8_sentinel_0 => return Type.initTag(.manyptr_const_u8_sentinel_0), - - .const_slice => { - const elem_type = self.castTag(.const_slice).?.data; - buffer.* = .{ - .elem_type = .{ - .base = .{ .tag = .many_const_pointer }, - .data = elem_type, - }, - }; - return Type.initPayload(&buffer.elem_type.base); - }, - .mut_slice => { - const elem_type = self.castTag(.mut_slice).?.data; - buffer.* = .{ - .elem_type = .{ - .base = .{ .tag = .many_mut_pointer }, - .data = elem_type, - }, - }; - return Type.initPayload(&buffer.elem_type.base); - }, - .pointer => { const payload = self.castTag(.pointer).?.data; assert(payload.size == .Slice); - if (payload.sentinel != null or - payload.@"align" != 0 or - payload.@"addrspace" != .generic or - payload.bit_offset != 0 or - payload.host_size != 0 or - payload.vector_index != .none or - payload.@"allowzero" or - payload.@"volatile") - { - buffer.* = .{ - .pointer = .{ - .data = .{ - .pointee_type = payload.pointee_type, - .sentinel = payload.sentinel, - .@"align" = payload.@"align", - .@"addrspace" = payload.@"addrspace", - .bit_offset = payload.bit_offset, - .host_size = payload.host_size, - .vector_index = payload.vector_index, - .@"allowzero" = payload.@"allowzero", - .mutable = payload.mutable, - .@"volatile" = payload.@"volatile", - .size = .Many, - }, + buffer.* = .{ + .pointer = .{ + .data = .{ + .pointee_type = payload.pointee_type, + .sentinel = payload.sentinel, + .@"align" = payload.@"align", + .@"addrspace" = payload.@"addrspace", + .bit_offset = payload.bit_offset, + .host_size = payload.host_size, + .vector_index = payload.vector_index, + .@"allowzero" = payload.@"allowzero", + .mutable = payload.mutable, + .@"volatile" = payload.@"volatile", + .size = .Many, }, - }; - return Type.initPayload(&buffer.pointer.base); - } else if (payload.mutable) { - buffer.* = .{ - .elem_type = .{ - .base = .{ .tag = .many_mut_pointer }, - .data = payload.pointee_type, - }, - }; - return Type.initPayload(&buffer.elem_type.base); - } else { - buffer.* = .{ - .elem_type = .{ - .base = .{ .tag = .many_const_pointer }, - .data = payload.pointee_type, - }, - }; - return Type.initPayload(&buffer.elem_type.base); - } + }, + }; + return Type.initPayload(&buffer.pointer.base); }, else => unreachable, @@ -3663,19 +3014,7 @@ pub const Type = struct { pub fn isConstPtr(self: Type) bool { return switch (self.tag()) { - .single_const_pointer, - .many_const_pointer, - .c_const_pointer, - .single_const_pointer_to_comptime_int, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .const_slice, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - => true, - .pointer => !self.castTag(.pointer).?.data.mutable, - else => false, }; } @@ -3702,49 +3041,46 @@ pub const Type = struct { pub fn isCPtr(self: Type) bool { return switch (self.tag()) { - .c_const_pointer, - .c_mut_pointer, - => return true, - .pointer => self.castTag(.pointer).?.data.size == .C, else => return false, }; } - pub fn isPtrAtRuntime(self: Type, mod: *const Module) bool { - switch (self.tag()) { - .c_const_pointer, - .c_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - .manyptr_u8, - .optional_single_const_pointer, - .optional_single_mut_pointer, - .single_const_pointer, - .single_const_pointer_to_comptime_int, - .single_mut_pointer, - => return true, + pub fn isPtrAtRuntime(ty: Type, mod: *const Module) bool { + switch (ty.ip_index) { + .none => switch (ty.tag()) { + .pointer => switch (ty.castTag(.pointer).?.data.size) { + .Slice => return false, + .One, .Many, .C => return true, + }, - .pointer => switch (self.castTag(.pointer).?.data.size) { - .Slice => return false, - .One, .Many, .C => return true, + .optional => { + const child_type = ty.optionalChild(mod); + if (child_type.zigTypeTag(mod) != .Pointer) return false; + const info = child_type.ptrInfo(mod); + switch (info.size) { + .Slice, .C => return false, + .Many, .One => return !info.@"allowzero", + } + }, + + else => return false, }, - - .optional => { - var buf: Payload.ElemType = undefined; - const child_type = self.optionalChild(&buf); - if (child_type.zigTypeTag(mod) != .Pointer) return false; - const info = child_type.ptrInfo().data; - switch (info.size) { - .Slice, .C => return false, - .Many, .One => return !info.@"allowzero", - } + else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) { + .ptr_type => |ptr_type| switch (ptr_type.size) { + .Slice => false, + .One, .Many, .C => true, + }, + .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { + .ptr_type => |p| switch (p.size) { + .Slice, .C => false, + .Many, .One => !p.is_allowzero, + }, + else => false, + }, + else => false, }, - - else => return false, } } @@ -3754,23 +3090,17 @@ pub const Type = struct { if (ty.isPtrLikeOptional(mod)) { return true; } - return ty.ptrInfo().data.@"allowzero"; + return ty.ptrInfo(mod).@"allowzero"; } /// See also `isPtrLikeOptional`. pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool { switch (ty.tag()) { - .optional_single_const_pointer, - .optional_single_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - => return true, - .optional => { const child_ty = ty.castTag(.optional).?.data; switch (child_ty.zigTypeTag(mod)) { .Pointer => { - const info = child_ty.ptrInfo().data; + const info = child_ty.ptrInfo(mod); switch (info.size) { .C => return false, .Slice, .Many, .One => return !info.@"allowzero", @@ -3793,7 +3123,7 @@ pub const Type = struct { pub fn isPtrLikeOptional(ty: Type, mod: *const Module) bool { if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) { .ptr_type => |ptr_type| ptr_type.size == .C, - .optional_type => |o| switch (mod.intern_pool.indexToKey(o.payload_type)) { + .opt_type => |child| switch (mod.intern_pool.indexToKey(child)) { .ptr_type => |ptr_type| switch (ptr_type.size) { .Slice, .C => false, .Many, .One => !ptr_type.is_allowzero, @@ -3803,16 +3133,10 @@ pub const Type = struct { else => false, }; switch (ty.tag()) { - .optional_single_const_pointer, - .optional_single_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - => return true, - .optional => { const child_ty = ty.castTag(.optional).?.data; if (child_ty.zigTypeTag(mod) != .Pointer) return false; - const info = child_ty.ptrInfo().data; + const info = child_ty.ptrInfo(mod); switch (info.size) { .Slice, .C => return false, .Many, .One => return !info.@"allowzero", @@ -3828,42 +3152,23 @@ pub const Type = struct { /// For *[N]T, returns [N]T. /// For *T, returns T. /// For [*]T, returns T. - pub fn childType(ty: Type) Type { - return switch (ty.tag()) { - .vector => ty.castTag(.vector).?.data.elem_type, - .array => ty.castTag(.array).?.data.elem_type, - .array_sentinel => ty.castTag(.array_sentinel).?.data.elem_type, - .optional_single_mut_pointer, - .optional_single_const_pointer, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, - => ty.castPointer().?.data, - - .array_u8, - .array_u8_sentinel_0, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - => Type.u8, - - .single_const_pointer_to_comptime_int => Type.comptime_int, - .pointer => ty.castTag(.pointer).?.data.pointee_type, - - else => unreachable, - }; + pub fn childType(ty: Type, mod: *const Module) Type { + return childTypeIp(ty, mod.intern_pool); } - /// Asserts the type is a pointer or array type. - /// TODO this is deprecated in favor of `childType`. - pub const elemType = childType; + pub fn childTypeIp(ty: Type, ip: InternPool) Type { + return switch (ty.ip_index) { + .none => switch (ty.tag()) { + .array => ty.castTag(.array).?.data.elem_type, + .array_sentinel => ty.castTag(.array_sentinel).?.data.elem_type, + + .pointer => ty.castTag(.pointer).?.data.pointee_type, + + else => unreachable, + }, + else => ip.childType(ty.ip_index).toType(), + }; + } /// For *[N]T, returns T. /// For ?*T, returns T. @@ -3875,54 +3180,42 @@ pub const Type = struct { /// For []T, returns T. /// For anyframe->T, returns T. pub fn elemType2(ty: Type, mod: *const Module) Type { - return switch (ty.tag()) { - .vector => ty.castTag(.vector).?.data.elem_type, - .array => ty.castTag(.array).?.data.elem_type, - .array_sentinel => ty.castTag(.array_sentinel).?.data.elem_type, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, - => ty.castPointer().?.data, + return switch (ty.ip_index) { + .none => switch (ty.tag()) { + .array => ty.castTag(.array).?.data.elem_type, + .array_sentinel => ty.castTag(.array_sentinel).?.data.elem_type, - .single_const_pointer, - .single_mut_pointer, - => ty.castPointer().?.data.shallowElemType(mod), + .pointer => { + const info = ty.castTag(.pointer).?.data; + const child_ty = info.pointee_type; + if (info.size == .One) { + return child_ty.shallowElemType(mod); + } else { + return child_ty; + } + }, + .optional => ty.castTag(.optional).?.data.childType(mod), - .array_u8, - .array_u8_sentinel_0, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - => Type.u8, + .anyframe_T => ty.castTag(.anyframe_T).?.data, - .single_const_pointer_to_comptime_int => Type.comptime_int, - .pointer => { - const info = ty.castTag(.pointer).?.data; - const child_ty = info.pointee_type; - if (info.size == .One) { - return child_ty.shallowElemType(mod); - } else { - return child_ty; - } + else => unreachable, + }, + else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { + .ptr_type => |ptr_type| switch (ptr_type.size) { + .One => ptr_type.elem_type.toType().shallowElemType(mod), + .Many, .C, .Slice => ptr_type.elem_type.toType(), + }, + .vector_type => |vector_type| vector_type.child.toType(), + .array_type => |array_type| array_type.child.toType(), + .opt_type => |child| mod.intern_pool.childType(child).toType(), + else => unreachable, }, - .optional => ty.castTag(.optional).?.data.childType(), - .optional_single_mut_pointer => ty.castPointer().?.data, - .optional_single_const_pointer => ty.castPointer().?.data, - - .anyframe_T => ty.castTag(.anyframe_T).?.data, - - else => unreachable, }; } fn shallowElemType(child_ty: Type, mod: *const Module) Type { return switch (child_ty.zigTypeTag(mod)) { - .Array, .Vector => child_ty.childType(), + .Array, .Vector => child_ty.childType(mod), else => child_ty, }; } @@ -3930,7 +3223,7 @@ pub const Type = struct { /// For vectors, returns the element type. Otherwise returns self. pub fn scalarType(ty: Type, mod: *const Module) Type { return switch (ty.zigTypeTag(mod)) { - .Vector => ty.childType(), + .Vector => ty.childType(mod), else => ty, }; } @@ -3938,53 +3231,27 @@ pub const Type = struct { /// Asserts that the type is an optional. /// Resulting `Type` will have inner memory referencing `buf`. /// Note that for C pointers this returns the type unmodified. - pub fn optionalChild(ty: Type, buf: *Payload.ElemType) Type { - return switch (ty.tag()) { - .optional => ty.castTag(.optional).?.data, - .optional_single_mut_pointer => { - buf.* = .{ - .base = .{ .tag = .single_mut_pointer }, - .data = ty.castPointer().?.data, - }; - return Type.initPayload(&buf.base); - }, - .optional_single_const_pointer => { - buf.* = .{ - .base = .{ .tag = .single_const_pointer }, - .data = ty.castPointer().?.data, - }; - return Type.initPayload(&buf.base); - }, + pub fn optionalChild(ty: Type, mod: *const Module) Type { + return switch (ty.ip_index) { + .none => switch (ty.tag()) { + .optional => ty.castTag(.optional).?.data, - .pointer, // here we assume it is a C pointer - .c_const_pointer, - .c_mut_pointer, - => return ty, + .pointer, // here we assume it is a C pointer + => return ty, - else => unreachable, + else => unreachable, + }, + else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { + .opt_type => |child| child.toType(), + .ptr_type => |ptr_type| b: { + assert(ptr_type.size == .C); + break :b ty; + }, + else => unreachable, + }, }; } - /// Asserts that the type is an optional. - /// Same as `optionalChild` but allocates the buffer if needed. - pub fn optionalChildAlloc(ty: Type, allocator: Allocator) !Type { - switch (ty.tag()) { - .optional => return ty.castTag(.optional).?.data, - .optional_single_mut_pointer => { - return Tag.single_mut_pointer.create(allocator, ty.castPointer().?.data); - }, - .optional_single_const_pointer => { - return Tag.single_const_pointer.create(allocator, ty.castPointer().?.data); - }, - .pointer, // here we assume it is a C pointer - .c_const_pointer, - .c_mut_pointer, - => return ty, - - else => unreachable, - } - } - /// Returns the tag type of a union, if the type is a union and it has a tag type. /// Otherwise, returns `null`. pub fn unionTagType(ty: Type) ?Type { @@ -4071,19 +3338,25 @@ pub const Type = struct { } /// Asserts that the type is an error union. - pub fn errorUnionPayload(self: Type) Type { - return switch (self.tag()) { - .anyerror_void_error_union => Type.void, - .error_union => self.castTag(.error_union).?.data.payload, - else => unreachable, + pub fn errorUnionPayload(ty: Type) Type { + return switch (ty.ip_index) { + .anyerror_void_error_union_type => Type.void, + .none => switch (ty.tag()) { + .error_union => ty.castTag(.error_union).?.data.payload, + else => unreachable, + }, + else => @panic("TODO"), }; } - pub fn errorUnionSet(self: Type) Type { - return switch (self.tag()) { - .anyerror_void_error_union => Type.anyerror, - .error_union => self.castTag(.error_union).?.data.error_set, - else => unreachable, + pub fn errorUnionSet(ty: Type) Type { + return switch (ty.ip_index) { + .anyerror_void_error_union_type => Type.anyerror, + .none => switch (ty.tag()) { + .error_union => ty.castTag(.error_union).?.data.error_set, + else => unreachable, + }, + else => @panic("TODO"), }; } @@ -4168,67 +3441,73 @@ pub const Type = struct { } /// Asserts the type is an array or vector or struct. - pub fn arrayLen(ty: Type) u64 { - return switch (ty.tag()) { - .vector => ty.castTag(.vector).?.data.len, - .array => ty.castTag(.array).?.data.len, - .array_sentinel => ty.castTag(.array_sentinel).?.data.len, - .array_u8 => ty.castTag(.array_u8).?.data, - .array_u8_sentinel_0 => ty.castTag(.array_u8_sentinel_0).?.data, - .tuple => ty.castTag(.tuple).?.data.types.len, - .anon_struct => ty.castTag(.anon_struct).?.data.types.len, - .@"struct" => ty.castTag(.@"struct").?.data.fields.count(), - .empty_struct, .empty_struct_literal => 0, + pub fn arrayLen(ty: Type, mod: *const Module) u64 { + return arrayLenIp(ty, mod.intern_pool); + } - else => unreachable, + pub fn arrayLenIp(ty: Type, ip: InternPool) u64 { + return switch (ty.ip_index) { + .none => switch (ty.tag()) { + .array => ty.castTag(.array).?.data.len, + .array_sentinel => ty.castTag(.array_sentinel).?.data.len, + .tuple => ty.castTag(.tuple).?.data.types.len, + .anon_struct => ty.castTag(.anon_struct).?.data.types.len, + .@"struct" => ty.castTag(.@"struct").?.data.fields.count(), + .empty_struct, .empty_struct_literal => 0, + + else => unreachable, + }, + else => switch (ip.indexToKey(ty.ip_index)) { + .vector_type => |vector_type| vector_type.len, + .array_type => |array_type| array_type.len, + else => unreachable, + }, }; } - pub fn arrayLenIncludingSentinel(ty: Type) u64 { - return ty.arrayLen() + @boolToInt(ty.sentinel() != null); + pub fn arrayLenIncludingSentinel(ty: Type, mod: *const Module) u64 { + return ty.arrayLen(mod) + @boolToInt(ty.sentinel(mod) != null); } - pub fn vectorLen(ty: Type) u32 { - return switch (ty.tag()) { - .vector => @intCast(u32, ty.castTag(.vector).?.data.len), - .tuple => @intCast(u32, ty.castTag(.tuple).?.data.types.len), - .anon_struct => @intCast(u32, ty.castTag(.anon_struct).?.data.types.len), - else => unreachable, + pub fn vectorLen(ty: Type, mod: *const Module) u32 { + return switch (ty.ip_index) { + .none => switch (ty.tag()) { + .tuple => @intCast(u32, ty.castTag(.tuple).?.data.types.len), + .anon_struct => @intCast(u32, ty.castTag(.anon_struct).?.data.types.len), + else => unreachable, + }, + else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { + .vector_type => |vector_type| vector_type.len, + else => unreachable, + }, }; } /// Asserts the type is an array, pointer or vector. - pub fn sentinel(self: Type) ?Value { - return switch (self.tag()) { - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .single_const_pointer_to_comptime_int, - .vector, - .array, - .array_u8, - .manyptr_u8, - .manyptr_const_u8, - .const_slice_u8, - .const_slice, - .mut_slice, - .tuple, - .empty_struct_literal, - .@"struct", - => return null, + pub fn sentinel(ty: Type, mod: *const Module) ?Value { + return switch (ty.ip_index) { + .none => switch (ty.tag()) { + .array, + .tuple, + .empty_struct_literal, + .@"struct", + => null, - .pointer => return self.castTag(.pointer).?.data.sentinel, - .array_sentinel => return self.castTag(.array_sentinel).?.data.sentinel, + .pointer => ty.castTag(.pointer).?.data.sentinel, + .array_sentinel => ty.castTag(.array_sentinel).?.data.sentinel, - .array_u8_sentinel_0, - .const_slice_u8_sentinel_0, - .manyptr_const_u8_sentinel_0, - => return Value.zero, + else => unreachable, + }, + else => switch (mod.intern_pool.indexToKey(ty.ip_index)) { + .vector_type, + .struct_type, + => null, - else => unreachable, + .array_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null, + .ptr_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null, + + else => unreachable, + }, }; } @@ -4292,8 +3571,6 @@ pub const Type = struct { return .{ .signedness = .unsigned, .bits = 16 }; }, - .vector => ty = ty.castTag(.vector).?.data.elem_type, - .@"struct" => { const struct_obj = ty.castTag(.@"struct").?.data; assert(struct_obj.layout == .Packed); @@ -4321,8 +3598,9 @@ pub const Type = struct { .int_type => |int_type| return int_type, .ptr_type => unreachable, .array_type => unreachable, - .vector_type => @panic("TODO"), - .optional_type => unreachable, + .vector_type => |vector_type| ty = vector_type.child.toType(), + + .opt_type => unreachable, .error_union_type => unreachable, .simple_type => unreachable, // handled via Index enum tag above .struct_type => @panic("TODO"), @@ -4426,7 +3704,11 @@ pub const Type = struct { /// Asserts the type is a function or a function pointer. pub fn fnReturnType(ty: Type) Type { - const fn_ty = if (ty.castPointer()) |p| p.data else ty; + const fn_ty = switch (ty.tag()) { + .pointer => ty.castTag(.pointer).?.data.pointee_type, + .function => ty, + else => unreachable, + }; return fn_ty.castTag(.function).?.data.return_type; } @@ -4516,8 +3798,12 @@ pub const Type = struct { }, .ptr_type => @panic("TODO"), .array_type => @panic("TODO"), - .vector_type => @panic("TODO"), - .optional_type => @panic("TODO"), + .vector_type => |vector_type| { + if (vector_type.len == 0) return Value.initTag(.empty_array); + if (vector_type.child.toType().onePossibleValue(mod)) |v| return v; + return null; + }, + .opt_type => @panic("TODO"), .error_union_type => @panic("TODO"), .simple_type => |t| switch (t) { .f16, @@ -4580,34 +3866,15 @@ pub const Type = struct { .error_set, .error_set_merged, .function, - .single_const_pointer_to_comptime_int, .array_sentinel, - .array_u8_sentinel_0, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .const_slice, - .mut_slice, - .optional_single_mut_pointer, - .optional_single_const_pointer, - .anyerror_void_error_union, .error_set_inferred, .@"opaque", - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, .anyframe_T, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .single_const_pointer, - .single_mut_pointer, .pointer, => return null, .optional => { - var buf: Payload.ElemType = undefined; - const child_ty = ty.optionalChild(&buf); + const child_ty = ty.optionalChild(mod); if (child_ty.isNoReturn()) { return Value.null; } else { @@ -4690,10 +3957,10 @@ pub const Type = struct { .empty_struct, .empty_struct_literal => return Value.initTag(.empty_struct_value), - .vector, .array, .array_u8 => { - if (ty.arrayLen() == 0) + .array => { + if (ty.arrayLen(mod) == 0) return Value.initTag(.empty_array); - if (ty.elemType().onePossibleValue(mod) != null) + if (ty.childType(mod).onePossibleValue(mod) != null) return Value.initTag(.the_only_possible_value); return null; }, @@ -4711,9 +3978,9 @@ pub const Type = struct { if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) { .int_type => false, .ptr_type => @panic("TODO"), - .array_type => @panic("TODO"), - .vector_type => @panic("TODO"), - .optional_type => @panic("TODO"), + .array_type => |array_type| return array_type.child.toType().comptimeOnly(mod), + .vector_type => |vector_type| return vector_type.child.toType().comptimeOnly(mod), + .opt_type => @panic("TODO"), .error_union_type => @panic("TODO"), .simple_type => |t| switch (t) { .f16, @@ -4772,12 +4039,6 @@ pub const Type = struct { }; return switch (ty.tag()) { - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, - .const_slice_u8, - .const_slice_u8_sentinel_0, - .anyerror_void_error_union, .empty_struct_literal, .empty_struct, .error_set, @@ -4785,35 +4046,21 @@ pub const Type = struct { .error_set_inferred, .error_set_merged, .@"opaque", - .array_u8, - .array_u8_sentinel_0, .enum_simple, => false, - .single_const_pointer_to_comptime_int, // These are function bodies, not function pointers. - .function, - => true, + .function => true, .inferred_alloc_mut => unreachable, .inferred_alloc_const => unreachable, .array, .array_sentinel, - .vector, - => return ty.childType().comptimeOnly(mod), + => return ty.childType(mod).comptimeOnly(mod), - .pointer, - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, - => { - const child_ty = ty.childType(); + .pointer => { + const child_ty = ty.childType(mod); if (child_ty.zigTypeTag(mod) == .Fn) { return false; } else { @@ -4821,12 +4068,8 @@ pub const Type = struct { } }, - .optional, - .optional_single_mut_pointer, - .optional_single_const_pointer, - => { - var buf: Type.Payload.ElemType = undefined; - return ty.optionalChild(&buf).comptimeOnly(mod); + .optional => { + return ty.optionalChild(mod).comptimeOnly(mod); }, .tuple, .anon_struct => { @@ -4882,6 +4125,10 @@ pub const Type = struct { }; } + pub fn isVector(ty: Type, mod: *const Module) bool { + return ty.zigTypeTag(mod) == .Vector; + } + pub fn isArrayOrVector(ty: Type, mod: *const Module) bool { return switch (ty.zigTypeTag(mod)) { .Array, .Vector => true, @@ -4892,9 +4139,9 @@ pub const Type = struct { pub fn isIndexable(ty: Type, mod: *const Module) bool { return switch (ty.zigTypeTag(mod)) { .Array, .Vector => true, - .Pointer => switch (ty.ptrSize()) { + .Pointer => switch (ty.ptrSize(mod)) { .Slice, .Many, .C => true, - .One => ty.elemType().zigTypeTag(mod) == .Array, + .One => ty.childType(mod).zigTypeTag(mod) == .Array, }, .Struct => ty.isTuple(), else => false, @@ -4904,10 +4151,10 @@ pub const Type = struct { pub fn indexableHasLen(ty: Type, mod: *const Module) bool { return switch (ty.zigTypeTag(mod)) { .Array, .Vector => true, - .Pointer => switch (ty.ptrSize()) { + .Pointer => switch (ty.ptrSize(mod)) { .Many, .C => false, .Slice => true, - .One => ty.elemType().zigTypeTag(mod) == .Array, + .One => ty.childType(mod).zigTypeTag(mod) == .Array, }, .Struct => ty.isTuple(), else => false, @@ -5527,14 +4774,6 @@ pub const Type = struct { /// with different enum tags, because the the former requires more payload data than the latter. /// See `zigTypeTag` for the function that corresponds to `std.builtin.TypeId`. pub const Tag = enum(usize) { - // The first section of this enum are tags that require no payload. - manyptr_u8, - manyptr_const_u8, - manyptr_const_u8_sentinel_0, - single_const_pointer_to_comptime_int, - const_slice_u8, - const_slice_u8_sentinel_0, - anyerror_void_error_union, /// Same as `empty_struct` except it has an empty namespace. empty_struct_literal, /// This is a special value that tracks a set of types that have been stored @@ -5545,28 +4784,15 @@ pub const Type = struct { inferred_alloc_const, // See last_no_payload_tag below. // After this, the tag requires a payload. - array_u8, - array_u8_sentinel_0, array, array_sentinel, - vector, /// Possible Value tags for this: @"struct" tuple, /// Possible Value tags for this: @"struct" anon_struct, pointer, - single_const_pointer, - single_mut_pointer, - many_const_pointer, - many_mut_pointer, - c_const_pointer, - c_mut_pointer, - const_slice, - mut_slice, function, optional, - optional_single_mut_pointer, - optional_single_const_pointer, error_union, anyframe_T, error_set, @@ -5590,33 +4816,12 @@ pub const Type = struct { pub fn Type(comptime t: Tag) type { return switch (t) { - .single_const_pointer_to_comptime_int, - .anyerror_void_error_union, - .const_slice_u8, - .const_slice_u8_sentinel_0, .inferred_alloc_const, .inferred_alloc_mut, .empty_struct_literal, - .manyptr_u8, - .manyptr_const_u8, - .manyptr_const_u8_sentinel_0, => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"), - .array_u8, - .array_u8_sentinel_0, - => Payload.Len, - - .single_const_pointer, - .single_mut_pointer, - .many_const_pointer, - .many_mut_pointer, - .c_const_pointer, - .c_mut_pointer, - .const_slice, - .mut_slice, .optional, - .optional_single_mut_pointer, - .optional_single_const_pointer, .anyframe_T, => Payload.ElemType, @@ -5624,7 +4829,7 @@ pub const Type = struct { .error_set_inferred => Payload.ErrorSetInferred, .error_set_merged => Payload.ErrorSetMerged, - .array, .vector => Payload.Array, + .array => Payload.Array, .array_sentinel => Payload.ArraySentinel, .pointer => Payload.Pointer, .function => Payload.Function, @@ -5847,15 +5052,28 @@ pub const Type = struct { @"volatile": bool = false, size: std.builtin.Type.Pointer.Size = .One, - pub const VectorIndex = enum(u32) { - none = std.math.maxInt(u32), - runtime = std.math.maxInt(u32) - 1, - _, - }; + pub const VectorIndex = InternPool.Key.PtrType.VectorIndex; + pub fn alignment(data: Data, mod: *const Module) u32 { if (data.@"align" != 0) return data.@"align"; return abiAlignment(data.pointee_type, mod); } + + pub fn fromKey(p: InternPool.Key.PtrType) Data { + return .{ + .pointee_type = p.elem_type.toType(), + .sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null, + .@"align" = p.alignment, + .@"addrspace" = p.address_space, + .bit_offset = p.bit_offset, + .host_size = p.host_size, + .vector_index = p.vector_index, + .@"allowzero" = p.is_allowzero, + .mutable = !p.is_const, + .@"volatile" = p.is_volatile, + .size = p.size, + }; + } }; }; @@ -5986,6 +5204,17 @@ pub const Type = struct { pub const @"c_ulonglong": Type = .{ .ip_index = .c_ulonglong_type, .legacy = undefined }; pub const @"c_longdouble": Type = .{ .ip_index = .c_longdouble_type, .legacy = undefined }; + pub const const_slice_u8: Type = .{ .ip_index = .const_slice_u8_type, .legacy = undefined }; + pub const manyptr_u8: Type = .{ .ip_index = .manyptr_u8_type, .legacy = undefined }; + pub const single_const_pointer_to_comptime_int: Type = .{ + .ip_index = .single_const_pointer_to_comptime_int_type, + .legacy = undefined, + }; + pub const const_slice_u8_sentinel_0: Type = .{ + .ip_index = .const_slice_u8_sentinel_0_type, + .legacy = undefined, + }; + pub const generic_poison: Type = .{ .ip_index = .generic_poison_type, .legacy = undefined }; pub const err_int = Type.u16; @@ -6019,50 +5248,6 @@ pub const Type = struct { } } - if (d.@"align" == 0 and d.@"addrspace" == .generic and - d.bit_offset == 0 and d.host_size == 0 and d.vector_index == .none and - !d.@"allowzero" and !d.@"volatile") - { - if (d.sentinel) |sent| { - if (!d.mutable and d.pointee_type.eql(Type.u8, mod)) { - switch (d.size) { - .Slice => { - if (sent.compareAllWithZero(.eq, mod)) { - return Type.initTag(.const_slice_u8_sentinel_0); - } - }, - .Many => { - if (sent.compareAllWithZero(.eq, mod)) { - return Type.initTag(.manyptr_const_u8_sentinel_0); - } - }, - else => {}, - } - } - } else if (!d.mutable and d.pointee_type.eql(Type.u8, mod)) { - switch (d.size) { - .Slice => return Type.initTag(.const_slice_u8), - .Many => return Type.initTag(.manyptr_const_u8), - else => {}, - } - } else { - const T = Type.Tag; - const type_payload = try arena.create(Type.Payload.ElemType); - type_payload.* = .{ - .base = .{ - .tag = switch (d.size) { - .One => if (d.mutable) T.single_mut_pointer else T.single_const_pointer, - .Many => if (d.mutable) T.many_mut_pointer else T.many_const_pointer, - .C => if (d.mutable) T.c_mut_pointer else T.c_const_pointer, - .Slice => if (d.mutable) T.mut_slice else T.const_slice, - }, - }, - .data = d.pointee_type, - }; - return Type.initPayload(&type_payload.base); - } - } - return Type.Tag.pointer.create(arena, d); } @@ -6073,13 +5258,21 @@ pub const Type = struct { elem_type: Type, mod: *Module, ) Allocator.Error!Type { - if (elem_type.eql(Type.u8, mod)) { - if (sent) |some| { - if (some.eql(Value.zero, elem_type, mod)) { - return Tag.array_u8_sentinel_0.create(arena, len); + if (elem_type.ip_index != .none) { + if (sent) |s| { + if (s.ip_index != .none) { + return mod.arrayType(.{ + .len = len, + .child = elem_type.ip_index, + .sentinel = s.ip_index, + }); } } else { - return Tag.array_u8.create(arena, len); + return mod.arrayType(.{ + .len = len, + .child = elem_type.ip_index, + .sentinel = .none, + }); } } @@ -6097,24 +5290,11 @@ pub const Type = struct { }); } - pub fn vector(arena: Allocator, len: u64, elem_type: Type) Allocator.Error!Type { - return Tag.vector.create(arena, .{ - .len = len, - .elem_type = elem_type, - }); - } - - pub fn optional(arena: Allocator, child_type: Type) Allocator.Error!Type { - switch (child_type.tag()) { - .single_const_pointer => return Type.Tag.optional_single_const_pointer.create( - arena, - child_type.elemType(), - ), - .single_mut_pointer => return Type.Tag.optional_single_mut_pointer.create( - arena, - child_type.elemType(), - ), - else => return Type.Tag.optional.create(arena, child_type), + pub fn optional(arena: Allocator, child_type: Type, mod: *Module) Allocator.Error!Type { + if (child_type.ip_index != .none) { + return mod.optionalType(child_type.ip_index); + } else { + return Type.Tag.optional.create(arena, child_type); } } @@ -6125,12 +5305,6 @@ pub const Type = struct { mod: *Module, ) Allocator.Error!Type { assert(error_set.zigTypeTag(mod) == .ErrorSet); - if (error_set.eql(Type.anyerror, mod) and - payload.eql(Type.void, mod)) - { - return Type.initTag(.anyerror_void_error_union); - } - return Type.Tag.error_union.create(arena, .{ .error_set = error_set, .payload = payload, diff --git a/src/value.zig b/src/value.zig index cbf18c672c..6f7210c884 100644 --- a/src/value.zig +++ b/src/value.zig @@ -33,14 +33,6 @@ pub const Value = struct { // Keep in sync with tools/stage2_pretty_printers_common.py pub const Tag = enum(usize) { // The first section of this enum are tags that require no payload. - manyptr_u8_type, - manyptr_const_u8_type, - manyptr_const_u8_sentinel_0_type, - single_const_pointer_to_comptime_int_type, - const_slice_u8_type, - const_slice_u8_sentinel_0_type, - anyerror_void_error_union_type, - undef, zero, one, @@ -140,11 +132,6 @@ pub const Value = struct { pub fn Type(comptime t: Tag) type { return switch (t) { - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .const_slice_u8_sentinel_0_type, - .anyerror_void_error_union_type, - .undef, .zero, .one, @@ -153,9 +140,6 @@ pub const Value = struct { .empty_struct_value, .empty_array, .null_value, - .manyptr_u8_type, - .manyptr_const_u8_type, - .manyptr_const_u8_sentinel_0_type, => @compileError("Value Tag " ++ @tagName(t) ++ " has no payload"), .int_big_positive, @@ -280,9 +264,7 @@ pub const Value = struct { } pub fn castTag(self: Value, comptime t: Tag) ?*t.Type() { - if (self.ip_index != .none) { - return null; - } + assert(self.ip_index == .none); if (@enumToInt(self.legacy.tag_if_small_enough) < Tag.no_payload_count) return null; @@ -305,11 +287,6 @@ pub const Value = struct { .legacy = .{ .tag_if_small_enough = self.legacy.tag_if_small_enough }, }; } else switch (self.legacy.ptr_otherwise.tag) { - .single_const_pointer_to_comptime_int_type, - .const_slice_u8_type, - .const_slice_u8_sentinel_0_type, - .anyerror_void_error_union_type, - .undef, .zero, .one, @@ -318,9 +295,6 @@ pub const Value = struct { .empty_array, .null_value, .empty_struct_value, - .manyptr_u8_type, - .manyptr_const_u8_type, - .manyptr_const_u8_sentinel_0_type, => unreachable, .ty, .lazy_align, .lazy_size => { @@ -553,14 +527,6 @@ pub const Value = struct { } var val = start_val; while (true) switch (val.tag()) { - .single_const_pointer_to_comptime_int_type => return out_stream.writeAll("*const comptime_int"), - .const_slice_u8_type => return out_stream.writeAll("[]const u8"), - .const_slice_u8_sentinel_0_type => return out_stream.writeAll("[:0]const u8"), - .anyerror_void_error_union_type => return out_stream.writeAll("anyerror!void"), - .manyptr_u8_type => return out_stream.writeAll("[*]u8"), - .manyptr_const_u8_type => return out_stream.writeAll("[*]const u8"), - .manyptr_const_u8_sentinel_0_type => return out_stream.writeAll("[*:0]const u8"), - .empty_struct_value => return out_stream.writeAll("struct {}{}"), .aggregate => { return out_stream.writeAll("(aggregate)"); @@ -674,7 +640,7 @@ pub const Value = struct { switch (val.tag()) { .bytes => { const bytes = val.castTag(.bytes).?.data; - const adjusted_len = bytes.len - @boolToInt(ty.sentinel() != null); + const adjusted_len = bytes.len - @boolToInt(ty.sentinel(mod) != null); const adjusted_bytes = bytes[0..adjusted_len]; return allocator.dupe(u8, adjusted_bytes); }, @@ -686,7 +652,7 @@ pub const Value = struct { .enum_literal => return allocator.dupe(u8, val.castTag(.enum_literal).?.data), .repeated => { const byte = @intCast(u8, val.castTag(.repeated).?.data.toUnsignedInt(mod)); - const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen())); + const result = try allocator.alloc(u8, @intCast(usize, ty.arrayLen(mod))); @memset(result, byte); return result; }, @@ -701,7 +667,7 @@ pub const Value = struct { const slice = val.castTag(.slice).?.data; return arrayToAllocatedBytes(slice.ptr, slice.len.toUnsignedInt(mod), allocator, mod); }, - else => return arrayToAllocatedBytes(val, ty.arrayLen(), allocator, mod), + else => return arrayToAllocatedBytes(val, ty.arrayLen(mod), allocator, mod), } } @@ -720,13 +686,6 @@ pub const Value = struct { if (self.ip_index != .none) return self.ip_index.toType(); return switch (self.tag()) { .ty => self.castTag(.ty).?.data, - .single_const_pointer_to_comptime_int_type => Type.initTag(.single_const_pointer_to_comptime_int), - .const_slice_u8_type => Type.initTag(.const_slice_u8), - .const_slice_u8_sentinel_0_type => Type.initTag(.const_slice_u8_sentinel_0), - .anyerror_void_error_union_type => Type.initTag(.anyerror_void_error_union), - .manyptr_u8_type => Type.initTag(.manyptr_u8), - .manyptr_const_u8_type => Type.initTag(.manyptr_const_u8), - .manyptr_const_u8_sentinel_0_type => Type.initTag(.manyptr_const_u8_sentinel_0), else => unreachable, }; @@ -1096,8 +1055,8 @@ pub const Value = struct { else => unreachable, }, .Array => { - const len = ty.arrayLen(); - const elem_ty = ty.childType(); + const len = ty.arrayLen(mod); + const elem_ty = ty.childType(mod); const elem_size = @intCast(usize, elem_ty.abiSize(mod)); var elem_i: usize = 0; var elem_value_buf: ElemValueBuffer = undefined; @@ -1150,8 +1109,7 @@ pub const Value = struct { }, .Optional => { if (!ty.isPtrLikeOptional(mod)) return error.IllDefinedMemoryLayout; - var buf: Type.Payload.ElemType = undefined; - const child = ty.optionalChild(&buf); + const child = ty.optionalChild(mod); const opt_val = val.optionalValue(mod); if (opt_val) |some| { return some.writeToMemory(child, mod, buffer); @@ -1220,9 +1178,9 @@ pub const Value = struct { else => unreachable, }, .Vector => { - const elem_ty = ty.childType(); + const elem_ty = ty.childType(mod); const elem_bit_size = @intCast(u16, elem_ty.bitSize(mod)); - const len = @intCast(usize, ty.arrayLen()); + const len = @intCast(usize, ty.arrayLen(mod)); var bits: u16 = 0; var elem_i: usize = 0; @@ -1267,8 +1225,7 @@ pub const Value = struct { }, .Optional => { assert(ty.isPtrLikeOptional(mod)); - var buf: Type.Payload.ElemType = undefined; - const child = ty.optionalChild(&buf); + const child = ty.optionalChild(mod); const opt_val = val.optionalValue(mod); if (opt_val) |some| { return some.writeToPackedMemory(child, mod, buffer, bit_offset); @@ -1335,9 +1292,9 @@ pub const Value = struct { else => unreachable, }, .Array => { - const elem_ty = ty.childType(); + const elem_ty = ty.childType(mod); const elem_size = elem_ty.abiSize(mod); - const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen())); + const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen(mod))); var offset: usize = 0; for (elems) |*elem| { elem.* = try readFromMemory(elem_ty, mod, buffer[offset..], arena); @@ -1386,8 +1343,7 @@ pub const Value = struct { }, .Optional => { assert(ty.isPtrLikeOptional(mod)); - var buf: Type.Payload.ElemType = undefined; - const child = ty.optionalChild(&buf); + const child = ty.optionalChild(mod); return readFromMemory(child, mod, buffer, arena); }, else => @panic("TODO implement readFromMemory for more types"), @@ -1449,8 +1405,8 @@ pub const Value = struct { else => unreachable, }, .Vector => { - const elem_ty = ty.childType(); - const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen())); + const elem_ty = ty.childType(mod); + const elems = try arena.alloc(Value, @intCast(usize, ty.arrayLen(mod))); var bits: u16 = 0; const elem_bit_size = @intCast(u16, elem_ty.bitSize(mod)); @@ -1483,8 +1439,7 @@ pub const Value = struct { }, .Optional => { assert(ty.isPtrLikeOptional(mod)); - var buf: Type.Payload.ElemType = undefined; - const child = ty.optionalChild(&buf); + const child = ty.optionalChild(mod); return readFromPackedMemory(child, mod, buffer, bit_offset, arena); }, else => @panic("TODO implement readFromPackedMemory for more types"), @@ -1956,7 +1911,7 @@ pub const Value = struct { pub fn compareAll(lhs: Value, op: std.math.CompareOperator, rhs: Value, ty: Type, mod: *Module) bool { if (ty.zigTypeTag(mod) == .Vector) { var i: usize = 0; - while (i < ty.vectorLen()) : (i += 1) { + while (i < ty.vectorLen(mod)) : (i += 1) { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; const lhs_elem = lhs.elemValueBuffer(mod, i, &lhs_buf); @@ -2092,8 +2047,7 @@ pub const Value = struct { .opt_payload => { const a_payload = a.castTag(.opt_payload).?.data; const b_payload = b.castTag(.opt_payload).?.data; - var buffer: Type.Payload.ElemType = undefined; - const payload_ty = ty.optionalChild(&buffer); + const payload_ty = ty.optionalChild(mod); return eqlAdvanced(a_payload, payload_ty, b_payload, payload_ty, mod, opt_sema); }, .slice => { @@ -2175,7 +2129,7 @@ pub const Value = struct { return true; } - const elem_ty = ty.childType(); + const elem_ty = ty.childType(mod); for (a_field_vals, 0..) |a_elem, i| { const b_elem = b_field_vals[i]; @@ -2239,8 +2193,8 @@ pub const Value = struct { return eqlAdvanced(a_val, int_ty, b_val, int_ty, mod, opt_sema); }, .Array, .Vector => { - const len = ty.arrayLen(); - const elem_ty = ty.childType(); + const len = ty.arrayLen(mod); + const elem_ty = ty.childType(mod); var i: usize = 0; var a_buf: ElemValueBuffer = undefined; var b_buf: ElemValueBuffer = undefined; @@ -2253,11 +2207,11 @@ pub const Value = struct { } return true; }, - .Pointer => switch (ty.ptrSize()) { + .Pointer => switch (ty.ptrSize(mod)) { .Slice => { - const a_len = switch (a_ty.ptrSize()) { + const a_len = switch (a_ty.ptrSize(mod)) { .Slice => a.sliceLen(mod), - .One => a_ty.childType().arrayLen(), + .One => a_ty.childType(mod).arrayLen(mod), else => unreachable, }; if (a_len != b.sliceLen(mod)) { @@ -2266,7 +2220,7 @@ pub const Value = struct { var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined; const ptr_ty = ty.slicePtrFieldType(&ptr_buf); - const a_ptr = switch (a_ty.ptrSize()) { + const a_ptr = switch (a_ty.ptrSize(mod)) { .Slice => a.slicePtr(), .One => a, else => unreachable, @@ -2412,8 +2366,8 @@ pub const Value = struct { else => return hashPtr(val, hasher, mod), }, .Array, .Vector => { - const len = ty.arrayLen(); - const elem_ty = ty.childType(); + const len = ty.arrayLen(mod); + const elem_ty = ty.childType(mod); var index: usize = 0; var elem_value_buf: ElemValueBuffer = undefined; while (index < len) : (index += 1) { @@ -2438,8 +2392,7 @@ pub const Value = struct { if (val.castTag(.opt_payload)) |payload| { std.hash.autoHash(hasher, true); // non-null const sub_val = payload.data; - var buffer: Type.Payload.ElemType = undefined; - const sub_ty = ty.optionalChild(&buffer); + const sub_ty = ty.optionalChild(mod); sub_val.hash(sub_ty, hasher, mod); } else { std.hash.autoHash(hasher, false); // null @@ -2534,8 +2487,8 @@ pub const Value = struct { else => val.hashPtr(hasher, mod), }, .Array, .Vector => { - const len = ty.arrayLen(); - const elem_ty = ty.childType(); + const len = ty.arrayLen(mod); + const elem_ty = ty.childType(mod); var index: usize = 0; var elem_value_buf: ElemValueBuffer = undefined; while (index < len) : (index += 1) { @@ -2544,8 +2497,7 @@ pub const Value = struct { } }, .Optional => if (val.castTag(.opt_payload)) |payload| { - var buf: Type.Payload.ElemType = undefined; - const child_ty = ty.optionalChild(&buf); + const child_ty = ty.optionalChild(mod); payload.data.hashUncoerced(child_ty, hasher, mod); } else std.hash.autoHash(hasher, std.builtin.TypeId.Null), .ErrorSet, .ErrorUnion => if (val.getError()) |err| hasher.update(err) else { @@ -2720,7 +2672,7 @@ pub const Value = struct { const decl_index = val.castTag(.decl_ref).?.data; const decl = mod.declPtr(decl_index); if (decl.ty.zigTypeTag(mod) == .Array) { - return decl.ty.arrayLen(); + return decl.ty.arrayLen(mod); } else { return 1; } @@ -2729,7 +2681,7 @@ pub const Value = struct { const decl_index = val.castTag(.decl_ref_mut).?.data.decl_index; const decl = mod.declPtr(decl_index); if (decl.ty.zigTypeTag(mod) == .Array) { - return decl.ty.arrayLen(); + return decl.ty.arrayLen(mod); } else { return 1; } @@ -2737,7 +2689,7 @@ pub const Value = struct { .comptime_field_ptr => { const payload = val.castTag(.comptime_field_ptr).?.data; if (payload.field_ty.zigTypeTag(mod) == .Array) { - return payload.field_ty.arrayLen(); + return payload.field_ty.arrayLen(mod); } else { return 1; } @@ -3137,7 +3089,7 @@ pub const Value = struct { pub fn intToFloatAdvanced(val: Value, arena: Allocator, int_ty: Type, float_ty: Type, mod: *Module, opt_sema: ?*Sema) !Value { if (int_ty.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, int_ty.vectorLen()); + const result_data = try arena.alloc(Value, int_ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -3250,7 +3202,7 @@ pub const Value = struct { mod: *Module, ) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, ty.vectorLen()); + const result_data = try arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3298,7 +3250,7 @@ pub const Value = struct { mod: *Module, ) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, ty.vectorLen()); + const result_data = try arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3345,8 +3297,8 @@ pub const Value = struct { mod: *Module, ) !OverflowArithmeticResult { if (ty.zigTypeTag(mod) == .Vector) { - const overflowed_data = try arena.alloc(Value, ty.vectorLen()); - const result_data = try arena.alloc(Value, ty.vectorLen()); + const overflowed_data = try arena.alloc(Value, ty.vectorLen(mod)); + const result_data = try arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3408,7 +3360,7 @@ pub const Value = struct { mod: *Module, ) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, ty.vectorLen()); + const result_data = try arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3452,7 +3404,7 @@ pub const Value = struct { mod: *Module, ) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, ty.vectorLen()); + const result_data = try arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3527,7 +3479,7 @@ pub const Value = struct { /// operands must be (vectors of) integers; handles undefined scalars. pub fn bitwiseNot(val: Value, ty: Type, arena: Allocator, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, ty.vectorLen()); + const result_data = try arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -3565,7 +3517,7 @@ pub const Value = struct { /// operands must be (vectors of) integers; handles undefined scalars. pub fn bitwiseAnd(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3601,7 +3553,7 @@ pub const Value = struct { /// operands must be (vectors of) integers; handles undefined scalars. pub fn bitwiseNand(lhs: Value, rhs: Value, ty: Type, arena: Allocator, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, ty.vectorLen()); + const result_data = try arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3631,7 +3583,7 @@ pub const Value = struct { /// operands must be (vectors of) integers; handles undefined scalars. pub fn bitwiseOr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3666,7 +3618,7 @@ pub const Value = struct { /// operands must be (vectors of) integers; handles undefined scalars. pub fn bitwiseXor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3701,7 +3653,7 @@ pub const Value = struct { pub fn intDiv(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3741,7 +3693,7 @@ pub const Value = struct { pub fn intDivFloor(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3781,7 +3733,7 @@ pub const Value = struct { pub fn intMod(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3857,7 +3809,7 @@ pub const Value = struct { pub fn floatRem(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3904,7 +3856,7 @@ pub const Value = struct { pub fn floatMod(lhs: Value, rhs: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3950,7 +3902,7 @@ pub const Value = struct { pub fn intMul(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -3986,7 +3938,7 @@ pub const Value = struct { pub fn intTrunc(val: Value, ty: Type, allocator: Allocator, signedness: std.builtin.Signedness, bits: u16, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4007,7 +3959,7 @@ pub const Value = struct { mod: *Module, ) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4038,7 +3990,7 @@ pub const Value = struct { pub fn shl(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -4078,8 +4030,8 @@ pub const Value = struct { mod: *Module, ) !OverflowArithmeticResult { if (ty.zigTypeTag(mod) == .Vector) { - const overflowed_data = try allocator.alloc(Value, ty.vectorLen()); - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const overflowed_data = try allocator.alloc(Value, ty.vectorLen(mod)); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -4136,7 +4088,7 @@ pub const Value = struct { mod: *Module, ) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, ty.vectorLen()); + const result_data = try arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -4184,7 +4136,7 @@ pub const Value = struct { mod: *Module, ) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, ty.vectorLen()); + const result_data = try arena.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -4212,7 +4164,7 @@ pub const Value = struct { pub fn shr(lhs: Value, rhs: Value, ty: Type, allocator: Allocator, mod: *Module) !Value { if (ty.zigTypeTag(mod) == .Vector) { - const result_data = try allocator.alloc(Value, ty.vectorLen()); + const result_data = try allocator.alloc(Value, ty.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -4264,7 +4216,7 @@ pub const Value = struct { ) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4300,7 +4252,7 @@ pub const Value = struct { ) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -4359,7 +4311,7 @@ pub const Value = struct { ) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -4418,7 +4370,7 @@ pub const Value = struct { ) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -4477,7 +4429,7 @@ pub const Value = struct { ) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var lhs_buf: Value.ElemValueBuffer = undefined; var rhs_buf: Value.ElemValueBuffer = undefined; @@ -4530,7 +4482,7 @@ pub const Value = struct { pub fn sqrt(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4570,7 +4522,7 @@ pub const Value = struct { pub fn sin(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4610,7 +4562,7 @@ pub const Value = struct { pub fn cos(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4650,7 +4602,7 @@ pub const Value = struct { pub fn tan(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4690,7 +4642,7 @@ pub const Value = struct { pub fn exp(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4730,7 +4682,7 @@ pub const Value = struct { pub fn exp2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4770,7 +4722,7 @@ pub const Value = struct { pub fn log(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4810,7 +4762,7 @@ pub const Value = struct { pub fn log2(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4850,7 +4802,7 @@ pub const Value = struct { pub fn log10(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4890,7 +4842,7 @@ pub const Value = struct { pub fn fabs(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4930,7 +4882,7 @@ pub const Value = struct { pub fn floor(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -4970,7 +4922,7 @@ pub const Value = struct { pub fn ceil(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -5010,7 +4962,7 @@ pub const Value = struct { pub fn round(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -5050,7 +5002,7 @@ pub const Value = struct { pub fn trunc(val: Value, float_type: Type, arena: Allocator, mod: *Module) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var buf: Value.ElemValueBuffer = undefined; const elem_val = val.elemValueBuffer(mod, i, &buf); @@ -5097,7 +5049,7 @@ pub const Value = struct { ) !Value { const target = mod.getTarget(); if (float_type.zigTypeTag(mod) == .Vector) { - const result_data = try arena.alloc(Value, float_type.vectorLen()); + const result_data = try arena.alloc(Value, float_type.vectorLen(mod)); for (result_data, 0..) |*scalar, i| { var mulend1_buf: Value.ElemValueBuffer = undefined; const mulend1_elem = mulend1.elemValueBuffer(mod, i, &mulend1_buf);