compiler: eliminate legacy Type.Tag.pointer

Now pointer types are stored only in InternPool.
This commit is contained in:
Andrew Kelley
2023-05-18 22:02:55 -07:00
parent 607737d841
commit 7bf91fc79a
15 changed files with 295 additions and 673 deletions

View File

@@ -42,7 +42,6 @@ pub const Type = struct {
.error_set_merged,
=> return .ErrorSet,
.pointer,
.inferred_alloc_const,
.inferred_alloc_mut,
=> return .Pointer,
@@ -250,17 +249,9 @@ pub const Type = struct {
return elem_ty;
}
/// Asserts the type is a pointer.
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,
},
};
return !mod.intern_pool.indexToKey(ty.ip_index).ptr_type.is_const;
}
pub const ArrayInfo = struct {
@@ -277,24 +268,21 @@ pub const Type = struct {
};
}
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,
else => unreachable,
},
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,
},
pub fn ptrInfoIp(ty: Type, ip: InternPool) InternPool.Key.PtrType {
return switch (ip.indexToKey(ty.ip_index)) {
.ptr_type => |p| p,
.opt_type => |child| switch (ip.indexToKey(child)) {
.ptr_type => |p| p,
else => unreachable,
},
else => unreachable,
};
}
pub fn ptrInfo(ty: Type, mod: *const Module) Payload.Pointer.Data {
return Payload.Pointer.Data.fromKey(ptrInfoIp(ty, mod.intern_pool));
}
pub fn eql(a: Type, b: Type, mod: *Module) bool {
if (a.ip_index != .none or b.ip_index != .none) {
// The InternPool data structure hashes based on Key to make interned objects
@@ -335,7 +323,6 @@ pub const Type = struct {
return true;
},
.pointer,
.inferred_alloc_const,
.inferred_alloc_mut,
=> {
@@ -434,7 +421,6 @@ pub const Type = struct {
std.hash.autoHash(hasher, ies);
},
.pointer,
.inferred_alloc_const,
.inferred_alloc_mut,
=> {
@@ -512,26 +498,6 @@ pub const Type = struct {
.inferred_alloc_mut,
=> unreachable,
.pointer => {
const payload = self.castTag(.pointer).?.data;
const sent: ?Value = if (payload.sentinel) |some|
try some.copy(allocator)
else
null;
return Tag.pointer.create(allocator, .{
.pointee_type = try payload.pointee_type.copy(allocator),
.sentinel = sent,
.@"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 = payload.size,
});
},
.error_union => {
const payload = self.castTag(.error_union).?.data;
return Tag.error_union.create(allocator, .{
@@ -623,41 +589,6 @@ pub const Type = struct {
while (true) {
const t = ty.tag();
switch (t) {
.pointer => {
const payload = ty.castTag(.pointer).?.data;
if (payload.sentinel) |some| switch (payload.size) {
.One, .C => unreachable,
.Many => try writer.print("[*:{}]", .{some.fmtDebug()}),
.Slice => try writer.print("[:{}]", .{some.fmtDebug()}),
} else switch (payload.size) {
.One => try writer.writeAll("*"),
.Many => try writer.writeAll("[*]"),
.C => try writer.writeAll("[*c]"),
.Slice => try writer.writeAll("[]"),
}
if (payload.@"align" != 0 or payload.host_size != 0 or payload.vector_index != .none) {
try writer.print("align({d}", .{payload.@"align"});
if (payload.bit_offset != 0 or payload.host_size != 0) {
try writer.print(":{d}:{d}", .{ payload.bit_offset, payload.host_size });
}
if (payload.vector_index == .runtime) {
try writer.writeAll(":?");
} else if (payload.vector_index != .none) {
try writer.print(":{d}", .{@enumToInt(payload.vector_index)});
}
try writer.writeAll(") ");
}
if (payload.@"addrspace" != .generic) {
try writer.print("addrspace(.{s}) ", .{@tagName(payload.@"addrspace")});
}
if (!payload.mutable) try writer.writeAll("const ");
if (payload.@"volatile") try writer.writeAll("volatile ");
if (payload.@"allowzero" and payload.size != .C) try writer.writeAll("allowzero ");
ty = payload.pointee_type;
continue;
},
.error_union => {
const payload = ty.castTag(.error_union).?.data;
try payload.error_set.dump("", .{}, writer);
@@ -734,47 +665,6 @@ pub const Type = struct {
try print(error_union.payload, writer, mod);
},
.pointer => {
const info = ty.ptrInfo(mod);
if (info.sentinel) |s| switch (info.size) {
.One, .C => unreachable,
.Many => try writer.print("[*:{}]", .{s.fmtValue(info.pointee_type, mod)}),
.Slice => try writer.print("[:{}]", .{s.fmtValue(info.pointee_type, mod)}),
} else switch (info.size) {
.One => try writer.writeAll("*"),
.Many => try writer.writeAll("[*]"),
.C => try writer.writeAll("[*c]"),
.Slice => try writer.writeAll("[]"),
}
if (info.@"align" != 0 or info.host_size != 0 or info.vector_index != .none) {
if (info.@"align" != 0) {
try writer.print("align({d}", .{info.@"align"});
} else {
const alignment = info.pointee_type.abiAlignment(mod);
try writer.print("align({d}", .{alignment});
}
if (info.bit_offset != 0 or info.host_size != 0) {
try writer.print(":{d}:{d}", .{ info.bit_offset, info.host_size });
}
if (info.vector_index == .runtime) {
try writer.writeAll(":?");
} else if (info.vector_index != .none) {
try writer.print(":{d}", .{@enumToInt(info.vector_index)});
}
try writer.writeAll(") ");
}
if (info.@"addrspace" != .generic) {
try writer.print("addrspace(.{s}) ", .{@tagName(info.@"addrspace")});
}
if (!info.mutable) try writer.writeAll("const ");
if (info.@"volatile") try writer.writeAll("volatile ");
if (info.@"allowzero" and info.size != .C) try writer.writeAll("allowzero ");
try print(info.pointee_type, writer, mod);
},
.error_set => {
const names = ty.castTag(.error_set).?.data.names.keys();
try writer.writeAll("error{");
@@ -951,8 +841,8 @@ pub const Type = struct {
try writer.writeAll("...");
}
try writer.writeAll(") ");
if (fn_info.alignment != 0) {
try writer.print("align({d}) ", .{fn_info.alignment});
if (fn_info.alignment.toByteUnitsOptional()) |a| {
try writer.print("align({d}) ", .{a});
}
if (fn_info.cc != .Unspecified) {
try writer.writeAll("callconv(.");
@@ -1032,20 +922,6 @@ pub const Type = struct {
.error_set_merged,
=> return true,
// Pointers to zero-bit types still have a runtime address; however, pointers
// to comptime-only types do not, with the exception of function pointers.
.pointer => {
if (ignore_comptime_only) {
return true;
} else if (ty.childType(mod).zigTypeTag(mod) == .Fn) {
return !mod.typeToFunc(ty.childType(mod)).?.is_generic;
} else if (strat == .sema) {
return !(try strat.sema.typeRequiresComptime(ty));
} else {
return !comptimeOnly(ty, mod);
}
},
.inferred_alloc_const => unreachable,
.inferred_alloc_mut => unreachable,
},
@@ -1231,8 +1107,6 @@ pub const Type = struct {
.empty_struct_type => false,
.none => switch (ty.tag()) {
.pointer => true,
.error_set,
.error_set_single,
.error_set_inferred,
@@ -1410,51 +1284,27 @@ pub const Type = struct {
}
pub fn ptrAlignmentAdvanced(ty: Type, mod: *Module, opt_sema: ?*Sema) !u32 {
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;
}
},
else => unreachable,
return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.ptr_type => |ptr_type| {
if (ptr_type.alignment.toByteUnitsOptional()) |a| {
return @intCast(u32, a);
} 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;
}
},
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.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,
},
}
.opt_type => |child| child.toType().ptrAlignmentAdvanced(mod, opt_sema),
else => unreachable,
};
}
pub fn ptrAddressSpace(ty: Type, mod: *const Module) std.builtin.AddressSpace {
return switch (ty.ip_index) {
.none => switch (ty.tag()) {
.pointer => ty.castTag(.pointer).?.data.@"addrspace",
else => unreachable,
},
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.ptr_type => |ptr_type| ptr_type.address_space,
.opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space,
else => unreachable,
},
return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.ptr_type => |ptr_type| ptr_type.address_space,
.opt_type => |child| mod.intern_pool.indexToKey(child).ptr_type.address_space,
else => unreachable,
};
}
@@ -1504,7 +1354,6 @@ pub const Type = struct {
switch (ty.ip_index) {
.empty_struct_type => return AbiAlignmentAdvanced{ .scalar = 0 },
.none => switch (ty.tag()) {
.pointer => return AbiAlignmentAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },
// TODO revisit this when we have the concept of the error tag type
.error_set_inferred,
@@ -1541,10 +1390,11 @@ pub const Type = struct {
.opt_type => return abiAlignmentAdvancedOptional(ty, mod, strat),
.error_union_type => return abiAlignmentAdvancedErrorUnion(ty, mod, strat),
// represents machine code; not a pointer
.func_type => |func_type| {
const alignment = @intCast(u32, func_type.alignment);
if (alignment != 0) return AbiAlignmentAdvanced{ .scalar = alignment };
return AbiAlignmentAdvanced{ .scalar = target_util.defaultFunctionAlignment(target) };
.func_type => |func_type| return AbiAlignmentAdvanced{
.scalar = if (func_type.alignment.toByteUnitsOptional()) |a|
@intCast(u32, a)
else
target_util.defaultFunctionAlignment(target),
},
.simple_type => |t| switch (t) {
@@ -1882,11 +1732,6 @@ pub const Type = struct {
.inferred_alloc_const => unreachable,
.inferred_alloc_mut => unreachable,
.pointer => switch (ty.castTag(.pointer).?.data.size) {
.Slice => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) * 2 },
else => return AbiSizeAdvanced{ .scalar = @divExact(target.ptrBitWidth(), 8) },
},
// TODO revisit this when we have the concept of the error tag type
.error_set_inferred,
.error_set,
@@ -2201,11 +2046,6 @@ pub const Type = struct {
.inferred_alloc_const => unreachable,
.inferred_alloc_mut => unreachable,
.pointer => switch (ty.castTag(.pointer).?.data.size) {
.Slice => return target.ptrBitWidth() * 2,
else => return target.ptrBitWidth(),
},
.error_set,
.error_set_single,
.error_set_inferred,
@@ -2384,8 +2224,6 @@ pub const Type = struct {
.inferred_alloc_mut,
=> true,
.pointer => ty.castTag(.pointer).?.data.size == .One,
else => false,
},
else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
@@ -2408,8 +2246,6 @@ pub const Type = struct {
.inferred_alloc_mut,
=> .One,
.pointer => ty.castTag(.pointer).?.data.size,
else => null,
},
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
@@ -2421,10 +2257,7 @@ pub const Type = struct {
pub fn isSlice(ty: Type, mod: *const Module) bool {
return switch (ty.ip_index) {
.none => switch (ty.tag()) {
.pointer => ty.castTag(.pointer).?.data.size == .Slice,
else => false,
},
.none => false,
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.ptr_type => |ptr_type| ptr_type.size == .Slice,
else => false,
@@ -2432,50 +2265,14 @@ pub const Type = struct {
};
}
pub const SlicePtrFieldTypeBuffer = union {
pointer: Payload.Pointer,
};
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,
},
},
};
return Type.initPayload(&buffer.pointer.base);
},
else => unreachable,
},
else => return mod.intern_pool.slicePtrType(ty.ip_index).toType(),
}
pub fn slicePtrFieldType(ty: Type, mod: *const Module) Type {
return mod.intern_pool.slicePtrType(ty.ip_index).toType();
}
pub fn isConstPtr(ty: Type, mod: *const Module) bool {
return switch (ty.ip_index) {
.none => switch (ty.tag()) {
.pointer => !ty.castTag(.pointer).?.data.mutable,
else => false,
},
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.none => false,
else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.ptr_type => |ptr_type| ptr_type.is_const,
else => false,
},
@@ -2488,10 +2285,7 @@ pub const Type = struct {
pub fn isVolatilePtrIp(ty: Type, ip: InternPool) bool {
return switch (ty.ip_index) {
.none => switch (ty.tag()) {
.pointer => ty.castTag(.pointer).?.data.@"volatile",
else => false,
},
.none => false,
else => switch (ip.indexToKey(ty.ip_index)) {
.ptr_type => |ptr_type| ptr_type.is_volatile,
else => false,
@@ -2501,12 +2295,10 @@ pub const Type = struct {
pub fn isAllowzeroPtr(ty: Type, mod: *const Module) bool {
return switch (ty.ip_index) {
.none => switch (ty.tag()) {
.pointer => ty.castTag(.pointer).?.data.@"allowzero",
else => ty.zigTypeTag(mod) == .Optional,
},
.none => false,
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.ptr_type => |ptr_type| ptr_type.is_allowzero,
.opt_type => true,
else => false,
},
};
@@ -2514,10 +2306,7 @@ pub const Type = struct {
pub fn isCPtr(ty: Type, mod: *const Module) bool {
return switch (ty.ip_index) {
.none => switch (ty.tag()) {
.pointer => ty.castTag(.pointer).?.data.size == .C,
else => false,
},
.none => false,
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.ptr_type => |ptr_type| ptr_type.size == .C,
else => false,
@@ -2526,16 +2315,9 @@ pub const Type = struct {
}
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,
},
else => return false,
},
else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
return switch (ty.ip_index) {
.none => false,
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.ptr_type => |ptr_type| switch (ptr_type.size) {
.Slice => false,
.One, .Many, .C => true,
@@ -2549,7 +2331,7 @@ pub const Type = struct {
},
else => false,
},
}
};
}
/// For pointer-like optionals, returns true, otherwise returns the allowzero property
@@ -2563,47 +2345,43 @@ pub const Type = struct {
/// See also `isPtrLikeOptional`.
pub fn optionalReprIsPayload(ty: Type, mod: *const Module) bool {
if (ty.ip_index != .none) return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.opt_type => |child| switch (child.toType().zigTypeTag(mod)) {
.Pointer => {
const info = child.toType().ptrInfo(mod);
switch (info.size) {
.C => return false,
else => return !info.@"allowzero",
}
return switch (ty.ip_index) {
.none => false,
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.opt_type => |child| switch (child.toType().zigTypeTag(mod)) {
.Pointer => {
const info = child.toType().ptrInfo(mod);
return switch (info.size) {
.C => false,
else => !info.@"allowzero",
};
},
.ErrorSet => true,
else => false,
},
.ErrorSet => true,
else => false,
},
else => false,
};
switch (ty.tag()) {
.pointer => return ty.castTag(.pointer).?.data.size == .C,
else => return false,
}
}
/// Returns true if the type is optional and would be lowered to a single pointer
/// address value, using 0 for null. Note that this returns true for C pointers.
/// This function must be kept in sync with `Sema.typePtrOrOptionalPtrTy`.
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,
.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,
return switch (ty.ip_index) {
.none => false,
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.ptr_type => |ptr_type| ptr_type.size == .C,
.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,
},
else => false,
},
else => false,
},
else => false,
};
switch (ty.tag()) {
.pointer => return ty.castTag(.pointer).?.data.size == .C,
else => return false,
}
}
/// For *[N]T, returns [N]T.
@@ -2614,14 +2392,7 @@ pub const Type = struct {
}
pub fn childTypeIp(ty: Type, ip: InternPool) Type {
return switch (ty.ip_index) {
.none => switch (ty.tag()) {
.pointer => ty.castTag(.pointer).?.data.pointee_type,
else => unreachable,
},
else => ip.childType(ty.ip_index).toType(),
};
return ip.childType(ty.ip_index).toType();
}
/// For *[N]T, returns T.
@@ -2634,34 +2405,19 @@ 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.ip_index) {
.none => switch (ty.tag()) {
.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,
return 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(),
},
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(),
},
.anyframe_type => |child| {
assert(child != .none);
return child.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,
.anyframe_type => |child| {
assert(child != .none);
return child.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,
};
}
@@ -2683,21 +2439,13 @@ pub const Type = struct {
/// Asserts that the type is an optional.
/// Note that for C pointers this returns the type unmodified.
pub fn optionalChild(ty: Type, mod: *const Module) Type {
return switch (ty.ip_index) {
.none => switch (ty.tag()) {
.pointer, // here we assume it is a C pointer
=> return ty,
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,
return 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,
};
}
@@ -2921,23 +2669,16 @@ pub const Type = struct {
/// Asserts the type is an array, pointer or vector.
pub fn sentinel(ty: Type, mod: *const Module) ?Value {
return switch (ty.ip_index) {
.none => switch (ty.tag()) {
.pointer => ty.castTag(.pointer).?.data.sentinel,
return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.vector_type,
.struct_type,
.anon_struct_type,
=> null,
else => unreachable,
},
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
.vector_type,
.struct_type,
.anon_struct_type,
=> null,
.array_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null,
.ptr_type => |t| if (t.sentinel != .none) t.sentinel.toValue() else null,
.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,
},
else => unreachable,
};
}
@@ -3196,7 +2937,6 @@ pub const Type = struct {
.error_set,
.error_set_merged,
.error_set_inferred,
.pointer,
=> return null,
.inferred_alloc_const => unreachable,
@@ -3400,15 +3140,6 @@ pub const Type = struct {
.inferred_alloc_mut => unreachable,
.inferred_alloc_const => unreachable,
.pointer => {
const child_ty = ty.childType(mod);
if (child_ty.zigTypeTag(mod) == .Fn) {
return false;
} else {
return child_ty.comptimeOnly(mod);
}
},
.error_union => return ty.errorUnionPayload().comptimeOnly(mod),
},
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
@@ -4096,7 +3827,6 @@ pub const Type = struct {
inferred_alloc_const, // See last_no_payload_tag below.
// After this, the tag requires a payload.
pointer,
error_union,
error_set,
error_set_single,
@@ -4117,7 +3847,6 @@ pub const Type = struct {
.error_set_inferred => Payload.ErrorSetInferred,
.error_set_merged => Payload.ErrorSetMerged,
.pointer => Payload.Pointer,
.error_union => Payload.ErrorUnion,
.error_set_single => Payload.Name,
};
@@ -4230,10 +3959,8 @@ pub const Type = struct {
data: *Module.Fn.InferredErrorSet,
};
/// TODO: remove this data structure since we have `InternPool.Key.PtrType`.
pub const Pointer = struct {
pub const base_tag = Tag.pointer;
base: Payload = Payload{ .tag = base_tag },
data: Data,
pub const Data = struct {
@@ -4270,7 +3997,7 @@ pub const Type = struct {
return .{
.pointee_type = p.elem_type.toType(),
.sentinel = if (p.sentinel != .none) p.sentinel.toValue() else null,
.@"align" = @intCast(u32, p.alignment),
.@"align" = @intCast(u32, p.alignment.toByteUnits(0)),
.@"addrspace" = p.address_space,
.bit_offset = p.bit_offset,
.host_size = p.host_size,
@@ -4368,11 +4095,11 @@ pub const Type = struct {
pub const err_int = Type.u16;
pub fn ptr(arena: Allocator, mod: *Module, data: Payload.Pointer.Data) !Type {
var d = data;
// TODO: update callsites of this function to directly call mod.ptrType
// and then delete this function.
_ = arena;
if (d.size == .C) {
d.@"allowzero" = true;
}
var d = data;
// Canonicalize non-zero alignment. If it matches the ABI alignment of the pointee
// type, we change it to 0 here. If this causes an assertion trip because the
@@ -4396,32 +4123,19 @@ pub const Type = struct {
}
}
ip: {
if (d.pointee_type.ip_index == .none) break :ip;
if (d.sentinel) |s| {
switch (s.ip_index) {
.none, .null_value => break :ip,
else => {},
}
}
return mod.ptrType(.{
.elem_type = d.pointee_type.ip_index,
.sentinel = if (d.sentinel) |s| s.ip_index else .none,
.alignment = d.@"align",
.host_size = d.host_size,
.bit_offset = d.bit_offset,
.vector_index = d.vector_index,
.size = d.size,
.is_const = !d.mutable,
.is_volatile = d.@"volatile",
.is_allowzero = d.@"allowzero",
.address_space = d.@"addrspace",
});
}
return Type.Tag.pointer.create(arena, d);
return mod.ptrType(.{
.elem_type = d.pointee_type.ip_index,
.sentinel = if (d.sentinel) |s| s.ip_index else .none,
.alignment = InternPool.Alignment.fromByteUnits(d.@"align"),
.host_size = d.host_size,
.bit_offset = d.bit_offset,
.vector_index = d.vector_index,
.size = d.size,
.is_const = !d.mutable,
.is_volatile = d.@"volatile",
.is_allowzero = d.@"allowzero",
.address_space = d.@"addrspace",
});
}
pub fn array(