authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-05-18 20:02:10-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-10 20:47:53-07:00
log607737d841bc2279cbe5fee68a0a546b9a5a802e
treeabc69a87afc874b9257a9a02ab5042a5ad5cd7ea
parentf21ca3da190c8c64fd99c700f0840af59792b6b2

compiler: eliminate legacy Type.Tag.optional

Now optional types are only stored in InternPool.

2 files changed, 19 insertions(+), 184 deletions(-)

src/Sema.zig+6-44
......@@ -18589,12 +18589,10 @@ fn fieldType(
1858918589 return sema.addType(field.ty);
1859018590 },
1859118591 .Optional => {
18592 if (cur_ty.castTag(.optional)) |some| {
18593 // Struct/array init through optional requires the child type to not be a pointer.
18594 // If the child of .optional is a pointer it'll error on the next loop.
18595 cur_ty = some.data;
18596 continue;
18597 }
18592 // Struct/array init through optional requires the child type to not be a pointer.
18593 // If the child of .optional is a pointer it'll error on the next loop.
18594 cur_ty = mod.intern_pool.indexToKey(cur_ty.ip_index).opt_type.toType();
18595 continue;
1859818596 },
1859918597 .ErrorUnion => {
1860018598 cur_ty = cur_ty.errorUnionPayload();
......@@ -20390,7 +20388,7 @@ fn zirAlignCast(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2039020388 ptr_info.@"align" = dest_align;
2039120389 var dest_ty = try Type.ptr(sema.arena, sema.mod, ptr_info);
2039220390 if (ptr_ty.zigTypeTag(mod) == .Optional) {
20393 dest_ty = try Type.Tag.optional.create(sema.arena, dest_ty);
20391 dest_ty = try mod.optionalType(dest_ty.toIntern());
2039420392 }
2039520393
2039620394 if (try sema.resolveDefinedValue(block, ptr_src, ptr)) |val| {
......@@ -31622,10 +31620,6 @@ pub fn resolveTypeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3162231620 }
3162331621 },
3162431622
31625 .optional => {
31626 return sema.resolveTypeRequiresComptime(ty.optionalChild(mod));
31627 },
31628
3162931623 .error_union => return sema.resolveTypeRequiresComptime(ty.errorUnionPayload()),
3163031624 },
3163131625 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
......@@ -33057,15 +33051,6 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3305733051 .pointer,
3305833052 => return null,
3305933053
33060 .optional => {
33061 const child_ty = ty.optionalChild(mod);
33062 if (child_ty.isNoReturn()) {
33063 return Value.null;
33064 } else {
33065 return null;
33066 }
33067 },
33068
3306933054 .inferred_alloc_const => unreachable,
3307033055 .inferred_alloc_mut => unreachable,
3307133056 },
......@@ -33628,26 +33613,6 @@ fn typePtrOrOptionalPtrTy(sema: *Sema, ty: Type) !?Type {
3362833613 .inferred_alloc_const => unreachable,
3362933614 .inferred_alloc_mut => unreachable,
3363033615
33631 .optional => {
33632 const child_type = ty.optionalChild(mod);
33633 if (child_type.zigTypeTag(mod) != .Pointer) return null;
33634
33635 const info = child_type.ptrInfo(mod);
33636 switch (info.size) {
33637 .Slice, .C => return null,
33638 .Many, .One => {
33639 if (info.@"allowzero") return null;
33640
33641 // optionals of zero sized types behave like bools, not pointers
33642 if ((try sema.typeHasOnePossibleValue(child_type)) != null) {
33643 return null;
33644 }
33645
33646 return child_type;
33647 },
33648 }
33649 },
33650
3365133616 else => return null,
3365233617 }
3365333618}
......@@ -33682,10 +33647,6 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3368233647 }
3368333648 },
3368433649
33685 .optional => {
33686 return sema.typeRequiresComptime(ty.optionalChild(mod));
33687 },
33688
3368933650 .error_union => return sema.typeRequiresComptime(ty.errorUnionPayload()),
3369033651 },
3369133652 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
......@@ -33705,6 +33666,7 @@ pub fn typeRequiresComptime(sema: *Sema, ty: Type) CompileError!bool {
3370533666 .array_type => |array_type| return sema.typeRequiresComptime(array_type.child.toType()),
3370633667 .vector_type => |vector_type| return sema.typeRequiresComptime(vector_type.child.toType()),
3370733668 .opt_type => |child| return sema.typeRequiresComptime(child.toType()),
33669
3370833670 .error_union_type => |error_union_type| {
3370933671 return sema.typeRequiresComptime(error_union_type.payload_type.toType());
3371033672 },
src/type.zig+13-140
......@@ -47,8 +47,6 @@ pub const Type = struct {
4747 .inferred_alloc_mut,
4848 => return .Pointer,
4949
50 .optional => return .Optional,
51
5250 .error_union => return .ErrorUnion,
5351 },
5452 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
......@@ -283,10 +281,6 @@ pub const Type = struct {
283281 return switch (ty.ip_index) {
284282 .none => switch (ty.tag()) {
285283 .pointer => ty.castTag(.pointer).?.data,
286 .optional => b: {
287 const child_type = ty.optionalChild(mod);
288 break :b child_type.ptrInfo(mod);
289 },
290284
291285 else => unreachable,
292286 },
......@@ -387,12 +381,6 @@ pub const Type = struct {
387381 return true;
388382 },
389383
390 .optional => {
391 if (b.zigTypeTag(mod) != .Optional) return false;
392
393 return a.optionalChild(mod).eql(b.optionalChild(mod), mod);
394 },
395
396384 .error_union => {
397385 if (b.zigTypeTag(mod) != .ErrorUnion) return false;
398386
......@@ -466,12 +454,6 @@ pub const Type = struct {
466454 std.hash.autoHash(hasher, info.size);
467455 },
468456
469 .optional => {
470 std.hash.autoHash(hasher, std.builtin.TypeId.Optional);
471
472 hashWithHasher(ty.optionalChild(mod), hasher, mod);
473 },
474
475457 .error_union => {
476458 std.hash.autoHash(hasher, std.builtin.TypeId.ErrorUnion);
477459
......@@ -530,19 +512,6 @@ pub const Type = struct {
530512 .inferred_alloc_mut,
531513 => unreachable,
532514
533 .optional => {
534 const payload = self.cast(Payload.ElemType).?;
535 const new_payload = try allocator.create(Payload.ElemType);
536 new_payload.* = .{
537 .base = .{ .tag = payload.base.tag },
538 .data = try payload.data.copy(allocator),
539 };
540 return Type{
541 .ip_index = .none,
542 .legacy = .{ .ptr_otherwise = &new_payload.base },
543 };
544 },
545
546515 .pointer => {
547516 const payload = self.castTag(.pointer).?.data;
548517 const sent: ?Value = if (payload.sentinel) |some|
......@@ -654,13 +623,6 @@ pub const Type = struct {
654623 while (true) {
655624 const t = ty.tag();
656625 switch (t) {
657 .optional => {
658 const child_type = ty.castTag(.optional).?.data;
659 try writer.writeByte('?');
660 ty = child_type;
661 continue;
662 },
663
664626 .pointer => {
665627 const payload = ty.castTag(.pointer).?.data;
666628 if (payload.sentinel) |some| switch (payload.size) {
......@@ -813,11 +775,6 @@ pub const Type = struct {
813775 try print(info.pointee_type, writer, mod);
814776 },
815777
816 .optional => {
817 const child_type = ty.castTag(.optional).?.data;
818 try writer.writeByte('?');
819 try print(child_type, writer, mod);
820 },
821778 .error_set => {
822779 const names = ty.castTag(.error_set).?.data.names.keys();
823780 try writer.writeAll("error{");
......@@ -911,8 +868,7 @@ pub const Type = struct {
911868 },
912869 .opt_type => |child| {
913870 try writer.writeByte('?');
914 try print(child.toType(), writer, mod);
915 return;
871 return print(child.toType(), writer, mod);
916872 },
917873 .error_union_type => |error_union_type| {
918874 try print(error_union_type.error_set_type.toType(), writer, mod);
......@@ -1090,21 +1046,6 @@ pub const Type = struct {
10901046 }
10911047 },
10921048
1093 .optional => {
1094 const child_ty = ty.optionalChild(mod);
1095 if (child_ty.isNoReturn()) {
1096 // Then the optional is comptime-known to be null.
1097 return false;
1098 }
1099 if (ignore_comptime_only) {
1100 return true;
1101 } else if (strat == .sema) {
1102 return !(try strat.sema.typeRequiresComptime(child_ty));
1103 } else {
1104 return !comptimeOnly(child_ty, mod);
1105 }
1106 },
1107
11081049 .inferred_alloc_const => unreachable,
11091050 .inferred_alloc_mut => unreachable,
11101051 },
......@@ -1301,8 +1242,6 @@ pub const Type = struct {
13011242
13021243 .inferred_alloc_mut => unreachable,
13031244 .inferred_alloc_const => unreachable,
1304
1305 .optional => ty.isPtrLikeOptional(mod),
13061245 },
13071246 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
13081247 .int_type,
......@@ -1319,7 +1258,7 @@ pub const Type = struct {
13191258 => false,
13201259
13211260 .array_type => |array_type| array_type.child.toType().hasWellDefinedLayout(mod),
1322 .opt_type => |child| child.toType().isPtrLikeOptional(mod),
1261 .opt_type => ty.isPtrLikeOptional(mod),
13231262
13241263 .simple_type => |t| switch (t) {
13251264 .f16,
......@@ -1484,7 +1423,6 @@ pub const Type = struct {
14841423 return (ptr_info.pointee_type.abiAlignmentAdvanced(mod, .eager) catch unreachable).scalar;
14851424 }
14861425 },
1487 .optional => return ty.castTag(.optional).?.data.ptrAlignmentAdvanced(mod, opt_sema),
14881426
14891427 else => unreachable,
14901428 },
......@@ -1510,11 +1448,6 @@ pub const Type = struct {
15101448 .none => switch (ty.tag()) {
15111449 .pointer => ty.castTag(.pointer).?.data.@"addrspace",
15121450
1513 .optional => {
1514 const child_type = ty.optionalChild(mod);
1515 return child_type.ptrAddressSpace(mod);
1516 },
1517
15181451 else => unreachable,
15191452 },
15201453 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
......@@ -1580,7 +1513,6 @@ pub const Type = struct {
15801513 .error_set_merged,
15811514 => return AbiAlignmentAdvanced{ .scalar = 2 },
15821515
1583 .optional => return abiAlignmentAdvancedOptional(ty, mod, strat),
15841516 .error_union => return abiAlignmentAdvancedErrorUnion(ty, mod, strat),
15851517
15861518 .inferred_alloc_const,
......@@ -1962,8 +1894,6 @@ pub const Type = struct {
19621894 .error_set_single,
19631895 => return AbiSizeAdvanced{ .scalar = 2 },
19641896
1965 .optional => return ty.abiSizeAdvancedOptional(mod, strat),
1966
19671897 .error_union => {
19681898 // This code needs to be kept in sync with the equivalent switch prong
19691899 // in abiAlignmentAdvanced.
......@@ -2282,7 +2212,7 @@ pub const Type = struct {
22822212 .error_set_merged,
22832213 => return 16, // TODO revisit this when we have the concept of the error tag type
22842214
2285 .optional, .error_union => {
2215 .error_union => {
22862216 // Optionals and error unions are not packed so their bitsize
22872217 // includes padding bits.
22882218 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
......@@ -2310,7 +2240,11 @@ pub const Type = struct {
23102240 const elem_bit_size = try bitSizeAdvanced(child_ty, mod, opt_sema);
23112241 return elem_bit_size * vector_type.len;
23122242 },
2313 .opt_type => @panic("TODO"),
2243 .opt_type => {
2244 // Optionals and error unions are not packed so their bitsize
2245 // includes padding bits.
2246 return (try abiSizeAdvanced(ty, mod, strat)).scalar * 8;
2247 },
23142248 .error_union_type => @panic("TODO"),
23152249 .func_type => unreachable, // represents machine code; not a pointer
23162250 .simple_type => |t| switch (t) {
......@@ -2499,7 +2433,6 @@ pub const Type = struct {
24992433 }
25002434
25012435 pub const SlicePtrFieldTypeBuffer = union {
2502 elem_type: Payload.ElemType,
25032436 pointer: Payload.Pointer,
25042437 };
25052438
......@@ -2600,16 +2533,6 @@ pub const Type = struct {
26002533 .One, .Many, .C => return true,
26012534 },
26022535
2603 .optional => {
2604 const child_type = ty.optionalChild(mod);
2605 if (child_type.zigTypeTag(mod) != .Pointer) return false;
2606 const info = child_type.ptrInfo(mod);
2607 switch (info.size) {
2608 .Slice, .C => return false,
2609 .Many, .One => return !info.@"allowzero",
2610 }
2611 },
2612
26132536 else => return false,
26142537 },
26152538 else => return switch (mod.intern_pool.indexToKey(ty.ip_index)) {
......@@ -2655,21 +2578,6 @@ pub const Type = struct {
26552578 else => false,
26562579 };
26572580 switch (ty.tag()) {
2658 .optional => {
2659 const child_ty = ty.castTag(.optional).?.data;
2660 switch (child_ty.zigTypeTag(mod)) {
2661 .Pointer => {
2662 const info = child_ty.ptrInfo(mod);
2663 switch (info.size) {
2664 .C => return false,
2665 .Slice, .Many, .One => return !info.@"allowzero",
2666 }
2667 },
2668 .ErrorSet => return true,
2669 else => return false,
2670 }
2671 },
2672
26732581 .pointer => return ty.castTag(.pointer).?.data.size == .C,
26742582
26752583 else => return false,
......@@ -2692,16 +2600,6 @@ pub const Type = struct {
26922600 else => false,
26932601 };
26942602 switch (ty.tag()) {
2695 .optional => {
2696 const child_ty = ty.castTag(.optional).?.data;
2697 if (child_ty.zigTypeTag(mod) != .Pointer) return false;
2698 const info = child_ty.ptrInfo(mod);
2699 switch (info.size) {
2700 .Slice, .C => return false,
2701 .Many, .One => return !info.@"allowzero",
2702 }
2703 },
2704
27052603 .pointer => return ty.castTag(.pointer).?.data.size == .C,
27062604
27072605 else => return false,
......@@ -2747,7 +2645,6 @@ pub const Type = struct {
27472645 return child_ty;
27482646 }
27492647 },
2750 .optional => ty.castTag(.optional).?.data.childType(mod),
27512648
27522649 else => unreachable,
27532650 },
......@@ -2784,13 +2681,10 @@ pub const Type = struct {
27842681 }
27852682
27862683 /// Asserts that the type is an optional.
2787 /// Resulting `Type` will have inner memory referencing `buf`.
27882684 /// Note that for C pointers this returns the type unmodified.
27892685 pub fn optionalChild(ty: Type, mod: *const Module) Type {
27902686 return switch (ty.ip_index) {
27912687 .none => switch (ty.tag()) {
2792 .optional => ty.castTag(.optional).?.data,
2793
27942688 .pointer, // here we assume it is a C pointer
27952689 => return ty,
27962690
......@@ -3305,15 +3199,6 @@ pub const Type = struct {
33053199 .pointer,
33063200 => return null,
33073201
3308 .optional => {
3309 const child_ty = ty.optionalChild(mod);
3310 if (child_ty.isNoReturn()) {
3311 return Value.null;
3312 } else {
3313 return null;
3314 }
3315 },
3316
33173202 .inferred_alloc_const => unreachable,
33183203 .inferred_alloc_mut => unreachable,
33193204 },
......@@ -3524,10 +3409,6 @@ pub const Type = struct {
35243409 }
35253410 },
35263411
3527 .optional => {
3528 return ty.optionalChild(mod).comptimeOnly(mod);
3529 },
3530
35313412 .error_union => return ty.errorUnionPayload().comptimeOnly(mod),
35323413 },
35333414 else => switch (mod.intern_pool.indexToKey(ty.ip_index)) {
......@@ -4216,7 +4097,6 @@ pub const Type = struct {
42164097 // After this, the tag requires a payload.
42174098
42184099 pointer,
4219 optional,
42204100 error_union,
42214101 error_set,
42224102 error_set_single,
......@@ -4233,8 +4113,6 @@ pub const Type = struct {
42334113 .inferred_alloc_mut,
42344114 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
42354115
4236 .optional => Payload.ElemType,
4237
42384116 .error_set => Payload.ErrorSet,
42394117 .error_set_inferred => Payload.ErrorSetInferred,
42404118 .error_set_merged => Payload.ErrorSetMerged,
......@@ -4326,11 +4204,6 @@ pub const Type = struct {
43264204 data: u64,
43274205 };
43284206
4329 pub const ElemType = struct {
4330 base: Payload,
4331 data: Type,
4332 };
4333
43344207 pub const Bits = struct {
43354208 base: Payload,
43364209 data: u16,
......@@ -4570,11 +4443,11 @@ pub const Type = struct {
45704443 }
45714444
45724445 pub fn optional(arena: Allocator, child_type: Type, mod: *Module) Allocator.Error!Type {
4573 if (child_type.ip_index != .none) {
4574 return mod.optionalType(child_type.ip_index);
4575 } else {
4576 return Type.Tag.optional.create(arena, child_type);
4577 }
4446 // TODO: update callsites of this function to directly call
4447 // mod.optionalType and then delete this function.
4448 _ = arena;
4449
4450 return mod.optionalType(child_type.ip_index);
45784451 }
45794452
45804453 pub fn errorUnion(