authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-30 19:57:11-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-12-30 21:41:02-08:00
log133da8692e80532797dd91b32539cf2175280a95
tree8ff37b28c783d14be6aa459673202909de47b1ec
parent2622575fde2b5d70926fe62ed272412d72eef7b0

stage2: rework Type Payload layout

Add `Type.castTag` and note that it is preferable to call than `Type.cast`. This matches other abstractions in the codebase. Added a convenience function `Type.Tag.create` which really cleans up the callsites of creating `Type` objects. `Type` payloads can now share types. This is in preparation for another improvement that I want to do.

8 files changed, 424 insertions(+), 395 deletions(-)

src/Compilation.zig+5-3
...@@ -825,9 +825,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -825,9 +825,11 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
825825
826 const root_scope = rs: {826 const root_scope = rs: {
827 if (mem.endsWith(u8, root_pkg.root_src_path, ".zig")) {827 if (mem.endsWith(u8, root_pkg.root_src_path, ".zig")) {
828 const struct_payload = try gpa.create(Type.Payload.EmptyStruct);
829 const root_scope = try gpa.create(Module.Scope.File);828 const root_scope = try gpa.create(Module.Scope.File);
830 struct_payload.* = .{ .scope = &root_scope.root_container };829 const struct_ty = try Type.Tag.empty_struct.create(
830 gpa,
831 &root_scope.root_container,
832 );
831 root_scope.* = .{833 root_scope.* = .{
832 // TODO this is duped so it can be freed in Container.deinit834 // TODO this is duped so it can be freed in Container.deinit
833 .sub_file_path = try gpa.dupe(u8, root_pkg.root_src_path),835 .sub_file_path = try gpa.dupe(u8, root_pkg.root_src_path),
...@@ -838,7 +840,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {...@@ -838,7 +840,7 @@ pub fn create(gpa: *Allocator, options: InitOptions) !*Compilation {
838 .root_container = .{840 .root_container = .{
839 .file_scope = root_scope,841 .file_scope = root_scope,
840 .decls = .{},842 .decls = .{},
841 .ty = Type.initPayload(&struct_payload.base),843 .ty = struct_ty,
842 },844 },
843 };845 };
844 break :rs &root_scope.base;846 break :rs &root_scope.base;
src/Module.zig+51-76
...@@ -562,7 +562,7 @@ pub const Scope = struct {...@@ -562,7 +562,7 @@ pub const Scope = struct {
562 pub fn deinit(self: *Container, gpa: *Allocator) void {562 pub fn deinit(self: *Container, gpa: *Allocator) void {
563 self.decls.deinit(gpa);563 self.decls.deinit(gpa);
564 // TODO either Container of File should have an arena for sub_file_path and ty564 // TODO either Container of File should have an arena for sub_file_path and ty
565 gpa.destroy(self.ty.cast(Type.Payload.EmptyStruct).?);565 gpa.destroy(self.ty.castTag(.empty_struct).?);
566 gpa.free(self.file_scope.sub_file_path);566 gpa.free(self.file_scope.sub_file_path);
567 self.* = undefined;567 self.* = undefined;
568 }568 }
...@@ -2528,12 +2528,11 @@ pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []...@@ -2528,12 +2528,11 @@ pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []
2528 }2528 }
25292529
2530 // TODO Scope.Container arena for ty and sub_file_path2530 // TODO Scope.Container arena for ty and sub_file_path
2531 const struct_payload = try self.gpa.create(Type.Payload.EmptyStruct);
2532 errdefer self.gpa.destroy(struct_payload);
2533 const file_scope = try self.gpa.create(Scope.File);2531 const file_scope = try self.gpa.create(Scope.File);
2534 errdefer self.gpa.destroy(file_scope);2532 errdefer self.gpa.destroy(file_scope);
2533 const struct_ty = try Type.Tag.empty_struct.create(self.gpa, &file_scope.root_container);
2534 errdefer self.gpa.destroy(struct_ty.castTag(.empty_struct).?);
25352535
2536 struct_payload.* = .{ .scope = &file_scope.root_container };
2537 file_scope.* = .{2536 file_scope.* = .{
2538 .sub_file_path = resolved_path,2537 .sub_file_path = resolved_path,
2539 .source = .{ .unloaded = {} },2538 .source = .{ .unloaded = {} },
...@@ -2543,7 +2542,7 @@ pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []...@@ -2543,7 +2542,7 @@ pub fn analyzeImport(self: *Module, scope: *Scope, src: usize, target_string: []
2543 .root_container = .{2542 .root_container = .{
2544 .file_scope = file_scope,2543 .file_scope = file_scope,
2545 .decls = .{},2544 .decls = .{},
2546 .ty = Type.initPayload(&struct_payload.base),2545 .ty = struct_ty,
2547 },2546 },
2548 };2547 };
2549 self.analyzeContainer(&file_scope.root_container) catch |err| switch (err) {2548 self.analyzeContainer(&file_scope.root_container) catch |err| switch (err) {
...@@ -2564,7 +2563,7 @@ pub fn cmpNumeric(...@@ -2564,7 +2563,7 @@ pub fn cmpNumeric(
2564 lhs: *Inst,2563 lhs: *Inst,
2565 rhs: *Inst,2564 rhs: *Inst,
2566 op: std.math.CompareOperator,2565 op: std.math.CompareOperator,
2567) !*Inst {2566) InnerError!*Inst {
2568 assert(lhs.ty.isNumeric());2567 assert(lhs.ty.isNumeric());
2569 assert(rhs.ty.isNumeric());2568 assert(rhs.ty.isNumeric());
25702569
...@@ -2738,15 +2737,14 @@ fn wrapOptional(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*In...@@ -2738,15 +2737,14 @@ fn wrapOptional(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*In
2738}2737}
27392738
2740fn makeIntType(self: *Module, scope: *Scope, signed: bool, bits: u16) !Type {2739fn makeIntType(self: *Module, scope: *Scope, signed: bool, bits: u16) !Type {
2741 if (signed) {2740 const int_payload = try scope.arena().create(Type.Payload.Bits);
2742 const int_payload = try scope.arena().create(Type.Payload.IntSigned);2741 int_payload.* = .{
2743 int_payload.* = .{ .bits = bits };2742 .base = .{
2744 return Type.initPayload(&int_payload.base);2743 .tag = if (signed) .int_signed else .int_unsigned,
2745 } else {2744 },
2746 const int_payload = try scope.arena().create(Type.Payload.IntUnsigned);2745 .data = bits,
2747 int_payload.* = .{ .bits = bits };2746 };
2748 return Type.initPayload(&int_payload.base);2747 return Type.initPayload(&int_payload.base);
2749 }
2750}2748}
27512749
2752pub fn resolvePeerTypes(self: *Module, scope: *Scope, instructions: []*Inst) !Type {2750pub fn resolvePeerTypes(self: *Module, scope: *Scope, instructions: []*Inst) !Type {
...@@ -2829,7 +2827,7 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst...@@ -2829,7 +2827,7 @@ pub fn coerce(self: *Module, scope: *Scope, dest_type: Type, inst: *Inst) !*Inst
28292827
2830 // T to ?T2828 // T to ?T
2831 if (dest_type.zigTypeTag() == .Optional) {2829 if (dest_type.zigTypeTag() == .Optional) {
2832 var buf: Type.Payload.PointerSimple = undefined;2830 var buf: Type.Payload.ElemType = undefined;
2833 const child_type = dest_type.optionalChild(&buf);2831 const child_type = dest_type.optionalChild(&buf);
2834 if (child_type.eql(inst.ty)) {2832 if (child_type.eql(inst.ty)) {
2835 return self.wrapOptional(scope, dest_type, inst);2833 return self.wrapOptional(scope, dest_type, inst);
...@@ -3225,7 +3223,7 @@ pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mu...@@ -3225,7 +3223,7 @@ pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mu
3225 // TODO stage1 type inference bug3223 // TODO stage1 type inference bug
3226 const T = Type.Tag;3224 const T = Type.Tag;
32273225
3228 const type_payload = try scope.arena().create(Type.Payload.PointerSimple);3226 const type_payload = try scope.arena().create(Type.Payload.ElemType);
3229 type_payload.* = .{3227 type_payload.* = .{
3230 .base = .{3228 .base = .{
3231 .tag = switch (size) {3229 .tag = switch (size) {
...@@ -3235,7 +3233,7 @@ pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mu...@@ -3235,7 +3233,7 @@ pub fn simplePtrType(self: *Module, scope: *Scope, src: usize, elem_ty: Type, mu
3235 .Slice => if (mutable) T.mut_slice else T.const_slice,3233 .Slice => if (mutable) T.mut_slice else T.const_slice,
3236 },3234 },
3237 },3235 },
3238 .pointee_type = elem_ty,3236 .data = elem_ty,
3239 };3237 };
3240 return Type.initPayload(&type_payload.base);3238 return Type.initPayload(&type_payload.base);
3241}3239}
...@@ -3257,8 +3255,7 @@ pub fn ptrType(...@@ -3257,8 +3255,7 @@ pub fn ptrType(
3257 assert(host_size == 0 or bit_offset < host_size * 8);3255 assert(host_size == 0 or bit_offset < host_size * 8);
32583256
3259 // TODO check if type can be represented by simplePtrType3257 // TODO check if type can be represented by simplePtrType
3260 const type_payload = try scope.arena().create(Type.Payload.Pointer);3258 return Type.Tag.pointer.create(scope.arena(), .{
3261 type_payload.* = .{
3262 .pointee_type = elem_ty,3259 .pointee_type = elem_ty,
3263 .sentinel = sentinel,3260 .sentinel = sentinel,
3264 .@"align" = @"align",3261 .@"align" = @"align",
...@@ -3268,95 +3265,73 @@ pub fn ptrType(...@@ -3268,95 +3265,73 @@ pub fn ptrType(
3268 .mutable = mutable,3265 .mutable = mutable,
3269 .@"volatile" = @"volatile",3266 .@"volatile" = @"volatile",
3270 .size = size,3267 .size = size,
3271 };3268 });
3272 return Type.initPayload(&type_payload.base);
3273}3269}
32743270
3275pub fn optionalType(self: *Module, scope: *Scope, child_type: Type) Allocator.Error!Type {3271pub fn optionalType(self: *Module, scope: *Scope, child_type: Type) Allocator.Error!Type {
3276 return Type.initPayload(switch (child_type.tag()) {3272 switch (child_type.tag()) {
3277 .single_const_pointer => blk: {3273 .single_const_pointer => return Type.Tag.optional_single_const_pointer.create(
3278 const payload = try scope.arena().create(Type.Payload.PointerSimple);3274 scope.arena(),
3279 payload.* = .{3275 child_type.elemType(),
3280 .base = .{ .tag = .optional_single_const_pointer },3276 ),
3281 .pointee_type = child_type.elemType(),3277 .single_mut_pointer => return Type.Tag.optional_single_mut_pointer.create(
3282 };3278 scope.arena(),
3283 break :blk &payload.base;3279 child_type.elemType(),
3284 },3280 ),
3285 .single_mut_pointer => blk: {3281 else => return Type.Tag.optional.create(scope.arena(), child_type),
3286 const payload = try scope.arena().create(Type.Payload.PointerSimple);3282 }
3287 payload.* = .{
3288 .base = .{ .tag = .optional_single_mut_pointer },
3289 .pointee_type = child_type.elemType(),
3290 };
3291 break :blk &payload.base;
3292 },
3293 else => blk: {
3294 const payload = try scope.arena().create(Type.Payload.Optional);
3295 payload.* = .{
3296 .child_type = child_type,
3297 };
3298 break :blk &payload.base;
3299 },
3300 });
3301}3283}
33023284
3303pub fn arrayType(self: *Module, scope: *Scope, len: u64, sentinel: ?Value, elem_type: Type) Allocator.Error!Type {3285pub fn arrayType(
3286 self: *Module,
3287 scope: *Scope,
3288 len: u64,
3289 sentinel: ?Value,
3290 elem_type: Type,
3291) Allocator.Error!Type {
3304 if (elem_type.eql(Type.initTag(.u8))) {3292 if (elem_type.eql(Type.initTag(.u8))) {
3305 if (sentinel) |some| {3293 if (sentinel) |some| {
3306 if (some.eql(Value.initTag(.zero))) {3294 if (some.eql(Value.initTag(.zero))) {
3307 const payload = try scope.arena().create(Type.Payload.Array_u8_Sentinel0);3295 return Type.Tag.array_u8_sentinel_0.create(scope.arena(), len);
3308 payload.* = .{
3309 .len = len,
3310 };
3311 return Type.initPayload(&payload.base);
3312 }3296 }
3313 } else {3297 } else {
3314 const payload = try scope.arena().create(Type.Payload.Array_u8);3298 return Type.Tag.array_u8.create(scope.arena(), len);
3315 payload.* = .{
3316 .len = len,
3317 };
3318 return Type.initPayload(&payload.base);
3319 }3299 }
3320 }3300 }
33213301
3322 if (sentinel) |some| {3302 if (sentinel) |some| {
3323 const payload = try scope.arena().create(Type.Payload.ArraySentinel);3303 return Type.Tag.array_sentinel.create(scope.arena(), .{
3324 payload.* = .{
3325 .len = len,3304 .len = len,
3326 .sentinel = some,3305 .sentinel = some,
3327 .elem_type = elem_type,3306 .elem_type = elem_type,
3328 };3307 });
3329 return Type.initPayload(&payload.base);
3330 }3308 }
33313309
3332 const payload = try scope.arena().create(Type.Payload.Array);3310 return Type.Tag.array.create(scope.arena(), .{
3333 payload.* = .{
3334 .len = len,3311 .len = len,
3335 .elem_type = elem_type,3312 .elem_type = elem_type,
3336 };3313 });
3337 return Type.initPayload(&payload.base);
3338}3314}
33393315
3340pub fn errorUnionType(self: *Module, scope: *Scope, error_set: Type, payload: Type) Allocator.Error!Type {3316pub fn errorUnionType(
3317 self: *Module,
3318 scope: *Scope,
3319 error_set: Type,
3320 payload: Type,
3321) Allocator.Error!Type {
3341 assert(error_set.zigTypeTag() == .ErrorSet);3322 assert(error_set.zigTypeTag() == .ErrorSet);
3342 if (error_set.eql(Type.initTag(.anyerror)) and payload.eql(Type.initTag(.void))) {3323 if (error_set.eql(Type.initTag(.anyerror)) and payload.eql(Type.initTag(.void))) {
3343 return Type.initTag(.anyerror_void_error_union);3324 return Type.initTag(.anyerror_void_error_union);
3344 }3325 }
33453326
3346 const result = try scope.arena().create(Type.Payload.ErrorUnion);3327 return Type.Tag.error_union.create(scope.arena(), .{
3347 result.* = .{
3348 .error_set = error_set,3328 .error_set = error_set,
3349 .payload = payload,3329 .payload = payload,
3350 };3330 });
3351 return Type.initPayload(&result.base);
3352}3331}
33533332
3354pub fn anyframeType(self: *Module, scope: *Scope, return_type: Type) Allocator.Error!Type {3333pub fn anyframeType(self: *Module, scope: *Scope, return_type: Type) Allocator.Error!Type {
3355 const result = try scope.arena().create(Type.Payload.AnyFrame);3334 return Type.Tag.anyframe_T.create(scope.arena(), return_type);
3356 result.* = .{
3357 .return_type = return_type,
3358 };
3359 return Type.initPayload(&result.base);
3360}3335}
33613336
3362pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {3337pub fn dumpInst(self: *Module, scope: *Scope, inst: *Inst) void {
src/astgen.zig+1-1
...@@ -2723,7 +2723,7 @@ fn rlWrap(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr...@@ -2723,7 +2723,7 @@ fn rlWrap(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr
2723 return mod.fail(scope, result.src, "TODO implement rlWrap .bitcasted_ptr", .{});2723 return mod.fail(scope, result.src, "TODO implement rlWrap .bitcasted_ptr", .{});
2724 },2724 },
2725 .inferred_ptr => |alloc| {2725 .inferred_ptr => |alloc| {
2726 return mod.fail(scope, result.src, "TODO implement rlWrap .inferred_ptr", .{});2726 return addZIRBinOp(mod, scope, result.src, .store, &alloc.base, result);
2727 },2727 },
2728 .block_ptr => |block_ptr| {2728 .block_ptr => |block_ptr| {
2729 return mod.fail(scope, result.src, "TODO implement rlWrap .block_ptr", .{});2729 return mod.fail(scope, result.src, "TODO implement rlWrap .block_ptr", .{});
src/codegen.zig+1-1
...@@ -3262,7 +3262,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {...@@ -3262,7 +3262,7 @@ fn Function(comptime arch: std.Target.Cpu.Arch) type {
3262 if (typed_value.val.isNull())3262 if (typed_value.val.isNull())
3263 return MCValue{ .immediate = 0 };3263 return MCValue{ .immediate = 0 };
32643264
3265 var buf: Type.Payload.PointerSimple = undefined;3265 var buf: Type.Payload.ElemType = undefined;
3266 return self.genTypedValue(src, .{3266 return self.genTypedValue(src, .{
3267 .ty = typed_value.ty.optionalChild(&buf),3267 .ty = typed_value.ty.optionalChild(&buf),
3268 .val = typed_value.val,3268 .val = typed_value.val,
src/type.zig+339-274
...@@ -112,18 +112,39 @@ pub const Type = extern union {...@@ -112,18 +112,39 @@ pub const Type = extern union {
112 }112 }
113 }113 }
114114
115 /// Prefer `castTag` to this.
115 pub fn cast(self: Type, comptime T: type) ?*T {116 pub fn cast(self: Type, comptime T: type) ?*T {
116 if (self.tag_if_small_enough < Tag.no_payload_count)117 if (@hasField(T, "base_tag")) {
118 return base.castTag(T.base_tag);
119 }
120 if (self.tag_if_small_enough < Tag.no_payload_count) {
117 return null;121 return null;
122 }
123 inline for (@typeInfo(Tag).Enum.fields) |field| {
124 if (field.value < Tag.no_payload_count)
125 continue;
126 const t = @intToEnum(Tag, field.value);
127 if (self.ptr_otherwise.tag == t) {
128 if (T == t.Type()) {
129 return @fieldParentPtr(T, "base", self.ptr_otherwise);
130 }
131 return null;
132 }
133 }
134 unreachable;
135 }
118136
119 const expected_tag = std.meta.fieldInfo(T, "base").default_value.?.tag;137 pub fn castTag(self: Type, comptime t: Tag) ?*t.Type() {
120 if (self.ptr_otherwise.tag != expected_tag)138 if (self.tag_if_small_enough < Tag.no_payload_count)
121 return null;139 return null;
122140
123 return @fieldParentPtr(T, "base", self.ptr_otherwise);141 if (self.ptr_otherwise.tag == t)
142 return @fieldParentPtr(t.Type(), "base", self.ptr_otherwise);
143
144 return null;
124 }145 }
125146
126 pub fn castPointer(self: Type) ?*Payload.PointerSimple {147 pub fn castPointer(self: Type) ?*Payload.ElemType {
127 return switch (self.tag()) {148 return switch (self.tag()) {
128 .single_const_pointer,149 .single_const_pointer,
129 .single_mut_pointer,150 .single_mut_pointer,
...@@ -135,7 +156,8 @@ pub const Type = extern union {...@@ -135,7 +156,8 @@ pub const Type = extern union {
135 .mut_slice,156 .mut_slice,
136 .optional_single_const_pointer,157 .optional_single_const_pointer,
137 .optional_single_mut_pointer,158 .optional_single_mut_pointer,
138 => @fieldParentPtr(Payload.PointerSimple, "base", self.ptr_otherwise),159 => self.cast(Payload.ElemType),
160
139 else => null,161 else => null,
140 };162 };
141 }163 }
...@@ -165,7 +187,7 @@ pub const Type = extern union {...@@ -165,7 +187,7 @@ pub const Type = extern union {
165 // Hot path for common case:187 // Hot path for common case:
166 if (a.castPointer()) |a_payload| {188 if (a.castPointer()) |a_payload| {
167 if (b.castPointer()) |b_payload| {189 if (b.castPointer()) |b_payload| {
168 return a.tag() == b.tag() and eql(a_payload.pointee_type, b_payload.pointee_type);190 return a.tag() == b.tag() and eql(a_payload.data, b_payload.data);
169 }191 }
170 }192 }
171 const is_slice_a = isSlice(a);193 const is_slice_a = isSlice(a);
...@@ -230,8 +252,8 @@ pub const Type = extern union {...@@ -230,8 +252,8 @@ pub const Type = extern union {
230 return true;252 return true;
231 },253 },
232 .Optional => {254 .Optional => {
233 var buf_a: Payload.PointerSimple = undefined;255 var buf_a: Payload.ElemType = undefined;
234 var buf_b: Payload.PointerSimple = undefined;256 var buf_b: Payload.ElemType = undefined;
235 return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b));257 return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b));
236 },258 },
237 .Float,259 .Float,
...@@ -294,7 +316,7 @@ pub const Type = extern union {...@@ -294,7 +316,7 @@ pub const Type = extern union {
294 }316 }
295 },317 },
296 .Optional => {318 .Optional => {
297 var buf: Payload.PointerSimple = undefined;319 var buf: Payload.ElemType = undefined;
298 std.hash.autoHash(&hasher, self.optionalChild(&buf).hash());320 std.hash.autoHash(&hasher, self.optionalChild(&buf).hash());
299 },321 },
300 .Float,322 .Float,
...@@ -364,68 +386,64 @@ pub const Type = extern union {...@@ -364,68 +386,64 @@ pub const Type = extern union {
364 .@"anyframe",386 .@"anyframe",
365 => unreachable,387 => unreachable,
366388
367 .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0),389 .array_u8,
368 .array_u8 => return self.copyPayloadShallow(allocator, Payload.Array_u8),390 .array_u8_sentinel_0,
391 => return self.copyPayloadShallow(allocator, Payload.Len),
392
393 .single_const_pointer,
394 .single_mut_pointer,
395 .many_const_pointer,
396 .many_mut_pointer,
397 .c_const_pointer,
398 .c_mut_pointer,
399 .const_slice,
400 .mut_slice,
401 .optional,
402 .optional_single_mut_pointer,
403 .optional_single_const_pointer,
404 .anyframe_T,
405 => return self.copyPayloadShallow(allocator, Payload.ElemType),
406
407 .int_signed,
408 .int_unsigned,
409 => return self.copyPayloadShallow(allocator, Payload.Bits),
410
369 .array => {411 .array => {
370 const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);412 const payload = self.castTag(.array).?.data;
371 const new_payload = try allocator.create(Payload.Array);413 return Tag.array.create(allocator, .{
372 new_payload.* = .{
373 .base = payload.base,
374 .len = payload.len,414 .len = payload.len,
375 .elem_type = try payload.elem_type.copy(allocator),415 .elem_type = try payload.elem_type.copy(allocator),
376 };416 });
377 return Type{ .ptr_otherwise = &new_payload.base };
378 },417 },
379 .array_sentinel => {418 .array_sentinel => {
380 const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise);419 const payload = self.castTag(.array_sentinel).?.data;
381 const new_payload = try allocator.create(Payload.ArraySentinel);420 return Tag.array_sentinel.create(allocator, .{
382 new_payload.* = .{
383 .base = payload.base,
384 .len = payload.len,421 .len = payload.len,
385 .sentinel = try payload.sentinel.copy(allocator),422 .sentinel = try payload.sentinel.copy(allocator),
386 .elem_type = try payload.elem_type.copy(allocator),423 .elem_type = try payload.elem_type.copy(allocator),
387 };424 });
388 return Type{ .ptr_otherwise = &new_payload.base };
389 },425 },
390 .int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned),
391 .int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned),
392 .function => {426 .function => {
393 const payload = @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise);427 const payload = self.castTag(.function).?.data;
394 const new_payload = try allocator.create(Payload.Function);
395 const param_types = try allocator.alloc(Type, payload.param_types.len);428 const param_types = try allocator.alloc(Type, payload.param_types.len);
396 for (payload.param_types) |param_type, i| {429 for (payload.param_types) |param_type, i| {
397 param_types[i] = try param_type.copy(allocator);430 param_types[i] = try param_type.copy(allocator);
398 }431 }
399 new_payload.* = .{432 return Tag.function.create(allocator, .{
400 .base = payload.base,
401 .return_type = try payload.return_type.copy(allocator),433 .return_type = try payload.return_type.copy(allocator),
402 .param_types = param_types,434 .param_types = param_types,
403 .cc = payload.cc,435 .cc = payload.cc,
404 };436 });
405 return Type{ .ptr_otherwise = &new_payload.base };
406 },437 },
407 .optional => return self.copyPayloadSingleField(allocator, Payload.Optional, "child_type"),
408 .single_const_pointer,
409 .single_mut_pointer,
410 .many_const_pointer,
411 .many_mut_pointer,
412 .c_const_pointer,
413 .c_mut_pointer,
414 .const_slice,
415 .mut_slice,
416 .optional_single_mut_pointer,
417 .optional_single_const_pointer,
418 => return self.copyPayloadSingleField(allocator, Payload.PointerSimple, "pointee_type"),
419 .anyframe_T => return self.copyPayloadSingleField(allocator, Payload.AnyFrame, "return_type"),
420
421 .pointer => {438 .pointer => {
422 const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);439 const payload = self.castTag(.pointer).?.data;
423 const new_payload = try allocator.create(Payload.Pointer);440 const sent: ?Value = if (payload.sentinel) |some|
424 new_payload.* = .{441 try some.copy(allocator)
425 .base = payload.base,442 else
426443 null;
444 return Tag.pointer.create(allocator, .{
427 .pointee_type = try payload.pointee_type.copy(allocator),445 .pointee_type = try payload.pointee_type.copy(allocator),
428 .sentinel = if (payload.sentinel) |some| try some.copy(allocator) else null,446 .sentinel = sent,
429 .@"align" = payload.@"align",447 .@"align" = payload.@"align",
430 .bit_offset = payload.bit_offset,448 .bit_offset = payload.bit_offset,
431 .host_size = payload.host_size,449 .host_size = payload.host_size,
...@@ -433,41 +451,28 @@ pub const Type = extern union {...@@ -433,41 +451,28 @@ pub const Type = extern union {
433 .mutable = payload.mutable,451 .mutable = payload.mutable,
434 .@"volatile" = payload.@"volatile",452 .@"volatile" = payload.@"volatile",
435 .size = payload.size,453 .size = payload.size,
436 };454 });
437 return Type{ .ptr_otherwise = &new_payload.base };
438 },455 },
439 .error_union => {456 .error_union => {
440 const payload = @fieldParentPtr(Payload.ErrorUnion, "base", self.ptr_otherwise);457 const payload = self.castTag(.error_union).?.data;
441 const new_payload = try allocator.create(Payload.ErrorUnion);458 return Tag.error_union.create(allocator, .{
442 new_payload.* = .{
443 .base = payload.base,
444
445 .error_set = try payload.error_set.copy(allocator),459 .error_set = try payload.error_set.copy(allocator),
446 .payload = try payload.payload.copy(allocator),460 .payload = try payload.payload.copy(allocator),
447 };461 });
448 return Type{ .ptr_otherwise = &new_payload.base };
449 },462 },
450 .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet),463 .error_set => return self.copyPayloadShallow(allocator, Payload.Decl),
451 .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle),464 .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name),
452 .empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct),465 .empty_struct => return self.copyPayloadShallow(allocator, Payload.ContainerScope),
453 }466 }
454 }467 }
455468
456 fn copyPayloadShallow(self: Type, allocator: *Allocator, comptime T: type) error{OutOfMemory}!Type {469 fn copyPayloadShallow(self: Type, allocator: *Allocator, comptime T: type) error{OutOfMemory}!Type {
457 const payload = @fieldParentPtr(T, "base", self.ptr_otherwise);470 const payload = self.cast(T).?;
458 const new_payload = try allocator.create(T);471 const new_payload = try allocator.create(T);
459 new_payload.* = payload.*;472 new_payload.* = payload.*;
460 return Type{ .ptr_otherwise = &new_payload.base };473 return Type{ .ptr_otherwise = &new_payload.base };
461 }474 }
462475
463 fn copyPayloadSingleField(self: Type, allocator: *Allocator, comptime T: type, comptime field_name: []const u8) error{OutOfMemory}!Type {
464 const payload = @fieldParentPtr(T, "base", self.ptr_otherwise);
465 const new_payload = try allocator.create(T);
466 new_payload.base = payload.base;
467 @field(new_payload, field_name) = try @field(payload, field_name).copy(allocator);
468 return Type{ .ptr_otherwise = &new_payload.base };
469 }
470
471 pub fn format(476 pub fn format(
472 self: Type,477 self: Type,
473 comptime fmt: []const u8,478 comptime fmt: []const u8,
...@@ -527,7 +532,7 @@ pub const Type = extern union {...@@ -527,7 +532,7 @@ pub const Type = extern union {
527 .fn_ccc_void_no_args => return out_stream.writeAll("fn() callconv(.C) void"),532 .fn_ccc_void_no_args => return out_stream.writeAll("fn() callconv(.C) void"),
528 .single_const_pointer_to_comptime_int => return out_stream.writeAll("*const comptime_int"),533 .single_const_pointer_to_comptime_int => return out_stream.writeAll("*const comptime_int"),
529 .function => {534 .function => {
530 const payload = @fieldParentPtr(Payload.Function, "base", ty.ptr_otherwise);535 const payload = ty.castTag(.function).?.data;
531 try out_stream.writeAll("fn(");536 try out_stream.writeAll("fn(");
532 for (payload.param_types) |param_type, i| {537 for (payload.param_types) |param_type, i| {
533 if (i != 0) try out_stream.writeAll(", ");538 if (i != 0) try out_stream.writeAll(", ");
...@@ -539,108 +544,108 @@ pub const Type = extern union {...@@ -539,108 +544,108 @@ pub const Type = extern union {
539 },544 },
540545
541 .anyframe_T => {546 .anyframe_T => {
542 const payload = @fieldParentPtr(Payload.AnyFrame, "base", ty.ptr_otherwise);547 const return_type = ty.castTag(.anyframe_T).?.data;
543 try out_stream.print("anyframe->", .{});548 try out_stream.print("anyframe->", .{});
544 ty = payload.return_type;549 ty = return_type;
545 continue;550 continue;
546 },551 },
547 .array_u8 => {552 .array_u8 => {
548 const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise);553 const len = ty.castTag(.array_u8).?.data;
549 return out_stream.print("[{}]u8", .{payload.len});554 return out_stream.print("[{}]u8", .{len});
550 },555 },
551 .array_u8_sentinel_0 => {556 .array_u8_sentinel_0 => {
552 const payload = @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", ty.ptr_otherwise);557 const len = ty.castTag(.array_u8_sentinel_0).?.data;
553 return out_stream.print("[{}:0]u8", .{payload.len});558 return out_stream.print("[{}:0]u8", .{len});
554 },559 },
555 .array => {560 .array => {
556 const payload = @fieldParentPtr(Payload.Array, "base", ty.ptr_otherwise);561 const payload = ty.castTag(.array).?.data;
557 try out_stream.print("[{}]", .{payload.len});562 try out_stream.print("[{}]", .{payload.len});
558 ty = payload.elem_type;563 ty = payload.elem_type;
559 continue;564 continue;
560 },565 },
561 .array_sentinel => {566 .array_sentinel => {
562 const payload = @fieldParentPtr(Payload.ArraySentinel, "base", ty.ptr_otherwise);567 const payload = ty.castTag(.array_sentinel).?.data;
563 try out_stream.print("[{}:{}]", .{ payload.len, payload.sentinel });568 try out_stream.print("[{}:{}]", .{ payload.len, payload.sentinel });
564 ty = payload.elem_type;569 ty = payload.elem_type;
565 continue;570 continue;
566 },571 },
567 .single_const_pointer => {572 .single_const_pointer => {
568 const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);573 const pointee_type = ty.castTag(.single_const_pointer).?.data;
569 try out_stream.writeAll("*const ");574 try out_stream.writeAll("*const ");
570 ty = payload.pointee_type;575 ty = pointee_type;
571 continue;576 continue;
572 },577 },
573 .single_mut_pointer => {578 .single_mut_pointer => {
574 const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);579 const pointee_type = ty.castTag(.single_mut_pointer).?.data;
575 try out_stream.writeAll("*");580 try out_stream.writeAll("*");
576 ty = payload.pointee_type;581 ty = pointee_type;
577 continue;582 continue;
578 },583 },
579 .many_const_pointer => {584 .many_const_pointer => {
580 const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);585 const pointee_type = ty.castTag(.many_const_pointer).?.data;
581 try out_stream.writeAll("[*]const ");586 try out_stream.writeAll("[*]const ");
582 ty = payload.pointee_type;587 ty = pointee_type;
583 continue;588 continue;
584 },589 },
585 .many_mut_pointer => {590 .many_mut_pointer => {
586 const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);591 const pointee_type = ty.castTag(.many_mut_pointer).?.data;
587 try out_stream.writeAll("[*]");592 try out_stream.writeAll("[*]");
588 ty = payload.pointee_type;593 ty = pointee_type;
589 continue;594 continue;
590 },595 },
591 .c_const_pointer => {596 .c_const_pointer => {
592 const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);597 const pointee_type = ty.castTag(.c_const_pointer).?.data;
593 try out_stream.writeAll("[*c]const ");598 try out_stream.writeAll("[*c]const ");
594 ty = payload.pointee_type;599 ty = pointee_type;
595 continue;600 continue;
596 },601 },
597 .c_mut_pointer => {602 .c_mut_pointer => {
598 const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);603 const pointee_type = ty.castTag(.c_mut_pointer).?.data;
599 try out_stream.writeAll("[*c]");604 try out_stream.writeAll("[*c]");
600 ty = payload.pointee_type;605 ty = pointee_type;
601 continue;606 continue;
602 },607 },
603 .const_slice => {608 .const_slice => {
604 const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);609 const pointee_type = ty.castTag(.const_slice).?.data;
605 try out_stream.writeAll("[]const ");610 try out_stream.writeAll("[]const ");
606 ty = payload.pointee_type;611 ty = pointee_type;
607 continue;612 continue;
608 },613 },
609 .mut_slice => {614 .mut_slice => {
610 const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);615 const pointee_type = ty.castTag(.mut_slice).?.data;
611 try out_stream.writeAll("[]");616 try out_stream.writeAll("[]");
612 ty = payload.pointee_type;617 ty = pointee_type;
613 continue;618 continue;
614 },619 },
615 .int_signed => {620 .int_signed => {
616 const payload = @fieldParentPtr(Payload.IntSigned, "base", ty.ptr_otherwise);621 const bits = ty.castTag(.int_signed).?.data;
617 return out_stream.print("i{}", .{payload.bits});622 return out_stream.print("i{d}", .{bits});
618 },623 },
619 .int_unsigned => {624 .int_unsigned => {
620 const payload = @fieldParentPtr(Payload.IntUnsigned, "base", ty.ptr_otherwise);625 const bits = ty.castTag(.int_unsigned).?.data;
621 return out_stream.print("u{}", .{payload.bits});626 return out_stream.print("u{d}", .{bits});
622 },627 },
623 .optional => {628 .optional => {
624 const payload = @fieldParentPtr(Payload.Optional, "base", ty.ptr_otherwise);629 const child_type = ty.castTag(.optional).?.data;
625 try out_stream.writeByte('?');630 try out_stream.writeByte('?');
626 ty = payload.child_type;631 ty = child_type;
627 continue;632 continue;
628 },633 },
629 .optional_single_const_pointer => {634 .optional_single_const_pointer => {
630 const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);635 const pointee_type = ty.castTag(.optional_single_const_pointer).?.data;
631 try out_stream.writeAll("?*const ");636 try out_stream.writeAll("?*const ");
632 ty = payload.pointee_type;637 ty = pointee_type;
633 continue;638 continue;
634 },639 },
635 .optional_single_mut_pointer => {640 .optional_single_mut_pointer => {
636 const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise);641 const pointee_type = ty.castTag(.optional_single_mut_pointer).?.data;
637 try out_stream.writeAll("?*");642 try out_stream.writeAll("?*");
638 ty = payload.pointee_type;643 ty = pointee_type;
639 continue;644 continue;
640 },645 },
641646
642 .pointer => {647 .pointer => {
643 const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise);648 const payload = ty.castTag(.pointer).?.data;
644 if (payload.sentinel) |some| switch (payload.size) {649 if (payload.sentinel) |some| switch (payload.size) {
645 .One, .C => unreachable,650 .One, .C => unreachable,
646 .Many => try out_stream.print("[*:{}]", .{some}),651 .Many => try out_stream.print("[*:{}]", .{some}),
...@@ -652,10 +657,10 @@ pub const Type = extern union {...@@ -652,10 +657,10 @@ pub const Type = extern union {
652 .Slice => try out_stream.writeAll("[]"),657 .Slice => try out_stream.writeAll("[]"),
653 }658 }
654 if (payload.@"align" != 0) {659 if (payload.@"align" != 0) {
655 try out_stream.print("align({}", .{payload.@"align"});660 try out_stream.print("align({d}", .{payload.@"align"});
656661
657 if (payload.bit_offset != 0) {662 if (payload.bit_offset != 0) {
658 try out_stream.print(":{}:{}", .{ payload.bit_offset, payload.host_size });663 try out_stream.print(":{d}:{d}", .{ payload.bit_offset, payload.host_size });
659 }664 }
660 try out_stream.writeAll(") ");665 try out_stream.writeAll(") ");
661 }666 }
...@@ -667,19 +672,19 @@ pub const Type = extern union {...@@ -667,19 +672,19 @@ pub const Type = extern union {
667 continue;672 continue;
668 },673 },
669 .error_union => {674 .error_union => {
670 const payload = @fieldParentPtr(Payload.ErrorUnion, "base", ty.ptr_otherwise);675 const payload = ty.castTag(.error_union).?.data;
671 try payload.error_set.format("", .{}, out_stream);676 try payload.error_set.format("", .{}, out_stream);
672 try out_stream.writeAll("!");677 try out_stream.writeAll("!");
673 ty = payload.payload;678 ty = payload.payload;
674 continue;679 continue;
675 },680 },
676 .error_set => {681 .error_set => {
677 const payload = @fieldParentPtr(Payload.ErrorSet, "base", ty.ptr_otherwise);682 const decl = ty.castTag(.error_set).?.data;
678 return out_stream.writeAll(std.mem.spanZ(payload.decl.name));683 return out_stream.writeAll(std.mem.spanZ(decl.name));
679 },684 },
680 .error_set_single => {685 .error_set_single => {
681 const payload = @fieldParentPtr(Payload.ErrorSetSingle, "base", ty.ptr_otherwise);686 const name = ty.castTag(.error_set_single).?.data;
682 return out_stream.print("error{{{}}}", .{payload.name});687 return out_stream.print("error{{{s}}}", .{name});
683 },688 },
684 }689 }
685 unreachable;690 unreachable;
...@@ -784,11 +789,10 @@ pub const Type = extern union {...@@ -784,11 +789,10 @@ pub const Type = extern union {
784 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,789 .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0,
785 .array_u8 => self.arrayLen() != 0,790 .array_u8 => self.arrayLen() != 0,
786 .array_sentinel, .single_const_pointer, .single_mut_pointer, .many_const_pointer, .many_mut_pointer, .c_const_pointer, .c_mut_pointer, .const_slice, .mut_slice, .pointer => self.elemType().hasCodeGenBits(),791 .array_sentinel, .single_const_pointer, .single_mut_pointer, .many_const_pointer, .many_mut_pointer, .c_const_pointer, .c_mut_pointer, .const_slice, .mut_slice, .pointer => self.elemType().hasCodeGenBits(),
787 .int_signed => self.cast(Payload.IntSigned).?.bits != 0,792 .int_signed, .int_unsigned => self.cast(Payload.Bits).?.data != 0,
788 .int_unsigned => self.cast(Payload.IntUnsigned).?.bits != 0,
789793
790 .error_union => {794 .error_union => {
791 const payload = self.cast(Payload.ErrorUnion).?;795 const payload = self.castTag(.error_union).?.data;
792 return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();796 return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits();
793 },797 },
794798
...@@ -855,7 +859,7 @@ pub const Type = extern union {...@@ -855,7 +859,7 @@ pub const Type = extern union {
855 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),859 => return @divExact(target.cpu.arch.ptrBitWidth(), 8),
856860
857 .pointer => {861 .pointer => {
858 const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);862 const payload = self.castTag(.pointer).?.data;
859863
860 if (payload.@"align" != 0) return payload.@"align";864 if (payload.@"align" != 0) return payload.@"align";
861 return @divExact(target.cpu.arch.ptrBitWidth(), 8);865 return @divExact(target.cpu.arch.ptrBitWidth(), 8);
...@@ -885,18 +889,12 @@ pub const Type = extern union {...@@ -885,18 +889,12 @@ pub const Type = extern union {
885 .array, .array_sentinel => return self.elemType().abiAlignment(target),889 .array, .array_sentinel => return self.elemType().abiAlignment(target),
886890
887 .int_signed, .int_unsigned => {891 .int_signed, .int_unsigned => {
888 const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|892 const bits: u16 = self.cast(Payload.Bits).?.data;
889 pl.bits
890 else if (self.cast(Payload.IntUnsigned)) |pl|
891 pl.bits
892 else
893 unreachable;
894
895 return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8);893 return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8);
896 },894 },
897895
898 .optional => {896 .optional => {
899 var buf: Payload.PointerSimple = undefined;897 var buf: Payload.ElemType = undefined;
900 const child_type = self.optionalChild(&buf);898 const child_type = self.optionalChild(&buf);
901 if (!child_type.hasCodeGenBits()) return 1;899 if (!child_type.hasCodeGenBits()) return 1;
902900
...@@ -907,7 +905,7 @@ pub const Type = extern union {...@@ -907,7 +905,7 @@ pub const Type = extern union {
907 },905 },
908906
909 .error_union => {907 .error_union => {
910 const payload = self.cast(Payload.ErrorUnion).?;908 const payload = self.castTag(.error_union).?.data;
911 if (!payload.error_set.hasCodeGenBits()) {909 if (!payload.error_set.hasCodeGenBits()) {
912 return payload.payload.abiAlignment(target);910 return payload.payload.abiAlignment(target);
913 } else if (!payload.payload.hasCodeGenBits()) {911 } else if (!payload.payload.hasCodeGenBits()) {
...@@ -955,16 +953,19 @@ pub const Type = extern union {...@@ -955,16 +953,19 @@ pub const Type = extern union {
955 .bool,953 .bool,
956 => return 1,954 => return 1,
957955
958 .array_u8 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len,956 .array_u8 => self.castTag(.array_u8).?.data,
959 .array_u8_sentinel_0 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len + 1,957 .array_u8_sentinel_0 => self.castTag(.array_u8_sentinel_0).?.data + 1,
960 .array => {958 .array => {
961 const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise);959 const payload = self.castTag(.array).?.data;
962 const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));960 const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));
963 return payload.len * elem_size;961 return payload.len * elem_size;
964 },962 },
965 .array_sentinel => {963 .array_sentinel => {
966 const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise);964 const payload = self.castTag(.array_sentinel).?.data;
967 const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target));965 const elem_size = std.math.max(
966 payload.elem_type.abiAlignment(target),
967 payload.elem_type.abiSize(target),
968 );
968 return (payload.len + 1) * elem_size;969 return (payload.len + 1) * elem_size;
969 },970 },
970 .i16, .u16 => return 2,971 .i16, .u16 => return 2,
...@@ -1022,18 +1023,12 @@ pub const Type = extern union {...@@ -1022,18 +1023,12 @@ pub const Type = extern union {
1022 => return 2, // TODO revisit this when we have the concept of the error tag type1023 => return 2, // TODO revisit this when we have the concept of the error tag type
10231024
1024 .int_signed, .int_unsigned => {1025 .int_signed, .int_unsigned => {
1025 const bits: u16 = if (self.cast(Payload.IntSigned)) |pl|1026 const bits: u16 = self.cast(Payload.Bits).?.data;
1026 pl.bits
1027 else if (self.cast(Payload.IntUnsigned)) |pl|
1028 pl.bits
1029 else
1030 unreachable;
1031
1032 return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8);1027 return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8);
1033 },1028 },
10341029
1035 .optional => {1030 .optional => {
1036 var buf: Payload.PointerSimple = undefined;1031 var buf: Payload.ElemType = undefined;
1037 const child_type = self.optionalChild(&buf);1032 const child_type = self.optionalChild(&buf);
1038 if (!child_type.hasCodeGenBits()) return 1;1033 if (!child_type.hasCodeGenBits()) return 1;
10391034
...@@ -1048,7 +1043,7 @@ pub const Type = extern union {...@@ -1048,7 +1043,7 @@ pub const Type = extern union {
1048 },1043 },
10491044
1050 .error_union => {1045 .error_union => {
1051 const payload = self.cast(Payload.ErrorUnion).?;1046 const payload = self.castTag(.error_union).?.data;
1052 if (!payload.error_set.hasCodeGenBits() and !payload.payload.hasCodeGenBits()) {1047 if (!payload.error_set.hasCodeGenBits() and !payload.payload.hasCodeGenBits()) {
1053 return 0;1048 return 0;
1054 } else if (!payload.error_set.hasCodeGenBits()) {1049 } else if (!payload.error_set.hasCodeGenBits()) {
...@@ -1132,7 +1127,7 @@ pub const Type = extern union {...@@ -1132,7 +1127,7 @@ pub const Type = extern union {
1132 .single_const_pointer_to_comptime_int,1127 .single_const_pointer_to_comptime_int,
1133 => true,1128 => true,
11341129
1135 .pointer => self.cast(Payload.Pointer).?.size == .One,1130 .pointer => self.castTag(.pointer).?.data.size == .One,
1136 };1131 };
1137 }1132 }
11381133
...@@ -1214,7 +1209,7 @@ pub const Type = extern union {...@@ -1214,7 +1209,7 @@ pub const Type = extern union {
1214 .single_const_pointer_to_comptime_int,1209 .single_const_pointer_to_comptime_int,
1215 => .One,1210 => .One,
12161211
1217 .pointer => self.cast(Payload.Pointer).?.size,1212 .pointer => self.castTag(.pointer).?.data.size,
1218 };1213 };
1219 }1214 }
12201215
...@@ -1289,7 +1284,7 @@ pub const Type = extern union {...@@ -1289,7 +1284,7 @@ pub const Type = extern union {
1289 .const_slice_u8,1284 .const_slice_u8,
1290 => true,1285 => true,
12911286
1292 .pointer => self.cast(Payload.Pointer).?.size == .Slice,1287 .pointer => self.castTag(.pointer).?.data.size == .Slice,
1293 };1288 };
1294 }1289 }
12951290
...@@ -1364,7 +1359,7 @@ pub const Type = extern union {...@@ -1364,7 +1359,7 @@ pub const Type = extern union {
1364 .const_slice,1359 .const_slice,
1365 => true,1360 => true,
13661361
1367 .pointer => !self.cast(Payload.Pointer).?.mutable,1362 .pointer => !self.castTag(.pointer).?.data.mutable,
1368 };1363 };
1369 }1364 }
13701365
...@@ -1438,7 +1433,7 @@ pub const Type = extern union {...@@ -1438,7 +1433,7 @@ pub const Type = extern union {
1438 => false,1433 => false,
14391434
1440 .pointer => {1435 .pointer => {
1441 const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);1436 const payload = self.castTag(.pointer).?.data;
1442 return payload.@"volatile";1437 return payload.@"volatile";
1443 },1438 },
1444 };1439 };
...@@ -1514,7 +1509,7 @@ pub const Type = extern union {...@@ -1514,7 +1509,7 @@ pub const Type = extern union {
1514 => false,1509 => false,
15151510
1516 .pointer => {1511 .pointer => {
1517 const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise);1512 const payload = self.castTag(.pointer).?.data;
1518 return payload.@"allowzero";1513 return payload.@"allowzero";
1519 },1514 },
1520 };1515 };
...@@ -1525,7 +1520,7 @@ pub const Type = extern union {...@@ -1525,7 +1520,7 @@ pub const Type = extern union {
1525 switch (self.tag()) {1520 switch (self.tag()) {
1526 .optional_single_const_pointer, .optional_single_mut_pointer => return true,1521 .optional_single_const_pointer, .optional_single_mut_pointer => return true,
1527 .optional => {1522 .optional => {
1528 var buf: Payload.PointerSimple = undefined;1523 var buf: Payload.ElemType = undefined;
1529 const child_type = self.optionalChild(&buf);1524 const child_type = self.optionalChild(&buf);
1530 // optionals of zero sized pointers behave like bools1525 // optionals of zero sized pointers behave like bools
1531 if (!child_type.hasCodeGenBits()) return false;1526 if (!child_type.hasCodeGenBits()) return false;
...@@ -1563,7 +1558,7 @@ pub const Type = extern union {...@@ -1563,7 +1558,7 @@ pub const Type = extern union {
1563 => return false,1558 => return false,
15641559
1565 .Optional => {1560 .Optional => {
1566 var buf: Payload.PointerSimple = undefined;1561 var buf: Payload.ElemType = undefined;
1567 return ty.optionalChild(&buf).isValidVarType(is_extern);1562 return ty.optionalChild(&buf).isValidVarType(is_extern);
1568 },1563 },
1569 .Pointer, .Array => ty = ty.elemType(),1564 .Pointer, .Array => ty = ty.elemType(),
...@@ -1631,8 +1626,8 @@ pub const Type = extern union {...@@ -1631,8 +1626,8 @@ pub const Type = extern union {
1631 .empty_struct,1626 .empty_struct,
1632 => unreachable,1627 => unreachable,
16331628
1634 .array => self.cast(Payload.Array).?.elem_type,1629 .array => self.castTag(.array).?.data.elem_type,
1635 .array_sentinel => self.cast(Payload.ArraySentinel).?.elem_type,1630 .array_sentinel => self.castTag(.array_sentinel).?.data.elem_type,
1636 .single_const_pointer,1631 .single_const_pointer,
1637 .single_mut_pointer,1632 .single_mut_pointer,
1638 .many_const_pointer,1633 .many_const_pointer,
...@@ -1641,28 +1636,29 @@ pub const Type = extern union {...@@ -1641,28 +1636,29 @@ pub const Type = extern union {
1641 .c_mut_pointer,1636 .c_mut_pointer,
1642 .const_slice,1637 .const_slice,
1643 .mut_slice,1638 .mut_slice,
1644 => self.castPointer().?.pointee_type,1639 => self.castPointer().?.data,
1645 .array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),1640 .array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8),
1646 .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),1641 .single_const_pointer_to_comptime_int => Type.initTag(.comptime_int),
1647 .pointer => self.cast(Payload.Pointer).?.pointee_type,1642 .pointer => self.castTag(.pointer).?.data.pointee_type,
1648 };1643 };
1649 }1644 }
16501645
1651 /// Asserts that the type is an optional.1646 /// Asserts that the type is an optional.
1652 pub fn optionalChild(self: Type, buf: *Payload.PointerSimple) Type {1647 /// Resulting `Type` will have inner memory referencing `buf`.
1648 pub fn optionalChild(self: Type, buf: *Payload.ElemType) Type {
1653 return switch (self.tag()) {1649 return switch (self.tag()) {
1654 .optional => self.cast(Payload.Optional).?.child_type,1650 .optional => self.castTag(.optional).?.data,
1655 .optional_single_mut_pointer => {1651 .optional_single_mut_pointer => {
1656 buf.* = .{1652 buf.* = .{
1657 .base = .{ .tag = .single_mut_pointer },1653 .base = .{ .tag = .single_mut_pointer },
1658 .pointee_type = self.castPointer().?.pointee_type,1654 .data = self.castPointer().?.data,
1659 };1655 };
1660 return Type.initPayload(&buf.base);1656 return Type.initPayload(&buf.base);
1661 },1657 },
1662 .optional_single_const_pointer => {1658 .optional_single_const_pointer => {
1663 buf.* = .{1659 buf.* = .{
1664 .base = .{ .tag = .single_const_pointer },1660 .base = .{ .tag = .single_const_pointer },
1665 .pointee_type = self.castPointer().?.pointee_type,1661 .data = self.castPointer().?.data,
1666 };1662 };
1667 return Type.initPayload(&buf.base);1663 return Type.initPayload(&buf.base);
1668 },1664 },
...@@ -1673,23 +1669,16 @@ pub const Type = extern union {...@@ -1673,23 +1669,16 @@ pub const Type = extern union {
1673 /// Asserts that the type is an optional.1669 /// Asserts that the type is an optional.
1674 /// Same as `optionalChild` but allocates the buffer if needed.1670 /// Same as `optionalChild` but allocates the buffer if needed.
1675 pub fn optionalChildAlloc(self: Type, allocator: *Allocator) !Type {1671 pub fn optionalChildAlloc(self: Type, allocator: *Allocator) !Type {
1676 return switch (self.tag()) {1672 switch (self.tag()) {
1677 .optional => self.cast(Payload.Optional).?.child_type,1673 .optional => return self.castTag(.optional).?.data,
1678 .optional_single_mut_pointer, .optional_single_const_pointer => {1674 .optional_single_mut_pointer => {
1679 const payload = try allocator.create(Payload.PointerSimple);1675 return Tag.single_mut_pointer.create(allocator, self.castPointer().?.data);
1680 payload.* = .{1676 },
1681 .base = .{1677 .optional_single_const_pointer => {
1682 .tag = if (self.tag() == .optional_single_const_pointer)1678 return Tag.single_const_pointer.create(allocator, self.castPointer().?.data);
1683 .single_const_pointer
1684 else
1685 .single_mut_pointer,
1686 },
1687 .pointee_type = self.castPointer().?.pointee_type,
1688 };
1689 return Type.initPayload(&payload.base);
1690 },1679 },
1691 else => unreachable,1680 else => unreachable,
1692 };1681 }
1693 }1682 }
16941683
1695 /// Asserts the type is an array or vector.1684 /// Asserts the type is an array or vector.
...@@ -1759,10 +1748,10 @@ pub const Type = extern union {...@@ -1759,10 +1748,10 @@ pub const Type = extern union {
1759 .empty_struct,1748 .empty_struct,
1760 => unreachable,1749 => unreachable,
17611750
1762 .array => self.cast(Payload.Array).?.len,1751 .array => self.castTag(.array).?.data.len,
1763 .array_sentinel => self.cast(Payload.ArraySentinel).?.len,1752 .array_sentinel => self.castTag(.array_sentinel).?.data.len,
1764 .array_u8 => self.cast(Payload.Array_u8).?.len,1753 .array_u8 => self.castTag(.array_u8).?.data,
1765 .array_u8_sentinel_0 => self.cast(Payload.Array_u8_Sentinel0).?.len,1754 .array_u8_sentinel_0 => self.castTag(.array_u8_sentinel_0).?.data,
1766 };1755 };
1767 }1756 }
17681757
...@@ -1836,8 +1825,8 @@ pub const Type = extern union {...@@ -1836,8 +1825,8 @@ pub const Type = extern union {
1836 .array_u8,1825 .array_u8,
1837 => return null,1826 => return null,
18381827
1839 .pointer => return self.cast(Payload.Pointer).?.sentinel,1828 .pointer => return self.castTag(.pointer).?.data.sentinel,
1840 .array_sentinel => return self.cast(Payload.ArraySentinel).?.sentinel,1829 .array_sentinel => return self.castTag(.array_sentinel).?.data.sentinel,
1841 .array_u8_sentinel_0 => return Value.initTag(.zero),1830 .array_u8_sentinel_0 => return Value.initTag(.zero),
1842 };1831 };
1843 }1832 }
...@@ -2048,8 +2037,14 @@ pub const Type = extern union {...@@ -2048,8 +2037,14 @@ pub const Type = extern union {
2048 .empty_struct,2037 .empty_struct,
2049 => unreachable,2038 => unreachable,
20502039
2051 .int_unsigned => .{ .signedness = .unsigned, .bits = self.cast(Payload.IntUnsigned).?.bits },2040 .int_unsigned => .{
2052 .int_signed => .{ .signedness = .signed, .bits = self.cast(Payload.IntSigned).?.bits },2041 .signedness = .unsigned,
2042 .bits = self.castTag(.int_unsigned).?.data,
2043 },
2044 .int_signed => .{
2045 .signedness = .signed,
2046 .bits = self.castTag(.int_signed).?.data,
2047 },
2053 .u8 => .{ .signedness = .unsigned, .bits = 8 },2048 .u8 => .{ .signedness = .unsigned, .bits = 8 },
2054 .i8 => .{ .signedness = .signed, .bits = 8 },2049 .i8 => .{ .signedness = .signed, .bits = 8 },
2055 .u16 => .{ .signedness = .unsigned, .bits = 16 },2050 .u16 => .{ .signedness = .unsigned, .bits = 16 },
...@@ -2178,7 +2173,7 @@ pub const Type = extern union {...@@ -2178,7 +2173,7 @@ pub const Type = extern union {
2178 .fn_void_no_args => 0,2173 .fn_void_no_args => 0,
2179 .fn_naked_noreturn_no_args => 0,2174 .fn_naked_noreturn_no_args => 0,
2180 .fn_ccc_void_no_args => 0,2175 .fn_ccc_void_no_args => 0,
2181 .function => @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise).param_types.len,2176 .function => self.castTag(.function).?.data.param_types.len,
21822177
2183 .f16,2178 .f16,
2184 .f32,2179 .f32,
...@@ -2254,7 +2249,7 @@ pub const Type = extern union {...@@ -2254,7 +2249,7 @@ pub const Type = extern union {
2254 .fn_naked_noreturn_no_args => return,2249 .fn_naked_noreturn_no_args => return,
2255 .fn_ccc_void_no_args => return,2250 .fn_ccc_void_no_args => return,
2256 .function => {2251 .function => {
2257 const payload = @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise);2252 const payload = self.castTag(.function).?.data;
2258 std.mem.copy(Type, types, payload.param_types);2253 std.mem.copy(Type, types, payload.param_types);
2259 },2254 },
22602255
...@@ -2327,7 +2322,7 @@ pub const Type = extern union {...@@ -2327,7 +2322,7 @@ pub const Type = extern union {
2327 pub fn fnParamType(self: Type, index: usize) Type {2322 pub fn fnParamType(self: Type, index: usize) Type {
2328 switch (self.tag()) {2323 switch (self.tag()) {
2329 .function => {2324 .function => {
2330 const payload = @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise);2325 const payload = self.castTag(.function).?.data;
2331 return payload.param_types[index];2326 return payload.param_types[index];
2332 },2327 },
23332328
...@@ -2410,7 +2405,7 @@ pub const Type = extern union {...@@ -2410,7 +2405,7 @@ pub const Type = extern union {
2410 .fn_ccc_void_no_args,2405 .fn_ccc_void_no_args,
2411 => Type.initTag(.void),2406 => Type.initTag(.void),
24122407
2413 .function => @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise).return_type,2408 .function => self.castTag(.function).?.data.return_type,
24142409
2415 .f16,2410 .f16,
2416 .f32,2411 .f32,
...@@ -2484,7 +2479,7 @@ pub const Type = extern union {...@@ -2484,7 +2479,7 @@ pub const Type = extern union {
2484 .fn_void_no_args => .Unspecified,2479 .fn_void_no_args => .Unspecified,
2485 .fn_naked_noreturn_no_args => .Naked,2480 .fn_naked_noreturn_no_args => .Naked,
2486 .fn_ccc_void_no_args => .C,2481 .fn_ccc_void_no_args => .C,
2487 .function => @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise).cc,2482 .function => self.castTag(.function).?.data.cc,
24882483
2489 .f16,2484 .f16,
2490 .f32,2485 .f32,
...@@ -2760,15 +2755,8 @@ pub const Type = extern union {...@@ -2760,15 +2755,8 @@ pub const Type = extern union {
2760 .@"null" => return Value.initTag(.null_value),2755 .@"null" => return Value.initTag(.null_value),
2761 .@"undefined" => return Value.initTag(.undef),2756 .@"undefined" => return Value.initTag(.undef),
27622757
2763 .int_unsigned => {2758 .int_unsigned, .int_signed => {
2764 if (ty.cast(Payload.IntUnsigned).?.bits == 0) {2759 if (ty.cast(Payload.Bits).?.data == 0) {
2765 return Value.initTag(.zero);
2766 } else {
2767 return null;
2768 }
2769 },
2770 .int_signed => {
2771 if (ty.cast(Payload.IntSigned).?.bits == 0) {
2772 return Value.initTag(.zero);2760 return Value.initTag(.zero);
2773 } else {2761 } else {
2774 return null;2762 return null;
...@@ -2787,12 +2775,11 @@ pub const Type = extern union {...@@ -2787,12 +2775,11 @@ pub const Type = extern union {
2787 .single_const_pointer,2775 .single_const_pointer,
2788 .single_mut_pointer,2776 .single_mut_pointer,
2789 => {2777 => {
2790 const ptr = ty.castPointer().?;2778 ty = ty.castPointer().?.data;
2791 ty = ptr.pointee_type;
2792 continue;2779 continue;
2793 },2780 },
2794 .pointer => {2781 .pointer => {
2795 ty = ty.cast(Payload.Pointer).?.pointee_type;2782 ty = ty.castTag(.pointer).?.data.pointee_type;
2796 continue;2783 continue;
2797 },2784 },
2798 };2785 };
...@@ -2869,7 +2856,7 @@ pub const Type = extern union {...@@ -2869,7 +2856,7 @@ pub const Type = extern union {
2869 .c_mut_pointer,2856 .c_mut_pointer,
2870 => return true,2857 => return true,
28712858
2872 .pointer => self.cast(Payload.Pointer).?.size == .C,2859 .pointer => self.castTag(.pointer).?.data.size == .C,
2873 };2860 };
2874 }2861 }
28752862
...@@ -2950,7 +2937,7 @@ pub const Type = extern union {...@@ -2950,7 +2937,7 @@ pub const Type = extern union {
2950 .pointer,2937 .pointer,
2951 => unreachable,2938 => unreachable,
29522939
2953 .empty_struct => self.cast(Type.Payload.EmptyStruct).?.scope,2940 .empty_struct => self.castTag(.empty_struct).?.data,
2954 };2941 };
2955 }2942 }
29562943
...@@ -3105,117 +3092,195 @@ pub const Type = extern union {...@@ -3105,117 +3092,195 @@ pub const Type = extern union {
31053092
3106 pub const last_no_payload_tag = Tag.const_slice_u8;3093 pub const last_no_payload_tag = Tag.const_slice_u8;
3107 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;3094 pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1;
3108 };
31093095
3110 pub const Payload = struct {3096 pub fn Type(comptime t: Tag) type {
3111 tag: Tag,3097 return switch (t) {
3098 .u8,
3099 .i8,
3100 .u16,
3101 .i16,
3102 .u32,
3103 .i32,
3104 .u64,
3105 .i64,
3106 .usize,
3107 .isize,
3108 .c_short,
3109 .c_ushort,
3110 .c_int,
3111 .c_uint,
3112 .c_long,
3113 .c_ulong,
3114 .c_longlong,
3115 .c_ulonglong,
3116 .c_longdouble,
3117 .f16,
3118 .f32,
3119 .f64,
3120 .f128,
3121 .c_void,
3122 .bool,
3123 .void,
3124 .type,
3125 .anyerror,
3126 .comptime_int,
3127 .comptime_float,
3128 .noreturn,
3129 .enum_literal,
3130 .@"null",
3131 .@"undefined",
3132 .fn_noreturn_no_args,
3133 .fn_void_no_args,
3134 .fn_naked_noreturn_no_args,
3135 .fn_ccc_void_no_args,
3136 .single_const_pointer_to_comptime_int,
3137 .anyerror_void_error_union,
3138 .@"anyframe",
3139 .const_slice_u8,
3140 => @compileError("Type Tag " ++ @tagName(t) ++ " has no payload"),
3141
3142 .array_u8,
3143 .array_u8_sentinel_0,
3144 => Payload.Len,
3145
3146 .single_const_pointer,
3147 .single_mut_pointer,
3148 .many_const_pointer,
3149 .many_mut_pointer,
3150 .c_const_pointer,
3151 .c_mut_pointer,
3152 .const_slice,
3153 .mut_slice,
3154 .optional,
3155 .optional_single_mut_pointer,
3156 .optional_single_const_pointer,
3157 .anyframe_T,
3158 => Payload.ElemType,
3159
3160 .int_signed,
3161 .int_unsigned,
3162 => Payload.Bits,
3163
3164 .array => Payload.Array,
3165 .array_sentinel => Payload.ArraySentinel,
3166 .pointer => Payload.Pointer,
3167 .function => Payload.Function,
3168 .error_union => Payload.ErrorUnion,
3169 .error_set => Payload.Decl,
3170 .error_set_single => Payload.Name,
3171 .empty_struct => Payload.ContainerScope,
3172 };
3173 }
31123174
3113 pub const Array_u8_Sentinel0 = struct {3175 pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Type {
3114 base: Payload = Payload{ .tag = .array_u8_sentinel_0 },3176 const ptr = try ally.create(t.Type());
3177 ptr.* = .{
3178 .base = .{ .tag = t },
3179 .data = data,
3180 };
3181 return Type{ .ptr_otherwise = &ptr.base };
3182 }
31153183
3116 len: u64,3184 pub fn Data(comptime t: Tag) type {
3117 };3185 return std.meta.fieldInfo(t.Type(), "data").field_type;
3186 }
3187 };
31183188
3119 pub const Array_u8 = struct {3189 /// The sub-types are named after what fields they contain.
3120 base: Payload = Payload{ .tag = .array_u8 },3190 pub const Payload = struct {
3191 tag: Tag,
31213192
3122 len: u64,3193 pub const Len = struct {
3194 base: Payload,
3195 data: u64,
3123 };3196 };
31243197
3125 pub const Array = struct {3198 pub const Array = struct {
3126 base: Payload = Payload{ .tag = .array },3199 pub const base_tag = Tag.array;
31273200
3128 len: u64,3201 base: Payload = Payload{ .tag = base_tag },
3129 elem_type: Type,3202 data: struct {
3203 len: u64,
3204 elem_type: Type,
3205 },
3130 };3206 };
31313207
3132 pub const ArraySentinel = struct {3208 pub const ArraySentinel = struct {
3133 base: Payload = Payload{ .tag = .array_sentinel },3209 pub const base_tag = Tag.array_sentinel;
31343210
3135 len: u64,3211 base: Payload = Payload{ .tag = base_tag },
3136 sentinel: Value,3212 data: struct {
3137 elem_type: Type,3213 len: u64,
3214 sentinel: Value,
3215 elem_type: Type,
3216 },
3138 };3217 };
31393218
3140 pub const PointerSimple = struct {3219 pub const ElemType = struct {
3141 base: Payload,3220 base: Payload,
31423221 data: Type,
3143 pointee_type: Type,
3144 };3222 };
31453223
3146 pub const IntSigned = struct {3224 pub const Bits = struct {
3147 base: Payload = Payload{ .tag = .int_signed },3225 base: Payload,
31483226 data: u16,
3149 bits: u16,
3150 };
3151
3152 pub const IntUnsigned = struct {
3153 base: Payload = Payload{ .tag = .int_unsigned },
3154
3155 bits: u16,
3156 };3227 };
31573228
3158 pub const Function = struct {3229 pub const Function = struct {
3159 base: Payload = Payload{ .tag = .function },3230 pub const base_tag = Tag.function;
3160
3161 param_types: []Type,
3162 return_type: Type,
3163 cc: std.builtin.CallingConvention,
3164 };
3165
3166 pub const Optional = struct {
3167 base: Payload = Payload{ .tag = .optional },
31683231
3169 child_type: Type,3232 base: Payload = Payload{ .tag = base_tag },
3233 data: struct {
3234 param_types: []Type,
3235 return_type: Type,
3236 cc: std.builtin.CallingConvention,
3237 },
3170 };3238 };
31713239
3172 pub const Pointer = struct {3240 pub const Pointer = struct {
3173 base: Payload = .{ .tag = .pointer },3241 pub const base_tag = Tag.pointer;
31743242
3175 pointee_type: Type,3243 base: Payload = Payload{ .tag = base_tag },
3176 sentinel: ?Value,3244 data: struct {
3177 /// If zero use pointee_type.AbiAlign()3245 pointee_type: Type,
3178 @"align": u32,3246 sentinel: ?Value,
3179 bit_offset: u16,3247 /// If zero use pointee_type.AbiAlign()
3180 host_size: u16,3248 @"align": u32,
3181 @"allowzero": bool,3249 bit_offset: u16,
3182 mutable: bool,3250 host_size: u16,
3183 @"volatile": bool,3251 @"allowzero": bool,
3184 size: std.builtin.TypeInfo.Pointer.Size,3252 mutable: bool,
3253 @"volatile": bool,
3254 size: std.builtin.TypeInfo.Pointer.Size,
3255 },
3185 };3256 };
31863257
3187 pub const ErrorUnion = struct {3258 pub const ErrorUnion = struct {
3188 base: Payload = .{ .tag = .error_union },3259 pub const base_tag = Tag.error_union;
31893260
3190 error_set: Type,3261 base: Payload = Payload{ .tag = base_tag },
3191 payload: Type,3262 data: struct {
3192 };3263 error_set: Type,
31933264 payload: Type,
3194 pub const AnyFrame = struct {3265 },
3195 base: Payload = .{ .tag = .anyframe_T },
3196
3197 return_type: Type,
3198 };3266 };
31993267
3200 pub const ErrorSet = struct {3268 pub const Decl = struct {
3201 base: Payload = .{ .tag = .error_set },3269 base: Payload,
32023270 data: *Module.Decl,
3203 decl: *Module.Decl,
3204 };3271 };
32053272
3206 pub const ErrorSetSingle = struct {3273 pub const Name = struct {
3207 base: Payload = .{ .tag = .error_set_single },3274 base: Payload,
3208
3209 /// memory is owned by `Module`3275 /// memory is owned by `Module`
3210 name: []const u8,3276 data: []const u8,
3211 };3277 };
32123278
3213 /// Mostly used for namespace like structs with zero fields.3279 /// Mostly used for namespace like structs with zero fields.
3214 /// Most commonly used for files.3280 /// Most commonly used for files.
3215 pub const EmptyStruct = struct {3281 pub const ContainerScope = struct {
3216 base: Payload = .{ .tag = .empty_struct },3282 base: Payload,
32173283 data: *Module.Scope.Container,
3218 scope: *Module.Scope.Container,
3219 };3284 };
3220 };3285 };
3221};3286};
src/value.zig+16-19
...@@ -440,21 +440,18 @@ pub const Value = extern union {...@@ -440,21 +440,18 @@ pub const Value = extern union {
440440
441 .int_type => {441 .int_type => {
442 const payload = self.cast(Payload.IntType).?;442 const payload = self.cast(Payload.IntType).?;
443 if (payload.signed) {443 const new = try allocator.create(Type.Payload.Bits);
444 const new = try allocator.create(Type.Payload.IntSigned);444 new.* = .{
445 new.* = .{ .bits = payload.bits };445 .base = .{
446 return Type.initPayload(&new.base);446 .tag = if (payload.signed) .int_signed else .int_unsigned,
447 } else {447 },
448 const new = try allocator.create(Type.Payload.IntUnsigned);448 .data = payload.bits,
449 new.* = .{ .bits = payload.bits };449 };
450 return Type.initPayload(&new.base);450 return Type.initPayload(&new.base);
451 }
452 },451 },
453 .error_set => {452 .error_set => {
454 const payload = self.cast(Payload.ErrorSet).?;453 const payload = self.cast(Payload.ErrorSet).?;
455 const new = try allocator.create(Type.Payload.ErrorSet);454 return Type.Tag.error_set.create(allocator, payload.decl);
456 new.* = .{ .decl = payload.decl };
457 return Type.initPayload(&new.base);
458 },455 },
459456
460 .undef,457 .undef,
...@@ -1321,13 +1318,13 @@ pub const Value = extern union {...@@ -1321,13 +1318,13 @@ pub const Value = extern union {
1321 },1318 },
1322 .int_type => {1319 .int_type => {
1323 const payload = self.cast(Payload.IntType).?;1320 const payload = self.cast(Payload.IntType).?;
1324 if (payload.signed) {1321 var int_payload = Type.Payload.Bits{
1325 var new = Type.Payload.IntSigned{ .bits = payload.bits };1322 .base = .{
1326 return Type.initPayload(&new.base).hash();1323 .tag = if (payload.signed) .int_signed else .int_unsigned,
1327 } else {1324 },
1328 var new = Type.Payload.IntUnsigned{ .bits = payload.bits };1325 .data = payload.bits,
1329 return Type.initPayload(&new.base).hash();1326 };
1330 }1327 return Type.initPayload(&int_payload.base).hash();
1331 },1328 },
13321329
1333 .empty_struct_value,1330 .empty_struct_value,
src/zir.zig+1-1
...@@ -2785,7 +2785,7 @@ const EmitZIR = struct {...@@ -2785,7 +2785,7 @@ const EmitZIR = struct {
2785 }2785 }
2786 },2786 },
2787 .Optional => {2787 .Optional => {
2788 var buf: Type.Payload.PointerSimple = undefined;2788 var buf: Type.Payload.ElemType = undefined;
2789 const inst = try self.arena.allocator.create(Inst.UnOp);2789 const inst = try self.arena.allocator.create(Inst.UnOp);
2790 inst.* = .{2790 inst.* = .{
2791 .base = .{2791 .base = .{
src/zir_sema.zig+10-20
...@@ -480,14 +480,11 @@ fn analyzeInstStr(mod: *Module, scope: *Scope, str_inst: *zir.Inst.Str) InnerErr...@@ -480,14 +480,11 @@ fn analyzeInstStr(mod: *Module, scope: *Scope, str_inst: *zir.Inst.Str) InnerErr
480 errdefer new_decl_arena.deinit();480 errdefer new_decl_arena.deinit();
481 const arena_bytes = try new_decl_arena.allocator.dupe(u8, str_inst.positionals.bytes);481 const arena_bytes = try new_decl_arena.allocator.dupe(u8, str_inst.positionals.bytes);
482482
483 const ty_payload = try scope.arena().create(Type.Payload.Array_u8_Sentinel0);
484 ty_payload.* = .{ .len = arena_bytes.len };
485
486 const bytes_payload = try scope.arena().create(Value.Payload.Bytes);483 const bytes_payload = try scope.arena().create(Value.Payload.Bytes);
487 bytes_payload.* = .{ .data = arena_bytes };484 bytes_payload.* = .{ .data = arena_bytes };
488485
489 const new_decl = try mod.createAnonymousDecl(scope, &new_decl_arena, .{486 const new_decl = try mod.createAnonymousDecl(scope, &new_decl_arena, .{
490 .ty = Type.initPayload(&ty_payload.base),487 .ty = try Type.Tag.array_u8_sentinel_0.create(scope.arena(), arena_bytes.len),
491 .val = Value.initPayload(&bytes_payload.base),488 .val = Value.initPayload(&bytes_payload.base),
492 });489 });
493 return mod.analyzeDeclRef(scope, str_inst.base.src, new_decl);490 return mod.analyzeDeclRef(scope, str_inst.base.src, new_decl);
...@@ -952,13 +949,12 @@ fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) Inne...@@ -952,13 +949,12 @@ fn analyzeInstFnType(mod: *Module, scope: *Scope, fntype: *zir.Inst.FnType) Inne
952 param_types[i] = resolved;949 param_types[i] = resolved;
953 }950 }
954951
955 const payload = try arena.create(Type.Payload.Function);952 const fn_ty = try Type.Tag.function.create(arena, .{
956 payload.* = .{
957 .cc = fntype.kw_args.cc,953 .cc = fntype.kw_args.cc,
958 .return_type = return_type,954 .return_type = return_type,
959 .param_types = param_types,955 .param_types = param_types,
960 };956 });
961 return mod.constType(scope, fntype.base.src, Type.initPayload(&payload.base));957 return mod.constType(scope, fntype.base.src, fn_ty);
962}958}
963959
964fn analyzeInstPrimitive(mod: *Module, scope: *Scope, primitive: *zir.Inst.Primitive) InnerError!*Inst {960fn analyzeInstPrimitive(mod: *Module, scope: *Scope, primitive: *zir.Inst.Primitive) InnerError!*Inst {
...@@ -1062,11 +1058,10 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr...@@ -1062,11 +1058,10 @@ fn analyzeInstFieldPtr(mod: *Module, scope: *Scope, fieldptr: *zir.Inst.FieldPtr
1062 const ref_payload = try scope.arena().create(Value.Payload.RefVal);1058 const ref_payload = try scope.arena().create(Value.Payload.RefVal);
1063 ref_payload.* = .{ .val = Value.initPayload(&error_payload.base) };1059 ref_payload.* = .{ .val = Value.initPayload(&error_payload.base) };
10641060
1065 const result_type = if (child_type.tag() == .anyerror) blk: {1061 const result_type = if (child_type.tag() == .anyerror)
1066 const result_payload = try scope.arena().create(Type.Payload.ErrorSetSingle);1062 try Type.Tag.error_set_single.create(scope.arena(), entry.key)
1067 result_payload.* = .{ .name = entry.key };1063 else
1068 break :blk Type.initPayload(&result_payload.base);1064 child_type;
1069 } else child_type;
10701065
1071 return mod.constInst(scope, fieldptr.base.src, .{1066 return mod.constInst(scope, fieldptr.base.src, .{
1072 .ty = try mod.simplePtrType(scope, fieldptr.base.src, result_type, false, .One),1067 .ty = try mod.simplePtrType(scope, fieldptr.base.src, result_type, false, .One),
...@@ -1195,15 +1190,10 @@ fn analyzeInstElemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inne...@@ -1195,15 +1190,10 @@ fn analyzeInstElemPtr(mod: *Module, scope: *Scope, inst: *zir.Inst.ElemPtr) Inne
1195 // @intCast here because it would have been impossible to construct a value that1190 // @intCast here because it would have been impossible to construct a value that
1196 // required a larger index.1191 // required a larger index.
1197 const elem_ptr = try array_ptr_val.elemPtr(scope.arena(), @intCast(usize, index_u64));1192 const elem_ptr = try array_ptr_val.elemPtr(scope.arena(), @intCast(usize, index_u64));
11981193 const pointee_type = elem_ty.elemType().elemType();
1199 const type_payload = try scope.arena().create(Type.Payload.PointerSimple);
1200 type_payload.* = .{
1201 .base = .{ .tag = .single_const_pointer },
1202 .pointee_type = elem_ty.elemType().elemType(),
1203 };
12041194
1205 return mod.constInst(scope, inst.base.src, .{1195 return mod.constInst(scope, inst.base.src, .{
1206 .ty = Type.initPayload(&type_payload.base),1196 .ty = try Type.Tag.single_const_pointer.create(scope.arena(), pointee_type),
1207 .val = elem_ptr,1197 .val = elem_ptr,
1208 });1198 });
1209 }1199 }