InternPool: add a slice encoding

This uses the data field to reference its pointer field type, which
allows for efficient and infallible access of a slice type's pointer
type.
This commit is contained in:
Andrew Kelley 2023-05-05 19:13:43 -07:00
parent 08e9763951
commit 31aee50c1a
15 changed files with 119 additions and 64 deletions

View File

@ -668,6 +668,9 @@ pub const Tag = enum(u8) {
/// A fully explicitly specified pointer type.
/// data is payload to Pointer.
type_pointer,
/// A slice type.
/// data is Index of underlying pointer type.
type_slice,
/// An optional type.
/// data is the child type.
type_optional,
@ -984,6 +987,13 @@ pub fn indexToKey(ip: InternPool, index: Index) Key {
} };
},
.type_slice => {
const ptr_ty_index = @intToEnum(Index, data);
var result = indexToKey(ip, ptr_ty_index);
result.ptr_type.size = .Slice;
return result;
},
.type_optional => .{ .opt_type = @intToEnum(Index, data) },
.type_error_union => @panic("TODO"),
@ -1041,6 +1051,19 @@ pub fn get(ip: *InternPool, gpa: Allocator, key: Key) Allocator.Error!Index {
},
.ptr_type => |ptr_type| {
assert(ptr_type.elem_type != .none);
if (ptr_type.size == .Slice) {
var new_key = key;
new_key.ptr_type.size = .Many;
const ptr_ty_index = try get(ip, gpa, new_key);
try ip.items.ensureUnusedCapacity(gpa, 1);
ip.items.appendAssumeCapacity(.{
.tag = .type_slice,
.data = @enumToInt(ptr_ty_index),
});
return @intToEnum(Index, ip.items.len - 1);
}
// TODO introduce more pointer encodings
ip.items.appendAssumeCapacity(.{
.tag = .type_pointer,
@ -1401,6 +1424,20 @@ pub fn childType(ip: InternPool, i: Index) Index {
};
}
/// Given a slice type, returns the type of the pointer field.
pub fn slicePtrType(ip: InternPool, i: Index) Index {
switch (i) {
.const_slice_u8_type => return .manyptr_const_u8_type,
.const_slice_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,
else => {},
}
const item = ip.items.get(@enumToInt(i));
switch (item.tag) {
.type_slice => return @intToEnum(Index, item.data),
else => unreachable, // not a slice type
}
}
pub fn dump(ip: InternPool) void {
dumpFallible(ip, std.heap.page_allocator) catch return;
}
@ -1438,6 +1475,7 @@ fn dumpFallible(ip: InternPool, arena: Allocator) anyerror!void {
.type_array => @sizeOf(Vector),
.type_vector => @sizeOf(Vector),
.type_pointer => @sizeOf(Pointer),
.type_slice => 0,
.type_optional => 0,
.type_error_union => @sizeOf(ErrorUnion),
.type_enum_simple => @sizeOf(EnumSimple),

View File

@ -6553,7 +6553,7 @@ pub fn populateTestFunctions(
}
const decl = mod.declPtr(decl_index);
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf).childType(mod);
const tmp_test_fn_ty = decl.ty.slicePtrFieldType(&buf, mod).childType(mod);
const array_decl_index = d: {
// Add mod.test_functions to an array decl then make the test_functions

View File

@ -24201,7 +24201,7 @@ fn fieldPtr(
if (mem.eql(u8, field_name, "ptr")) {
const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);
const slice_ptr_ty = inner_ty.slicePtrFieldType(buf);
const slice_ptr_ty = inner_ty.slicePtrFieldType(buf, mod);
const result_ty = try Type.ptr(sema.arena, sema.mod, .{
.pointee_type = slice_ptr_ty,
@ -27804,7 +27804,7 @@ fn beginComptimePtrMutation(
sema,
block,
src,
parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)),
parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),
&val_ptr.castTag(.slice).?.data.ptr,
ptr_elem_ty,
parent.decl_ref_mut,
@ -27859,7 +27859,7 @@ fn beginComptimePtrMutation(
sema,
block,
src,
parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)),
parent.ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),
&val_ptr.castTag(.slice).?.data.ptr,
ptr_elem_ty,
parent.decl_ref_mut,
@ -28256,7 +28256,7 @@ fn beginComptimePtrLoad(
const slice_val = tv.val.castTag(.slice).?.data;
deref.pointee = switch (field_index) {
Value.Payload.Slice.ptr_index => TypedValue{
.ty = field_ptr.container_ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer)),
.ty = field_ptr.container_ty.slicePtrFieldType(try sema.arena.create(Type.SlicePtrFieldTypeBuffer), mod),
.val = slice_val.ptr,
},
Value.Payload.Slice.len_index => TypedValue{
@ -29339,8 +29339,9 @@ fn analyzeSlicePtr(
slice: Air.Inst.Ref,
slice_ty: Type,
) CompileError!Air.Inst.Ref {
const mod = sema.mod;
const buf = try sema.arena.create(Type.SlicePtrFieldTypeBuffer);
const result_ty = slice_ty.slicePtrFieldType(buf);
const result_ty = slice_ty.slicePtrFieldType(buf, mod);
if (try sema.resolveMaybeUndefVal(slice)) |val| {
if (val.isUndef()) return sema.addConstUndef(result_ty);
return sema.addConstant(result_ty, val.slicePtr());

View File

@ -3435,7 +3435,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const slice_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = slice_ty.slicePtrFieldType(&buf);
const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod);
const slice_mcv = try self.resolveInst(bin_op.lhs);
const base_mcv = slicePtr(slice_mcv);

View File

@ -2433,7 +2433,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const slice_ty = self.typeOf(bin_op.lhs);
const result: MCValue = if (!slice_ty.isVolatilePtr(mod) and self.liveness.isUnused(inst)) .dead else result: {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = slice_ty.slicePtrFieldType(&buf);
const ptr_ty = slice_ty.slicePtrFieldType(&buf, mod);
const slice_mcv = try self.resolveInst(bin_op.lhs);
const base_mcv = slicePtr(slice_mcv);

View File

@ -2462,7 +2462,7 @@ fn airSliceElemVal(self: *Self, inst: Air.Inst.Index) !void {
const elem_size = elem_ty.abiSize(mod);
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
const index_lock: ?RegisterLock = if (index_mcv == .register)
self.register_manager.lockRegAssumeUnused(index_mcv.register)

View File

@ -4056,7 +4056,7 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
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);
const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
const index_ty = self.typeOf(rhs);
const index_mcv = try self.resolveInst(rhs);
@ -4081,11 +4081,12 @@ fn genSliceElemPtr(self: *Self, lhs: Air.Inst.Ref, rhs: Air.Inst.Ref) !MCValue {
}
fn airSliceElemVal(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 slice_ty = self.typeOf(bin_op.lhs);
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf);
const slice_ptr_field_type = slice_ty.slicePtrFieldType(&buf, mod);
const elem_ptr = try self.genSliceElemPtr(bin_op.lhs, bin_op.rhs);
const dst_mcv = try self.allocRegOrMem(inst, false);
try self.load(dst_mcv, slice_ptr_field_type, elem_ptr);
@ -8682,7 +8683,7 @@ fn isNull(self: *Self, inst: Air.Inst.Index, opt_ty: Type, opt_mcv: MCValue) !MC
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
.{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
.{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf, mod) else pl_ty }
else
.{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
@ -8774,7 +8775,7 @@ fn isNullPtr(self: *Self, inst: Air.Inst.Index, ptr_ty: Type, ptr_mcv: MCValue)
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const some_info: struct { off: i32, ty: Type } = if (opt_ty.optionalReprIsPayload(mod))
.{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf) else pl_ty }
.{ .off = 0, .ty = if (pl_ty.isSlice(mod)) pl_ty.slicePtrFieldType(&ptr_buf, mod) else pl_ty }
else
.{ .off = @intCast(i32, pl_ty.abiSize(mod)), .ty = Type.bool };
@ -10813,7 +10814,7 @@ fn airMemset(self: *Self, inst: Air.Inst.Index, safety: bool) !void {
switch (dst_ptr_ty.ptrSize(mod)) {
.Slice => {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(&buf);
const slice_ptr_ty = dst_ptr_ty.slicePtrFieldType(&buf, mod);
// TODO: this only handles slices stored in the stack
const ptr = dst_ptr;

View File

@ -361,7 +361,7 @@ pub fn generateSymbol(
// generate ptr
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf);
const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod);
switch (try generateSymbol(bin_file, src_loc, .{
.ty = slice_ptr_field_type,
.val = slice.ptr,
@ -851,7 +851,7 @@ fn lowerParentPtr(
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
break :offset switch (field_ptr.field_index) {
0 => 0,
1 => field_ptr.container_ty.slicePtrFieldType(&buf).abiSize(mod),
1 => field_ptr.container_ty.slicePtrFieldType(&buf, mod).abiSize(mod),
else => unreachable,
};
},
@ -951,7 +951,7 @@ fn lowerDeclRef(
if (typed_value.ty.isSlice(mod)) {
// generate ptr
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf);
const slice_ptr_field_type = typed_value.ty.slicePtrFieldType(&buf, mod);
switch (try generateSymbol(bin_file, src_loc, .{
.ty = slice_ptr_field_type,
.val = typed_value.val,

View File

@ -566,7 +566,7 @@ pub const DeclGen = struct {
}
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
try dg.renderValue(writer, ty.slicePtrFieldType(&buf), val.slicePtr(), .Initializer);
try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), val.slicePtr(), .Initializer);
var len_pl: Value.Payload.U64 = .{
.base = .{ .tag = .int_u64 },
@ -787,7 +787,7 @@ pub const DeclGen = struct {
try writer.writeAll("{(");
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = ty.slicePtrFieldType(&buf);
const ptr_ty = ty.slicePtrFieldType(&buf, mod);
try dg.renderType(writer, ptr_ty);
return writer.print("){x}, {0x}}}", .{try dg.fmtIntLiteral(Type.usize, val, .Other)});
} else {
@ -1088,7 +1088,7 @@ pub const DeclGen = struct {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
try writer.writeByte('{');
try dg.renderValue(writer, ty.slicePtrFieldType(&buf), slice.ptr, initializer_type);
try dg.renderValue(writer, ty.slicePtrFieldType(&buf, mod), slice.ptr, initializer_type);
try writer.writeAll(", ");
try dg.renderValue(writer, Type.usize, slice.len, initializer_type);
try writer.writeByte('}');
@ -4107,6 +4107,7 @@ fn airMinMax(f: *Function, inst: Air.Inst.Index, operator: u8, operation: []cons
}
fn airSlice(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 bin_op = f.air.extraData(Air.Bin, ty_pl.payload).data;
@ -4116,7 +4117,7 @@ fn airSlice(f: *Function, inst: Air.Inst.Index) !CValue {
const inst_ty = f.typeOfIndex(inst);
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = inst_ty.slicePtrFieldType(&buf);
const ptr_ty = inst_ty.slicePtrFieldType(&buf, mod);
const writer = f.object.writer();
const local = try f.allocLocal(inst, inst_ty);
@ -5112,7 +5113,7 @@ fn airIsNull(
TypedValue{ .ty = payload_ty, .val = Value.zero }
else if (payload_ty.isSlice(mod) and optional_ty.optionalReprIsPayload(mod)) rhs: {
try writer.writeAll(".ptr");
const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf);
const slice_ptr_ty = payload_ty.slicePtrFieldType(&slice_ptr_buf, mod);
break :rhs TypedValue{ .ty = slice_ptr_ty, .val = Value.null };
} else rhs: {
try writer.writeAll(".is_null");
@ -5845,7 +5846,7 @@ fn airArrayToSlice(f: *Function, inst: Air.Inst.Index) !CValue {
// &(*(void *)p)[0], although LLVM does via GetElementPtr
if (operand == .undef) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf) }, .Initializer);
try f.writeCValue(writer, .{ .undef = inst_ty.slicePtrFieldType(&buf, mod) }, .Initializer);
} else if (array_ty.hasRuntimeBitsIgnoreComptime(mod)) {
try writer.writeAll("&(");
try f.writeCValueDeref(writer, operand);

View File

@ -1432,7 +1432,7 @@ pub const CType = extern union {
.payload => unreachable,
}) |fwd_idx| {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = ty.slicePtrFieldType(&buf);
const ptr_ty = ty.slicePtrFieldType(&buf, mod);
if (try lookup.typeToIndex(ptr_ty, kind)) |ptr_idx| {
self.storage = .{ .anon = undefined };
self.storage.anon.fields[0] = .{

View File

@ -1638,7 +1638,7 @@ pub const Object = struct {
if (ty.isSlice(mod)) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = ty.slicePtrFieldType(&buf);
const ptr_ty = ty.slicePtrFieldType(&buf, mod);
const len_ty = Type.usize;
const name = try ty.nameAlloc(gpa, o.module);
@ -2822,7 +2822,7 @@ pub const DeclGen = struct {
.Pointer => {
if (t.isSlice(mod)) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_type = t.slicePtrFieldType(&buf);
const ptr_type = t.slicePtrFieldType(&buf, mod);
const fields: [2]*llvm.Type = .{
try dg.lowerType(ptr_type),
@ -3182,9 +3182,9 @@ pub const DeclGen = struct {
const param_ty = fn_info.param_types[it.zig_index - 1];
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = if (param_ty.zigTypeTag(mod) == .Optional)
param_ty.optionalChild(mod).slicePtrFieldType(&buf)
param_ty.optionalChild(mod).slicePtrFieldType(&buf, mod)
else
param_ty.slicePtrFieldType(&buf);
param_ty.slicePtrFieldType(&buf, mod);
const ptr_llvm_ty = try dg.lowerType(ptr_ty);
const len_llvm_ty = try dg.lowerType(Type.usize);
@ -3387,7 +3387,7 @@ pub const DeclGen = struct {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const fields: [2]*llvm.Value = .{
try dg.lowerValue(.{
.ty = tv.ty.slicePtrFieldType(&buf),
.ty = tv.ty.slicePtrFieldType(&buf, mod),
.val = slice.ptr,
}),
try dg.lowerValue(.{
@ -4169,7 +4169,7 @@ pub const DeclGen = struct {
const mod = self.module;
if (tv.ty.isSlice(mod)) {
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = tv.ty.slicePtrFieldType(&buf);
const ptr_ty = tv.ty.slicePtrFieldType(&buf, mod);
var slice_len: Value.Payload.U64 = .{
.base = .{ .tag = .int_u64 },
.data = tv.val.sliceLen(mod),
@ -6654,7 +6654,7 @@ pub const FuncGen = struct {
if (payload_ty.isSlice(mod)) {
const slice_ptr = self.builder.buildExtractValue(loaded, 0, "");
var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(&slice_buf));
const ptr_ty = try self.dg.lowerType(payload_ty.slicePtrFieldType(&slice_buf, mod));
return self.builder.buildICmp(pred, slice_ptr, ptr_ty.constNull(), "");
}
return self.builder.buildICmp(pred, loaded, optional_llvm_ty.constNull(), "");

View File

@ -669,7 +669,7 @@ pub const DeclGen = struct {
const slice = val.castTag(.slice).?.data;
var buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = ty.slicePtrFieldType(&buf);
const ptr_ty = ty.slicePtrFieldType(&buf, mod);
try self.lower(ptr_ty, slice.ptr);
try self.addInt(Type.usize, slice.len);
@ -2489,7 +2489,7 @@ pub const DeclGen = struct {
const index_id = try self.resolve(bin_op.rhs);
var slice_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = slice_ty.slicePtrFieldType(&slice_buf);
const ptr_ty = slice_ty.slicePtrFieldType(&slice_buf, mod);
const ptr_ty_ref = try self.resolveType(ptr_ty, .direct);
const slice_ptr = try self.extractField(ptr_ty, slice_id, 0);
@ -2987,7 +2987,7 @@ pub const DeclGen = struct {
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = if (payload_ty.isSlice(mod))
payload_ty.slicePtrFieldType(&ptr_buf)
payload_ty.slicePtrFieldType(&ptr_buf, mod)
else
payload_ty;

View File

@ -278,7 +278,7 @@ pub const DeclState = struct {
var index = dbg_info_buffer.items.len;
try dbg_info_buffer.resize(index + 4);
var buf = try arena.create(Type.SlicePtrFieldTypeBuffer);
const ptr_ty = ty.slicePtrFieldType(buf);
const ptr_ty = ty.slicePtrFieldType(buf, mod);
try self.addTypeRelocGlobal(atom_index, ptr_ty, @intCast(u32, index));
// DW.AT.data_member_location, DW.FORM.udata
try dbg_info_buffer.ensureUnusedCapacity(6);

View File

@ -2042,7 +2042,18 @@ pub const Type = struct {
else => unreachable,
},
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
else => @panic("TODO"),
.ptr_type => |ptr_type| {
if (ptr_type.alignment != 0) {
return @intCast(u32, ptr_type.alignment);
} else if (opt_sema) |sema| {
const res = try ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .{ .sema = sema });
return res.scalar;
} else {
return (ptr_type.elem_type.toType().abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
}
},
.opt_type => |child| return child.toType().ptrAlignmentAdvanced(mod, opt_sema),
else => unreachable,
},
}
}
@ -3060,33 +3071,36 @@ pub const Type = struct {
pointer: Payload.Pointer,
};
pub fn slicePtrFieldType(self: Type, buffer: *SlicePtrFieldTypeBuffer) Type {
switch (self.tag()) {
.pointer => {
const payload = self.castTag(.pointer).?.data;
assert(payload.size == .Slice);
pub fn slicePtrFieldType(ty: Type, buffer: *SlicePtrFieldTypeBuffer, mod: *const Module) Type {
switch (ty.ip_index) {
.none => switch (ty.tag()) {
.pointer => {
const payload = ty.castTag(.pointer).?.data;
assert(payload.size == .Slice);
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);
},
};
return Type.initPayload(&buffer.pointer.base);
},
else => unreachable,
else => unreachable,
},
else => return mod.intern_pool.slicePtrType(ty.ip_index).toType(),
}
}

View File

@ -2078,7 +2078,7 @@ pub const Value = struct {
}
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
return eqlAdvanced(a_payload.ptr, ptr_ty, b_payload.ptr, ptr_ty, mod, opt_sema);
},
@ -2237,7 +2237,7 @@ pub const Value = struct {
}
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
const a_ptr = switch (a_ty.ptrSize(mod)) {
.Slice => a.slicePtr(),
.One => a,
@ -2376,7 +2376,7 @@ pub const Value = struct {
.slice => {
const slice = val.castTag(.slice).?.data;
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
hash(slice.ptr, ptr_ty, hasher, mod);
hash(slice.len, Type.usize, hasher, mod);
},
@ -2499,7 +2499,7 @@ pub const Value = struct {
.slice => {
const slice = val.castTag(.slice).?.data;
var ptr_buf: Type.SlicePtrFieldTypeBuffer = undefined;
const ptr_ty = ty.slicePtrFieldType(&ptr_buf);
const ptr_ty = ty.slicePtrFieldType(&ptr_buf, mod);
slice.ptr.hashUncoerced(ptr_ty, hasher, mod);
},
else => val.hashPtr(hasher, mod),