| ... | ... | @@ -112,18 +112,39 @@ pub const Type = extern union { |
| 112 | 112 | } |
| 113 | 113 | } |
| 114 | 114 | |
| 115 | /// Prefer `castTag` to this. |
| 115 | 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 | 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 | } |
| 118 | 136 | |
| 119 | | const expected_tag = std.meta.fieldInfo(T, "base").default_value.?.tag; |
| 120 | | if (self.ptr_otherwise.tag != expected_tag) |
| 137 | pub fn castTag(self: Type, comptime t: Tag) ?*t.Type() { |
| 138 | if (self.tag_if_small_enough < Tag.no_payload_count) |
| 121 | 139 | return null; |
| 122 | 140 | |
| 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 | } |
| 125 | 146 | |
| 126 | | pub fn castPointer(self: Type) ?*Payload.PointerSimple { |
| 147 | pub fn castPointer(self: Type) ?*Payload.ElemType { |
| 127 | 148 | return switch (self.tag()) { |
| 128 | 149 | .single_const_pointer, |
| 129 | 150 | .single_mut_pointer, |
| ... | ... | @@ -135,7 +156,8 @@ pub const Type = extern union { |
| 135 | 156 | .mut_slice, |
| 136 | 157 | .optional_single_const_pointer, |
| 137 | 158 | .optional_single_mut_pointer, |
| 138 | | => @fieldParentPtr(Payload.PointerSimple, "base", self.ptr_otherwise), |
| 159 | => self.cast(Payload.ElemType), |
| 160 | |
| 139 | 161 | else => null, |
| 140 | 162 | }; |
| 141 | 163 | } |
| ... | ... | @@ -165,7 +187,7 @@ pub const Type = extern union { |
| 165 | 187 | // Hot path for common case: |
| 166 | 188 | if (a.castPointer()) |a_payload| { |
| 167 | 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 | 193 | const is_slice_a = isSlice(a); |
| ... | ... | @@ -230,8 +252,8 @@ pub const Type = extern union { |
| 230 | 252 | return true; |
| 231 | 253 | }, |
| 232 | 254 | .Optional => { |
| 233 | | var buf_a: Payload.PointerSimple = undefined; |
| 234 | | var buf_b: Payload.PointerSimple = undefined; |
| 255 | var buf_a: Payload.ElemType = undefined; |
| 256 | var buf_b: Payload.ElemType = undefined; |
| 235 | 257 | return a.optionalChild(&buf_a).eql(b.optionalChild(&buf_b)); |
| 236 | 258 | }, |
| 237 | 259 | .Float, |
| ... | ... | @@ -294,7 +316,7 @@ pub const Type = extern union { |
| 294 | 316 | } |
| 295 | 317 | }, |
| 296 | 318 | .Optional => { |
| 297 | | var buf: Payload.PointerSimple = undefined; |
| 319 | var buf: Payload.ElemType = undefined; |
| 298 | 320 | std.hash.autoHash(&hasher, self.optionalChild(&buf).hash()); |
| 299 | 321 | }, |
| 300 | 322 | .Float, |
| ... | ... | @@ -364,68 +386,64 @@ pub const Type = extern union { |
| 364 | 386 | .@"anyframe", |
| 365 | 387 | => unreachable, |
| 366 | 388 | |
| 367 | | .array_u8_sentinel_0 => return self.copyPayloadShallow(allocator, Payload.Array_u8_Sentinel0), |
| 368 | | .array_u8 => return self.copyPayloadShallow(allocator, Payload.Array_u8), |
| 389 | .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 | 411 | .array => { |
| 370 | | const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise); |
| 371 | | const new_payload = try allocator.create(Payload.Array); |
| 372 | | new_payload.* = .{ |
| 373 | | .base = payload.base, |
| 412 | const payload = self.castTag(.array).?.data; |
| 413 | return Tag.array.create(allocator, .{ |
| 374 | 414 | .len = payload.len, |
| 375 | 415 | .elem_type = try payload.elem_type.copy(allocator), |
| 376 | | }; |
| 377 | | return Type{ .ptr_otherwise = &new_payload.base }; |
| 416 | }); |
| 378 | 417 | }, |
| 379 | 418 | .array_sentinel => { |
| 380 | | const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise); |
| 381 | | const new_payload = try allocator.create(Payload.ArraySentinel); |
| 382 | | new_payload.* = .{ |
| 383 | | .base = payload.base, |
| 419 | const payload = self.castTag(.array_sentinel).?.data; |
| 420 | return Tag.array_sentinel.create(allocator, .{ |
| 384 | 421 | .len = payload.len, |
| 385 | 422 | .sentinel = try payload.sentinel.copy(allocator), |
| 386 | 423 | .elem_type = try payload.elem_type.copy(allocator), |
| 387 | | }; |
| 388 | | return Type{ .ptr_otherwise = &new_payload.base }; |
| 424 | }); |
| 389 | 425 | }, |
| 390 | | .int_signed => return self.copyPayloadShallow(allocator, Payload.IntSigned), |
| 391 | | .int_unsigned => return self.copyPayloadShallow(allocator, Payload.IntUnsigned), |
| 392 | 426 | .function => { |
| 393 | | const payload = @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise); |
| 394 | | const new_payload = try allocator.create(Payload.Function); |
| 427 | const payload = self.castTag(.function).?.data; |
| 395 | 428 | const param_types = try allocator.alloc(Type, payload.param_types.len); |
| 396 | 429 | for (payload.param_types) |param_type, i| { |
| 397 | 430 | param_types[i] = try param_type.copy(allocator); |
| 398 | 431 | } |
| 399 | | new_payload.* = .{ |
| 400 | | .base = payload.base, |
| 432 | return Tag.function.create(allocator, .{ |
| 401 | 433 | .return_type = try payload.return_type.copy(allocator), |
| 402 | 434 | .param_types = param_types, |
| 403 | 435 | .cc = payload.cc, |
| 404 | | }; |
| 405 | | return Type{ .ptr_otherwise = &new_payload.base }; |
| 436 | }); |
| 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 | 438 | .pointer => { |
| 422 | | const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise); |
| 423 | | const new_payload = try allocator.create(Payload.Pointer); |
| 424 | | new_payload.* = .{ |
| 425 | | .base = payload.base, |
| 426 | | |
| 439 | const payload = self.castTag(.pointer).?.data; |
| 440 | const sent: ?Value = if (payload.sentinel) |some| |
| 441 | try some.copy(allocator) |
| 442 | else |
| 443 | null; |
| 444 | return Tag.pointer.create(allocator, .{ |
| 427 | 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 | 447 | .@"align" = payload.@"align", |
| 430 | 448 | .bit_offset = payload.bit_offset, |
| 431 | 449 | .host_size = payload.host_size, |
| ... | ... | @@ -433,41 +451,28 @@ pub const Type = extern union { |
| 433 | 451 | .mutable = payload.mutable, |
| 434 | 452 | .@"volatile" = payload.@"volatile", |
| 435 | 453 | .size = payload.size, |
| 436 | | }; |
| 437 | | return Type{ .ptr_otherwise = &new_payload.base }; |
| 454 | }); |
| 438 | 455 | }, |
| 439 | 456 | .error_union => { |
| 440 | | const payload = @fieldParentPtr(Payload.ErrorUnion, "base", self.ptr_otherwise); |
| 441 | | const new_payload = try allocator.create(Payload.ErrorUnion); |
| 442 | | new_payload.* = .{ |
| 443 | | .base = payload.base, |
| 444 | | |
| 457 | const payload = self.castTag(.error_union).?.data; |
| 458 | return Tag.error_union.create(allocator, .{ |
| 445 | 459 | .error_set = try payload.error_set.copy(allocator), |
| 446 | 460 | .payload = try payload.payload.copy(allocator), |
| 447 | | }; |
| 448 | | return Type{ .ptr_otherwise = &new_payload.base }; |
| 461 | }); |
| 449 | 462 | }, |
| 450 | | .error_set => return self.copyPayloadShallow(allocator, Payload.ErrorSet), |
| 451 | | .error_set_single => return self.copyPayloadShallow(allocator, Payload.ErrorSetSingle), |
| 452 | | .empty_struct => return self.copyPayloadShallow(allocator, Payload.EmptyStruct), |
| 463 | .error_set => return self.copyPayloadShallow(allocator, Payload.Decl), |
| 464 | .error_set_single => return self.copyPayloadShallow(allocator, Payload.Name), |
| 465 | .empty_struct => return self.copyPayloadShallow(allocator, Payload.ContainerScope), |
| 453 | 466 | } |
| 454 | 467 | } |
| 455 | 468 | |
| 456 | 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 | 471 | const new_payload = try allocator.create(T); |
| 459 | 472 | new_payload.* = payload.*; |
| 460 | 473 | return Type{ .ptr_otherwise = &new_payload.base }; |
| 461 | 474 | } |
| 462 | 475 | |
| 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 | 476 | pub fn format( |
| 472 | 477 | self: Type, |
| 473 | 478 | comptime fmt: []const u8, |
| ... | ... | @@ -527,7 +532,7 @@ pub const Type = extern union { |
| 527 | 532 | .fn_ccc_void_no_args => return out_stream.writeAll("fn() callconv(.C) void"), |
| 528 | 533 | .single_const_pointer_to_comptime_int => return out_stream.writeAll("*const comptime_int"), |
| 529 | 534 | .function => { |
| 530 | | const payload = @fieldParentPtr(Payload.Function, "base", ty.ptr_otherwise); |
| 535 | const payload = ty.castTag(.function).?.data; |
| 531 | 536 | try out_stream.writeAll("fn("); |
| 532 | 537 | for (payload.param_types) |param_type, i| { |
| 533 | 538 | if (i != 0) try out_stream.writeAll(", "); |
| ... | ... | @@ -539,108 +544,108 @@ pub const Type = extern union { |
| 539 | 544 | }, |
| 540 | 545 | |
| 541 | 546 | .anyframe_T => { |
| 542 | | const payload = @fieldParentPtr(Payload.AnyFrame, "base", ty.ptr_otherwise); |
| 547 | const return_type = ty.castTag(.anyframe_T).?.data; |
| 543 | 548 | try out_stream.print("anyframe->", .{}); |
| 544 | | ty = payload.return_type; |
| 549 | ty = return_type; |
| 545 | 550 | continue; |
| 546 | 551 | }, |
| 547 | 552 | .array_u8 => { |
| 548 | | const payload = @fieldParentPtr(Payload.Array_u8, "base", ty.ptr_otherwise); |
| 549 | | return out_stream.print("[{}]u8", .{payload.len}); |
| 553 | const len = ty.castTag(.array_u8).?.data; |
| 554 | return out_stream.print("[{}]u8", .{len}); |
| 550 | 555 | }, |
| 551 | 556 | .array_u8_sentinel_0 => { |
| 552 | | const payload = @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", ty.ptr_otherwise); |
| 553 | | return out_stream.print("[{}:0]u8", .{payload.len}); |
| 557 | const len = ty.castTag(.array_u8_sentinel_0).?.data; |
| 558 | return out_stream.print("[{}:0]u8", .{len}); |
| 554 | 559 | }, |
| 555 | 560 | .array => { |
| 556 | | const payload = @fieldParentPtr(Payload.Array, "base", ty.ptr_otherwise); |
| 561 | const payload = ty.castTag(.array).?.data; |
| 557 | 562 | try out_stream.print("[{}]", .{payload.len}); |
| 558 | 563 | ty = payload.elem_type; |
| 559 | 564 | continue; |
| 560 | 565 | }, |
| 561 | 566 | .array_sentinel => { |
| 562 | | const payload = @fieldParentPtr(Payload.ArraySentinel, "base", ty.ptr_otherwise); |
| 567 | const payload = ty.castTag(.array_sentinel).?.data; |
| 563 | 568 | try out_stream.print("[{}:{}]", .{ payload.len, payload.sentinel }); |
| 564 | 569 | ty = payload.elem_type; |
| 565 | 570 | continue; |
| 566 | 571 | }, |
| 567 | 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 | 574 | try out_stream.writeAll("*const "); |
| 570 | | ty = payload.pointee_type; |
| 575 | ty = pointee_type; |
| 571 | 576 | continue; |
| 572 | 577 | }, |
| 573 | 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 | 580 | try out_stream.writeAll("*"); |
| 576 | | ty = payload.pointee_type; |
| 581 | ty = pointee_type; |
| 577 | 582 | continue; |
| 578 | 583 | }, |
| 579 | 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 | 586 | try out_stream.writeAll("[*]const "); |
| 582 | | ty = payload.pointee_type; |
| 587 | ty = pointee_type; |
| 583 | 588 | continue; |
| 584 | 589 | }, |
| 585 | 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 | 592 | try out_stream.writeAll("[*]"); |
| 588 | | ty = payload.pointee_type; |
| 593 | ty = pointee_type; |
| 589 | 594 | continue; |
| 590 | 595 | }, |
| 591 | 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 | 598 | try out_stream.writeAll("[*c]const "); |
| 594 | | ty = payload.pointee_type; |
| 599 | ty = pointee_type; |
| 595 | 600 | continue; |
| 596 | 601 | }, |
| 597 | 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 | 604 | try out_stream.writeAll("[*c]"); |
| 600 | | ty = payload.pointee_type; |
| 605 | ty = pointee_type; |
| 601 | 606 | continue; |
| 602 | 607 | }, |
| 603 | 608 | .const_slice => { |
| 604 | | const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); |
| 609 | const pointee_type = ty.castTag(.const_slice).?.data; |
| 605 | 610 | try out_stream.writeAll("[]const "); |
| 606 | | ty = payload.pointee_type; |
| 611 | ty = pointee_type; |
| 607 | 612 | continue; |
| 608 | 613 | }, |
| 609 | 614 | .mut_slice => { |
| 610 | | const payload = @fieldParentPtr(Payload.PointerSimple, "base", ty.ptr_otherwise); |
| 615 | const pointee_type = ty.castTag(.mut_slice).?.data; |
| 611 | 616 | try out_stream.writeAll("[]"); |
| 612 | | ty = payload.pointee_type; |
| 617 | ty = pointee_type; |
| 613 | 618 | continue; |
| 614 | 619 | }, |
| 615 | 620 | .int_signed => { |
| 616 | | const payload = @fieldParentPtr(Payload.IntSigned, "base", ty.ptr_otherwise); |
| 617 | | return out_stream.print("i{}", .{payload.bits}); |
| 621 | const bits = ty.castTag(.int_signed).?.data; |
| 622 | return out_stream.print("i{d}", .{bits}); |
| 618 | 623 | }, |
| 619 | 624 | .int_unsigned => { |
| 620 | | const payload = @fieldParentPtr(Payload.IntUnsigned, "base", ty.ptr_otherwise); |
| 621 | | return out_stream.print("u{}", .{payload.bits}); |
| 625 | const bits = ty.castTag(.int_unsigned).?.data; |
| 626 | return out_stream.print("u{d}", .{bits}); |
| 622 | 627 | }, |
| 623 | 628 | .optional => { |
| 624 | | const payload = @fieldParentPtr(Payload.Optional, "base", ty.ptr_otherwise); |
| 629 | const child_type = ty.castTag(.optional).?.data; |
| 625 | 630 | try out_stream.writeByte('?'); |
| 626 | | ty = payload.child_type; |
| 631 | ty = child_type; |
| 627 | 632 | continue; |
| 628 | 633 | }, |
| 629 | 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 | 636 | try out_stream.writeAll("?*const "); |
| 632 | | ty = payload.pointee_type; |
| 637 | ty = pointee_type; |
| 633 | 638 | continue; |
| 634 | 639 | }, |
| 635 | 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 | 642 | try out_stream.writeAll("?*"); |
| 638 | | ty = payload.pointee_type; |
| 643 | ty = pointee_type; |
| 639 | 644 | continue; |
| 640 | 645 | }, |
| 641 | 646 | |
| 642 | 647 | .pointer => { |
| 643 | | const payload = @fieldParentPtr(Payload.Pointer, "base", ty.ptr_otherwise); |
| 648 | const payload = ty.castTag(.pointer).?.data; |
| 644 | 649 | if (payload.sentinel) |some| switch (payload.size) { |
| 645 | 650 | .One, .C => unreachable, |
| 646 | 651 | .Many => try out_stream.print("[*:{}]", .{some}), |
| ... | ... | @@ -652,10 +657,10 @@ pub const Type = extern union { |
| 652 | 657 | .Slice => try out_stream.writeAll("[]"), |
| 653 | 658 | } |
| 654 | 659 | if (payload.@"align" != 0) { |
| 655 | | try out_stream.print("align({}", .{payload.@"align"}); |
| 660 | try out_stream.print("align({d}", .{payload.@"align"}); |
| 656 | 661 | |
| 657 | 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 | 665 | try out_stream.writeAll(") "); |
| 661 | 666 | } |
| ... | ... | @@ -667,19 +672,19 @@ pub const Type = extern union { |
| 667 | 672 | continue; |
| 668 | 673 | }, |
| 669 | 674 | .error_union => { |
| 670 | | const payload = @fieldParentPtr(Payload.ErrorUnion, "base", ty.ptr_otherwise); |
| 675 | const payload = ty.castTag(.error_union).?.data; |
| 671 | 676 | try payload.error_set.format("", .{}, out_stream); |
| 672 | 677 | try out_stream.writeAll("!"); |
| 673 | 678 | ty = payload.payload; |
| 674 | 679 | continue; |
| 675 | 680 | }, |
| 676 | 681 | .error_set => { |
| 677 | | const payload = @fieldParentPtr(Payload.ErrorSet, "base", ty.ptr_otherwise); |
| 678 | | return out_stream.writeAll(std.mem.spanZ(payload.decl.name)); |
| 682 | const decl = ty.castTag(.error_set).?.data; |
| 683 | return out_stream.writeAll(std.mem.spanZ(decl.name)); |
| 679 | 684 | }, |
| 680 | 685 | .error_set_single => { |
| 681 | | const payload = @fieldParentPtr(Payload.ErrorSetSingle, "base", ty.ptr_otherwise); |
| 682 | | return out_stream.print("error{{{}}}", .{payload.name}); |
| 686 | const name = ty.castTag(.error_set_single).?.data; |
| 687 | return out_stream.print("error{{{s}}}", .{name}); |
| 683 | 688 | }, |
| 684 | 689 | } |
| 685 | 690 | unreachable; |
| ... | ... | @@ -784,11 +789,10 @@ pub const Type = extern union { |
| 784 | 789 | .array => self.elemType().hasCodeGenBits() and self.arrayLen() != 0, |
| 785 | 790 | .array_u8 => self.arrayLen() != 0, |
| 786 | 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, |
| 788 | | .int_unsigned => self.cast(Payload.IntUnsigned).?.bits != 0, |
| 792 | .int_signed, .int_unsigned => self.cast(Payload.Bits).?.data != 0, |
| 789 | 793 | |
| 790 | 794 | .error_union => { |
| 791 | | const payload = self.cast(Payload.ErrorUnion).?; |
| 795 | const payload = self.castTag(.error_union).?.data; |
| 792 | 796 | return payload.error_set.hasCodeGenBits() or payload.payload.hasCodeGenBits(); |
| 793 | 797 | }, |
| 794 | 798 | |
| ... | ... | @@ -855,7 +859,7 @@ pub const Type = extern union { |
| 855 | 859 | => return @divExact(target.cpu.arch.ptrBitWidth(), 8), |
| 856 | 860 | |
| 857 | 861 | .pointer => { |
| 858 | | const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise); |
| 862 | const payload = self.castTag(.pointer).?.data; |
| 859 | 863 | |
| 860 | 864 | if (payload.@"align" != 0) return payload.@"align"; |
| 861 | 865 | return @divExact(target.cpu.arch.ptrBitWidth(), 8); |
| ... | ... | @@ -885,18 +889,12 @@ pub const Type = extern union { |
| 885 | 889 | .array, .array_sentinel => return self.elemType().abiAlignment(target), |
| 886 | 890 | |
| 887 | 891 | .int_signed, .int_unsigned => { |
| 888 | | const bits: u16 = if (self.cast(Payload.IntSigned)) |pl| |
| 889 | | pl.bits |
| 890 | | else if (self.cast(Payload.IntUnsigned)) |pl| |
| 891 | | pl.bits |
| 892 | | else |
| 893 | | unreachable; |
| 894 | | |
| 892 | const bits: u16 = self.cast(Payload.Bits).?.data; |
| 895 | 893 | return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8); |
| 896 | 894 | }, |
| 897 | 895 | |
| 898 | 896 | .optional => { |
| 899 | | var buf: Payload.PointerSimple = undefined; |
| 897 | var buf: Payload.ElemType = undefined; |
| 900 | 898 | const child_type = self.optionalChild(&buf); |
| 901 | 899 | if (!child_type.hasCodeGenBits()) return 1; |
| 902 | 900 | |
| ... | ... | @@ -907,7 +905,7 @@ pub const Type = extern union { |
| 907 | 905 | }, |
| 908 | 906 | |
| 909 | 907 | .error_union => { |
| 910 | | const payload = self.cast(Payload.ErrorUnion).?; |
| 908 | const payload = self.castTag(.error_union).?.data; |
| 911 | 909 | if (!payload.error_set.hasCodeGenBits()) { |
| 912 | 910 | return payload.payload.abiAlignment(target); |
| 913 | 911 | } else if (!payload.payload.hasCodeGenBits()) { |
| ... | ... | @@ -955,16 +953,19 @@ pub const Type = extern union { |
| 955 | 953 | .bool, |
| 956 | 954 | => return 1, |
| 957 | 955 | |
| 958 | | .array_u8 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len, |
| 959 | | .array_u8_sentinel_0 => @fieldParentPtr(Payload.Array_u8_Sentinel0, "base", self.ptr_otherwise).len + 1, |
| 956 | .array_u8 => self.castTag(.array_u8).?.data, |
| 957 | .array_u8_sentinel_0 => self.castTag(.array_u8_sentinel_0).?.data + 1, |
| 960 | 958 | .array => { |
| 961 | | const payload = @fieldParentPtr(Payload.Array, "base", self.ptr_otherwise); |
| 959 | const payload = self.castTag(.array).?.data; |
| 962 | 960 | const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target)); |
| 963 | 961 | return payload.len * elem_size; |
| 964 | 962 | }, |
| 965 | 963 | .array_sentinel => { |
| 966 | | const payload = @fieldParentPtr(Payload.ArraySentinel, "base", self.ptr_otherwise); |
| 967 | | const elem_size = std.math.max(payload.elem_type.abiAlignment(target), payload.elem_type.abiSize(target)); |
| 964 | const payload = self.castTag(.array_sentinel).?.data; |
| 965 | const elem_size = std.math.max( |
| 966 | payload.elem_type.abiAlignment(target), |
| 967 | payload.elem_type.abiSize(target), |
| 968 | ); |
| 968 | 969 | return (payload.len + 1) * elem_size; |
| 969 | 970 | }, |
| 970 | 971 | .i16, .u16 => return 2, |
| ... | ... | @@ -1022,18 +1023,12 @@ pub const Type = extern union { |
| 1022 | 1023 | => return 2, // TODO revisit this when we have the concept of the error tag type |
| 1023 | 1024 | |
| 1024 | 1025 | .int_signed, .int_unsigned => { |
| 1025 | | const bits: u16 = if (self.cast(Payload.IntSigned)) |pl| |
| 1026 | | pl.bits |
| 1027 | | else if (self.cast(Payload.IntUnsigned)) |pl| |
| 1028 | | pl.bits |
| 1029 | | else |
| 1030 | | unreachable; |
| 1031 | | |
| 1026 | const bits: u16 = self.cast(Payload.Bits).?.data; |
| 1032 | 1027 | return std.math.ceilPowerOfTwoPromote(u16, (bits + 7) / 8); |
| 1033 | 1028 | }, |
| 1034 | 1029 | |
| 1035 | 1030 | .optional => { |
| 1036 | | var buf: Payload.PointerSimple = undefined; |
| 1031 | var buf: Payload.ElemType = undefined; |
| 1037 | 1032 | const child_type = self.optionalChild(&buf); |
| 1038 | 1033 | if (!child_type.hasCodeGenBits()) return 1; |
| 1039 | 1034 | |
| ... | ... | @@ -1048,7 +1043,7 @@ pub const Type = extern union { |
| 1048 | 1043 | }, |
| 1049 | 1044 | |
| 1050 | 1045 | .error_union => { |
| 1051 | | const payload = self.cast(Payload.ErrorUnion).?; |
| 1046 | const payload = self.castTag(.error_union).?.data; |
| 1052 | 1047 | if (!payload.error_set.hasCodeGenBits() and !payload.payload.hasCodeGenBits()) { |
| 1053 | 1048 | return 0; |
| 1054 | 1049 | } else if (!payload.error_set.hasCodeGenBits()) { |
| ... | ... | @@ -1132,7 +1127,7 @@ pub const Type = extern union { |
| 1132 | 1127 | .single_const_pointer_to_comptime_int, |
| 1133 | 1128 | => true, |
| 1134 | 1129 | |
| 1135 | | .pointer => self.cast(Payload.Pointer).?.size == .One, |
| 1130 | .pointer => self.castTag(.pointer).?.data.size == .One, |
| 1136 | 1131 | }; |
| 1137 | 1132 | } |
| 1138 | 1133 | |
| ... | ... | @@ -1214,7 +1209,7 @@ pub const Type = extern union { |
| 1214 | 1209 | .single_const_pointer_to_comptime_int, |
| 1215 | 1210 | => .One, |
| 1216 | 1211 | |
| 1217 | | .pointer => self.cast(Payload.Pointer).?.size, |
| 1212 | .pointer => self.castTag(.pointer).?.data.size, |
| 1218 | 1213 | }; |
| 1219 | 1214 | } |
| 1220 | 1215 | |
| ... | ... | @@ -1289,7 +1284,7 @@ pub const Type = extern union { |
| 1289 | 1284 | .const_slice_u8, |
| 1290 | 1285 | => true, |
| 1291 | 1286 | |
| 1292 | | .pointer => self.cast(Payload.Pointer).?.size == .Slice, |
| 1287 | .pointer => self.castTag(.pointer).?.data.size == .Slice, |
| 1293 | 1288 | }; |
| 1294 | 1289 | } |
| 1295 | 1290 | |
| ... | ... | @@ -1364,7 +1359,7 @@ pub const Type = extern union { |
| 1364 | 1359 | .const_slice, |
| 1365 | 1360 | => true, |
| 1366 | 1361 | |
| 1367 | | .pointer => !self.cast(Payload.Pointer).?.mutable, |
| 1362 | .pointer => !self.castTag(.pointer).?.data.mutable, |
| 1368 | 1363 | }; |
| 1369 | 1364 | } |
| 1370 | 1365 | |
| ... | ... | @@ -1438,7 +1433,7 @@ pub const Type = extern union { |
| 1438 | 1433 | => false, |
| 1439 | 1434 | |
| 1440 | 1435 | .pointer => { |
| 1441 | | const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise); |
| 1436 | const payload = self.castTag(.pointer).?.data; |
| 1442 | 1437 | return payload.@"volatile"; |
| 1443 | 1438 | }, |
| 1444 | 1439 | }; |
| ... | ... | @@ -1514,7 +1509,7 @@ pub const Type = extern union { |
| 1514 | 1509 | => false, |
| 1515 | 1510 | |
| 1516 | 1511 | .pointer => { |
| 1517 | | const payload = @fieldParentPtr(Payload.Pointer, "base", self.ptr_otherwise); |
| 1512 | const payload = self.castTag(.pointer).?.data; |
| 1518 | 1513 | return payload.@"allowzero"; |
| 1519 | 1514 | }, |
| 1520 | 1515 | }; |
| ... | ... | @@ -1525,7 +1520,7 @@ pub const Type = extern union { |
| 1525 | 1520 | switch (self.tag()) { |
| 1526 | 1521 | .optional_single_const_pointer, .optional_single_mut_pointer => return true, |
| 1527 | 1522 | .optional => { |
| 1528 | | var buf: Payload.PointerSimple = undefined; |
| 1523 | var buf: Payload.ElemType = undefined; |
| 1529 | 1524 | const child_type = self.optionalChild(&buf); |
| 1530 | 1525 | // optionals of zero sized pointers behave like bools |
| 1531 | 1526 | if (!child_type.hasCodeGenBits()) return false; |
| ... | ... | @@ -1563,7 +1558,7 @@ pub const Type = extern union { |
| 1563 | 1558 | => return false, |
| 1564 | 1559 | |
| 1565 | 1560 | .Optional => { |
| 1566 | | var buf: Payload.PointerSimple = undefined; |
| 1561 | var buf: Payload.ElemType = undefined; |
| 1567 | 1562 | return ty.optionalChild(&buf).isValidVarType(is_extern); |
| 1568 | 1563 | }, |
| 1569 | 1564 | .Pointer, .Array => ty = ty.elemType(), |
| ... | ... | @@ -1631,8 +1626,8 @@ pub const Type = extern union { |
| 1631 | 1626 | .empty_struct, |
| 1632 | 1627 | => unreachable, |
| 1633 | 1628 | |
| 1634 | | .array => self.cast(Payload.Array).?.elem_type, |
| 1635 | | .array_sentinel => self.cast(Payload.ArraySentinel).?.elem_type, |
| 1629 | .array => self.castTag(.array).?.data.elem_type, |
| 1630 | .array_sentinel => self.castTag(.array_sentinel).?.data.elem_type, |
| 1636 | 1631 | .single_const_pointer, |
| 1637 | 1632 | .single_mut_pointer, |
| 1638 | 1633 | .many_const_pointer, |
| ... | ... | @@ -1641,28 +1636,29 @@ pub const Type = extern union { |
| 1641 | 1636 | .c_mut_pointer, |
| 1642 | 1637 | .const_slice, |
| 1643 | 1638 | .mut_slice, |
| 1644 | | => self.castPointer().?.pointee_type, |
| 1639 | => self.castPointer().?.data, |
| 1645 | 1640 | .array_u8, .array_u8_sentinel_0, .const_slice_u8 => Type.initTag(.u8), |
| 1646 | 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 | } |
| 1650 | 1645 | |
| 1651 | 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 | 1649 | return switch (self.tag()) { |
| 1654 | | .optional => self.cast(Payload.Optional).?.child_type, |
| 1650 | .optional => self.castTag(.optional).?.data, |
| 1655 | 1651 | .optional_single_mut_pointer => { |
| 1656 | 1652 | buf.* = .{ |
| 1657 | 1653 | .base = .{ .tag = .single_mut_pointer }, |
| 1658 | | .pointee_type = self.castPointer().?.pointee_type, |
| 1654 | .data = self.castPointer().?.data, |
| 1659 | 1655 | }; |
| 1660 | 1656 | return Type.initPayload(&buf.base); |
| 1661 | 1657 | }, |
| 1662 | 1658 | .optional_single_const_pointer => { |
| 1663 | 1659 | buf.* = .{ |
| 1664 | 1660 | .base = .{ .tag = .single_const_pointer }, |
| 1665 | | .pointee_type = self.castPointer().?.pointee_type, |
| 1661 | .data = self.castPointer().?.data, |
| 1666 | 1662 | }; |
| 1667 | 1663 | return Type.initPayload(&buf.base); |
| 1668 | 1664 | }, |
| ... | ... | @@ -1673,23 +1669,16 @@ pub const Type = extern union { |
| 1673 | 1669 | /// Asserts that the type is an optional. |
| 1674 | 1670 | /// Same as `optionalChild` but allocates the buffer if needed. |
| 1675 | 1671 | pub fn optionalChildAlloc(self: Type, allocator: *Allocator) !Type { |
| 1676 | | return switch (self.tag()) { |
| 1677 | | .optional => self.cast(Payload.Optional).?.child_type, |
| 1678 | | .optional_single_mut_pointer, .optional_single_const_pointer => { |
| 1679 | | const payload = try allocator.create(Payload.PointerSimple); |
| 1680 | | payload.* = .{ |
| 1681 | | .base = .{ |
| 1682 | | .tag = if (self.tag() == .optional_single_const_pointer) |
| 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); |
| 1672 | switch (self.tag()) { |
| 1673 | .optional => return self.castTag(.optional).?.data, |
| 1674 | .optional_single_mut_pointer => { |
| 1675 | return Tag.single_mut_pointer.create(allocator, self.castPointer().?.data); |
| 1676 | }, |
| 1677 | .optional_single_const_pointer => { |
| 1678 | return Tag.single_const_pointer.create(allocator, self.castPointer().?.data); |
| 1690 | 1679 | }, |
| 1691 | 1680 | else => unreachable, |
| 1692 | | }; |
| 1681 | } |
| 1693 | 1682 | } |
| 1694 | 1683 | |
| 1695 | 1684 | /// Asserts the type is an array or vector. |
| ... | ... | @@ -1759,10 +1748,10 @@ pub const Type = extern union { |
| 1759 | 1748 | .empty_struct, |
| 1760 | 1749 | => unreachable, |
| 1761 | 1750 | |
| 1762 | | .array => self.cast(Payload.Array).?.len, |
| 1763 | | .array_sentinel => self.cast(Payload.ArraySentinel).?.len, |
| 1764 | | .array_u8 => self.cast(Payload.Array_u8).?.len, |
| 1765 | | .array_u8_sentinel_0 => self.cast(Payload.Array_u8_Sentinel0).?.len, |
| 1751 | .array => self.castTag(.array).?.data.len, |
| 1752 | .array_sentinel => self.castTag(.array_sentinel).?.data.len, |
| 1753 | .array_u8 => self.castTag(.array_u8).?.data, |
| 1754 | .array_u8_sentinel_0 => self.castTag(.array_u8_sentinel_0).?.data, |
| 1766 | 1755 | }; |
| 1767 | 1756 | } |
| 1768 | 1757 | |
| ... | ... | @@ -1836,8 +1825,8 @@ pub const Type = extern union { |
| 1836 | 1825 | .array_u8, |
| 1837 | 1826 | => return null, |
| 1838 | 1827 | |
| 1839 | | .pointer => return self.cast(Payload.Pointer).?.sentinel, |
| 1840 | | .array_sentinel => return self.cast(Payload.ArraySentinel).?.sentinel, |
| 1828 | .pointer => return self.castTag(.pointer).?.data.sentinel, |
| 1829 | .array_sentinel => return self.castTag(.array_sentinel).?.data.sentinel, |
| 1841 | 1830 | .array_u8_sentinel_0 => return Value.initTag(.zero), |
| 1842 | 1831 | }; |
| 1843 | 1832 | } |
| ... | ... | @@ -2048,8 +2037,14 @@ pub const Type = extern union { |
| 2048 | 2037 | .empty_struct, |
| 2049 | 2038 | => unreachable, |
| 2050 | 2039 | |
| 2051 | | .int_unsigned => .{ .signedness = .unsigned, .bits = self.cast(Payload.IntUnsigned).?.bits }, |
| 2052 | | .int_signed => .{ .signedness = .signed, .bits = self.cast(Payload.IntSigned).?.bits }, |
| 2040 | .int_unsigned => .{ |
| 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 | 2048 | .u8 => .{ .signedness = .unsigned, .bits = 8 }, |
| 2054 | 2049 | .i8 => .{ .signedness = .signed, .bits = 8 }, |
| 2055 | 2050 | .u16 => .{ .signedness = .unsigned, .bits = 16 }, |
| ... | ... | @@ -2178,7 +2173,7 @@ pub const Type = extern union { |
| 2178 | 2173 | .fn_void_no_args => 0, |
| 2179 | 2174 | .fn_naked_noreturn_no_args => 0, |
| 2180 | 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, |
| 2182 | 2177 | |
| 2183 | 2178 | .f16, |
| 2184 | 2179 | .f32, |
| ... | ... | @@ -2254,7 +2249,7 @@ pub const Type = extern union { |
| 2254 | 2249 | .fn_naked_noreturn_no_args => return, |
| 2255 | 2250 | .fn_ccc_void_no_args => return, |
| 2256 | 2251 | .function => { |
| 2257 | | const payload = @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise); |
| 2252 | const payload = self.castTag(.function).?.data; |
| 2258 | 2253 | std.mem.copy(Type, types, payload.param_types); |
| 2259 | 2254 | }, |
| 2260 | 2255 | |
| ... | ... | @@ -2327,7 +2322,7 @@ pub const Type = extern union { |
| 2327 | 2322 | pub fn fnParamType(self: Type, index: usize) Type { |
| 2328 | 2323 | switch (self.tag()) { |
| 2329 | 2324 | .function => { |
| 2330 | | const payload = @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise); |
| 2325 | const payload = self.castTag(.function).?.data; |
| 2331 | 2326 | return payload.param_types[index]; |
| 2332 | 2327 | }, |
| 2333 | 2328 | |
| ... | ... | @@ -2410,7 +2405,7 @@ pub const Type = extern union { |
| 2410 | 2405 | .fn_ccc_void_no_args, |
| 2411 | 2406 | => Type.initTag(.void), |
| 2412 | 2407 | |
| 2413 | | .function => @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise).return_type, |
| 2408 | .function => self.castTag(.function).?.data.return_type, |
| 2414 | 2409 | |
| 2415 | 2410 | .f16, |
| 2416 | 2411 | .f32, |
| ... | ... | @@ -2484,7 +2479,7 @@ pub const Type = extern union { |
| 2484 | 2479 | .fn_void_no_args => .Unspecified, |
| 2485 | 2480 | .fn_naked_noreturn_no_args => .Naked, |
| 2486 | 2481 | .fn_ccc_void_no_args => .C, |
| 2487 | | .function => @fieldParentPtr(Payload.Function, "base", self.ptr_otherwise).cc, |
| 2482 | .function => self.castTag(.function).?.data.cc, |
| 2488 | 2483 | |
| 2489 | 2484 | .f16, |
| 2490 | 2485 | .f32, |
| ... | ... | @@ -2760,15 +2755,8 @@ pub const Type = extern union { |
| 2760 | 2755 | .@"null" => return Value.initTag(.null_value), |
| 2761 | 2756 | .@"undefined" => return Value.initTag(.undef), |
| 2762 | 2757 | |
| 2763 | | .int_unsigned => { |
| 2764 | | if (ty.cast(Payload.IntUnsigned).?.bits == 0) { |
| 2765 | | return Value.initTag(.zero); |
| 2766 | | } else { |
| 2767 | | return null; |
| 2768 | | } |
| 2769 | | }, |
| 2770 | | .int_signed => { |
| 2771 | | if (ty.cast(Payload.IntSigned).?.bits == 0) { |
| 2758 | .int_unsigned, .int_signed => { |
| 2759 | if (ty.cast(Payload.Bits).?.data == 0) { |
| 2772 | 2760 | return Value.initTag(.zero); |
| 2773 | 2761 | } else { |
| 2774 | 2762 | return null; |
| ... | ... | @@ -2787,12 +2775,11 @@ pub const Type = extern union { |
| 2787 | 2775 | .single_const_pointer, |
| 2788 | 2776 | .single_mut_pointer, |
| 2789 | 2777 | => { |
| 2790 | | const ptr = ty.castPointer().?; |
| 2791 | | ty = ptr.pointee_type; |
| 2778 | ty = ty.castPointer().?.data; |
| 2792 | 2779 | continue; |
| 2793 | 2780 | }, |
| 2794 | 2781 | .pointer => { |
| 2795 | | ty = ty.cast(Payload.Pointer).?.pointee_type; |
| 2782 | ty = ty.castTag(.pointer).?.data.pointee_type; |
| 2796 | 2783 | continue; |
| 2797 | 2784 | }, |
| 2798 | 2785 | }; |
| ... | ... | @@ -2869,7 +2856,7 @@ pub const Type = extern union { |
| 2869 | 2856 | .c_mut_pointer, |
| 2870 | 2857 | => return true, |
| 2871 | 2858 | |
| 2872 | | .pointer => self.cast(Payload.Pointer).?.size == .C, |
| 2859 | .pointer => self.castTag(.pointer).?.data.size == .C, |
| 2873 | 2860 | }; |
| 2874 | 2861 | } |
| 2875 | 2862 | |
| ... | ... | @@ -2950,7 +2937,7 @@ pub const Type = extern union { |
| 2950 | 2937 | .pointer, |
| 2951 | 2938 | => unreachable, |
| 2952 | 2939 | |
| 2953 | | .empty_struct => self.cast(Type.Payload.EmptyStruct).?.scope, |
| 2940 | .empty_struct => self.castTag(.empty_struct).?.data, |
| 2954 | 2941 | }; |
| 2955 | 2942 | } |
| 2956 | 2943 | |
| ... | ... | @@ -3105,117 +3092,195 @@ pub const Type = extern union { |
| 3105 | 3092 | |
| 3106 | 3093 | pub const last_no_payload_tag = Tag.const_slice_u8; |
| 3107 | 3094 | pub const no_payload_count = @enumToInt(last_no_payload_tag) + 1; |
| 3108 | | }; |
| 3109 | 3095 | |
| 3110 | | pub const Payload = struct { |
| 3111 | | tag: Tag, |
| 3096 | pub fn Type(comptime t: Tag) type { |
| 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 | } |
| 3112 | 3174 | |
| 3113 | | pub const Array_u8_Sentinel0 = struct { |
| 3114 | | base: Payload = Payload{ .tag = .array_u8_sentinel_0 }, |
| 3175 | pub fn create(comptime t: Tag, ally: *Allocator, data: Data(t)) error{OutOfMemory}!Type { |
| 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 | } |
| 3115 | 3183 | |
| 3116 | | len: u64, |
| 3117 | | }; |
| 3184 | pub fn Data(comptime t: Tag) type { |
| 3185 | return std.meta.fieldInfo(t.Type(), "data").field_type; |
| 3186 | } |
| 3187 | }; |
| 3118 | 3188 | |
| 3119 | | pub const Array_u8 = struct { |
| 3120 | | base: Payload = Payload{ .tag = .array_u8 }, |
| 3189 | /// The sub-types are named after what fields they contain. |
| 3190 | pub const Payload = struct { |
| 3191 | tag: Tag, |
| 3121 | 3192 | |
| 3122 | | len: u64, |
| 3193 | pub const Len = struct { |
| 3194 | base: Payload, |
| 3195 | data: u64, |
| 3123 | 3196 | }; |
| 3124 | 3197 | |
| 3125 | 3198 | pub const Array = struct { |
| 3126 | | base: Payload = Payload{ .tag = .array }, |
| 3199 | pub const base_tag = Tag.array; |
| 3127 | 3200 | |
| 3128 | | len: u64, |
| 3129 | | elem_type: Type, |
| 3201 | base: Payload = Payload{ .tag = base_tag }, |
| 3202 | data: struct { |
| 3203 | len: u64, |
| 3204 | elem_type: Type, |
| 3205 | }, |
| 3130 | 3206 | }; |
| 3131 | 3207 | |
| 3132 | 3208 | pub const ArraySentinel = struct { |
| 3133 | | base: Payload = Payload{ .tag = .array_sentinel }, |
| 3209 | pub const base_tag = Tag.array_sentinel; |
| 3134 | 3210 | |
| 3135 | | len: u64, |
| 3136 | | sentinel: Value, |
| 3137 | | elem_type: Type, |
| 3211 | base: Payload = Payload{ .tag = base_tag }, |
| 3212 | data: struct { |
| 3213 | len: u64, |
| 3214 | sentinel: Value, |
| 3215 | elem_type: Type, |
| 3216 | }, |
| 3138 | 3217 | }; |
| 3139 | 3218 | |
| 3140 | | pub const PointerSimple = struct { |
| 3219 | pub const ElemType = struct { |
| 3141 | 3220 | base: Payload, |
| 3142 | | |
| 3143 | | pointee_type: Type, |
| 3221 | data: Type, |
| 3144 | 3222 | }; |
| 3145 | 3223 | |
| 3146 | | pub const IntSigned = struct { |
| 3147 | | base: Payload = Payload{ .tag = .int_signed }, |
| 3148 | | |
| 3149 | | bits: u16, |
| 3150 | | }; |
| 3151 | | |
| 3152 | | pub const IntUnsigned = struct { |
| 3153 | | base: Payload = Payload{ .tag = .int_unsigned }, |
| 3154 | | |
| 3155 | | bits: u16, |
| 3224 | pub const Bits = struct { |
| 3225 | base: Payload, |
| 3226 | data: u16, |
| 3156 | 3227 | }; |
| 3157 | 3228 | |
| 3158 | 3229 | pub const Function = struct { |
| 3159 | | base: Payload = Payload{ .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 }, |
| 3230 | pub const base_tag = Tag.function; |
| 3168 | 3231 | |
| 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 | }; |
| 3171 | 3239 | |
| 3172 | 3240 | pub const Pointer = struct { |
| 3173 | | base: Payload = .{ .tag = .pointer }, |
| 3174 | | |
| 3175 | | pointee_type: Type, |
| 3176 | | sentinel: ?Value, |
| 3177 | | /// If zero use pointee_type.AbiAlign() |
| 3178 | | @"align": u32, |
| 3179 | | bit_offset: u16, |
| 3180 | | host_size: u16, |
| 3181 | | @"allowzero": bool, |
| 3182 | | mutable: bool, |
| 3183 | | @"volatile": bool, |
| 3184 | | size: std.builtin.TypeInfo.Pointer.Size, |
| 3241 | pub const base_tag = Tag.pointer; |
| 3242 | |
| 3243 | base: Payload = Payload{ .tag = base_tag }, |
| 3244 | data: struct { |
| 3245 | pointee_type: Type, |
| 3246 | sentinel: ?Value, |
| 3247 | /// If zero use pointee_type.AbiAlign() |
| 3248 | @"align": u32, |
| 3249 | bit_offset: u16, |
| 3250 | host_size: u16, |
| 3251 | @"allowzero": bool, |
| 3252 | mutable: bool, |
| 3253 | @"volatile": bool, |
| 3254 | size: std.builtin.TypeInfo.Pointer.Size, |
| 3255 | }, |
| 3185 | 3256 | }; |
| 3186 | 3257 | |
| 3187 | 3258 | pub const ErrorUnion = struct { |
| 3188 | | base: Payload = .{ .tag = .error_union }, |
| 3259 | pub const base_tag = Tag.error_union; |
| 3189 | 3260 | |
| 3190 | | error_set: Type, |
| 3191 | | payload: Type, |
| 3192 | | }; |
| 3193 | | |
| 3194 | | pub const AnyFrame = struct { |
| 3195 | | base: Payload = .{ .tag = .anyframe_T }, |
| 3196 | | |
| 3197 | | return_type: Type, |
| 3261 | base: Payload = Payload{ .tag = base_tag }, |
| 3262 | data: struct { |
| 3263 | error_set: Type, |
| 3264 | payload: Type, |
| 3265 | }, |
| 3198 | 3266 | }; |
| 3199 | 3267 | |
| 3200 | | pub const ErrorSet = struct { |
| 3201 | | base: Payload = .{ .tag = .error_set }, |
| 3202 | | |
| 3203 | | decl: *Module.Decl, |
| 3268 | pub const Decl = struct { |
| 3269 | base: Payload, |
| 3270 | data: *Module.Decl, |
| 3204 | 3271 | }; |
| 3205 | 3272 | |
| 3206 | | pub const ErrorSetSingle = struct { |
| 3207 | | base: Payload = .{ .tag = .error_set_single }, |
| 3208 | | |
| 3273 | pub const Name = struct { |
| 3274 | base: Payload, |
| 3209 | 3275 | /// memory is owned by `Module` |
| 3210 | | name: []const u8, |
| 3276 | data: []const u8, |
| 3211 | 3277 | }; |
| 3212 | 3278 | |
| 3213 | 3279 | /// Mostly used for namespace like structs with zero fields. |
| 3214 | 3280 | /// Most commonly used for files. |
| 3215 | | pub const EmptyStruct = struct { |
| 3216 | | base: Payload = .{ .tag = .empty_struct }, |
| 3217 | | |
| 3218 | | scope: *Module.Scope.Container, |
| 3281 | pub const ContainerScope = struct { |
| 3282 | base: Payload, |
| 3283 | data: *Module.Scope.Container, |
| 3219 | 3284 | }; |
| 3220 | 3285 | }; |
| 3221 | 3286 | }; |