mirror of
https://github.com/ziglang/zig.git
synced 2026-01-10 01:15:14 +00:00
compiler: eliminate legacy Type.Tag.optional
Now optional types are only stored in InternPool.
This commit is contained in:
parent
f21ca3da19
commit
607737d841
50
src/Sema.zig
50
src/Sema.zig
@ -18589,12 +18589,10 @@ fn fieldType(
|
||||
return sema.addType(field.ty);
|
||||
},
|
||||
.Optional => {
|
||||
if (cur_ty.castTag(.optional)) |some| {
|
||||
// Struct/array init through optional requires the child type to not be a pointer.
|
||||
// If the child of .optional is a pointer it'll error on the next loop.
|
||||
cur_ty = some.data;
|
||||
continue;
|
||||
}
|
||||
// Struct/array init through optional requires the child type to not be a pointer.
|
||||
// If the child of .optional is a pointer it'll error on the next loop.
|
||||
cur_ty = mod.intern_pool.indexToKey(cur_ty.ip_index).opt_type.toType();
|
||||
continue;
|
||||
},
|
||||
.ErrorUnion => {
|
||||
cur_ty = cur_ty.errorUnionPayload();
|
||||
@ -20390,7 +20388,7 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
|
||||
ptr_info.@"align" = dest_align;
|
||||
var dest_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);
|
||||
if (ptr_ty.zigTypeTag(mod) == .Optional) {
|
||||
dest_ty = try Type.Tag.optional.create(sema.arena, dest_ty);
|
||||
dest_ty = try mod.optionalType(dest_ty.toIntern());
|
||||
}
|
||||
|
||||
if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| {
|
||||
@ -31622,10 +31620,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
|
||||
}
|
||||
},
|
||||
|
||||
.optional => {
|
||||
return sema.resolveTypeRequiresComptime(ty.optionalChild(mod));
|
||||
},
|
||||
|
||||
.error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()),
|
||||
},
|
||||
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
@ -33057,15 +33051,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
|
||||
.pointer,
|
||||
=> return null,
|
||||
|
||||
.optional => {
|
||||
const child_ty = ty.optionalChild(mod);
|
||||
if (child_ty.isNoReturn()) {
|
||||
return Value.null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
.inferred_alloc_const => unreachable,
|
||||
.inferred_alloc_mut => unreachable,
|
||||
},
|
||||
@ -33628,26 +33613,6 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
|
||||
.inferred_alloc_const => unreachable,
|
||||
.inferred_alloc_mut => unreachable,
|
||||
|
||||
.optional => {
|
||||
const child_type = ty.optionalChild(mod);
|
||||
if (child_type.zigTypeTag(mod) != .Pointer) return null;
|
||||
|
||||
const info = child_type.ptrInfo(mod);
|
||||
switch (info.size) {
|
||||
.Slice, .C => return null,
|
||||
.Many, .One => {
|
||||
if (info.@"allowzero") return null;
|
||||
|
||||
// optionals of zero sized types behave like bools, not pointers
|
||||
if ((try sema.typeHasOnePossibleValue(child_type)) != null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return child_type;
|
||||
},
|
||||
}
|
||||
},
|
||||
|
||||
else => return null,
|
||||
}
|
||||
}
|
||||
@ -33682,10 +33647,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
|
||||
}
|
||||
},
|
||||
|
||||
.optional => {
|
||||
return sema.typeRequiresComptime(ty.optionalChild(mod));
|
||||
},
|
||||
|
||||
.error_union => return sema.typeRequiresComptime(ty.errorUnionPayload()),
|
||||
},
|
||||
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
@ -33705,6 +33666,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
|
||||
.array_type => |array_type| return sema.typeRequiresComptime(array_type.child.toType()),
|
||||
.vector_type => |vector_type| return sema.typeRequiresComptime(vector_type.child.toType()),
|
||||
.opt_type => |child| return sema.typeRequiresComptime(child.toType()),
|
||||
|
||||
.error_union_type => |error_union_type| {
|
||||
return sema.typeRequiresComptime(error_union_type.payload_type.toType());
|
||||
},
|
||||
|
||||
153
src/type.zig
153
src/type.zig
@ -47,8 +47,6 @@ pub const Type = struct {
|
||||
.inferred_alloc_mut,
|
||||
=> return .Pointer,
|
||||
|
||||
.optional => return .Optional,
|
||||
|
||||
.error_union => return .ErrorUnion,
|
||||
},
|
||||
else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
@ -283,10 +281,6 @@ pub const Type = struct {
|
||||
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,
|
||||
},
|
||||
@ -387,12 +381,6 @@ pub const Type = struct {
|
||||
return true;
|
||||
},
|
||||
|
||||
.optional => {
|
||||
if (b.zigTypeTag(mod) != .Optional) return false;
|
||||
|
||||
return a.optionalChild(mod).eql(b.optionalChild(mod), mod);
|
||||
},
|
||||
|
||||
.error_union => {
|
||||
if (b.zigTypeTag(mod) != .ErrorUnion) return false;
|
||||
|
||||
@ -466,12 +454,6 @@ pub const Type = struct {
|
||||
std.hash.autoHash(hasher, info.size);
|
||||
},
|
||||
|
||||
.optional => {
|
||||
std.hash.autoHash(hasher, std.builtin.TypeId.Optional);
|
||||
|
||||
hashWithHasher(ty.optionalChild(mod), hasher, mod);
|
||||
},
|
||||
|
||||
.error_union => {
|
||||
std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion);
|
||||
|
||||
@ -530,19 +512,6 @@ pub const Type = struct {
|
||||
.inferred_alloc_mut,
|
||||
=> unreachable,
|
||||
|
||||
.optional => {
|
||||
const payload = self.cast(Payload.ElemType).?;
|
||||
const new_payload = try allocator.create(Payload.ElemType);
|
||||
new_payload.* = .{
|
||||
.base = .{ .tag = payload.base.tag },
|
||||
.data = try payload.data.copy(allocator),
|
||||
};
|
||||
return Type{
|
||||
.ip_index = .none,
|
||||
.legacy = .{ .ptr_otherwise = &new_payload.base },
|
||||
};
|
||||
},
|
||||
|
||||
.pointer => {
|
||||
const payload = self.castTag(.pointer).?.data;
|
||||
const sent: ?Value = if (payload.sentinel) |some|
|
||||
@ -654,13 +623,6 @@ pub const Type = struct {
|
||||
while (true) {
|
||||
const t = ty.tag();
|
||||
switch (t) {
|
||||
.optional => {
|
||||
const child_type = ty.castTag(.optional).?.data;
|
||||
try writer.writeByte('?');
|
||||
ty = child_type;
|
||||
continue;
|
||||
},
|
||||
|
||||
.pointer => {
|
||||
const payload = ty.castTag(.pointer).?.data;
|
||||
if (payload.sentinel) |some| switch (payload.size) {
|
||||
@ -813,11 +775,6 @@ pub const Type = struct {
|
||||
try print(info.pointee_type, writer, mod);
|
||||
},
|
||||
|
||||
.optional => {
|
||||
const child_type = ty.castTag(.optional).?.data;
|
||||
try writer.writeByte('?');
|
||||
try print(child_type, writer, mod);
|
||||
},
|
||||
.error_set => {
|
||||
const names = ty.castTag(.error_set).?.data.names.keys();
|
||||
try writer.writeAll("error{");
|
||||
@ -911,8 +868,7 @@ pub const Type = struct {
|
||||
},
|
||||
.opt_type => |child| {
|
||||
try writer.writeByte('?');
|
||||
try print(child.toType(), writer, mod);
|
||||
return;
|
||||
return print(child.toType(), writer, mod);
|
||||
},
|
||||
.error_union_type => |error_union_type| {
|
||||
try print(error_union_type.error_set_type.toType(), writer, mod);
|
||||
@ -1090,21 +1046,6 @@ pub const Type = struct {
|
||||
}
|
||||
},
|
||||
|
||||
.optional => {
|
||||
const child_ty = ty.optionalChild(mod);
|
||||
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);
|
||||
}
|
||||
},
|
||||
|
||||
.inferred_alloc_const => unreachable,
|
||||
.inferred_alloc_mut => unreachable,
|
||||
},
|
||||
@ -1301,8 +1242,6 @@ pub const Type = struct {
|
||||
|
||||
.inferred_alloc_mut => unreachable,
|
||||
.inferred_alloc_const => unreachable,
|
||||
|
||||
.optional => ty.isPtrLikeOptional(mod),
|
||||
},
|
||||
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
.int_type,
|
||||
@ -1319,7 +1258,7 @@ pub const Type = struct {
|
||||
=> false,
|
||||
|
||||
.array_type => |array_type| array_type.child.toType().hasWellDefinedLayout(mod),
|
||||
.opt_type => |child| child.toType().isPtrLikeOptional(mod),
|
||||
.opt_type => ty.isPtrLikeOptional(mod),
|
||||
|
||||
.simple_type => |t| switch (t) {
|
||||
.f16,
|
||||
@ -1484,7 +1423,6 @@ pub const Type = struct {
|
||||
return (ptr_info.pointee_type.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
|
||||
}
|
||||
},
|
||||
.optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(mod, opt_sema),
|
||||
|
||||
else => unreachable,
|
||||
},
|
||||
@ -1510,11 +1448,6 @@ pub const Type = struct {
|
||||
.none => switch (ty.tag()) {
|
||||
.pointer => ty.castTag(.pointer).?.data.@"addrspace",
|
||||
|
||||
.optional => {
|
||||
const child_type = ty.optionalChild(mod);
|
||||
return child_type.ptrAddressSpace(mod);
|
||||
},
|
||||
|
||||
else => unreachable,
|
||||
},
|
||||
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
@ -1580,7 +1513,6 @@ pub const Type = struct {
|
||||
.error_set_merged,
|
||||
=> return AbiAlignmentAdvanced{ .scalar = 2 },
|
||||
|
||||
.optional => return abiAlignmentAdvancedOptional(ty, mod, strat),
|
||||
.error_union => return abiAlignmentAdvancedErrorUnion(ty, mod, strat),
|
||||
|
||||
.inferred_alloc_const,
|
||||
@ -1962,8 +1894,6 @@ pub const Type = struct {
|
||||
.error_set_single,
|
||||
=> return AbiSizeAdvanced{ .scalar = 2 },
|
||||
|
||||
.optional => return ty.abiSizeAdvancedOptional(mod, strat),
|
||||
|
||||
.error_union => {
|
||||
// This code needs to be kept in sync with the equivalent switch prong
|
||||
// in abiAlignmentAdvanced.
|
||||
@ -2282,7 +2212,7 @@ pub const Type = struct {
|
||||
.error_set_merged,
|
||||
=> return 16, // TODO revisit this when we have the concept of the error tag type
|
||||
|
||||
.optional, .error_union => {
|
||||
.error_union => {
|
||||
// Optionals and error unions are not packed so their bitsize
|
||||
// includes padding bits.
|
||||
return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
|
||||
@ -2310,7 +2240,11 @@ pub const Type = struct {
|
||||
const elem_bit_size = try bitSizeAdvanced(child_ty, mod, opt_sema);
|
||||
return elem_bit_size * vector_type.len;
|
||||
},
|
||||
.opt_type => @panic("TODO"),
|
||||
.opt_type => {
|
||||
// Optionals and error unions are not packed so their bitsize
|
||||
// includes padding bits.
|
||||
return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
|
||||
},
|
||||
.error_union_type => @panic("TODO"),
|
||||
.func_type => unreachable, // represents machine code; not a pointer
|
||||
.simple_type => |t| switch (t) {
|
||||
@ -2499,7 +2433,6 @@ pub const Type = struct {
|
||||
}
|
||||
|
||||
pub const SlicePtrFieldTypeBuffer = union {
|
||||
elem_type: Payload.ElemType,
|
||||
pointer: Payload.Pointer,
|
||||
};
|
||||
|
||||
@ -2600,16 +2533,6 @@ pub const Type = struct {
|
||||
.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,
|
||||
},
|
||||
else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
@ -2655,21 +2578,6 @@ pub const Type = struct {
|
||||
else => false,
|
||||
};
|
||||
switch (ty.tag()) {
|
||||
.optional => {
|
||||
const child_ty = ty.castTag(.optional).?.data;
|
||||
switch (child_ty.zigTypeTag(mod)) {
|
||||
.Pointer => {
|
||||
const info = child_ty.ptrInfo(mod);
|
||||
switch (info.size) {
|
||||
.C => return false,
|
||||
.Slice, .Many, .One => return !info.@"allowzero",
|
||||
}
|
||||
},
|
||||
.ErrorSet => return true,
|
||||
else => return false,
|
||||
}
|
||||
},
|
||||
|
||||
.pointer => return ty.castTag(.pointer).?.data.size == .C,
|
||||
|
||||
else => return false,
|
||||
@ -2692,16 +2600,6 @@ pub const Type = struct {
|
||||
else => false,
|
||||
};
|
||||
switch (ty.tag()) {
|
||||
.optional => {
|
||||
const child_ty = ty.castTag(.optional).?.data;
|
||||
if (child_ty.zigTypeTag(mod) != .Pointer) return false;
|
||||
const info = child_ty.ptrInfo(mod);
|
||||
switch (info.size) {
|
||||
.Slice, .C => return false,
|
||||
.Many, .One => return !info.@"allowzero",
|
||||
}
|
||||
},
|
||||
|
||||
.pointer => return ty.castTag(.pointer).?.data.size == .C,
|
||||
|
||||
else => return false,
|
||||
@ -2747,7 +2645,6 @@ pub const Type = struct {
|
||||
return child_ty;
|
||||
}
|
||||
},
|
||||
.optional => ty.castTag(.optional).?.data.childType(mod),
|
||||
|
||||
else => unreachable,
|
||||
},
|
||||
@ -2784,13 +2681,10 @@ 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, 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
|
||||
=> return ty,
|
||||
|
||||
@ -3305,15 +3199,6 @@ pub const Type = struct {
|
||||
.pointer,
|
||||
=> return null,
|
||||
|
||||
.optional => {
|
||||
const child_ty = ty.optionalChild(mod);
|
||||
if (child_ty.isNoReturn()) {
|
||||
return Value.null;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
.inferred_alloc_const => unreachable,
|
||||
.inferred_alloc_mut => unreachable,
|
||||
},
|
||||
@ -3524,10 +3409,6 @@ pub const Type = struct {
|
||||
}
|
||||
},
|
||||
|
||||
.optional => {
|
||||
return ty.optionalChild(mod).comptimeOnly(mod);
|
||||
},
|
||||
|
||||
.error_union => return ty.errorUnionPayload().comptimeOnly(mod),
|
||||
},
|
||||
else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
|
||||
@ -4216,7 +4097,6 @@ pub const Type = struct {
|
||||
// After this, the tag requires a payload.
|
||||
|
||||
pointer,
|
||||
optional,
|
||||
error_union,
|
||||
error_set,
|
||||
error_set_single,
|
||||
@ -4233,8 +4113,6 @@ pub const Type = struct {
|
||||
.inferred_alloc_mut,
|
||||
=> @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
|
||||
|
||||
.optional => Payload.ElemType,
|
||||
|
||||
.error_set => Payload.ErrorSet,
|
||||
.error_set_inferred => Payload.ErrorSetInferred,
|
||||
.error_set_merged => Payload.ErrorSetMerged,
|
||||
@ -4326,11 +4204,6 @@ pub const Type = struct {
|
||||
data: u64,
|
||||
};
|
||||
|
||||
pub const ElemType = struct {
|
||||
base: Payload,
|
||||
data: Type,
|
||||
};
|
||||
|
||||
pub const Bits = struct {
|
||||
base: Payload,
|
||||
data: u16,
|
||||
@ -4570,11 +4443,11 @@ pub const Type = struct {
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
// TODO: update callsites of this function to directly call
|
||||
// mod.optionalType and then delete this function.
|
||||
_ = arena;
|
||||
|
||||
return mod.optionalType(child_type.ip_index);
|
||||
}
|
||||
|
||||
pub fn errorUnion(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user