authorgravatar for mlugg@mlugg.co.ukMatthew Lugg <mlugg@mlugg.co.uk> 2025-11-23 07:50:29+00:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-11-23 07:50:29+00:00
log6d543bcf94b2deefa918cb29de93fc32a10d4abf
treed6d90938858a7479b682a3b97c98cb3ab67cd4df
parent0a9f666ea62829607d782dc0cac5d10099def180
parentdec1163fbb892f276179ae74b51007c656157d99
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #23733 from alichraghi/bp

replace @Type with individual type-creating builtins

122 files changed, 2665 insertions(+), 3322 deletions(-)

doc/langref.html.in+74-40
......@@ -638,7 +638,7 @@
638638 {#syntax#}i7{#endsyntax#} refers to a signed 7-bit integer. The maximum allowed bit-width of an
639639 integer type is {#syntax#}65535{#endsyntax#}.
640640 </p>
641 {#see_also|Integers|Floats|void|Errors|@Type#}
641 {#see_also|Integers|Floats|void|Errors|@Int#}
642642 {#header_close#}
643643 {#header_open|Primitive Values#}
644644 <div class="table-wrapper">
......@@ -3723,9 +3723,9 @@ void do_a_thing(struct Foo *foo) {
37233723 <td>{#syntax#}x{#endsyntax#} is a {#syntax#}@FieldType(T, "a"){#endsyntax#}</td>
37243724 </tr>
37253725 <tr>
3726 <th scope="row">{#syntax#}@Type(x){#endsyntax#}</th>
3726 <th scope="row">{#syntax#}@Int(x, y){#endsyntax#}</th>
37273727 <td>-</td>
3728 <td>{#syntax#}x{#endsyntax#} is a {#syntax#}std.builtin.Type{#endsyntax#}</td>
3728 <td>{#syntax#}x{#endsyntax#} is a {#syntax#}std.builtin.Signedness{#endsyntax#}, {#syntax#}y{#endsyntax#} is a {#syntax#}u16{#endsyntax#}</td>
37293729 </tr>
37303730 <tr>
37313731 <th scope="row">{#syntax#}@typeInfo(x){#endsyntax#}</th>
......@@ -3839,9 +3839,9 @@ void do_a_thing(struct Foo *foo) {
38393839 <td>{#syntax#}x{#endsyntax#} has no result location (typed initializers do not propagate result locations)</td>
38403840 </tr>
38413841 <tr>
3842 <th scope="row">{#syntax#}@Type(x){#endsyntax#}</th>
3843 <td>{#syntax#}ptr{#endsyntax#}</td>
3844 <td>{#syntax#}x{#endsyntax#} has no result location</td>
3842 <th scope="row">{#syntax#}@Int(x, y){#endsyntax#}</th>
3843 <td>-</td>
3844 <td>{#syntax#}x{#endsyntax#} and {#syntax#}y{#endsyntax#} do not have result locations</td>
38453845 </tr>
38463846 <tr>
38473847 <th scope="row">{#syntax#}@typeInfo(x){#endsyntax#}</th>
......@@ -5755,41 +5755,75 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
57555755 </p>
57565756 {#header_close#}
57575757
5758 {#header_open|@Type#}
5759 <pre>{#syntax#}@Type(comptime info: std.builtin.Type) type{#endsyntax#}</pre>
5760 <p>
5761 This function is the inverse of {#link|@typeInfo#}. It reifies type information
5762 into a {#syntax#}type{#endsyntax#}.
5763 </p>
5764 <p>
5765 It is available for the following types:
5766 </p>
5767 <ul>
5768 <li>{#syntax#}type{#endsyntax#}</li>
5769 <li>{#syntax#}noreturn{#endsyntax#}</li>
5770 <li>{#syntax#}void{#endsyntax#}</li>
5771 <li>{#syntax#}bool{#endsyntax#}</li>
5772 <li>{#link|Integers#} - The maximum bit count for an integer type is {#syntax#}65535{#endsyntax#}.</li>
5773 <li>{#link|Floats#}</li>
5774 <li>{#link|Pointers#}</li>
5775 <li>{#syntax#}comptime_int{#endsyntax#}</li>
5776 <li>{#syntax#}comptime_float{#endsyntax#}</li>
5777 <li>{#syntax#}@TypeOf(undefined){#endsyntax#}</li>
5778 <li>{#syntax#}@TypeOf(null){#endsyntax#}</li>
5779 <li>{#link|Arrays#}</li>
5780 <li>{#link|Optionals#}</li>
5781 <li>{#link|Error Set Type#}</li>
5782 <li>{#link|Error Union Type#}</li>
5783 <li>{#link|Vectors#}</li>
5784 <li>{#link|opaque#}</li>
5785 <li>{#syntax#}anyframe{#endsyntax#}</li>
5786 <li>{#link|struct#}</li>
5787 <li>{#link|enum#}</li>
5788 <li>{#link|Enum Literals#}</li>
5789 <li>{#link|union#}</li>
5790 <li>{#link|Functions#}</li>
5791 </ul>
5758 {#header_open|@EnumLiteral#}
5759 <pre>{#syntax#}@EnumLiteral() type{#endsyntax#}</pre>
5760 <p>Returns the comptime-only "enum literal" type. This is the type of uncoerced {#link|Enum Literals#}. Values of this type can coerce to any {#link|enum#} with a matching field.</p>
5761 {#header_close#}
5762
5763 {#header_open|@Int#}
5764 <pre>{#syntax#}@Int(comptime signedness: std.builtin.Signedness, comptime bits: u16) type{#endsyntax#}</pre>
5765 <p>Returns an integer type with the given signedness and bit width.</p>
5766 <p>For instance, {#syntax#}@Int(.unsigned, 18){#endsyntax#} returns the type {#syntax#}u18{#endsyntax#}.</p>
57925767 {#header_close#}
5768
5769 {#header_open|@Tuple#}
5770 <pre>{#syntax#}@Tuple(comptime field_types: []const type) type{#endsyntax#}</pre>
5771 <p>Returns a {#link|tuple|Tuples#} type with the given field types.</p>
5772 {#header_close#}
5773
5774 {#header_open|@Pointer#}
5775 <pre>{#syntax#}@Pointer(
5776 comptime size: std.builtin.Type.Pointer.Size,
5777 comptime attrs: std.builtin.Type.Pointer.Attributes,
5778 comptime Element: type,
5779 comptime sentinel: ?Element,
5780) type{#endsyntax#}</pre>
5781 <p>Returns a {#link|pointer|Pointers#} type with the properties specified by the arguments.</p>
5782 {#header_close#}
5783
5784 {#header_open|@Fn#}
5785 <pre>{#syntax#}@Fn(
5786 comptime param_types: []const type,
5787 comptime param_attrs: *const [param_types.len]std.builtin.Type.Fn.Param.Attributes,
5788 comptime ReturnType: type,
5789 comptime attrs: std.builtin.Type.Fn.Attributes,
5790) type{#endsyntax#}</pre>
5791 <p>Returns a {#link|function|Functions#} type with the properties specified by the arguments.</p>
5792 {#header_close#}
5793
5794 {#header_open|@Struct#}
5795 <pre>{#syntax#}@Struct(
5796 comptime layout: std.builtin.Type.ContainerLayout,
5797 comptime BackingInt: ?type,
5798 comptime field_names: []const []const u8,
5799 comptime field_types: *const [field_names.len]type,
5800 comptime field_attrs: *const [field_names.len]std.builtin.Type.StructField.Attributes,
5801) type{#endsyntax#}</pre>
5802 <p>Returns a {#link|struct#} type with the properties specified by the arguments.</p>
5803 {#header_close#}
5804
5805 {#header_open|@Union#}
5806 <pre>{#syntax#}@Union(
5807 comptime layout: std.builtin.Type.ContainerLayout,
5808 /// Either the integer tag type, or the integer backing type, depending on `layout`.
5809 comptime ArgType: ?type,
5810 comptime field_names: []const []const u8,
5811 comptime field_types: *const [field_names.len]type,
5812 comptime field_attrs: *const [field_names.len]std.builtin.Type.UnionField.Attributes,
5813) type{#endsyntax#}</pre>
5814 <p>Returns a {#link|union#} type with the properties specified by the arguments.</p>
5815 {#header_close#}
5816
5817 {#header_open|@Enum#}
5818 <pre>{#syntax#}@Enum(
5819 comptime TagInt: type,
5820 comptime mode: std.builtin.Type.Enum.Mode,
5821 comptime field_names: []const []const u8,
5822 comptime field_values: *const [field_names.len]TagInt,
5823) type{#endsyntax#}</pre>
5824 <p>Returns an {#link|enum#} type with the properties specified by the arguments.</p>
5825 {#header_close#}
5826
57935827 {#header_open|@typeInfo#}
57945828 <pre>{#syntax#}@typeInfo(comptime T: type) std.builtin.Type{#endsyntax#}</pre>
57955829 <p>
doc/langref/std_options.zig+1-1
......@@ -11,7 +11,7 @@ pub const std_options: std.Options = .{
1111
1212fn myLogFn(
1313 comptime level: std.log.Level,
14 comptime scope: @Type(.enum_literal),
14 comptime scope: @EnumLiteral(),
1515 comptime format: []const u8,
1616 args: anytype,
1717) void {
doc/langref/test_coerce_unions_enums.zig+1-1
......@@ -41,7 +41,7 @@ test "coercion between unions and enums" {
4141 try expect(u_4.tag() == 1);
4242
4343 // The following example is invalid.
44 // error: coercion from enum '@TypeOf(.enum_literal)' to union 'test_coerce_unions_enum.U2' must initialize 'f32' field 'b'
44 // error: coercion from enum '@EnumLiteral()' to union 'test_coerce_unions_enum.U2' must initialize 'f32' field 'b'
4545 //var u_5: U2 = .b;
4646 //try expect(u_5.tag() == 2);
4747}
lib/build-web/main.zig+1-1
......@@ -49,7 +49,7 @@ pub fn panic(msg: []const u8, st: ?*std.builtin.StackTrace, addr: ?usize) noretu
4949
5050fn logFn(
5151 comptime message_level: log.Level,
52 comptime scope: @TypeOf(.enum_literal),
52 comptime scope: @EnumLiteral(),
5353 comptime format: []const u8,
5454 args: anytype,
5555) void {
lib/compiler/aro/aro/Attribute.zig+6-16
......@@ -717,23 +717,13 @@ pub const Tag = std.meta.DeclEnum(attributes);
717717
718718pub const Arguments = blk: {
719719 const decls = @typeInfo(attributes).@"struct".decls;
720 var union_fields: [decls.len]ZigType.UnionField = undefined;
721 for (decls, &union_fields) |decl, *field| {
722 field.* = .{
723 .name = decl.name,
724 .type = @field(attributes, decl.name),
725 .alignment = @alignOf(@field(attributes, decl.name)),
726 };
720 var names: [decls.len][]const u8 = undefined;
721 var types: [decls.len]type = undefined;
722 for (decls, &names, &types) |decl, *name, *T| {
723 name.* = decl.name;
724 T.* = @field(attributes, decl.name);
727725 }
728
729 break :blk @Type(.{
730 .@"union" = .{
731 .layout = .auto,
732 .tag_type = null,
733 .fields = &union_fields,
734 .decls = &.{},
735 },
736 });
726 break :blk @Union(.auto, null, &names, &types, &@splat(.{}));
737727};
738728
739729pub fn ArgumentsForTag(comptime tag: Tag) type {
lib/compiler/aro/assembly_backend/x86_64.zig+1-1
......@@ -59,7 +59,7 @@ fn serializeFloat(comptime T: type, value: T, w: *std.Io.Writer) !void {
5959 else => {
6060 const size = @bitSizeOf(T);
6161 const storage_unit = std.meta.intToEnum(StorageUnit, size) catch unreachable;
62 const IntTy = @Type(.{ .int = .{ .signedness = .unsigned, .bits = size } });
62 const IntTy = @Int(.unsigned, size);
6363 const int_val: IntTy = @bitCast(value);
6464 return serializeInt(int_val, storage_unit, w);
6565 },
lib/compiler/resinator/code_pages.zig+7-6
......@@ -179,12 +179,13 @@ pub const UnsupportedCodePage = enum(u16) {
179179
180180pub const CodePage = blk: {
181181 const fields = @typeInfo(SupportedCodePage).@"enum".fields ++ @typeInfo(UnsupportedCodePage).@"enum".fields;
182 break :blk @Type(.{ .@"enum" = .{
183 .tag_type = u16,
184 .decls = &.{},
185 .fields = fields,
186 .is_exhaustive = true,
187 } });
182 var field_names: [fields.len][]const u8 = undefined;
183 var field_values: [fields.len]u16 = undefined;
184 for (fields, &field_names, &field_values) |field, *name, *val| {
185 name.* = field.name;
186 val.* = field.value;
187 }
188 break :blk @Enum(u16, .exhaustive, &field_names, &field_values);
188189};
189190
190191pub fn isSupported(code_page: CodePage) bool {
lib/compiler/resinator/errors.zig+12-9
......@@ -862,20 +862,23 @@ pub const ErrorDetails = struct {
862862pub const ErrorDetailsWithoutCodePage = blk: {
863863 const details_info = @typeInfo(ErrorDetails);
864864 const fields = details_info.@"struct".fields;
865 var fields_without_codepage: [fields.len - 1]std.builtin.Type.StructField = undefined;
865 var field_names: [fields.len - 1][]const u8 = undefined;
866 var field_types: [fields.len - 1]type = undefined;
867 var field_attrs: [fields.len - 1]std.builtin.Type.StructField.Attributes = undefined;
866868 var i: usize = 0;
867869 for (fields) |field| {
868870 if (std.mem.eql(u8, field.name, "code_page")) continue;
869 fields_without_codepage[i] = field;
871 field_names[i] = field.name;
872 field_types[i] = field.type;
873 field_attrs[i] = .{
874 .@"comptime" = field.is_comptime,
875 .@"align" = field.alignment,
876 .default_value_ptr = field.default_value_ptr,
877 };
870878 i += 1;
871879 }
872 std.debug.assert(i == fields_without_codepage.len);
873 break :blk @Type(.{ .@"struct" = .{
874 .layout = .auto,
875 .fields = &fields_without_codepage,
876 .decls = &.{},
877 .is_tuple = false,
878 } });
880 std.debug.assert(i == fields.len - 1);
881 break :blk @Struct(.auto, null, &field_names, &field_types, &field_attrs);
879882};
880883
881884fn cellCount(code_page: SupportedCodePage, source: []const u8, start_index: usize, end_index: usize) usize {
lib/compiler/test_runner.zig+1-1
......@@ -298,7 +298,7 @@ fn mainTerminal() void {
298298
299299pub fn log(
300300 comptime message_level: std.log.Level,
301 comptime scope: @Type(.enum_literal),
301 comptime scope: @EnumLiteral(),
302302 comptime format: []const u8,
303303 args: anytype,
304304) void {
lib/compiler_rt/common.zig+1-4
......@@ -290,10 +290,7 @@ pub fn normalize(comptime T: type, significand: *std.meta.Int(.unsigned, @typeIn
290290pub inline fn fneg(a: anytype) @TypeOf(a) {
291291 const F = @TypeOf(a);
292292 const bits = @typeInfo(F).float.bits;
293 const U = @Type(.{ .int = .{
294 .signedness = .unsigned,
295 .bits = bits,
296 } });
293 const U = @Int(.unsigned, bits);
297294 const sign_bit_mask = @as(U, 1) << (bits - 1);
298295 const negated = @as(U, @bitCast(a)) ^ sign_bit_mask;
299296 return @bitCast(negated);
lib/compiler_rt/float_from_int.zig+5-5
......@@ -66,17 +66,17 @@ pub inline fn floatFromBigInt(comptime T: type, comptime signedness: std.builtin
6666 switch (x.len) {
6767 0 => return 0,
6868 inline 1...4 => |limbs_len| return @floatFromInt(@as(
69 @Type(.{ .int = .{ .signedness = signedness, .bits = 32 * limbs_len } }),
69 @Int(signedness, 32 * limbs_len),
7070 @bitCast(x[0..limbs_len].*),
7171 )),
7272 else => {},
7373 }
7474
7575 // sign implicit fraction round sticky
76 const I = comptime @Type(.{ .int = .{
77 .signedness = signedness,
78 .bits = @as(u16, @intFromBool(signedness == .signed)) + 1 + math.floatFractionalBits(T) + 1 + 1,
79 } });
76 const I = comptime @Int(
77 signedness,
78 @as(u16, @intFromBool(signedness == .signed)) + 1 + math.floatFractionalBits(T) + 1 + 1,
79 );
8080
8181 const clrsb = clrsb: {
8282 var clsb: usize = 0;
lib/compiler_rt/int_from_float.zig+2-5
......@@ -56,7 +56,7 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul
5656 0 => return,
5757 inline 1...4 => |limbs_len| {
5858 result[0..limbs_len].* = @bitCast(@as(
59 @Type(.{ .int = .{ .signedness = signedness, .bits = 32 * limbs_len } }),
59 @Int(signedness, 32 * limbs_len),
6060 @intFromFloat(a),
6161 ));
6262 return;
......@@ -66,10 +66,7 @@ pub inline fn bigIntFromFloat(comptime signedness: std.builtin.Signedness, resul
6666
6767 // sign implicit fraction
6868 const significand_bits = 1 + math.floatFractionalBits(@TypeOf(a));
69 const I = @Type(comptime .{ .int = .{
70 .signedness = signedness,
71 .bits = @as(u16, @intFromBool(signedness == .signed)) + significand_bits,
72 } });
69 const I = @Int(signedness, @as(u16, @intFromBool(signedness == .signed)) + significand_bits);
7370
7471 const parts = math.frexp(a);
7572 const significand_bits_adjusted_to_handle_smin = @as(i32, significand_bits) +
lib/compiler_rt/memcpy.zig+1-1
......@@ -159,7 +159,7 @@ inline fn copyFixedLength(
159159 else if (len > @sizeOf(usize))
160160 @Vector(len, u8)
161161 else
162 @Type(.{ .int = .{ .signedness = .unsigned, .bits = len * 8 } });
162 @Int(.unsigned, len * 8);
163163
164164 const loop_count = @divExact(len, @sizeOf(T));
165165
lib/docs/wasm/main.zig+1-1
......@@ -41,7 +41,7 @@ pub fn panic(msg: []const u8, st: ?*std.builtin.StackTrace, addr: ?usize) noretu
4141
4242fn logFn(
4343 comptime message_level: log.Level,
44 comptime scope: @TypeOf(.enum_literal),
44 comptime scope: @EnumLiteral(),
4545 comptime format: []const u8,
4646 args: anytype,
4747) void {
lib/fuzzer.zig+1-1
......@@ -15,7 +15,7 @@ pub const std_options = std.Options{
1515
1616fn logOverride(
1717 comptime level: std.log.Level,
18 comptime scope: @Type(.enum_literal),
18 comptime scope: @EnumLiteral(),
1919 comptime format: []const u8,
2020 args: anytype,
2121) void {
lib/std/Build.zig+3-11
......@@ -416,7 +416,7 @@ fn createChildOnly(
416416fn userInputOptionsFromArgs(arena: Allocator, args: anytype) UserInputOptionsMap {
417417 var map = UserInputOptionsMap.init(arena);
418418 inline for (@typeInfo(@TypeOf(args)).@"struct".fields) |field| {
419 if (field.type == @Type(.null)) continue;
419 if (field.type == @TypeOf(null)) continue;
420420 addUserInputOptionFromArg(arena, &map, field, field.type, @field(args, field.name));
421421 }
422422 return map;
......@@ -526,16 +526,11 @@ fn addUserInputOptionFromArg(
526526 .pointer => |ptr_info| switch (ptr_info.size) {
527527 .one => switch (@typeInfo(ptr_info.child)) {
528528 .array => |array_info| {
529 comptime var slice_info = ptr_info;
530 slice_info.size = .slice;
531 slice_info.is_const = true;
532 slice_info.child = array_info.child;
533 slice_info.sentinel_ptr = null;
534529 addUserInputOptionFromArg(
535530 arena,
536531 map,
537532 field,
538 @Type(.{ .pointer = slice_info }),
533 @Pointer(.slice, .{ .@"const" = true }, array_info.child, null),
539534 maybe_value orelse null,
540535 );
541536 return;
......@@ -553,14 +548,11 @@ fn addUserInputOptionFromArg(
553548 }) catch @panic("OOM");
554549 },
555550 else => {
556 comptime var slice_info = ptr_info;
557 slice_info.is_const = true;
558 slice_info.sentinel_ptr = null;
559551 addUserInputOptionFromArg(
560552 arena,
561553 map,
562554 field,
563 @Type(.{ .pointer = slice_info }),
555 @Pointer(ptr_info.size, .{ .@"const" = true }, ptr_info.child, null),
564556 maybe_value orelse null,
565557 );
566558 return;
lib/std/Io.zig+8-32
......@@ -528,23 +528,7 @@ pub fn Poller(comptime StreamEnum: type) type {
528528/// Given an enum, returns a struct with fields of that enum, each field
529529/// representing an I/O stream for polling.
530530pub fn PollFiles(comptime StreamEnum: type) type {
531 const enum_fields = @typeInfo(StreamEnum).@"enum".fields;
532 var struct_fields: [enum_fields.len]std.builtin.Type.StructField = undefined;
533 for (&struct_fields, enum_fields) |*struct_field, enum_field| {
534 struct_field.* = .{
535 .name = enum_field.name,
536 .type = std.fs.File,
537 .default_value_ptr = null,
538 .is_comptime = false,
539 .alignment = @alignOf(std.fs.File),
540 };
541 }
542 return @Type(.{ .@"struct" = .{
543 .layout = .auto,
544 .fields = &struct_fields,
545 .decls = &.{},
546 .is_tuple = false,
547 } });
531 return @Struct(.auto, null, std.meta.fieldNames(StreamEnum), &@splat(std.fs.File), &@splat(.{}));
548532}
549533
550534test {
......@@ -1625,22 +1609,14 @@ pub fn sleep(io: Io, duration: Duration, clock: Clock) SleepError!void {
16251609/// fields, each field type the future's result.
16261610pub fn SelectUnion(S: type) type {
16271611 const struct_fields = @typeInfo(S).@"struct".fields;
1628 var fields: [struct_fields.len]std.builtin.Type.UnionField = undefined;
1629 for (&fields, struct_fields) |*union_field, struct_field| {
1630 const F = @typeInfo(struct_field.type).pointer.child;
1631 const Result = @TypeOf(@as(F, undefined).result);
1632 union_field.* = .{
1633 .name = struct_field.name,
1634 .type = Result,
1635 .alignment = struct_field.alignment,
1636 };
1612 var names: [struct_fields.len][]const u8 = undefined;
1613 var types: [struct_fields.len]type = undefined;
1614 for (struct_fields, &names, &types) |struct_field, *union_field_name, *UnionFieldType| {
1615 const FieldFuture = @typeInfo(struct_field.type).pointer.child;
1616 union_field_name.* = struct_field.name;
1617 UnionFieldType.* = @FieldType(FieldFuture, "result");
16371618 }
1638 return @Type(.{ .@"union" = .{
1639 .layout = .auto,
1640 .tag_type = std.meta.FieldEnum(S),
1641 .fields = &fields,
1642 .decls = &.{},
1643 } });
1619 return @Union(.auto, std.meta.FieldEnum(S), &names, &types, &@splat(.{}));
16441620}
16451621
16461622/// `s` is a struct with every field a `*Future(T)`, where `T` can be any type,
lib/std/Io/Reader.zig+5-8
......@@ -1273,20 +1273,17 @@ pub const TakeLeb128Error = Error || error{Overflow};
12731273/// Read a single LEB128 value as type T, or `error.Overflow` if the value cannot fit.
12741274pub fn takeLeb128(r: *Reader, comptime Result: type) TakeLeb128Error!Result {
12751275 const result_info = @typeInfo(Result).int;
1276 return std.math.cast(Result, try r.takeMultipleOf7Leb128(@Type(.{ .int = .{
1277 .signedness = result_info.signedness,
1278 .bits = std.mem.alignForwardAnyAlign(u16, result_info.bits, 7),
1279 } }))) orelse error.Overflow;
1276 return std.math.cast(Result, try r.takeMultipleOf7Leb128(@Int(
1277 result_info.signedness,
1278 std.mem.alignForwardAnyAlign(u16, result_info.bits, 7),
1279 ))) orelse error.Overflow;
12801280}
12811281
12821282fn takeMultipleOf7Leb128(r: *Reader, comptime Result: type) TakeLeb128Error!Result {
12831283 const result_info = @typeInfo(Result).int;
12841284 comptime assert(result_info.bits % 7 == 0);
12851285 var remaining_bits: std.math.Log2IntCeil(Result) = result_info.bits;
1286 const UnsignedResult = @Type(.{ .int = .{
1287 .signedness = .unsigned,
1288 .bits = result_info.bits,
1289 } });
1286 const UnsignedResult = @Int(.unsigned, result_info.bits);
12901287 var result: UnsignedResult = 0;
12911288 var fits = true;
12921289 while (true) {
lib/std/Io/Writer.zig+10-10
......@@ -1890,7 +1890,7 @@ pub fn writeUleb128(w: *Writer, value: anytype) Error!void {
18901890 try w.writeLeb128(switch (@typeInfo(@TypeOf(value))) {
18911891 .comptime_int => @as(std.math.IntFittingRange(0, @abs(value)), value),
18921892 .int => |value_info| switch (value_info.signedness) {
1893 .signed => @as(@Type(.{ .int = .{ .signedness = .unsigned, .bits = value_info.bits -| 1 } }), @intCast(value)),
1893 .signed => @as(@Int(.unsigned, value_info.bits -| 1), @intCast(value)),
18941894 .unsigned => value,
18951895 },
18961896 else => comptime unreachable,
......@@ -1903,7 +1903,7 @@ pub fn writeSleb128(w: *Writer, value: anytype) Error!void {
19031903 .comptime_int => @as(std.math.IntFittingRange(@min(value, -1), @max(0, value)), value),
19041904 .int => |value_info| switch (value_info.signedness) {
19051905 .signed => value,
1906 .unsigned => @as(@Type(.{ .int = .{ .signedness = .signed, .bits = value_info.bits + 1 } }), value),
1906 .unsigned => @as(@Int(.signed, value_info.bits + 1), value),
19071907 },
19081908 else => comptime unreachable,
19091909 });
......@@ -1912,10 +1912,10 @@ pub fn writeSleb128(w: *Writer, value: anytype) Error!void {
19121912/// Write a single integer as LEB128 to the given writer.
19131913pub fn writeLeb128(w: *Writer, value: anytype) Error!void {
19141914 const value_info = @typeInfo(@TypeOf(value)).int;
1915 try w.writeMultipleOf7Leb128(@as(@Type(.{ .int = .{
1916 .signedness = value_info.signedness,
1917 .bits = @max(std.mem.alignForwardAnyAlign(u16, value_info.bits, 7), 7),
1918 } }), value));
1915 try w.writeMultipleOf7Leb128(@as(@Int(
1916 value_info.signedness,
1917 @max(std.mem.alignForwardAnyAlign(u16, value_info.bits, 7), 7),
1918 ), value));
19191919}
19201920
19211921fn writeMultipleOf7Leb128(w: *Writer, value: anytype) Error!void {
......@@ -1929,10 +1929,10 @@ fn writeMultipleOf7Leb128(w: *Writer, value: anytype) Error!void {
19291929 .unsigned => remaining > std.math.maxInt(u7),
19301930 };
19311931 byte.* = .{
1932 .bits = @bitCast(@as(@Type(.{ .int = .{
1933 .signedness = value_info.signedness,
1934 .bits = 7,
1935 } }), @truncate(remaining))),
1932 .bits = @bitCast(@as(
1933 @Int(value_info.signedness, 7),
1934 @truncate(remaining),
1935 )),
19361936 .more = more,
19371937 };
19381938 if (value_info.bits > 7) remaining >>= 7;
lib/std/builtin.zig+50-9
......@@ -548,19 +548,19 @@ pub const TypeId = std.meta.Tag(Type);
548548/// This data structure is used by the Zig language code generation and
549549/// therefore must be kept in sync with the compiler implementation.
550550pub const Type = union(enum) {
551 type: void,
552 void: void,
553 bool: void,
554 noreturn: void,
551 type,
552 void,
553 bool,
554 noreturn,
555555 int: Int,
556556 float: Float,
557557 pointer: Pointer,
558558 array: Array,
559559 @"struct": Struct,
560 comptime_float: void,
561 comptime_int: void,
562 undefined: void,
563 null: void,
560 comptime_float,
561 comptime_int,
562 undefined,
563 null,
564564 optional: Optional,
565565 error_union: ErrorUnion,
566566 error_set: ErrorSet,
......@@ -571,7 +571,7 @@ pub const Type = union(enum) {
571571 frame: Frame,
572572 @"anyframe": AnyFrame,
573573 vector: Vector,
574 enum_literal: void,
574 enum_literal,
575575
576576 /// This data structure is used by the Zig language code generation and
577577 /// therefore must be kept in sync with the compiler implementation.
......@@ -619,6 +619,16 @@ pub const Type = union(enum) {
619619 slice,
620620 c,
621621 };
622
623 /// This data structure is used by the Zig language code generation and
624 /// therefore must be kept in sync with the compiler implementation.
625 pub const Attributes = struct {
626 @"const": bool = false,
627 @"volatile": bool = false,
628 @"allowzero": bool = false,
629 @"addrspace": ?AddressSpace = null,
630 @"align": ?usize = null,
631 };
622632 };
623633
624634 /// This data structure is used by the Zig language code generation and
......@@ -668,6 +678,14 @@ pub const Type = union(enum) {
668678 const dp: *const sf.type = @ptrCast(@alignCast(sf.default_value_ptr orelse return null));
669679 return dp.*;
670680 }
681
682 /// This data structure is used by the Zig language code generation and
683 /// therefore must be kept in sync with the compiler implementation.
684 pub const Attributes = struct {
685 @"comptime": bool = false,
686 @"align": ?usize = null,
687 default_value_ptr: ?*const anyopaque = null,
688 };
671689 };
672690
673691 /// This data structure is used by the Zig language code generation and
......@@ -718,6 +736,10 @@ pub const Type = union(enum) {
718736 fields: []const EnumField,
719737 decls: []const Declaration,
720738 is_exhaustive: bool,
739
740 /// This data structure is used by the Zig language code generation and
741 /// therefore must be kept in sync with the compiler implementation.
742 pub const Mode = enum { exhaustive, nonexhaustive };
721743 };
722744
723745 /// This data structure is used by the Zig language code generation and
......@@ -726,6 +748,12 @@ pub const Type = union(enum) {
726748 name: [:0]const u8,
727749 type: type,
728750 alignment: comptime_int,
751
752 /// This data structure is used by the Zig language code generation and
753 /// therefore must be kept in sync with the compiler implementation.
754 pub const Attributes = struct {
755 @"align": ?usize = null,
756 };
729757 };
730758
731759 /// This data structure is used by the Zig language code generation and
......@@ -753,6 +781,19 @@ pub const Type = union(enum) {
753781 is_generic: bool,
754782 is_noalias: bool,
755783 type: ?type,
784
785 /// This data structure is used by the Zig language code generation and
786 /// therefore must be kept in sync with the compiler implementation.
787 pub const Attributes = struct {
788 @"noalias": bool = false,
789 };
790 };
791
792 /// This data structure is used by the Zig language code generation and
793 /// therefore must be kept in sync with the compiler implementation.
794 pub const Attributes = struct {
795 @"callconv": CallingConvention = .auto,
796 varargs: bool = false,
756797 };
757798 };
758799
lib/std/crypto/phc_encoding.zig+4-4
......@@ -94,12 +94,12 @@ pub fn deserialize(comptime HashResult: type, str: []const u8) Error!HashResult
9494 if (kvSplit(field)) |opt_version| {
9595 if (mem.eql(u8, opt_version.key, version_param_name)) {
9696 if (@hasField(HashResult, "alg_version")) {
97 const value_type_info = switch (@typeInfo(@TypeOf(out.alg_version))) {
98 .optional => |opt| @typeInfo(opt.child),
99 else => |t| t,
97 const ValueType = switch (@typeInfo(@TypeOf(out.alg_version))) {
98 .optional => |opt| opt.child,
99 else => @TypeOf(out.alg_version),
100100 };
101101 out.alg_version = fmt.parseUnsigned(
102 @Type(value_type_info),
102 ValueType,
103103 opt_version.value,
104104 10,
105105 ) catch return Error.InvalidEncoding;
lib/std/crypto/tls.zig+1-1
......@@ -606,7 +606,7 @@ pub fn array(
606606 const elem_size = @divExact(@bitSizeOf(Elem), 8);
607607 var arr: [len_size + elem_size * elems.len]u8 = undefined;
608608 std.mem.writeInt(Len, arr[0..len_size], @intCast(elem_size * elems.len), .big);
609 const ElemInt = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(Elem) } });
609 const ElemInt = @Int(.unsigned, @bitSizeOf(Elem));
610610 for (0.., @as([elems.len]Elem, elems)) |index, elem| {
611611 std.mem.writeInt(
612612 ElemInt,
lib/std/enums.zig+11-29
......@@ -33,22 +33,8 @@ pub fn fromInt(comptime E: type, integer: anytype) ?E {
3333/// default, which may be undefined.
3434pub fn EnumFieldStruct(comptime E: type, comptime Data: type, comptime field_default: ?Data) type {
3535 @setEvalBranchQuota(@typeInfo(E).@"enum".fields.len + eval_branch_quota_cushion);
36 var struct_fields: [@typeInfo(E).@"enum".fields.len]std.builtin.Type.StructField = undefined;
37 for (&struct_fields, @typeInfo(E).@"enum".fields) |*struct_field, enum_field| {
38 struct_field.* = .{
39 .name = enum_field.name,
40 .type = Data,
41 .default_value_ptr = if (field_default) |d| @as(?*const anyopaque, @ptrCast(&d)) else null,
42 .is_comptime = false,
43 .alignment = if (@sizeOf(Data) > 0) @alignOf(Data) else 0,
44 };
45 }
46 return @Type(.{ .@"struct" = .{
47 .layout = .auto,
48 .fields = &struct_fields,
49 .decls = &.{},
50 .is_tuple = false,
51 } });
36 const default_ptr: ?*const anyopaque = if (field_default) |d| @ptrCast(&d) else null;
37 return @Struct(.auto, null, std.meta.fieldNames(E), &@splat(Data), &@splat(.{ .default_value_ptr = default_ptr }));
5238}
5339
5440/// Looks up the supplied fields in the given enum type.
......@@ -1532,19 +1518,15 @@ test "EnumIndexer empty" {
15321518test "EnumIndexer large dense unsorted" {
15331519 @setEvalBranchQuota(500_000); // many `comptimePrint`s
15341520 // Make an enum with 500 fields with values in *descending* order.
1535 const E = @Type(.{ .@"enum" = .{
1536 .tag_type = u32,
1537 .fields = comptime fields: {
1538 var fields: [500]EnumField = undefined;
1539 for (&fields, 0..) |*f, i| f.* = .{
1540 .name = std.fmt.comptimePrint("f{d}", .{i}),
1541 .value = 500 - i,
1542 };
1543 break :fields &fields;
1544 },
1545 .decls = &.{},
1546 .is_exhaustive = true,
1547 } });
1521 const E = @Enum(u32, .exhaustive, names: {
1522 var names: [500][]const u8 = undefined;
1523 for (&names, 0..) |*name, i| name.* = std.fmt.comptimePrint("f{d}", .{i});
1524 break :names &names;
1525 }, vals: {
1526 var vals: [500]u32 = undefined;
1527 for (&vals, 0..) |*val, i| val.* = 500 - i;
1528 break :vals &vals;
1529 });
15481530 const Indexer = EnumIndexer(E);
15491531 try testing.expectEqual(E.f0, Indexer.keyForIndex(499));
15501532 try testing.expectEqual(E.f499, Indexer.keyForIndex(0));
lib/std/fmt.zig+1-1
......@@ -279,7 +279,7 @@ pub fn Alt(
279279/// Helper for calling alternate format methods besides one named "format".
280280pub fn alt(
281281 context: anytype,
282 comptime func_name: @TypeOf(.enum_literal),
282 comptime func_name: @EnumLiteral(),
283283) Alt(@TypeOf(context), @field(@TypeOf(context), @tagName(func_name))) {
284284 return .{ .data = context };
285285}
lib/std/fmt/float.zig+2-2
......@@ -61,7 +61,7 @@ pub fn render(buf: []u8, value: anytype, options: Options) Error![]const u8 {
6161
6262 const T = @TypeOf(v);
6363 comptime std.debug.assert(@typeInfo(T) == .float);
64 const I = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(T) } });
64 const I = @Int(.unsigned, @bitSizeOf(T));
6565
6666 const DT = if (@bitSizeOf(T) <= 64) u64 else u128;
6767 const tables = switch (DT) {
......@@ -1516,7 +1516,7 @@ const FLOAT128_POW5_INV_ERRORS: [154]u64 = .{
15161516const builtin = @import("builtin");
15171517
15181518fn check(comptime T: type, value: T, comptime expected: []const u8) !void {
1519 const I = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(T) } });
1519 const I = @Int(.unsigned, @bitSizeOf(T));
15201520
15211521 var buf: [6000]u8 = undefined;
15221522 const value_bits: I = @bitCast(value);
lib/std/hash.zig+1-1
......@@ -42,7 +42,7 @@ pub fn int(input: anytype) @TypeOf(input) {
4242 const info = @typeInfo(@TypeOf(input)).int;
4343 const bits = info.bits;
4444 // Convert input to unsigned integer (easier to deal with)
45 const Uint = @Type(.{ .int = .{ .bits = bits, .signedness = .unsigned } });
45 const Uint = @Int(.unsigned, bits);
4646 const u_input: Uint = @bitCast(input);
4747 if (bits > 256) @compileError("bit widths > 256 are unsupported, use std.hash.autoHash functionality.");
4848 // For bit widths that don't have a dedicated function, use a heuristic
lib/std/hash/auto_hash.zig+1-4
......@@ -91,10 +91,7 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void {
9191 // Help the optimizer see that hashing an int is easy by inlining!
9292 // TODO Check if the situation is better after #561 is resolved.
9393 .int => |int| switch (int.signedness) {
94 .signed => hash(hasher, @as(@Type(.{ .int = .{
95 .bits = int.bits,
96 .signedness = .unsigned,
97 } }), @bitCast(key)), strat),
94 .signed => hash(hasher, @as(@Int(.unsigned, int.bits), @bitCast(key)), strat),
9895 .unsigned => {
9996 if (std.meta.hasUniqueRepresentation(Key)) {
10097 @call(.always_inline, Hasher.update, .{ hasher, std.mem.asBytes(&key) });
lib/std/log.zig+5-5
......@@ -57,13 +57,13 @@ pub const default_level: Level = switch (builtin.mode) {
5757};
5858
5959pub const ScopeLevel = struct {
60 scope: @Type(.enum_literal),
60 scope: @EnumLiteral(),
6161 level: Level,
6262};
6363
6464fn log(
6565 comptime level: Level,
66 comptime scope: @Type(.enum_literal),
66 comptime scope: @EnumLiteral(),
6767 comptime format: []const u8,
6868 args: anytype,
6969) void {
......@@ -73,7 +73,7 @@ fn log(
7373}
7474
7575/// Determine if a specific log message level and scope combination are enabled for logging.
76pub fn logEnabled(comptime level: Level, comptime scope: @Type(.enum_literal)) bool {
76pub fn logEnabled(comptime level: Level, comptime scope: @EnumLiteral()) bool {
7777 inline for (std.options.log_scope_levels) |scope_level| {
7878 if (scope_level.scope == scope) return @intFromEnum(level) <= @intFromEnum(scope_level.level);
7979 }
......@@ -87,7 +87,7 @@ pub fn logEnabled(comptime level: Level, comptime scope: @Type(.enum_literal)) b
8787/// function returns.
8888pub fn defaultLog(
8989 comptime level: Level,
90 comptime scope: @Type(.enum_literal),
90 comptime scope: @EnumLiteral(),
9191 comptime format: []const u8,
9292 args: anytype,
9393) void {
......@@ -115,7 +115,7 @@ pub fn defaultLog(
115115
116116/// Returns a scoped logging namespace that logs all messages using the scope
117117/// provided here.
118pub fn scoped(comptime scope: @Type(.enum_literal)) type {
118pub fn scoped(comptime scope: @EnumLiteral()) type {
119119 return struct {
120120 /// Log an error message. This log level is intended to be used
121121 /// when something has gone wrong. This might be recoverable or might
lib/std/math.zig+13-13
......@@ -450,12 +450,7 @@ pub fn wrap(x: anytype, r: anytype) @TypeOf(x) {
450450 // in the rare usecase of r not being comptime_int or float,
451451 // take the penalty of having an intermediary type conversion,
452452 // otherwise the alternative is to unwind iteratively to avoid overflow
453 const R = comptime do: {
454 var info = info_r;
455 info.int.bits += 1;
456 info.int.signedness = .signed;
457 break :do @Type(info);
458 };
453 const R = @Int(.signed, info_r.int.bits + 1);
459454 const radius: if (info_r.int.signedness == .signed) @TypeOf(r) else R = r;
460455 return @intCast(@mod(x - radius, 2 * @as(R, r)) - r); // provably impossible to overflow
461456 },
......@@ -799,14 +794,14 @@ pub fn Log2IntCeil(comptime T: type) type {
799794pub fn IntFittingRange(comptime from: comptime_int, comptime to: comptime_int) type {
800795 assert(from <= to);
801796 const signedness: std.builtin.Signedness = if (from < 0) .signed else .unsigned;
802 return @Type(.{ .int = .{
803 .signedness = signedness,
804 .bits = @as(u16, @intFromBool(signedness == .signed)) +
797 return @Int(
798 signedness,
799 @as(u16, @intFromBool(signedness == .signed)) +
805800 switch (if (from < 0) @max(@abs(from) - 1, to) else to) {
806801 0 => 0,
807802 else => |pos_max| 1 + log2(pos_max),
808803 },
809 } });
804 );
810805}
811806
812807test IntFittingRange {
......@@ -1107,9 +1102,14 @@ test cast {
11071102pub const AlignCastError = error{UnalignedMemory};
11081103
11091104fn AlignCastResult(comptime alignment: Alignment, comptime Ptr: type) type {
1110 var ptr_info = @typeInfo(Ptr);
1111 ptr_info.pointer.alignment = alignment.toByteUnits();
1112 return @Type(ptr_info);
1105 const orig = @typeInfo(Ptr).pointer;
1106 return @Pointer(orig.size, .{
1107 .@"const" = orig.is_const,
1108 .@"volatile" = orig.is_volatile,
1109 .@"allowzero" = orig.is_allowzero,
1110 .@"align" = alignment.toByteUnits(),
1111 .@"addrspace" = orig.address_space,
1112 }, orig.child, orig.sentinel());
11131113}
11141114
11151115/// Align cast a pointer but return an error if it's the wrong alignment
lib/std/math/big/int_test.zig+2-2
......@@ -2787,11 +2787,11 @@ test "bitNotWrap more than two limbs" {
27872787 const bits = @bitSizeOf(Limb) * 4 + 2;
27882788
27892789 try res.bitNotWrap(&a, .unsigned, bits);
2790 const Unsigned = @Type(.{ .int = .{ .signedness = .unsigned, .bits = bits } });
2790 const Unsigned = @Int(.unsigned, bits);
27912791 try testing.expectEqual((try res.toInt(Unsigned)), ~@as(Unsigned, maxInt(Limb)));
27922792
27932793 try res.bitNotWrap(&a, .signed, bits);
2794 const Signed = @Type(.{ .int = .{ .signedness = .signed, .bits = bits } });
2794 const Signed = @Int(.signed, bits);
27952795 try testing.expectEqual((try res.toInt(Signed)), ~@as(Signed, maxInt(Limb)));
27962796}
27972797
lib/std/math/float.zig+8-26
......@@ -14,22 +14,10 @@ pub fn FloatRepr(comptime Float: type) type {
1414 exponent: BiasedExponent,
1515 sign: std.math.Sign,
1616
17 pub const StoredMantissa = @Type(.{ .int = .{
18 .signedness = .unsigned,
19 .bits = floatMantissaBits(Float),
20 } });
21 pub const Mantissa = @Type(.{ .int = .{
22 .signedness = .unsigned,
23 .bits = 1 + fractional_bits,
24 } });
25 pub const Exponent = @Type(.{ .int = .{
26 .signedness = .signed,
27 .bits = exponent_bits,
28 } });
29 pub const BiasedExponent = enum(@Type(.{ .int = .{
30 .signedness = .unsigned,
31 .bits = exponent_bits,
32 } })) {
17 pub const StoredMantissa = @Int(.unsigned, floatMantissaBits(Float));
18 pub const Mantissa = @Int(.unsigned, 1 + fractional_bits);
19 pub const Exponent = @Int(.signed, exponent_bits);
20 pub const BiasedExponent = enum(@Int(.unsigned, exponent_bits)) {
3321 denormal = 0,
3422 min_normal = 1,
3523 zero = (1 << (exponent_bits - 1)) - 1,
......@@ -56,14 +44,8 @@ pub fn FloatRepr(comptime Float: type) type {
5644 fraction: Fraction,
5745 exponent: Normalized.Exponent,
5846
59 pub const Fraction = @Type(.{ .int = .{
60 .signedness = .unsigned,
61 .bits = fractional_bits,
62 } });
63 pub const Exponent = @Type(.{ .int = .{
64 .signedness = .signed,
65 .bits = 1 + exponent_bits,
66 } });
47 pub const Fraction = @Int(.unsigned, fractional_bits);
48 pub const Exponent = @Int(.signed, 1 + exponent_bits);
6749
6850 /// This currently truncates denormal values, which needs to be fixed before this can be used to
6951 /// produce a rounded value.
......@@ -122,7 +104,7 @@ inline fn mantissaOne(comptime T: type) comptime_int {
122104
123105/// Creates floating point type T from an unbiased exponent and raw mantissa.
124106inline fn reconstructFloat(comptime T: type, comptime exponent: comptime_int, comptime mantissa: comptime_int) T {
125 const TBits = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @bitSizeOf(T) } });
107 const TBits = @Int(.unsigned, @bitSizeOf(T));
126108 const biased_exponent = @as(TBits, exponent + floatExponentMax(T));
127109 return @as(T, @bitCast((biased_exponent << floatMantissaBits(T)) | @as(TBits, mantissa)));
128110}
......@@ -209,7 +191,7 @@ pub inline fn floatEps(comptime T: type) T {
209191pub inline fn floatEpsAt(comptime T: type, x: T) T {
210192 switch (@typeInfo(T)) {
211193 .float => |F| {
212 const U: type = @Type(.{ .int = .{ .signedness = .unsigned, .bits = F.bits } });
194 const U: type = @Int(.unsigned, F.bits);
213195 const u: U = @bitCast(x);
214196 const y: T = @bitCast(u ^ 1);
215197 return @abs(x - y);
lib/std/math/log2.zig+1-4
......@@ -33,10 +33,7 @@ pub fn log2(x: anytype) @TypeOf(x) {
3333 return result;
3434 },
3535 .int => |int_info| math.log2_int(switch (int_info.signedness) {
36 .signed => @Type(.{ .int = .{
37 .signedness = .unsigned,
38 .bits = int_info.bits -| 1,
39 } }),
36 .signed => @Int(.unsigned, int_info.bits -| 1),
4037 .unsigned => T,
4138 }, @intCast(x)),
4239 else => @compileError("log2 not implemented for " ++ @typeName(T)),
lib/std/math/log_int.zig+1-1
......@@ -65,7 +65,7 @@ test "log_int" {
6565 // Test all unsigned integers with 2, 3, ..., 64 bits.
6666 // We cannot test 0 or 1 bits since base must be > 1.
6767 inline for (2..64 + 1) |bits| {
68 const T = @Type(.{ .int = .{ .signedness = .unsigned, .bits = @intCast(bits) } });
68 const T = @Int(.unsigned, @intCast(bits));
6969
7070 // for base = 2, 3, ..., min(maxInt(T),1024)
7171 var base: T = 1;
lib/std/math/signbit.zig+1-4
......@@ -6,10 +6,7 @@ const expect = std.testing.expect;
66pub fn signbit(x: anytype) bool {
77 return switch (@typeInfo(@TypeOf(x))) {
88 .int, .comptime_int => x,
9 .float => |float| @as(@Type(.{ .int = .{
10 .signedness = .signed,
11 .bits = float.bits,
12 } }), @bitCast(x)),
9 .float => |float| @as(@Int(.signed, float.bits), @bitCast(x)),
1310 .comptime_float => @as(i128, @bitCast(@as(f128, x))), // any float type will do
1411 else => @compileError("std.math.signbit does not support " ++ @typeName(@TypeOf(x))),
1512 } < 0;
lib/std/math/sqrt.zig+1-1
......@@ -80,7 +80,7 @@ test sqrt_int {
8080/// Returns the return type `sqrt` will return given an operand of type `T`.
8181pub fn Sqrt(comptime T: type) type {
8282 return switch (@typeInfo(T)) {
83 .int => |int| @Type(.{ .int = .{ .signedness = .unsigned, .bits = (int.bits + 1) / 2 } }),
83 .int => |int| @Int(.unsigned, (int.bits + 1) / 2),
8484 else => T,
8585 };
8686}
lib/std/mem.zig+57-106
......@@ -846,17 +846,18 @@ fn Span(comptime T: type) type {
846846 return ?Span(optional_info.child);
847847 },
848848 .pointer => |ptr_info| {
849 var new_ptr_info = ptr_info;
850 switch (ptr_info.size) {
851 .c => {
852 new_ptr_info.sentinel_ptr = &@as(ptr_info.child, 0);
853 new_ptr_info.is_allowzero = false;
854 },
855 .many => if (ptr_info.sentinel() == null) @compileError("invalid type given to std.mem.span: " ++ @typeName(T)),
849 const new_sentinel: ?ptr_info.child = switch (ptr_info.size) {
856850 .one, .slice => @compileError("invalid type given to std.mem.span: " ++ @typeName(T)),
857 }
858 new_ptr_info.size = .slice;
859 return @Type(.{ .pointer = new_ptr_info });
851 .many => ptr_info.sentinel() orelse @compileError("invalid type given to std.mem.span: " ++ @typeName(T)),
852 .c => 0,
853 };
854 return @Pointer(.slice, .{
855 .@"const" = ptr_info.is_const,
856 .@"volatile" = ptr_info.is_volatile,
857 .@"allowzero" = ptr_info.is_allowzero and ptr_info.size != .c,
858 .@"align" = ptr_info.alignment,
859 .@"addrspace" = ptr_info.address_space,
860 }, ptr_info.child, new_sentinel);
860861 },
861862 else => {},
862863 }
......@@ -910,45 +911,18 @@ fn SliceTo(comptime T: type, comptime end: std.meta.Elem(T)) type {
910911 return ?SliceTo(optional_info.child, end);
911912 },
912913 .pointer => |ptr_info| {
913 var new_ptr_info = ptr_info;
914 new_ptr_info.size = .slice;
915 switch (ptr_info.size) {
916 .one => switch (@typeInfo(ptr_info.child)) {
917 .array => |array_info| {
918 new_ptr_info.child = array_info.child;
919 // The return type must only be sentinel terminated if we are guaranteed
920 // to find the value searched for, which is only the case if it matches
921 // the sentinel of the type passed.
922 if (array_info.sentinel()) |s| {
923 if (end == s) {
924 new_ptr_info.sentinel_ptr = &end;
925 } else {
926 new_ptr_info.sentinel_ptr = null;
927 }
928 }
929 },
930 else => {},
931 },
932 .many, .slice => {
933 // The return type must only be sentinel terminated if we are guaranteed
934 // to find the value searched for, which is only the case if it matches
935 // the sentinel of the type passed.
936 if (ptr_info.sentinel()) |s| {
937 if (end == s) {
938 new_ptr_info.sentinel_ptr = &end;
939 } else {
940 new_ptr_info.sentinel_ptr = null;
941 }
942 }
943 },
944 .c => {
945 new_ptr_info.sentinel_ptr = &end;
946 // C pointers are always allowzero, but we don't want the return type to be.
947 assert(new_ptr_info.is_allowzero);
948 new_ptr_info.is_allowzero = false;
949 },
950 }
951 return @Type(.{ .pointer = new_ptr_info });
914 const Elem = std.meta.Elem(T);
915 const have_sentinel: bool = switch (ptr_info.size) {
916 .one, .slice, .many => if (std.meta.sentinel(T)) |s| s == end else false,
917 .c => false,
918 };
919 return @Pointer(.slice, .{
920 .@"const" = ptr_info.is_const,
921 .@"volatile" = ptr_info.is_volatile,
922 .@"allowzero" = ptr_info.is_allowzero and ptr_info.size != .c,
923 .@"align" = ptr_info.alignment,
924 .@"addrspace" = ptr_info.address_space,
925 }, Elem, if (have_sentinel) end else null);
952926 },
953927 else => {},
954928 }
......@@ -3951,38 +3925,25 @@ test reverse {
39513925 }
39523926}
39533927fn ReverseIterator(comptime T: type) type {
3954 const Pointer = blk: {
3955 switch (@typeInfo(T)) {
3956 .pointer => |ptr_info| switch (ptr_info.size) {
3957 .one => switch (@typeInfo(ptr_info.child)) {
3958 .array => |array_info| {
3959 var new_ptr_info = ptr_info;
3960 new_ptr_info.size = .many;
3961 new_ptr_info.child = array_info.child;
3962 new_ptr_info.sentinel_ptr = array_info.sentinel_ptr;
3963 break :blk @Type(.{ .pointer = new_ptr_info });
3964 },
3965 else => {},
3966 },
3967 .slice => {
3968 var new_ptr_info = ptr_info;
3969 new_ptr_info.size = .many;
3970 break :blk @Type(.{ .pointer = new_ptr_info });
3971 },
3972 else => {},
3973 },
3974 else => {},
3975 }
3976 @compileError("expected slice or pointer to array, found '" ++ @typeName(T) ++ "'");
3928 const ptr = switch (@typeInfo(T)) {
3929 .pointer => |ptr| ptr,
3930 else => @compileError("expected slice or pointer to array, found '" ++ @typeName(T) ++ "'"),
39773931 };
3978 const Element = std.meta.Elem(Pointer);
3979 const ElementPointer = @Type(.{ .pointer = ptr: {
3980 var ptr = @typeInfo(Pointer).pointer;
3981 ptr.size = .one;
3982 ptr.child = Element;
3983 ptr.sentinel_ptr = null;
3984 break :ptr ptr;
3985 } });
3932 switch (ptr.size) {
3933 .slice => {},
3934 .one => if (@typeInfo(ptr.child) != .array) @compileError("expected slice or pointer to array, found '" ++ @typeName(T) ++ "'"),
3935 .many, .c => @compileError("expected slice or pointer to array, found '" ++ @typeName(T) ++ "'"),
3936 }
3937 const Element = std.meta.Elem(T);
3938 const attrs: std.builtin.Type.Pointer.Attributes = .{
3939 .@"const" = ptr.is_const,
3940 .@"volatile" = ptr.is_volatile,
3941 .@"allowzero" = ptr.is_allowzero,
3942 .@"align" = ptr.alignment,
3943 .@"addrspace" = ptr.address_space,
3944 };
3945 const Pointer = @Pointer(.many, attrs, Element, std.meta.sentinel(T));
3946 const ElementPointer = @Pointer(.one, attrs, Element, null);
39863947 return struct {
39873948 ptr: Pointer,
39883949 index: usize,
......@@ -4342,19 +4303,14 @@ fn CopyPtrAttrs(
43424303 comptime size: std.builtin.Type.Pointer.Size,
43434304 comptime child: type,
43444305) type {
4345 const info = @typeInfo(source).pointer;
4346 return @Type(.{
4347 .pointer = .{
4348 .size = size,
4349 .is_const = info.is_const,
4350 .is_volatile = info.is_volatile,
4351 .is_allowzero = info.is_allowzero,
4352 .alignment = info.alignment,
4353 .address_space = info.address_space,
4354 .child = child,
4355 .sentinel_ptr = null,
4356 },
4357 });
4306 const ptr = @typeInfo(source).pointer;
4307 return @Pointer(size, .{
4308 .@"const" = ptr.is_const,
4309 .@"volatile" = ptr.is_volatile,
4310 .@"allowzero" = ptr.is_allowzero,
4311 .@"align" = ptr.alignment,
4312 .@"addrspace" = ptr.address_space,
4313 }, child, null);
43584314}
43594315
43604316fn AsBytesReturnType(comptime P: type) type {
......@@ -4936,19 +4892,14 @@ test "freeing empty string with null-terminated sentinel" {
49364892/// Returns a slice with the given new alignment,
49374893/// all other pointer attributes copied from `AttributeSource`.
49384894fn AlignedSlice(comptime AttributeSource: type, comptime new_alignment: usize) type {
4939 const info = @typeInfo(AttributeSource).pointer;
4940 return @Type(.{
4941 .pointer = .{
4942 .size = .slice,
4943 .is_const = info.is_const,
4944 .is_volatile = info.is_volatile,
4945 .is_allowzero = info.is_allowzero,
4946 .alignment = new_alignment,
4947 .address_space = info.address_space,
4948 .child = info.child,
4949 .sentinel_ptr = null,
4950 },
4951 });
4895 const ptr = @typeInfo(AttributeSource).pointer;
4896 return @Pointer(.slice, .{
4897 .@"const" = ptr.is_const,
4898 .@"volatile" = ptr.is_volatile,
4899 .@"allowzero" = ptr.is_allowzero,
4900 .@"align" = new_alignment,
4901 .@"addrspace" = ptr.address_space,
4902 }, ptr.child, null);
49524903}
49534904
49544905/// Returns the largest slice in the given bytes that conforms to the new alignment,
lib/std/meta.zig+52-136
......@@ -171,58 +171,34 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type {
171171 switch (@typeInfo(T)) {
172172 .pointer => |info| switch (info.size) {
173173 .one => switch (@typeInfo(info.child)) {
174 .array => |array_info| return @Type(.{
175 .pointer = .{
176 .size = info.size,
177 .is_const = info.is_const,
178 .is_volatile = info.is_volatile,
179 .alignment = info.alignment,
180 .address_space = info.address_space,
181 .child = @Type(.{
182 .array = .{
183 .len = array_info.len,
184 .child = array_info.child,
185 .sentinel_ptr = @as(?*const anyopaque, @ptrCast(&sentinel_val)),
186 },
187 }),
188 .is_allowzero = info.is_allowzero,
189 .sentinel_ptr = info.sentinel_ptr,
190 },
191 }),
174 .array => |array_info| return @Pointer(.one, .{
175 .@"const" = info.is_const,
176 .@"volatile" = info.is_volatile,
177 .@"allowzero" = info.is_allowzero,
178 .@"align" = info.alignment,
179 .@"addrspace" = info.address_space,
180 }, [array_info.len:sentinel_val]array_info.child, null),
192181 else => {},
193182 },
194 .many, .slice => return @Type(.{
195 .pointer = .{
196 .size = info.size,
197 .is_const = info.is_const,
198 .is_volatile = info.is_volatile,
199 .alignment = info.alignment,
200 .address_space = info.address_space,
201 .child = info.child,
202 .is_allowzero = info.is_allowzero,
203 .sentinel_ptr = @as(?*const anyopaque, @ptrCast(&sentinel_val)),
204 },
205 }),
183 .many, .slice => |size| return @Pointer(size, .{
184 .@"const" = info.is_const,
185 .@"volatile" = info.is_volatile,
186 .@"allowzero" = info.is_allowzero,
187 .@"align" = info.alignment,
188 .@"addrspace" = info.address_space,
189 }, info.child, sentinel_val),
206190 else => {},
207191 },
208192 .optional => |info| switch (@typeInfo(info.child)) {
209193 .pointer => |ptr_info| switch (ptr_info.size) {
210 .many => return @Type(.{
211 .optional = .{
212 .child = @Type(.{
213 .pointer = .{
214 .size = ptr_info.size,
215 .is_const = ptr_info.is_const,
216 .is_volatile = ptr_info.is_volatile,
217 .alignment = ptr_info.alignment,
218 .address_space = ptr_info.address_space,
219 .child = ptr_info.child,
220 .is_allowzero = ptr_info.is_allowzero,
221 .sentinel_ptr = @as(?*const anyopaque, @ptrCast(&sentinel_val)),
222 },
223 }),
224 },
225 }),
194 .many => return ?@Pointer(.many, .{
195 .@"const" = ptr_info.is_const,
196 .@"volatile" = ptr_info.is_volatile,
197 .@"allowzero" = ptr_info.is_allowzero,
198 .@"align" = ptr_info.alignment,
199 .@"addrspace" = ptr_info.address_space,
200 .child = ptr_info.child,
201 }, ptr_info.child, sentinel_val),
226202 else => {},
227203 },
228204 else => {},
......@@ -487,46 +463,22 @@ test tags {
487463
488464/// Returns an enum with a variant named after each field of `T`.
489465pub fn FieldEnum(comptime T: type) type {
490 const field_infos = fields(T);
491
492 if (field_infos.len == 0) {
493 return @Type(.{
494 .@"enum" = .{
495 .tag_type = u0,
496 .fields = &.{},
497 .decls = &.{},
498 .is_exhaustive = true,
499 },
500 });
501 }
466 const field_names = fieldNames(T);
502467
503 if (@typeInfo(T) == .@"union") {
504 if (@typeInfo(T).@"union".tag_type) |tag_type| {
505 for (std.enums.values(tag_type), 0..) |v, i| {
468 switch (@typeInfo(T)) {
469 .@"union" => |@"union"| if (@"union".tag_type) |EnumTag| {
470 for (std.enums.values(EnumTag), 0..) |v, i| {
506471 if (@intFromEnum(v) != i) break; // enum values not consecutive
507 if (!std.mem.eql(u8, @tagName(v), field_infos[i].name)) break; // fields out of order
472 if (!std.mem.eql(u8, @tagName(v), field_names[i])) break; // fields out of order
508473 } else {
509 return tag_type;
474 return EnumTag;
510475 }
511 }
476 },
477 else => {},
512478 }
513479
514 var enumFields: [field_infos.len]std.builtin.Type.EnumField = undefined;
515 var decls = [_]std.builtin.Type.Declaration{};
516 inline for (field_infos, 0..) |field, i| {
517 enumFields[i] = .{
518 .name = field.name,
519 .value = i,
520 };
521 }
522 return @Type(.{
523 .@"enum" = .{
524 .tag_type = std.math.IntFittingRange(0, field_infos.len - 1),
525 .fields = &enumFields,
526 .decls = &decls,
527 .is_exhaustive = true,
528 },
529 });
480 const IntTag = std.math.IntFittingRange(0, field_names.len -| 1);
481 return @Enum(IntTag, .exhaustive, field_names, &std.simd.iota(IntTag, field_names.len));
530482}
531483
532484fn expectEqualEnum(expected: anytype, actual: @TypeOf(expected)) !void {
......@@ -583,20 +535,11 @@ test FieldEnum {
583535}
584536
585537pub fn DeclEnum(comptime T: type) type {
586 const fieldInfos = std.meta.declarations(T);
587 var enumDecls: [fieldInfos.len]std.builtin.Type.EnumField = undefined;
588 var decls = [_]std.builtin.Type.Declaration{};
589 inline for (fieldInfos, 0..) |field, i| {
590 enumDecls[i] = .{ .name = field.name, .value = i };
591 }
592 return @Type(.{
593 .@"enum" = .{
594 .tag_type = std.math.IntFittingRange(0, if (fieldInfos.len == 0) 0 else fieldInfos.len - 1),
595 .fields = &enumDecls,
596 .decls = &decls,
597 .is_exhaustive = true,
598 },
599 });
538 const decls = declarations(T);
539 var names: [decls.len][]const u8 = undefined;
540 for (&names, decls) |*name, decl| name.* = decl.name;
541 const IntTag = std.math.IntFittingRange(0, decls.len -| 1);
542 return @Enum(IntTag, .exhaustive, &names, &std.simd.iota(IntTag, decls.len));
600543}
601544
602545test DeclEnum {
......@@ -868,25 +811,26 @@ pub fn declList(comptime Namespace: type, comptime Decl: type) []const *const De
868811 }
869812}
870813
814/// Deprecated: use @Int
871815pub fn Int(comptime signedness: std.builtin.Signedness, comptime bit_count: u16) type {
872 return @Type(.{
873 .int = .{
874 .signedness = signedness,
875 .bits = bit_count,
876 },
877 });
816 return @Int(signedness, bit_count);
878817}
879818
880819pub fn Float(comptime bit_count: u8) type {
881 return @Type(.{
882 .float = .{ .bits = bit_count },
883 });
820 return switch (bit_count) {
821 16 => f16,
822 32 => f32,
823 64 => f64,
824 80 => f80,
825 128 => f128,
826 else => @compileError("invalid float bit count"),
827 };
884828}
885
886829test Float {
887830 try testing.expectEqual(f16, Float(16));
888831 try testing.expectEqual(f32, Float(32));
889832 try testing.expectEqual(f64, Float(64));
833 try testing.expectEqual(f80, Float(80));
890834 try testing.expectEqual(f128, Float(128));
891835}
892836
......@@ -912,42 +856,14 @@ pub fn ArgsTuple(comptime Function: type) type {
912856 argument_field_list[i] = T;
913857 }
914858
915 return CreateUniqueTuple(argument_field_list.len, argument_field_list);
859 return Tuple(&argument_field_list);
916860}
917861
918/// For a given anonymous list of types, returns a new tuple type
919/// with those types as fields.
862/// Deprecated; use `@Tuple` instead.
920863///
921/// Examples:
922/// - `Tuple(&[_]type {})` ⇒ `tuple { }`
923/// - `Tuple(&[_]type {f32})` ⇒ `tuple { f32 }`
924/// - `Tuple(&[_]type {f32,u32})` ⇒ `tuple { f32, u32 }`
864/// To be removed after Zig 0.16.0 releases.
925865pub fn Tuple(comptime types: []const type) type {
926 return CreateUniqueTuple(types.len, types[0..types.len].*);
927}
928
929fn CreateUniqueTuple(comptime N: comptime_int, comptime types: [N]type) type {
930 var tuple_fields: [types.len]std.builtin.Type.StructField = undefined;
931 inline for (types, 0..) |T, i| {
932 @setEvalBranchQuota(10_000);
933 var num_buf: [128]u8 = undefined;
934 tuple_fields[i] = .{
935 .name = std.fmt.bufPrintSentinel(&num_buf, "{d}", .{i}, 0) catch unreachable,
936 .type = T,
937 .default_value_ptr = null,
938 .is_comptime = false,
939 .alignment = @alignOf(T),
940 };
941 }
942
943 return @Type(.{
944 .@"struct" = .{
945 .is_tuple = true,
946 .layout = .auto,
947 .decls = &.{},
948 .fields = &tuple_fields,
949 },
950 });
866 return @Tuple(types);
951867}
952868
953869const TupleTester = struct {
lib/std/meta/trailer_flags.zig+9-17
......@@ -20,24 +20,16 @@ pub fn TrailerFlags(comptime Fields: type) type {
2020
2121 pub const ActiveFields = std.enums.EnumFieldStruct(FieldEnum, bool, false);
2222 pub const FieldValues = blk: {
23 var fields: [bit_count]Type.StructField = undefined;
24 for (@typeInfo(Fields).@"struct".fields, 0..) |struct_field, i| {
25 fields[i] = Type.StructField{
26 .name = struct_field.name,
27 .type = ?struct_field.type,
28 .default_value_ptr = &@as(?struct_field.type, null),
29 .is_comptime = false,
30 .alignment = @alignOf(?struct_field.type),
31 };
23 var field_names: [bit_count][]const u8 = undefined;
24 var field_types: [bit_count]type = undefined;
25 var field_attrs: [bit_count]std.builtin.Type.StructField.Attributes = undefined;
26 for (@typeInfo(Fields).@"struct".fields, &field_names, &field_types, &field_attrs) |field, *new_name, *NewType, *new_attrs| {
27 new_name.* = field.name;
28 NewType.* = ?field.type;
29 const default: ?field.type = null;
30 new_attrs.* = .{ .default_value_ptr = &default };
3231 }
33 break :blk @Type(.{
34 .@"struct" = .{
35 .layout = .auto,
36 .fields = &fields,
37 .decls = &.{},
38 .is_tuple = false,
39 },
40 });
32 break :blk @Struct(.auto, null, &field_names, &field_types, &field_attrs);
4133 };
4234
4335 pub const Self = @This();
lib/std/multi_array_list.zig+26-37
......@@ -32,12 +32,17 @@ pub fn MultiArrayList(comptime T: type) type {
3232 const Elem = switch (@typeInfo(T)) {
3333 .@"struct" => T,
3434 .@"union" => |u| struct {
35 pub const Bare = @Type(.{ .@"union" = .{
36 .layout = u.layout,
37 .tag_type = null,
38 .fields = u.fields,
39 .decls = &.{},
40 } });
35 pub const Bare = Bare: {
36 var field_names: [u.fields.len][]const u8 = undefined;
37 var field_types: [u.fields.len]type = undefined;
38 var field_attrs: [u.fields.len]std.builtin.Type.UnionField.Attributes = undefined;
39 for (u.fields, &field_names, &field_types, &field_attrs) |field, *name, *Type, *attrs| {
40 name.* = field.name;
41 Type.* = field.type;
42 attrs.* = .{ .@"align" = field.alignment };
43 }
44 break :Bare @Union(u.layout, null, &field_names, &field_types, &field_attrs);
45 };
4146 pub const Tag =
4247 u.tag_type orelse @compileError("MultiArrayList does not support untagged unions");
4348 tags: Tag,
......@@ -609,20 +614,18 @@ pub fn MultiArrayList(comptime T: type) type {
609614 }
610615
611616 const Entry = entry: {
612 var entry_fields: [fields.len]std.builtin.Type.StructField = undefined;
613 for (&entry_fields, sizes.fields) |*entry_field, i| entry_field.* = .{
614 .name = fields[i].name ++ "_ptr",
615 .type = *fields[i].type,
616 .default_value_ptr = null,
617 .is_comptime = fields[i].is_comptime,
618 .alignment = fields[i].alignment,
619 };
620 break :entry @Type(.{ .@"struct" = .{
621 .layout = .@"extern",
622 .fields = &entry_fields,
623 .decls = &.{},
624 .is_tuple = false,
625 } });
617 var field_names: [fields.len][]const u8 = undefined;
618 var field_types: [fields.len]type = undefined;
619 var field_attrs: [fields.len]std.builtin.Type.StructField.Attributes = undefined;
620 for (sizes.fields, &field_names, &field_types, &field_attrs) |i, *name, *Type, *attrs| {
621 name.* = fields[i].name ++ "_ptr";
622 Type.* = *fields[i].type;
623 attrs.* = .{
624 .@"comptime" = fields[i].is_comptime,
625 .@"align" = fields[i].alignment,
626 };
627 }
628 break :entry @Struct(.@"extern", null, &field_names, &field_types, &field_attrs);
626629 };
627630 /// This function is used in the debugger pretty formatters in tools/ to fetch the
628631 /// child field order and entry type to facilitate fancy debug printing for this type.
......@@ -1023,23 +1026,9 @@ test "struct with many fields" {
10231026 const ManyFields = struct {
10241027 fn Type(count: comptime_int) type {
10251028 @setEvalBranchQuota(50000);
1026 var fields: [count]std.builtin.Type.StructField = undefined;
1027 for (0..count) |i| {
1028 fields[i] = .{
1029 .name = std.fmt.comptimePrint("a{}", .{i}),
1030 .type = u32,
1031 .default_value_ptr = null,
1032 .is_comptime = false,
1033 .alignment = @alignOf(u32),
1034 };
1035 }
1036 const info: std.builtin.Type = .{ .@"struct" = .{
1037 .layout = .auto,
1038 .fields = &fields,
1039 .decls = &.{},
1040 .is_tuple = false,
1041 } };
1042 return @Type(info);
1029 var field_names: [count][]const u8 = undefined;
1030 for (&field_names, 0..) |*n, i| n.* = std.fmt.comptimePrint("a{d}", .{i});
1031 return @Struct(.@"extern", null, &field_names, &@splat(u32), &@splat(.{}));
10431032 }
10441033
10451034 fn doTest(ally: std.mem.Allocator, count: comptime_int) !void {
lib/std/std.zig+1-1
......@@ -124,7 +124,7 @@ pub const Options = struct {
124124
125125 logFn: fn (
126126 comptime message_level: log.Level,
127 comptime scope: @TypeOf(.enum_literal),
127 comptime scope: @EnumLiteral(),
128128 comptime format: []const u8,
129129 args: anytype,
130130 ) void = log.defaultLog,
lib/std/zig.zig+40-24
......@@ -773,7 +773,6 @@ pub const EnvVar = enum {
773773pub const SimpleComptimeReason = enum(u32) {
774774 // Evaluating at comptime because a builtin operand must be comptime-known.
775775 // These messages all mention a specific builtin.
776 operand_Type,
777776 operand_setEvalBranchQuota,
778777 operand_setFloatMode,
779778 operand_branchHint,
......@@ -809,25 +808,34 @@ pub const SimpleComptimeReason = enum(u32) {
809808 // Evaluating at comptime because types must be comptime-known.
810809 // Reasons other than `.type` are just more specific messages.
811810 type,
811 int_signedness,
812 int_bit_width,
812813 array_sentinel,
814 array_length,
815 pointer_size,
816 pointer_attrs,
813817 pointer_sentinel,
814818 slice_sentinel,
815 array_length,
816819 vector_length,
817 error_set_contents,
818 struct_fields,
819 enum_fields,
820 union_fields,
821 function_ret_ty,
822 function_parameters,
820 fn_ret_ty,
821 fn_param_types,
822 fn_param_attrs,
823 fn_attrs,
824 struct_layout,
825 struct_field_names,
826 struct_field_types,
827 struct_field_attrs,
828 union_layout,
829 union_field_names,
830 union_field_types,
831 union_field_attrs,
832 tuple_field_types,
833 enum_field_names,
834 enum_field_values,
823835
824836 // Evaluating at comptime because decl/field name must be comptime-known.
825837 decl_name,
826838 field_name,
827 struct_field_name,
828 enum_field_name,
829 union_field_name,
830 tuple_field_name,
831839 tuple_field_index,
832840
833841 // Evaluating at comptime because it is an attribute of a global declaration.
......@@ -856,7 +864,6 @@ pub const SimpleComptimeReason = enum(u32) {
856864 pub fn message(r: SimpleComptimeReason) []const u8 {
857865 return switch (r) {
858866 // zig fmt: off
859 .operand_Type => "operand to '@Type' must be comptime-known",
860867 .operand_setEvalBranchQuota => "operand to '@setEvalBranchQuota' must be comptime-known",
861868 .operand_setFloatMode => "operand to '@setFloatMode' must be comptime-known",
862869 .operand_branchHint => "operand to '@branchHint' must be comptime-known",
......@@ -888,24 +895,33 @@ pub const SimpleComptimeReason = enum(u32) {
888895 .clobber => "clobber must be comptime-known",
889896
890897 .type => "types must be comptime-known",
898 .int_signedness => "integer signedness must be comptime-known",
899 .int_bit_width => "integer bit width must be comptime-known",
891900 .array_sentinel => "array sentinel value must be comptime-known",
901 .array_length => "array length must be comptime-known",
902 .pointer_size => "pointer size must be comptime-known",
903 .pointer_attrs => "pointer attributes must be comptime-known",
892904 .pointer_sentinel => "pointer sentinel value must be comptime-known",
893905 .slice_sentinel => "slice sentinel value must be comptime-known",
894 .array_length => "array length must be comptime-known",
895906 .vector_length => "vector length must be comptime-known",
896 .error_set_contents => "error set contents must be comptime-known",
897 .struct_fields => "struct fields must be comptime-known",
898 .enum_fields => "enum fields must be comptime-known",
899 .union_fields => "union fields must be comptime-known",
900 .function_ret_ty => "function return type must be comptime-known",
901 .function_parameters => "function parameters must be comptime-known",
907 .fn_ret_ty => "function return type must be comptime-known",
908 .fn_param_types => "function parameter types must be comptime-known",
909 .fn_param_attrs => "function parameter attributes must be comptime-known",
910 .fn_attrs => "function attributes must be comptime-known",
911 .struct_layout => "struct layout must be comptime-known",
912 .struct_field_names => "struct field names must be comptime-known",
913 .struct_field_types => "struct field types must be comptime-known",
914 .struct_field_attrs => "struct field attributes must be comptime-known",
915 .union_layout => "union layout must be comptime-known",
916 .union_field_names => "union field names must be comptime-known",
917 .union_field_types => "union field types must be comptime-known",
918 .union_field_attrs => "union field attributes must be comptime-known",
919 .tuple_field_types => "tuple field types must be comptime-known",
920 .enum_field_names => "enum field names must be comptime-known",
921 .enum_field_values => "enum field values must be comptime-known",
902922
903923 .decl_name => "declaration name must be comptime-known",
904924 .field_name => "field name must be comptime-known",
905 .struct_field_name => "struct field name must be comptime-known",
906 .enum_field_name => "enum field name must be comptime-known",
907 .union_field_name => "union field name must be comptime-known",
908 .tuple_field_name => "tuple field name must be comptime-known",
909925 .tuple_field_index => "tuple field index must be comptime-known",
910926
911927 .container_var_init => "initializer of container-level variable must be comptime-known",
lib/std/zig/AstGen.zig+150-46
......@@ -833,7 +833,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
833833 => {
834834 var buf: [2]Ast.Node.Index = undefined;
835835 const params = tree.builtinCallParams(&buf, node).?;
836 return builtinCall(gz, scope, ri, node, params, false);
836 return builtinCall(gz, scope, ri, node, params, false, .anon);
837837 },
838838
839839 .call_one,
......@@ -1194,14 +1194,20 @@ fn nameStratExpr(
11941194 },
11951195 .builtin_call_two,
11961196 .builtin_call_two_comma,
1197 .builtin_call,
1198 .builtin_call_comma,
11971199 => {
11981200 const builtin_token = tree.nodeMainToken(node);
11991201 const builtin_name = tree.tokenSlice(builtin_token);
1200 if (!std.mem.eql(u8, builtin_name, "@Type")) return null;
1201 var buf: [2]Ast.Node.Index = undefined;
1202 const params = tree.builtinCallParams(&buf, node).?;
1203 if (params.len != 1) return null; // let `builtinCall` error
1204 return try builtinReify(gz, scope, ri, node, params[0], name_strat);
1202 const info = BuiltinFn.list.get(builtin_name) orelse return null;
1203 switch (info.tag) {
1204 .Enum, .Struct, .Union => {
1205 var buf: [2]Ast.Node.Index = undefined;
1206 const params = tree.builtinCallParams(&buf, node).?;
1207 return try builtinCall(gz, scope, ri, node, params, false, name_strat);
1208 },
1209 else => return null,
1210 }
12051211 },
12061212 else => return null,
12071213 }
......@@ -1406,7 +1412,7 @@ fn fnProtoExprInner(
14061412 .none;
14071413
14081414 const ret_ty_node = fn_proto.ast.return_type.unwrap().?;
1409 const ret_ty = try comptimeExpr(&block_scope, scope, coerced_type_ri, ret_ty_node, .function_ret_ty);
1415 const ret_ty = try comptimeExpr(&block_scope, scope, coerced_type_ri, ret_ty_node, .fn_ret_ty);
14101416
14111417 const result = try block_scope.addFunc(.{
14121418 .src_node = fn_proto.ast.proto_node,
......@@ -2629,7 +2635,7 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod
26292635 const params = tree.builtinCallParams(&buf, inner_node).?;
26302636
26312637 try emitDbgNode(gz, inner_node);
2632 const result = try builtinCall(gz, scope, .{ .rl = .none }, inner_node, params, allow_branch_hint);
2638 const result = try builtinCall(gz, scope, .{ .rl = .none }, inner_node, params, allow_branch_hint, .anon);
26332639 noreturn_src_node = try addEnsureResult(gz, result, inner_node);
26342640 },
26352641
......@@ -2707,6 +2713,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As
27072713 .elem_type,
27082714 .indexable_ptr_elem_type,
27092715 .splat_op_result_ty,
2716 .reify_int,
27102717 .vector_type,
27112718 .indexable_ptr_len,
27122719 .anyframe_type,
......@@ -8942,7 +8949,7 @@ fn unionInit(
89428949 params: []const Ast.Node.Index,
89438950) InnerError!Zir.Inst.Ref {
89448951 const union_type = try typeExpr(gz, scope, params[0]);
8945 const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .union_field_name);
8952 const field_name = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[1], .union_field_names);
89468953 const field_type = try gz.addPlNode(.field_type_ref, node, Zir.Inst.FieldTypeRef{
89478954 .container_type = union_type,
89488955 .field_name = field_name,
......@@ -9210,6 +9217,7 @@ fn builtinCall(
92109217 node: Ast.Node.Index,
92119218 params: []const Ast.Node.Index,
92129219 allow_branch_hint: bool,
9220 reify_name_strat: Zir.Inst.NameStrategy,
92139221) InnerError!Zir.Inst.Ref {
92149222 const astgen = gz.astgen;
92159223 const tree = astgen.tree;
......@@ -9443,9 +9451,140 @@ fn builtinCall(
94439451 return rvalue(gz, ri, try gz.addNodeExtended(.in_comptime, node), node);
94449452 },
94459453
9446 .Type => {
9447 return builtinReify(gz, scope, ri, node, params[0], .anon);
9454 .EnumLiteral => return rvalue(gz, ri, .enum_literal_type, node),
9455 .Int => {
9456 const signedness_ty = try gz.addBuiltinValue(node, .signedness);
9457 const result = try gz.addPlNode(.reify_int, node, Zir.Inst.Bin{
9458 .lhs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = signedness_ty } }, params[0], .int_signedness),
9459 .rhs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .u16_type } }, params[1], .int_bit_width),
9460 });
9461 return rvalue(gz, ri, result, node);
9462 },
9463 .Tuple => {
9464 const result = try gz.addExtendedPayload(.reify_tuple, Zir.Inst.UnNode{
9465 .node = gz.nodeIndexToRelative(node),
9466 .operand = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_type_type } }, params[0], .tuple_field_types),
9467 });
9468 return rvalue(gz, ri, result, node);
9469 },
9470 .Pointer => {
9471 const ptr_size_ty = try gz.addBuiltinValue(node, .pointer_size);
9472 const ptr_attrs_ty = try gz.addBuiltinValue(node, .pointer_attributes);
9473 const size = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = ptr_size_ty } }, params[0], .pointer_size);
9474 const attrs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = ptr_attrs_ty } }, params[1], .pointer_attrs);
9475 const elem_ty = try typeExpr(gz, scope, params[2]);
9476 const sentinel_ty = try gz.addExtendedPayload(.reify_pointer_sentinel_ty, Zir.Inst.UnNode{
9477 .node = gz.nodeIndexToRelative(params[2]),
9478 .operand = elem_ty,
9479 });
9480 const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = sentinel_ty } }, params[3], .pointer_sentinel);
9481 const result = try gz.addExtendedPayload(.reify_pointer, Zir.Inst.ReifyPointer{
9482 .node = gz.nodeIndexToRelative(node),
9483 .size = size,
9484 .attrs = attrs,
9485 .elem_ty = elem_ty,
9486 .sentinel = sentinel,
9487 });
9488 return rvalue(gz, ri, result, node);
94489489 },
9490 .Fn => {
9491 const fn_attrs_ty = try gz.addBuiltinValue(node, .fn_attributes);
9492 const param_types = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_type_type } }, params[0], .fn_param_types);
9493 const param_attrs_ty = try gz.addExtendedPayloadSmall(
9494 .reify_slice_arg_ty,
9495 @intFromEnum(Zir.Inst.ReifySliceArgInfo.type_to_fn_param_attrs),
9496 Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(params[0]), .operand = param_types },
9497 );
9498 const param_attrs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = param_attrs_ty } }, params[1], .fn_param_attrs);
9499 const ret_ty = try comptimeExpr(gz, scope, coerced_type_ri, params[2], .fn_ret_ty);
9500 const fn_attrs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = fn_attrs_ty } }, params[3], .fn_attrs);
9501 const result = try gz.addExtendedPayload(.reify_fn, Zir.Inst.ReifyFn{
9502 .node = gz.nodeIndexToRelative(node),
9503 .param_types = param_types,
9504 .param_attrs = param_attrs,
9505 .ret_ty = ret_ty,
9506 .fn_attrs = fn_attrs,
9507 });
9508 return rvalue(gz, ri, result, node);
9509 },
9510 .Struct => {
9511 const container_layout_ty = try gz.addBuiltinValue(node, .container_layout);
9512 const layout = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = container_layout_ty } }, params[0], .struct_layout);
9513 const backing_ty = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .optional_type_type } }, params[1], .type);
9514 const field_names = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_slice_const_u8_type } }, params[2], .struct_field_names);
9515 const field_types_ty = try gz.addExtendedPayloadSmall(
9516 .reify_slice_arg_ty,
9517 @intFromEnum(Zir.Inst.ReifySliceArgInfo.string_to_struct_field_type),
9518 Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(params[2]), .operand = field_names },
9519 );
9520 const field_attrs_ty = try gz.addExtendedPayloadSmall(
9521 .reify_slice_arg_ty,
9522 @intFromEnum(Zir.Inst.ReifySliceArgInfo.string_to_struct_field_attrs),
9523 Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(params[2]), .operand = field_names },
9524 );
9525 const field_types = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_types_ty } }, params[3], .struct_field_types);
9526 const field_attrs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_attrs_ty } }, params[4], .struct_field_attrs);
9527 const result = try gz.addExtendedPayloadSmall(.reify_struct, @intFromEnum(reify_name_strat), Zir.Inst.ReifyStruct{
9528 .src_line = gz.astgen.source_line,
9529 .node = node,
9530 .layout = layout,
9531 .backing_ty = backing_ty,
9532 .field_names = field_names,
9533 .field_types = field_types,
9534 .field_attrs = field_attrs,
9535 });
9536 return rvalue(gz, ri, result, node);
9537 },
9538 .Union => {
9539 const container_layout_ty = try gz.addBuiltinValue(node, .container_layout);
9540 const layout = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = container_layout_ty } }, params[0], .union_layout);
9541 const arg_ty = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .optional_type_type } }, params[1], .type);
9542 const field_names = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_slice_const_u8_type } }, params[2], .union_field_names);
9543 const field_types_ty = try gz.addExtendedPayloadSmall(
9544 .reify_slice_arg_ty,
9545 @intFromEnum(Zir.Inst.ReifySliceArgInfo.string_to_union_field_type),
9546 Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(params[2]), .operand = field_names },
9547 );
9548 const field_attrs_ty = try gz.addExtendedPayloadSmall(
9549 .reify_slice_arg_ty,
9550 @intFromEnum(Zir.Inst.ReifySliceArgInfo.string_to_union_field_attrs),
9551 Zir.Inst.UnNode{ .node = gz.nodeIndexToRelative(params[2]), .operand = field_names },
9552 );
9553 const field_types = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_types_ty } }, params[3], .union_field_types);
9554 const field_attrs = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_attrs_ty } }, params[4], .union_field_attrs);
9555 const result = try gz.addExtendedPayloadSmall(.reify_union, @intFromEnum(reify_name_strat), Zir.Inst.ReifyUnion{
9556 .src_line = gz.astgen.source_line,
9557 .node = node,
9558 .layout = layout,
9559 .arg_ty = arg_ty,
9560 .field_names = field_names,
9561 .field_types = field_types,
9562 .field_attrs = field_attrs,
9563 });
9564 return rvalue(gz, ri, result, node);
9565 },
9566 .Enum => {
9567 const enum_mode_ty = try gz.addBuiltinValue(node, .enum_mode);
9568 const tag_ty = try typeExpr(gz, scope, params[0]);
9569 const mode = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = enum_mode_ty } }, params[1], .type);
9570 const field_names = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = .slice_const_slice_const_u8_type } }, params[2], .enum_field_names);
9571 const field_values_ty = try gz.addExtendedPayload(.reify_enum_value_slice_ty, Zir.Inst.BinNode{
9572 .node = gz.nodeIndexToRelative(node),
9573 .lhs = tag_ty,
9574 .rhs = field_names,
9575 });
9576 const field_values = try comptimeExpr(gz, scope, .{ .rl = .{ .coerced_ty = field_values_ty } }, params[3], .enum_field_values);
9577 const result = try gz.addExtendedPayloadSmall(.reify_enum, @intFromEnum(reify_name_strat), Zir.Inst.ReifyEnum{
9578 .src_line = gz.astgen.source_line,
9579 .node = node,
9580 .tag_ty = tag_ty,
9581 .mode = mode,
9582 .field_names = field_names,
9583 .field_values = field_values,
9584 });
9585 return rvalue(gz, ri, result, node);
9586 },
9587
94499588 .panic => {
94509589 try emitDbgNode(gz, node);
94519590 return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .coerced_ty = .slice_const_u8_type } }, params[0], .panic);
......@@ -9764,41 +9903,6 @@ fn builtinCall(
97649903 },
97659904 }
97669905}
9767fn builtinReify(
9768 gz: *GenZir,
9769 scope: *Scope,
9770 ri: ResultInfo,
9771 node: Ast.Node.Index,
9772 arg_node: Ast.Node.Index,
9773 name_strat: Zir.Inst.NameStrategy,
9774) InnerError!Zir.Inst.Ref {
9775 const astgen = gz.astgen;
9776 const gpa = astgen.gpa;
9777
9778 const type_info_ty = try gz.addBuiltinValue(node, .type_info);
9779 const operand = try expr(gz, scope, .{ .rl = .{ .coerced_ty = type_info_ty } }, arg_node);
9780
9781 try gz.instructions.ensureUnusedCapacity(gpa, 1);
9782 try astgen.instructions.ensureUnusedCapacity(gpa, 1);
9783
9784 const payload_index = try astgen.addExtra(Zir.Inst.Reify{
9785 .node = node, // Absolute node index -- see the definition of `Reify`.
9786 .operand = operand,
9787 .src_line = astgen.source_line,
9788 });
9789 const new_index: Zir.Inst.Index = @enumFromInt(astgen.instructions.len);
9790 astgen.instructions.appendAssumeCapacity(.{
9791 .tag = .extended,
9792 .data = .{ .extended = .{
9793 .opcode = .reify,
9794 .small = @intFromEnum(name_strat),
9795 .operand = payload_index,
9796 } },
9797 });
9798 gz.instructions.appendAssumeCapacity(new_index);
9799 const result = new_index.toRef();
9800 return rvalue(gz, ri, result, node);
9801}
98029906
98039907fn hasDeclOrField(
98049908 gz: *GenZir,
lib/std/zig/AstRlAnnotate.zig+44-1
......@@ -866,6 +866,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
866866 // These builtins take no args and do not consume the result pointer.
867867 .src,
868868 .This,
869 .EnumLiteral,
869870 .return_address,
870871 .error_return_trace,
871872 .frame,
......@@ -906,7 +907,7 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
906907 .embed_file,
907908 .error_name,
908909 .set_runtime_safety,
909 .Type,
910 .Tuple,
910911 .c_undef,
911912 .c_include,
912913 .wasm_memory_size,
......@@ -1058,6 +1059,48 @@ fn builtinCall(astrl: *AstRlAnnotate, block: ?*Block, ri: ResultInfo, node: Ast.
10581059 _ = try astrl.expr(args[3], block, ResultInfo.none);
10591060 return false;
10601061 },
1062 .Int => {
1063 _ = try astrl.expr(args[0], block, ResultInfo.type_only);
1064 _ = try astrl.expr(args[1], block, ResultInfo.type_only);
1065 return false;
1066 },
1067 .Pointer => {
1068 _ = try astrl.expr(args[0], block, ResultInfo.type_only);
1069 _ = try astrl.expr(args[1], block, ResultInfo.type_only);
1070 _ = try astrl.expr(args[2], block, ResultInfo.type_only);
1071 _ = try astrl.expr(args[3], block, ResultInfo.type_only);
1072 return false;
1073 },
1074 .Fn => {
1075 _ = try astrl.expr(args[0], block, ResultInfo.type_only);
1076 _ = try astrl.expr(args[1], block, ResultInfo.type_only);
1077 _ = try astrl.expr(args[2], block, ResultInfo.type_only);
1078 _ = try astrl.expr(args[3], block, ResultInfo.type_only);
1079 return false;
1080 },
1081 .Struct => {
1082 _ = try astrl.expr(args[0], block, ResultInfo.type_only);
1083 _ = try astrl.expr(args[1], block, ResultInfo.type_only);
1084 _ = try astrl.expr(args[2], block, ResultInfo.type_only);
1085 _ = try astrl.expr(args[3], block, ResultInfo.type_only);
1086 _ = try astrl.expr(args[4], block, ResultInfo.type_only);
1087 return false;
1088 },
1089 .Union => {
1090 _ = try astrl.expr(args[0], block, ResultInfo.type_only);
1091 _ = try astrl.expr(args[1], block, ResultInfo.type_only);
1092 _ = try astrl.expr(args[2], block, ResultInfo.type_only);
1093 _ = try astrl.expr(args[3], block, ResultInfo.type_only);
1094 _ = try astrl.expr(args[4], block, ResultInfo.type_only);
1095 return false;
1096 },
1097 .Enum => {
1098 _ = try astrl.expr(args[0], block, ResultInfo.type_only);
1099 _ = try astrl.expr(args[1], block, ResultInfo.type_only);
1100 _ = try astrl.expr(args[2], block, ResultInfo.type_only);
1101 _ = try astrl.expr(args[3], block, ResultInfo.type_only);
1102 return false;
1103 },
10611104 .Vector => {
10621105 _ = try astrl.expr(args[0], block, ResultInfo.type_only);
10631106 _ = try astrl.expr(args[1], block, ResultInfo.type_only);
lib/std/zig/BuiltinFn.zig+59-3
......@@ -110,7 +110,14 @@ pub const Tag = enum {
110110 This,
111111 trap,
112112 truncate,
113 Type,
113 EnumLiteral,
114 Int,
115 Tuple,
116 Pointer,
117 Fn,
118 Struct,
119 Union,
120 Enum,
114121 type_info,
115122 type_name,
116123 TypeOf,
......@@ -937,12 +944,61 @@ pub const list = list: {
937944 },
938945 },
939946 .{
940 "@Type",
947 "@EnumLiteral",
941948 .{
942 .tag = .Type,
949 .tag = .EnumLiteral,
950 .param_count = 0,
951 },
952 },
953 .{
954 "@Int",
955 .{
956 .tag = .Int,
957 .param_count = 2,
958 },
959 },
960 .{
961 "@Tuple",
962 .{
963 .tag = .Tuple,
943964 .param_count = 1,
944965 },
945966 },
967 .{
968 "@Pointer",
969 .{
970 .tag = .Pointer,
971 .param_count = 4,
972 },
973 },
974 .{
975 "@Fn",
976 .{
977 .tag = .Fn,
978 .param_count = 4,
979 },
980 },
981 .{
982 "@Struct",
983 .{
984 .tag = .Struct,
985 .param_count = 5,
986 },
987 },
988 .{
989 "@Union",
990 .{
991 .tag = .Union,
992 .param_count = 5,
993 },
994 },
995 .{
996 "@Enum",
997 .{
998 .tag = .Enum,
999 .param_count = 4,
1000 },
1001 },
9461002 .{
9471003 "@typeInfo",
9481004 .{
lib/std/zig/Zir.zig+131-8
......@@ -260,6 +260,10 @@ pub const Inst = struct {
260260 /// `[N:S]T` syntax. Source location is the array type expression node.
261261 /// Uses the `pl_node` union field. Payload is `ArrayTypeSentinel`.
262262 array_type_sentinel,
263 /// `@Int` builtin.
264 /// Uses the `pl_node` union field with `Bin` payload.
265 /// lhs is signedness, rhs is bit count.
266 reify_int,
263267 /// `@Vector` builtin.
264268 /// Uses the `pl_node` union field with `Bin` payload.
265269 /// lhs is length, rhs is element type.
......@@ -1112,6 +1116,7 @@ pub const Inst = struct {
11121116 .array_mul,
11131117 .array_type,
11141118 .array_type_sentinel,
1119 .reify_int,
11151120 .vector_type,
11161121 .elem_type,
11171122 .indexable_ptr_elem_type,
......@@ -1409,6 +1414,7 @@ pub const Inst = struct {
14091414 .array_mul,
14101415 .array_type,
14111416 .array_type_sentinel,
1417 .reify_int,
14121418 .vector_type,
14131419 .elem_type,
14141420 .indexable_ptr_elem_type,
......@@ -1644,6 +1650,7 @@ pub const Inst = struct {
16441650 .array_mul = .pl_node,
16451651 .array_type = .pl_node,
16461652 .array_type_sentinel = .pl_node,
1653 .reify_int = .pl_node,
16471654 .vector_type = .pl_node,
16481655 .elem_type = .un_node,
16491656 .indexable_ptr_elem_type = .un_node,
......@@ -2035,10 +2042,43 @@ pub const Inst = struct {
20352042 /// Implement builtin `@errorFromInt`.
20362043 /// `operand` is payload index to `UnNode`.
20372044 error_from_int,
2038 /// Implement builtin `@Type`.
2039 /// `operand` is payload index to `Reify`.
2045 /// Given a comptime-known operand of type `[]const A`, returns the type `*const [operand.len]B`.
2046 /// The types `A` and `B` are determined from `ReifySliceArgInfo`.
2047 /// This instruction is used to provide result types to arguments of `@Fn`, `@Struct`, etc.
2048 /// `operand` is payload index to `UnNode`.
2049 /// `small` is a bitcast `ReifySliceArgInfo`.
2050 reify_slice_arg_ty,
2051 /// Like `reify_slice_arg_ty` for the specific case of `[]const []const u8` to `[]const TagInt`,
2052 /// as needed for `@Enum`.
2053 /// `operand` is payload index to `BinNode`. lhs is the type `TagInt`. rhs is the `[]const []const u8` value.
2054 /// `small` is unused.
2055 reify_enum_value_slice_ty,
2056 /// Given a comptime-known operand of type `type`, returns the type `?operand` if possible, otherwise `?noreturn`.
2057 /// Used for the final arg of `@Pointer` to allow reifying pointers to opaque types.
2058 /// `operand` is payload index to `UnNode`.
2059 /// `small` is unused.
2060 reify_pointer_sentinel_ty,
2061 /// Implements builtin `@Tuple`.
2062 /// `operand` is payload index to `UnNode`.
2063 reify_tuple,
2064 /// Implements builtin `@Pointer`.
2065 /// `operand` is payload index to `ReifyPointer`.
2066 reify_pointer,
2067 /// Implements builtin `@Fn`.
2068 /// `operand` is payload index to `ReifyFn`.
2069 reify_fn,
2070 /// Implements builtin `@Struct`.
2071 /// `operand` is payload index to `ReifyStruct`.
2072 /// `small` contains `NameStrategy`.
2073 reify_struct,
2074 /// Implements builtin `@Union`.
2075 /// `operand` is payload index to `ReifyUnion`.
2076 /// `small` contains `NameStrategy`.
2077 reify_union,
2078 /// Implements builtin `@Enum`.
2079 /// `operand` is payload index to `ReifyEnum`.
20402080 /// `small` contains `NameStrategy`.
2041 reify,
2081 reify_enum,
20422082 /// Implements the `@cmpxchgStrong` and `@cmpxchgWeak` builtins.
20432083 /// `small` 0=>weak 1=>strong
20442084 /// `operand` is payload index to `Cmpxchg`.
......@@ -2226,6 +2266,11 @@ pub const Inst = struct {
22262266 manyptr_const_u8_sentinel_0_type,
22272267 slice_const_u8_type,
22282268 slice_const_u8_sentinel_0_type,
2269 manyptr_const_slice_const_u8_type,
2270 slice_const_slice_const_u8_type,
2271 optional_type_type,
2272 manyptr_const_type_type,
2273 slice_const_type_type,
22292274 vector_8_i8_type,
22302275 vector_16_i8_type,
22312276 vector_32_i8_type,
......@@ -3169,6 +3214,23 @@ pub const Inst = struct {
31693214 rhs: Ref,
31703215 };
31713216
3217 pub const ReifySliceArgInfo = enum(u16) {
3218 /// Input element type is `type`.
3219 /// Output element type is `std.builtin.Type.Fn.Param.Attributes`.
3220 type_to_fn_param_attrs,
3221 /// Input element type is `[]const u8`.
3222 /// Output element type is `type`.
3223 string_to_struct_field_type,
3224 /// Identical to `string_to_struct_field_type` aside from emitting slightly different error messages.
3225 string_to_union_field_type,
3226 /// Input element type is `[]const u8`.
3227 /// Output element type is `std.builtin.Type.StructField.Attributes`.
3228 string_to_struct_field_attrs,
3229 /// Input element type is `[]const u8`.
3230 /// Output element type is `std.builtin.Type.UnionField.Attributes`.
3231 string_to_union_field_attrs,
3232 };
3233
31723234 pub const UnNode = struct {
31733235 node: Ast.Node.Offset,
31743236 operand: Ref,
......@@ -3179,12 +3241,55 @@ pub const Inst = struct {
31793241 index: u32,
31803242 };
31813243
3182 pub const Reify = struct {
3244 pub const ReifyPointer = struct {
3245 node: Ast.Node.Offset,
3246 size: Ref,
3247 attrs: Ref,
3248 elem_ty: Ref,
3249 sentinel: Ref,
3250 };
3251
3252 pub const ReifyFn = struct {
3253 node: Ast.Node.Offset,
3254 param_types: Ref,
3255 param_attrs: Ref,
3256 ret_ty: Ref,
3257 fn_attrs: Ref,
3258 };
3259
3260 pub const ReifyStruct = struct {
3261 src_line: u32,
31833262 /// This node is absolute, because `reify` instructions are tracked across updates, and
31843263 /// this simplifies the logic for getting source locations for types.
31853264 node: Ast.Node.Index,
3186 operand: Ref,
3265 layout: Ref,
3266 backing_ty: Ref,
3267 field_names: Ref,
3268 field_types: Ref,
3269 field_attrs: Ref,
3270 };
3271
3272 pub const ReifyUnion = struct {
31873273 src_line: u32,
3274 /// This node is absolute, because `reify` instructions are tracked across updates, and
3275 /// this simplifies the logic for getting source locations for types.
3276 node: Ast.Node.Index,
3277 layout: Ref,
3278 arg_ty: Ref,
3279 field_names: Ref,
3280 field_types: Ref,
3281 field_attrs: Ref,
3282 };
3283
3284 pub const ReifyEnum = struct {
3285 src_line: u32,
3286 /// This node is absolute, because `reify` instructions are tracked across updates, and
3287 /// this simplifies the logic for getting source locations for types.
3288 node: Ast.Node.Index,
3289 tag_ty: Ref,
3290 mode: Ref,
3291 field_names: Ref,
3292 field_values: Ref,
31883293 };
31893294
31903295 /// Trailing:
......@@ -3496,14 +3601,19 @@ pub const Inst = struct {
34963601 calling_convention,
34973602 address_space,
34983603 float_mode,
3604 signedness,
34993605 reduce_op,
35003606 call_modifier,
35013607 prefetch_options,
35023608 export_options,
35033609 extern_options,
3504 type_info,
35053610 branch_hint,
35063611 clobbers,
3612 pointer_size,
3613 pointer_attributes,
3614 fn_attributes,
3615 container_layout,
3616 enum_mode,
35073617 // Values
35083618 calling_convention_c,
35093619 calling_convention_inline,
......@@ -4190,6 +4300,7 @@ fn findTrackableInner(
41904300 .array_mul,
41914301 .array_type,
41924302 .array_type_sentinel,
4303 .reify_int,
41934304 .vector_type,
41944305 .elem_type,
41954306 .indexable_ptr_elem_type,
......@@ -4432,6 +4543,12 @@ fn findTrackableInner(
44324543 .select,
44334544 .int_from_error,
44344545 .error_from_int,
4546 .reify_slice_arg_ty,
4547 .reify_enum_value_slice_ty,
4548 .reify_pointer_sentinel_ty,
4549 .reify_tuple,
4550 .reify_pointer,
4551 .reify_fn,
44354552 .cmpxchg,
44364553 .c_va_arg,
44374554 .c_va_copy,
......@@ -4463,7 +4580,11 @@ fn findTrackableInner(
44634580 },
44644581
44654582 // Reifications and opaque declarations need tracking, but have no body.
4466 .reify, .opaque_decl => return contents.other.append(gpa, inst),
4583 .reify_enum,
4584 .reify_struct,
4585 .reify_union,
4586 .opaque_decl,
4587 => return contents.other.append(gpa, inst),
44674588
44684589 // Struct declarations need tracking and have bodies.
44694590 .struct_decl => {
......@@ -5246,7 +5367,9 @@ pub fn assertTrackable(zir: Zir, inst_idx: Zir.Inst.Index) void {
52465367 .union_decl,
52475368 .enum_decl,
52485369 .opaque_decl,
5249 .reify,
5370 .reify_enum,
5371 .reify_struct,
5372 .reify_union,
52505373 => {}, // tracked in order, as the owner instructions of explicit container types
52515374 else => unreachable, // assertion failure; not trackable
52525375 },
lib/std/zig/c_translation/helpers.zig+10-18
......@@ -81,23 +81,15 @@ fn ToUnsigned(comptime T: type) type {
8181}
8282
8383/// Constructs a [*c] pointer with the const and volatile annotations
84/// from SelfType for pointing to a C flexible array of ElementType.
85pub fn FlexibleArrayType(comptime SelfType: type, comptime ElementType: type) type {
86 switch (@typeInfo(SelfType)) {
87 .pointer => |ptr| {
88 return @Type(.{ .pointer = .{
89 .size = .c,
90 .is_const = ptr.is_const,
91 .is_volatile = ptr.is_volatile,
92 .alignment = @alignOf(ElementType),
93 .address_space = .generic,
94 .child = ElementType,
95 .is_allowzero = true,
96 .sentinel_ptr = null,
97 } });
98 },
99 else => |info| @compileError("Invalid self type \"" ++ @tagName(info) ++ "\" for flexible array getter: " ++ @typeName(SelfType)),
100 }
84/// from Self for pointing to a C flexible array of Element.
85pub fn FlexibleArrayType(comptime Self: type, comptime Element: type) type {
86 return switch (@typeInfo(Self)) {
87 .pointer => |ptr| @Pointer(.c, .{
88 .@"const" = ptr.is_const,
89 .@"volatile" = ptr.is_volatile,
90 }, Element, null),
91 else => |info| @compileError("Invalid self type \"" ++ @tagName(info) ++ "\" for flexible array getter: " ++ @typeName(Self)),
92 };
10193}
10294
10395/// Promote the type of an integer literal until it fits as C would.
......@@ -219,7 +211,7 @@ fn castInt(comptime DestType: type, target: anytype) DestType {
219211 const dest = @typeInfo(DestType).int;
220212 const source = @typeInfo(@TypeOf(target)).int;
221213
222 const Int = @Type(.{ .int = .{ .bits = dest.bits, .signedness = source.signedness } });
214 const Int = @Int(source.signedness, dest.bits);
223215
224216 if (dest.bits < source.bits)
225217 return @as(DestType, @bitCast(@as(Int, @truncate(target))))
lib/std/zig/llvm/Builder.zig+9-30
......@@ -8614,39 +8614,18 @@ pub const Metadata = packed struct(u32) {
86148614 nodes: anytype,
86158615 w: *Writer,
86168616 ) !void {
8617 comptime var fmt_str: []const u8 = "";
86188617 const names = comptime std.meta.fieldNames(@TypeOf(nodes));
8619 comptime var fields: [2 + names.len]std.builtin.Type.StructField = undefined;
8620 inline for (fields[0..2], .{ "distinct", "node" }) |*field, name| {
8621 fmt_str = fmt_str ++ "{[" ++ name ++ "]s}";
8622 field.* = .{
8623 .name = name,
8624 .type = []const u8,
8625 .default_value_ptr = null,
8626 .is_comptime = false,
8627 .alignment = @alignOf([]const u8),
8628 };
8629 }
8630 fmt_str = fmt_str ++ "(";
8631 inline for (fields[2..], names) |*field, name| {
8632 fmt_str = fmt_str ++ "{[" ++ name ++ "]f}";
8633 const T = std.fmt.Alt(FormatData, format);
8634 field.* = .{
8635 .name = name,
8636 .type = T,
8637 .default_value_ptr = null,
8638 .is_comptime = false,
8639 .alignment = @alignOf(T),
8640 };
8641 }
8618
8619 comptime var fmt_str: []const u8 = "{[distinct]s}{[node]s}(";
8620 inline for (names) |name| fmt_str = fmt_str ++ "{[" ++ name ++ "]f}";
86428621 fmt_str = fmt_str ++ ")\n";
86438622
8644 var fmt_args: @Type(.{ .@"struct" = .{
8645 .layout = .auto,
8646 .fields = &fields,
8647 .decls = &.{},
8648 .is_tuple = false,
8649 } }) = undefined;
8623 const field_names = @as([]const []const u8, &.{ "distinct", "node" }) ++ names;
8624 comptime var field_types: [2 + names.len]type = undefined;
8625 @memset(field_types[0..2], []const u8);
8626 @memset(field_types[2..], std.fmt.Alt(FormatData, format));
8627
8628 var fmt_args: @Struct(.auto, null, field_names, &field_types, &@splat(.{})) = undefined;
86508629 fmt_args.distinct = @tagName(distinct);
86518630 fmt_args.node = @tagName(node);
86528631 inline for (names) |name| @field(fmt_args, name) = try formatter.fmt(
src/Air.zig+5
......@@ -1062,6 +1062,11 @@ pub const Inst = struct {
10621062 manyptr_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.manyptr_const_u8_sentinel_0_type),
10631063 slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_u8_type),
10641064 slice_const_u8_sentinel_0_type = @intFromEnum(InternPool.Index.slice_const_u8_sentinel_0_type),
1065 manyptr_const_slice_const_u8_type = @intFromEnum(InternPool.Index.manyptr_const_slice_const_u8_type),
1066 slice_const_slice_const_u8_type = @intFromEnum(InternPool.Index.slice_const_slice_const_u8_type),
1067 optional_type_type = @intFromEnum(InternPool.Index.optional_type_type),
1068 manyptr_const_type_type = @intFromEnum(InternPool.Index.manyptr_const_type_type),
1069 slice_const_type_type = @intFromEnum(InternPool.Index.slice_const_type_type),
10651070 vector_8_i8_type = @intFromEnum(InternPool.Index.vector_8_i8_type),
10661071 vector_16_i8_type = @intFromEnum(InternPool.Index.vector_16_i8_type),
10671072 vector_32_i8_type = @intFromEnum(InternPool.Index.vector_32_i8_type),
src/InternPool.zig+90-79
......@@ -1153,23 +1153,17 @@ const Local = struct {
11531153 fn PtrArrayElem(comptime len: usize) type {
11541154 const elem_info = @typeInfo(Elem).@"struct";
11551155 const elem_fields = elem_info.fields;
1156 var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined;
1157 for (&new_fields, elem_fields) |*new_field, elem_field| {
1158 const T = *[len]elem_field.type;
1159 new_field.* = .{
1160 .name = elem_field.name,
1161 .type = T,
1162 .default_value_ptr = null,
1163 .is_comptime = false,
1164 .alignment = @alignOf(T),
1165 };
1156 var new_names: [elem_fields.len][]const u8 = undefined;
1157 var new_types: [elem_fields.len]type = undefined;
1158 for (elem_fields, &new_names, &new_types) |elem_field, *new_name, *NewType| {
1159 new_name.* = elem_field.name;
1160 NewType.* = *[len]elem_field.type;
1161 }
1162 if (elem_info.is_tuple) {
1163 return @Tuple(&new_types);
1164 } else {
1165 return @Struct(.auto, null, &new_names, &new_types, &@splat(.{}));
11661166 }
1167 return @Type(.{ .@"struct" = .{
1168 .layout = .auto,
1169 .fields = &new_fields,
1170 .decls = &.{},
1171 .is_tuple = elem_info.is_tuple,
1172 } });
11731167 }
11741168 fn PtrElem(comptime opts: struct {
11751169 size: std.builtin.Type.Pointer.Size,
......@@ -1177,32 +1171,17 @@ const Local = struct {
11771171 }) type {
11781172 const elem_info = @typeInfo(Elem).@"struct";
11791173 const elem_fields = elem_info.fields;
1180 var new_fields: [elem_fields.len]std.builtin.Type.StructField = undefined;
1181 for (&new_fields, elem_fields) |*new_field, elem_field| {
1182 const T = @Type(.{ .pointer = .{
1183 .size = opts.size,
1184 .is_const = opts.is_const,
1185 .is_volatile = false,
1186 .alignment = @alignOf(elem_field.type),
1187 .address_space = .generic,
1188 .child = elem_field.type,
1189 .is_allowzero = false,
1190 .sentinel_ptr = null,
1191 } });
1192 new_field.* = .{
1193 .name = elem_field.name,
1194 .type = T,
1195 .default_value_ptr = null,
1196 .is_comptime = false,
1197 .alignment = @alignOf(T),
1198 };
1174 var new_names: [elem_fields.len][]const u8 = undefined;
1175 var new_types: [elem_fields.len]type = undefined;
1176 for (elem_fields, &new_names, &new_types) |elem_field, *new_name, *NewType| {
1177 new_name.* = elem_field.name;
1178 NewType.* = @Pointer(opts.size, .{ .@"const" = opts.is_const }, elem_field.type, null);
1179 }
1180 if (elem_info.is_tuple) {
1181 return @Tuple(&new_types);
1182 } else {
1183 return @Struct(.auto, null, &new_names, &new_types, &@splat(.{}));
11991184 }
1200 return @Type(.{ .@"struct" = .{
1201 .layout = .auto,
1202 .fields = &new_fields,
1203 .decls = &.{},
1204 .is_tuple = elem_info.is_tuple,
1205 } });
12061185 }
12071186
12081187 pub fn addOne(mutable: Mutable) Allocator.Error!PtrElem(.{ .size = .one }) {
......@@ -2017,8 +1996,7 @@ pub const Key = union(enum) {
20171996 error_union_type: ErrorUnionType,
20181997 simple_type: SimpleType,
20191998 /// This represents a struct that has been explicitly declared in source code,
2020 /// or was created with `@Type`. It is unique and based on a declaration.
2021 /// It may be a tuple, if declared like this: `struct {A, B, C}`.
1999 /// or was created with `@Struct`. It is unique and based on a declaration.
20222000 struct_type: NamespaceType,
20232001 /// This is a tuple type. Tuples are logically similar to structs, but have some
20242002 /// important differences in semantics; they do not undergo staged type resolution,
......@@ -2175,7 +2153,7 @@ pub const Key = union(enum) {
21752153 /// The union for which this is a tag type.
21762154 union_type: Index,
21772155 },
2178 /// This type originates from a reification via `@Type`, or from an anonymous initialization.
2156 /// This type originates from a reification via `@Enum`, `@Struct`, `@Union` or from an anonymous initialization.
21792157 /// It is hashed based on its ZIR instruction index and fields, attributes, etc.
21802158 /// To avoid making this key overly complex, the type-specific data is hashed by Sema.
21812159 reified: struct {
......@@ -4641,6 +4619,13 @@ pub const Index = enum(u32) {
46414619 slice_const_u8_type,
46424620 slice_const_u8_sentinel_0_type,
46434621
4622 manyptr_const_slice_const_u8_type,
4623 slice_const_slice_const_u8_type,
4624
4625 optional_type_type,
4626 manyptr_const_type_type,
4627 slice_const_type_type,
4628
46444629 vector_8_i8_type,
46454630 vector_16_i8_type,
46464631 vector_32_i8_type,
......@@ -5201,6 +5186,45 @@ pub const static_keys: [static_len]Key = .{
52015186 },
52025187 } },
52035188
5189 // [*]const []const u8
5190 .{ .ptr_type = .{
5191 .child = .slice_const_u8_type,
5192 .flags = .{
5193 .size = .many,
5194 .is_const = true,
5195 },
5196 } },
5197
5198 // []const []const u8
5199 .{ .ptr_type = .{
5200 .child = .slice_const_u8_type,
5201 .flags = .{
5202 .size = .slice,
5203 .is_const = true,
5204 },
5205 } },
5206
5207 // ?type
5208 .{ .opt_type = .type_type },
5209
5210 // [*]const type
5211 .{ .ptr_type = .{
5212 .child = .type_type,
5213 .flags = .{
5214 .size = .many,
5215 .is_const = true,
5216 },
5217 } },
5218
5219 // []const type
5220 .{ .ptr_type = .{
5221 .child = .type_type,
5222 .flags = .{
5223 .size = .slice,
5224 .is_const = true,
5225 },
5226 } },
5227
52045228 // @Vector(8, i8)
52055229 .{ .vector_type = .{ .len = 8, .child = .i8_type } },
52065230 // @Vector(16, i8)
......@@ -10225,16 +10249,8 @@ pub fn getGeneratedTagEnumType(
1022510249}
1022610250
1022710251pub const OpaqueTypeInit = struct {
10228 key: union(enum) {
10229 declared: struct {
10230 zir_index: TrackedInst.Index,
10231 captures: []const CaptureValue,
10232 },
10233 reified: struct {
10234 zir_index: TrackedInst.Index,
10235 // No type hash since reifid opaques have no data other than the `@Type` location
10236 },
10237 },
10252 zir_index: TrackedInst.Index,
10253 captures: []const CaptureValue,
1023810254};
1023910255
1024010256pub fn getOpaqueType(
......@@ -10243,16 +10259,10 @@ pub fn getOpaqueType(
1024310259 tid: Zcu.PerThread.Id,
1024410260 ini: OpaqueTypeInit,
1024510261) Allocator.Error!WipNamespaceType.Result {
10246 var gop = try ip.getOrPutKey(gpa, tid, .{ .opaque_type = switch (ini.key) {
10247 .declared => |d| .{ .declared = .{
10248 .zir_index = d.zir_index,
10249 .captures = .{ .external = d.captures },
10250 } },
10251 .reified => |r| .{ .reified = .{
10252 .zir_index = r.zir_index,
10253 .type_hash = 0,
10254 } },
10255 } });
10262 var gop = try ip.getOrPutKey(gpa, tid, .{ .opaque_type = .{ .declared = .{
10263 .zir_index = ini.zir_index,
10264 .captures = .{ .external = ini.captures },
10265 } } });
1025610266 defer gop.deinit();
1025710267 if (gop == .existing) return .{ .existing = gop.existing };
1025810268
......@@ -10261,30 +10271,19 @@ pub fn getOpaqueType(
1026110271 const extra = local.getMutableExtra(gpa);
1026210272 try items.ensureUnusedCapacity(1);
1026310273
10264 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeOpaque).@"struct".fields.len + switch (ini.key) {
10265 .declared => |d| d.captures.len,
10266 .reified => 0,
10267 });
10274 try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeOpaque).@"struct".fields.len + ini.captures.len);
1026810275 const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{
1026910276 .name = undefined, // set by `finish`
1027010277 .name_nav = undefined, // set by `finish`
1027110278 .namespace = undefined, // set by `finish`
10272 .zir_index = switch (ini.key) {
10273 inline else => |x| x.zir_index,
10274 },
10275 .captures_len = switch (ini.key) {
10276 .declared => |d| @intCast(d.captures.len),
10277 .reified => std.math.maxInt(u32),
10278 },
10279 .zir_index = ini.zir_index,
10280 .captures_len = @intCast(ini.captures.len),
1027910281 });
1028010282 items.appendAssumeCapacity(.{
1028110283 .tag = .type_opaque,
1028210284 .data = extra_index,
1028310285 });
10284 switch (ini.key) {
10285 .declared => |d| extra.appendSliceAssumeCapacity(.{@ptrCast(d.captures)}),
10286 .reified => {},
10287 }
10286 extra.appendSliceAssumeCapacity(.{@ptrCast(ini.captures)});
1028810287 return .{
1028910288 .wip = .{
1029010289 .tid = tid,
......@@ -10555,6 +10554,8 @@ pub fn slicePtrType(ip: *const InternPool, index: Index) Index {
1055510554 switch (index) {
1055610555 .slice_const_u8_type => return .manyptr_const_u8_type,
1055710556 .slice_const_u8_sentinel_0_type => return .manyptr_const_u8_sentinel_0_type,
10557 .slice_const_slice_const_u8_type => return .manyptr_const_slice_const_u8_type,
10558 .slice_const_type_type => return .manyptr_const_type_type,
1055810559 else => {},
1055910560 }
1056010561 const item = index.unwrap(ip).getItem(ip);
......@@ -12013,8 +12014,13 @@ pub fn typeOf(ip: *const InternPool, index: Index) Index {
1201312014 .manyptr_u8_type,
1201412015 .manyptr_const_u8_type,
1201512016 .manyptr_const_u8_sentinel_0_type,
12017 .manyptr_const_slice_const_u8_type,
1201612018 .slice_const_u8_type,
1201712019 .slice_const_u8_sentinel_0_type,
12020 .slice_const_slice_const_u8_type,
12021 .optional_type_type,
12022 .manyptr_const_type_type,
12023 .slice_const_type_type,
1201812024 .vector_8_i8_type,
1201912025 .vector_16_i8_type,
1202012026 .vector_32_i8_type,
......@@ -12355,8 +12361,12 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1235512361 .manyptr_u8_type,
1235612362 .manyptr_const_u8_type,
1235712363 .manyptr_const_u8_sentinel_0_type,
12364 .manyptr_const_slice_const_u8_type,
1235812365 .slice_const_u8_type,
1235912366 .slice_const_u8_sentinel_0_type,
12367 .slice_const_slice_const_u8_type,
12368 .manyptr_const_type_type,
12369 .slice_const_type_type,
1236012370 => .pointer,
1236112371
1236212372 .vector_8_i8_type,
......@@ -12408,6 +12418,7 @@ pub fn zigTypeTag(ip: *const InternPool, index: Index) std.builtin.TypeId {
1240812418 .vector_8_f64_type,
1240912419 => .vector,
1241012420
12421 .optional_type_type => .optional,
1241112422 .optional_noreturn_type => .optional,
1241212423 .anyerror_void_error_union_type => .error_union,
1241312424 .empty_tuple_type => .@"struct",
src/Sema.zig+1194-1243
......@@ -1167,6 +1167,7 @@ fn analyzeBodyInner(
11671167 .array_mul => try sema.zirArrayMul(block, inst),
11681168 .array_type => try sema.zirArrayType(block, inst),
11691169 .array_type_sentinel => try sema.zirArrayTypeSentinel(block, inst),
1170 .reify_int => try sema.zirReifyInt(block, inst),
11701171 .vector_type => try sema.zirVectorType(block, inst),
11711172 .as_node => try sema.zirAsNode(block, inst),
11721173 .as_shift_operand => try sema.zirAsShiftOperand(block, inst),
......@@ -1411,7 +1412,6 @@ fn analyzeBodyInner(
14111412 .select => try sema.zirSelect( block, extended),
14121413 .int_from_error => try sema.zirIntFromError( block, extended),
14131414 .error_from_int => try sema.zirErrorFromInt( block, extended),
1414 .reify => try sema.zirReify( block, extended, inst),
14151415 .cmpxchg => try sema.zirCmpxchg( block, extended),
14161416 .c_va_arg => try sema.zirCVaArg( block, extended),
14171417 .c_va_copy => try sema.zirCVaCopy( block, extended),
......@@ -1424,6 +1424,16 @@ fn analyzeBodyInner(
14241424 .work_group_id => try sema.zirWorkItem( block, extended, extended.opcode),
14251425 .in_comptime => try sema.zirInComptime( block),
14261426 .closure_get => try sema.zirClosureGet( block, extended),
1427
1428 .reify_slice_arg_ty => try sema.zirReifySliceArgTy( block, extended),
1429 .reify_enum_value_slice_ty => try sema.zirReifyEnumValueSliceTy(block, extended),
1430 .reify_pointer_sentinel_ty => try sema.zirReifyPointerSentinelTy(block, extended),
1431 .reify_tuple => try sema.zirReifyTuple( block, extended),
1432 .reify_pointer => try sema.zirReifyPointer( block, extended),
1433 .reify_fn => try sema.zirReifyFn( block, extended),
1434 .reify_struct => try sema.zirReifyStruct( block, extended, inst),
1435 .reify_union => try sema.zirReifyUnion( block, extended, inst),
1436 .reify_enum => try sema.zirReifyEnum( block, extended, inst),
14271437 // zig fmt: on
14281438
14291439 .set_float_mode => {
......@@ -3517,10 +3527,8 @@ fn zirOpaqueDecl(
35173527 extra_index += captures_len * 2;
35183528
35193529 const opaque_init: InternPool.OpaqueTypeInit = .{
3520 .key = .{ .declared = .{
3521 .zir_index = tracked_inst,
3522 .captures = captures,
3523 } },
3530 .zir_index = tracked_inst,
3531 .captures = captures,
35243532 };
35253533 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, opaque_init)) {
35263534 .existing => |ty| {
......@@ -7386,7 +7394,7 @@ fn analyzeCall(
73867394 const body = sema.code.bodySlice(extra.end, extra.data.type.body_len);
73877395
73887396 generic_block.comptime_reason = .{ .reason = .{
7389 .r = .{ .simple = .function_parameters },
7397 .r = .{ .simple = .fn_param_types },
73907398 .src = param_src,
73917399 } };
73927400
......@@ -7470,7 +7478,7 @@ fn analyzeCall(
74707478 sema.inst_map = generic_inst_map;
74717479
74727480 generic_block.comptime_reason = .{ .reason = .{
7473 .r = .{ .simple = .function_ret_ty },
7481 .r = .{ .simple = .fn_ret_ty },
74747482 .src = func_ret_ty_src,
74757483 } };
74767484
......@@ -8927,7 +8935,7 @@ fn zirFunc(
89278935 const ret_ty_body = sema.code.bodySlice(extra_index, extra.data.ret_ty.body_len);
89288936 extra_index += ret_ty_body.len;
89298937
8930 const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, .type, .{ .simple = .function_ret_ty });
8938 const ret_ty_val = try sema.resolveGenericBody(block, ret_ty_src, ret_ty_body, inst, .type, .{ .simple = .fn_ret_ty });
89318939 break :blk ret_ty_val.toType();
89328940 },
89338941 };
......@@ -9171,6 +9179,181 @@ fn checkCallConvSupportsVarArgs(sema: *Sema, block: *Block, src: LazySrcLoc, cc:
91719179 }
91729180}
91739181
9182fn checkParamTypeCommon(
9183 sema: *Sema,
9184 block: *Block,
9185 param_idx: u32,
9186 param_ty: Type,
9187 param_is_noalias: bool,
9188 param_src: LazySrcLoc,
9189 cc: std.builtin.CallingConvention,
9190) CompileError!void {
9191 const pt = sema.pt;
9192 const zcu = pt.zcu;
9193 const target = zcu.getTarget();
9194
9195 if (!param_ty.isValidParamType(zcu)) {
9196 const opaque_str = if (param_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else "";
9197 return sema.fail(block, param_src, "parameter of {s}type '{f}' not allowed", .{
9198 opaque_str, param_ty.fmt(pt),
9199 });
9200 }
9201 if (!param_ty.isGenericPoison() and
9202 !target_util.fnCallConvAllowsZigTypes(cc) and
9203 !try sema.validateExternType(param_ty, .param_ty))
9204 {
9205 return sema.failWithOwnedErrorMsg(block, msg: {
9206 const msg = try sema.errMsg(param_src, "parameter of type '{f}' not allowed in function with calling convention '{s}'", .{
9207 param_ty.fmt(pt), @tagName(cc),
9208 });
9209 errdefer msg.destroy(sema.gpa);
9210
9211 try sema.explainWhyTypeIsNotExtern(msg, param_src, param_ty, .param_ty);
9212
9213 try sema.addDeclaredHereNote(msg, param_ty);
9214 break :msg msg;
9215 });
9216 }
9217 switch (cc) {
9218 .x86_64_interrupt, .x86_interrupt => {
9219 const err_code_size = target.ptrBitWidth();
9220 switch (param_idx) {
9221 0 => if (param_ty.zigTypeTag(zcu) != .pointer) return sema.fail(block, param_src, "first parameter of function with '{s}' calling convention must be a pointer type", .{@tagName(cc)}),
9222 1 => if (param_ty.bitSize(zcu) != err_code_size) return sema.fail(block, param_src, "second parameter of function with '{s}' calling convention must be a {d}-bit integer", .{ @tagName(cc), err_code_size }),
9223 else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc), param_idx + 1 }),
9224 }
9225 },
9226 .arc_interrupt,
9227 .arm_interrupt,
9228 .microblaze_interrupt,
9229 .mips64_interrupt,
9230 .mips_interrupt,
9231 .riscv64_interrupt,
9232 .riscv32_interrupt,
9233 .sh_interrupt,
9234 .avr_interrupt,
9235 .csky_interrupt,
9236 .m68k_interrupt,
9237 .msp430_interrupt,
9238 .avr_signal,
9239 => return sema.fail(block, param_src, "parameters are not allowed with '{s}' calling convention", .{@tagName(cc)}),
9240 else => {},
9241 }
9242 if (param_is_noalias and !param_ty.isGenericPoison() and !param_ty.isPtrAtRuntime(zcu) and !param_ty.isSliceAtRuntime(zcu)) {
9243 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});
9244 }
9245}
9246
9247fn checkReturnTypeAndCallConvCommon(
9248 sema: *Sema,
9249 block: *Block,
9250 bare_ret_ty: Type,
9251 ret_ty_src: LazySrcLoc,
9252 @"callconv": std.builtin.CallingConvention,
9253 callconv_src: LazySrcLoc,
9254 /// non-`null` only if the function is varargs.
9255 opt_varargs_src: ?LazySrcLoc,
9256 inferred_error_set: bool,
9257 is_noinline: bool,
9258) CompileError!void {
9259 const pt = sema.pt;
9260 const zcu = pt.zcu;
9261 const gpa = zcu.gpa;
9262 if (opt_varargs_src) |varargs_src| {
9263 try sema.checkCallConvSupportsVarArgs(block, varargs_src, @"callconv");
9264 }
9265 if (inferred_error_set and !bare_ret_ty.isGenericPoison()) {
9266 try sema.validateErrorUnionPayloadType(block, bare_ret_ty, ret_ty_src);
9267 }
9268 const ies_ret_ty_prefix: []const u8 = if (inferred_error_set) "!" else "";
9269 if (!bare_ret_ty.isValidReturnType(zcu)) {
9270 const opaque_str = if (bare_ret_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else "";
9271 return sema.fail(block, ret_ty_src, "{s}return type '{s}{f}' not allowed", .{
9272 opaque_str, ies_ret_ty_prefix, bare_ret_ty.fmt(pt),
9273 });
9274 }
9275 if (!bare_ret_ty.isGenericPoison() and
9276 !target_util.fnCallConvAllowsZigTypes(@"callconv") and
9277 (inferred_error_set or !try sema.validateExternType(bare_ret_ty, .ret_ty)))
9278 {
9279 return sema.failWithOwnedErrorMsg(block, msg: {
9280 const msg = try sema.errMsg(ret_ty_src, "return type '{s}{f}' not allowed in function with calling convention '{s}'", .{
9281 ies_ret_ty_prefix, bare_ret_ty.fmt(pt), @tagName(@"callconv"),
9282 });
9283 errdefer msg.destroy(gpa);
9284 if (!inferred_error_set) {
9285 try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src, bare_ret_ty, .ret_ty);
9286 try sema.addDeclaredHereNote(msg, bare_ret_ty);
9287 }
9288 break :msg msg;
9289 });
9290 }
9291 validate_incoming_stack_align: {
9292 const a: u64 = switch (@"callconv") {
9293 inline else => |payload| if (@TypeOf(payload) != void and @hasField(@TypeOf(payload), "incoming_stack_alignment"))
9294 payload.incoming_stack_alignment orelse break :validate_incoming_stack_align
9295 else
9296 break :validate_incoming_stack_align,
9297 };
9298 if (!std.math.isPowerOfTwo(a)) {
9299 return sema.fail(block, callconv_src, "calling convention incoming stack alignment '{d}' is not a power of two", .{a});
9300 }
9301 }
9302 switch (@"callconv") {
9303 .x86_64_interrupt,
9304 .x86_interrupt,
9305 .arm_interrupt,
9306 .mips64_interrupt,
9307 .mips_interrupt,
9308 .riscv64_interrupt,
9309 .riscv32_interrupt,
9310 .sh_interrupt,
9311 .arc_interrupt,
9312 .avr_interrupt,
9313 .csky_interrupt,
9314 .m68k_interrupt,
9315 .microblaze_interrupt,
9316 .msp430_interrupt,
9317 .avr_signal,
9318 => {
9319 const ret_ok = !inferred_error_set and switch (bare_ret_ty.toIntern()) {
9320 .void_type, .noreturn_type => true,
9321 else => false,
9322 };
9323 if (!ret_ok) {
9324 return sema.fail(block, ret_ty_src, "function with calling convention '{s}' must return 'void' or 'noreturn'", .{@tagName(@"callconv")});
9325 }
9326 },
9327 .@"inline" => if (is_noinline) {
9328 return sema.fail(block, callconv_src, "'noinline' function cannot have calling convention 'inline'", .{});
9329 },
9330 else => {},
9331 }
9332 switch (zcu.callconvSupported(@"callconv")) {
9333 .ok => {},
9334 .bad_arch => |allowed_archs| {
9335 const ArchListFormatter = struct {
9336 archs: []const std.Target.Cpu.Arch,
9337 pub fn format(formatter: @This(), w: *std.Io.Writer) std.Io.Writer.Error!void {
9338 for (formatter.archs, 0..) |arch, i| {
9339 if (i != 0)
9340 try w.writeAll(", ");
9341 try w.print("'{s}'", .{@tagName(arch)});
9342 }
9343 }
9344 };
9345 return sema.fail(block, callconv_src, "calling convention '{s}' only available on architectures {f}", .{
9346 @tagName(@"callconv"),
9347 ArchListFormatter{ .archs = allowed_archs },
9348 });
9349 },
9350 .bad_backend => |bad_backend| return sema.fail(block, callconv_src, "calling convention '{s}' not supported by compiler backend '{s}'", .{
9351 @tagName(@"callconv"),
9352 @tagName(bad_backend),
9353 }),
9354 }
9355}
9356
91749357fn callConvIsCallable(cc: std.builtin.CallingConvention.Tag) bool {
91759358 return switch (cc) {
91769359 .naked,
......@@ -9259,7 +9442,6 @@ fn funcCommon(
92599442 const pt = sema.pt;
92609443 const zcu = pt.zcu;
92619444 const gpa = sema.gpa;
9262 const target = zcu.getTarget();
92639445 const ip = &zcu.intern_pool;
92649446 const ret_ty_src = block.src(.{ .node_offset_fn_type_ret_ty = src_node_offset });
92659447 const cc_src = block.src(.{ .node_offset_fn_type_cc = src_node_offset });
......@@ -9293,26 +9475,14 @@ fn funcCommon(
92939475 if (param_ty_generic and !target_util.fnCallConvAllowsZigTypes(cc)) {
92949476 return sema.fail(block, param_src, "generic parameters not allowed in function with calling convention '{s}'", .{@tagName(cc)});
92959477 }
9296 if (!param_ty.isValidParamType(zcu)) {
9297 const opaque_str = if (param_ty.zigTypeTag(zcu) == .@"opaque") "opaque " else "";
9298 return sema.fail(block, param_src, "parameter of {s}type '{f}' not allowed", .{
9299 opaque_str, param_ty.fmt(pt),
9300 });
9301 }
9302 if (!param_ty_generic and !target_util.fnCallConvAllowsZigTypes(cc) and !try sema.validateExternType(param_ty, .param_ty)) {
9303 const msg = msg: {
9304 const msg = try sema.errMsg(param_src, "parameter of type '{f}' not allowed in function with calling convention '{s}'", .{
9305 param_ty.fmt(pt), @tagName(cc),
9306 });
9307 errdefer msg.destroy(sema.gpa);
9308
9309 try sema.explainWhyTypeIsNotExtern(msg, param_src, param_ty, .param_ty);
9310
9311 try sema.addDeclaredHereNote(msg, param_ty);
9312 break :msg msg;
9313 };
9314 return sema.failWithOwnedErrorMsg(block, msg);
9315 }
9478 try sema.checkParamTypeCommon(
9479 block,
9480 @intCast(i),
9481 param_ty,
9482 is_noalias,
9483 param_src,
9484 cc,
9485 );
93169486 if (param_ty_comptime and !param_is_comptime and has_body and !block.isComptime()) {
93179487 const msg = msg: {
93189488 const msg = try sema.errMsg(param_src, "parameter of type '{f}' must be declared comptime", .{
......@@ -9327,209 +9497,40 @@ fn funcCommon(
93279497 };
93289498 return sema.failWithOwnedErrorMsg(block, msg);
93299499 }
9330 if (!param_ty_generic and is_noalias and
9331 !(param_ty.zigTypeTag(zcu) == .pointer or param_ty.isPtrLikeOptional(zcu)))
9332 {
9333 return sema.fail(block, param_src, "non-pointer parameter declared noalias", .{});
9334 }
9335 switch (cc) {
9336 .x86_64_interrupt, .x86_interrupt => {
9337 const err_code_size = target.ptrBitWidth();
9338 switch (i) {
9339 0 => if (param_ty.zigTypeTag(zcu) != .pointer) return sema.fail(block, param_src, "first parameter of function with '{s}' calling convention must be a pointer type", .{@tagName(cc)}),
9340 1 => if (param_ty.bitSize(zcu) != err_code_size) return sema.fail(block, param_src, "second parameter of function with '{s}' calling convention must be a {d}-bit integer", .{ @tagName(cc), err_code_size }),
9341 else => return sema.fail(block, param_src, "'{s}' calling convention supports up to 2 parameters, found {d}", .{ @tagName(cc), i + 1 }),
9342 }
9343 },
9344 .arc_interrupt,
9345 .arm_interrupt,
9346 .microblaze_interrupt,
9347 .mips64_interrupt,
9348 .mips_interrupt,
9349 .riscv64_interrupt,
9350 .riscv32_interrupt,
9351 .sh_interrupt,
9352 .avr_interrupt,
9353 .csky_interrupt,
9354 .m68k_interrupt,
9355 .msp430_interrupt,
9356 .avr_signal,
9357 => return sema.fail(block, param_src, "parameters are not allowed with '{s}' calling convention", .{@tagName(cc)}),
9358 else => {},
9359 }
9360 }
9361
9362 if (var_args) {
9363 if (is_generic) {
9364 return sema.fail(block, func_src, "generic function cannot be variadic", .{});
9365 }
9366 const va_args_src = block.src(.{
9367 .fn_proto_param = .{
9368 .fn_proto_node_offset = src_node_offset,
9369 .param_index = @intCast(block.params.len), // va_arg must be the last parameter
9370 },
9371 });
9372 try sema.checkCallConvSupportsVarArgs(block, va_args_src, cc);
9373 }
9374
9375 const ret_poison = bare_return_type.isGenericPoison();
9376
9377 const param_types = block.params.items(.ty);
9378
9379 if (inferred_error_set) {
9380 assert(has_body);
9381 if (!ret_poison)
9382 try sema.validateErrorUnionPayloadType(block, bare_return_type, ret_ty_src);
9383 const func_index = try ip.getFuncDeclIes(gpa, pt.tid, .{
9384 .owner_nav = sema.owner.unwrap().nav_val,
9385
9386 .param_types = param_types,
9387 .noalias_bits = noalias_bits,
9388 .comptime_bits = comptime_bits,
9389 .bare_return_type = bare_return_type.toIntern(),
9390 .cc = cc,
9391 .is_var_args = var_args,
9392 .is_generic = is_generic,
9393 .is_noinline = is_noinline,
9394
9395 .zir_body_inst = try block.trackZir(func_inst),
9396 .lbrace_line = src_locs.lbrace_line,
9397 .rbrace_line = src_locs.rbrace_line,
9398 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
9399 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
9400 });
9401 return finishFunc(
9402 sema,
9403 block,
9404 func_index,
9405 .none,
9406 ret_poison,
9407 bare_return_type,
9408 ret_ty_src,
9409 cc,
9410 ret_ty_requires_comptime,
9411 func_inst,
9412 cc_src,
9413 is_noinline,
9414 );
94159500 }
94169501
9417 const func_ty = try ip.getFuncType(gpa, pt.tid, .{
9418 .param_types = param_types,
9419 .noalias_bits = noalias_bits,
9420 .comptime_bits = comptime_bits,
9421 .return_type = bare_return_type.toIntern(),
9422 .cc = cc,
9423 .is_var_args = var_args,
9424 .is_generic = is_generic,
9425 .is_noinline = is_noinline,
9426 });
9427
9428 if (has_body) {
9429 const func_index = try ip.getFuncDecl(gpa, pt.tid, .{
9430 .owner_nav = sema.owner.unwrap().nav_val,
9431 .ty = func_ty,
9432 .cc = cc,
9433 .is_noinline = is_noinline,
9434 .zir_body_inst = try block.trackZir(func_inst),
9435 .lbrace_line = src_locs.lbrace_line,
9436 .rbrace_line = src_locs.rbrace_line,
9437 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
9438 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
9439 });
9440 return finishFunc(
9441 sema,
9442 block,
9443 func_index,
9444 func_ty,
9445 ret_poison,
9446 bare_return_type,
9447 ret_ty_src,
9448 cc,
9449 ret_ty_requires_comptime,
9450 func_inst,
9451 cc_src,
9452 is_noinline,
9453 );
9502 if (var_args and is_generic) {
9503 return sema.fail(block, func_src, "generic function cannot be variadic", .{});
94549504 }
94559505
9456 return finishFunc(
9457 sema,
9506 try sema.checkReturnTypeAndCallConvCommon(
94589507 block,
9459 .none,
9460 func_ty,
9461 ret_poison,
94629508 bare_return_type,
94639509 ret_ty_src,
94649510 cc,
9465 ret_ty_requires_comptime,
9466 func_inst,
94679511 cc_src,
9512 if (var_args) block.src(.{ .fn_proto_param = .{
9513 .fn_proto_node_offset = src_node_offset,
9514 .param_index = @intCast(block.params.len),
9515 } }) else null,
9516 inferred_error_set,
94689517 is_noinline,
94699518 );
9470}
9471
9472fn finishFunc(
9473 sema: *Sema,
9474 block: *Block,
9475 opt_func_index: InternPool.Index,
9476 func_ty: InternPool.Index,
9477 ret_poison: bool,
9478 bare_return_type: Type,
9479 ret_ty_src: LazySrcLoc,
9480 cc_resolved: std.builtin.CallingConvention,
9481 ret_ty_requires_comptime: bool,
9482 func_inst: Zir.Inst.Index,
9483 cc_src: LazySrcLoc,
9484 is_noinline: bool,
9485) CompileError!Air.Inst.Ref {
9486 const pt = sema.pt;
9487 const zcu = pt.zcu;
9488 const ip = &zcu.intern_pool;
9489 const gpa = sema.gpa;
9490
9491 const return_type: Type = if (opt_func_index == .none or ret_poison)
9492 bare_return_type
9493 else
9494 .fromInterned(ip.funcTypeReturnType(ip.typeOf(opt_func_index)));
9495
9496 if (!return_type.isValidReturnType(zcu)) {
9497 const opaque_str = if (return_type.zigTypeTag(zcu) == .@"opaque") "opaque " else "";
9498 return sema.fail(block, ret_ty_src, "{s}return type '{f}' not allowed", .{
9499 opaque_str, return_type.fmt(pt),
9500 });
9501 }
9502 if (!ret_poison and !target_util.fnCallConvAllowsZigTypes(cc_resolved) and
9503 !try sema.validateExternType(return_type, .ret_ty))
9504 {
9505 const msg = msg: {
9506 const msg = try sema.errMsg(ret_ty_src, "return type '{f}' not allowed in function with calling convention '{s}'", .{
9507 return_type.fmt(pt), @tagName(cc_resolved),
9508 });
9509 errdefer msg.destroy(gpa);
9510
9511 try sema.explainWhyTypeIsNotExtern(msg, ret_ty_src, return_type, .ret_ty);
9512
9513 try sema.addDeclaredHereNote(msg, return_type);
9514 break :msg msg;
9515 };
9516 return sema.failWithOwnedErrorMsg(block, msg);
9517 }
95189519
95199520 // If the return type is comptime-only but not dependent on parameters then
95209521 // all parameter types also need to be comptime.
9521 if (opt_func_index != .none and ret_ty_requires_comptime and !block.isComptime()) comptime_check: {
9522 if (has_body and ret_ty_requires_comptime and !block.isComptime()) comptime_check: {
95229523 for (block.params.items(.is_comptime)) |is_comptime| {
95239524 if (!is_comptime) break;
95249525 } else break :comptime_check;
9525
9526 const ies_ret_ty_prefix: []const u8 = if (inferred_error_set) "!" else "";
95269527 const msg = try sema.errMsg(
95279528 ret_ty_src,
9528 "function with comptime-only return type '{f}' requires all parameters to be comptime",
9529 .{return_type.fmt(pt)},
9529 "function with comptime-only return type '{s}{f}' requires all parameters to be comptime",
9530 .{ ies_ret_ty_prefix, bare_return_type.fmt(pt) },
95309531 );
95319532 errdefer msg.destroy(sema.gpa);
9532 try sema.explainWhyTypeIsComptime(msg, ret_ty_src, return_type);
9533 try sema.explainWhyTypeIsComptime(msg, ret_ty_src, bare_return_type);
95339534
95349535 const tags = sema.code.instructions.items(.tag);
95359536 const data = sema.code.instructions.items(.data);
......@@ -9556,68 +9557,56 @@ fn finishFunc(
95569557 return sema.failWithOwnedErrorMsg(block, msg);
95579558 }
95589559
9559 validate_incoming_stack_align: {
9560 const a: u64 = switch (cc_resolved) {
9561 inline else => |payload| if (@TypeOf(payload) != void and @hasField(@TypeOf(payload), "incoming_stack_alignment"))
9562 payload.incoming_stack_alignment orelse break :validate_incoming_stack_align
9563 else
9564 break :validate_incoming_stack_align,
9565 };
9566 if (!std.math.isPowerOfTwo(a)) {
9567 return sema.fail(block, cc_src, "calling convention incoming stack alignment '{d}' is not a power of two", .{a});
9568 }
9569 }
9560 const param_types = block.params.items(.ty);
95709561
9571 switch (cc_resolved) {
9572 .x86_64_interrupt,
9573 .x86_interrupt,
9574 .arm_interrupt,
9575 .mips64_interrupt,
9576 .mips_interrupt,
9577 .riscv64_interrupt,
9578 .riscv32_interrupt,
9579 .sh_interrupt,
9580 .arc_interrupt,
9581 .avr_interrupt,
9582 .csky_interrupt,
9583 .m68k_interrupt,
9584 .microblaze_interrupt,
9585 .msp430_interrupt,
9586 .avr_signal,
9587 => if (return_type.zigTypeTag(zcu) != .void and return_type.zigTypeTag(zcu) != .noreturn) {
9588 return sema.fail(block, ret_ty_src, "function with calling convention '{s}' must return 'void' or 'noreturn'", .{@tagName(cc_resolved)});
9589 },
9590 .@"inline" => if (is_noinline) {
9591 return sema.fail(block, cc_src, "'noinline' function cannot have calling convention 'inline'", .{});
9592 },
9593 else => {},
9562 if (inferred_error_set) {
9563 assert(has_body);
9564 return .fromIntern(try ip.getFuncDeclIes(gpa, pt.tid, .{
9565 .owner_nav = sema.owner.unwrap().nav_val,
9566
9567 .param_types = param_types,
9568 .noalias_bits = noalias_bits,
9569 .comptime_bits = comptime_bits,
9570 .bare_return_type = bare_return_type.toIntern(),
9571 .cc = cc,
9572 .is_var_args = var_args,
9573 .is_generic = is_generic,
9574 .is_noinline = is_noinline,
9575
9576 .zir_body_inst = try block.trackZir(func_inst),
9577 .lbrace_line = src_locs.lbrace_line,
9578 .rbrace_line = src_locs.rbrace_line,
9579 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
9580 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
9581 }));
95949582 }
95959583
9596 switch (zcu.callconvSupported(cc_resolved)) {
9597 .ok => {},
9598 .bad_arch => |allowed_archs| {
9599 const ArchListFormatter = struct {
9600 archs: []const std.Target.Cpu.Arch,
9601 pub fn format(formatter: @This(), w: *std.Io.Writer) std.Io.Writer.Error!void {
9602 for (formatter.archs, 0..) |arch, i| {
9603 if (i != 0)
9604 try w.writeAll(", ");
9605 try w.print("'{s}'", .{@tagName(arch)});
9606 }
9607 }
9608 };
9609 return sema.fail(block, cc_src, "calling convention '{s}' only available on architectures {f}", .{
9610 @tagName(cc_resolved),
9611 ArchListFormatter{ .archs = allowed_archs },
9612 });
9613 },
9614 .bad_backend => |bad_backend| return sema.fail(block, cc_src, "calling convention '{s}' not supported by compiler backend '{s}'", .{
9615 @tagName(cc_resolved),
9616 @tagName(bad_backend),
9617 }),
9584 const func_ty = try ip.getFuncType(gpa, pt.tid, .{
9585 .param_types = param_types,
9586 .noalias_bits = noalias_bits,
9587 .comptime_bits = comptime_bits,
9588 .return_type = bare_return_type.toIntern(),
9589 .cc = cc,
9590 .is_var_args = var_args,
9591 .is_generic = is_generic,
9592 .is_noinline = is_noinline,
9593 });
9594
9595 if (has_body) {
9596 return .fromIntern(try ip.getFuncDecl(gpa, pt.tid, .{
9597 .owner_nav = sema.owner.unwrap().nav_val,
9598 .ty = func_ty,
9599 .cc = cc,
9600 .is_noinline = is_noinline,
9601 .zir_body_inst = try block.trackZir(func_inst),
9602 .lbrace_line = src_locs.lbrace_line,
9603 .rbrace_line = src_locs.rbrace_line,
9604 .lbrace_column = @as(u16, @truncate(src_locs.columns)),
9605 .rbrace_column = @as(u16, @truncate(src_locs.columns >> 16)),
9606 }));
96189607 }
96199608
9620 return Air.internedToRef(if (opt_func_index != .none) opt_func_index else func_ty);
9609 return .fromIntern(func_ty);
96219610}
96229611
96239612fn zirParam(
......@@ -19395,7 +19384,7 @@ fn zirUnionInit(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
1939519384 if (union_ty.zigTypeTag(pt.zcu) != .@"union") {
1939619385 return sema.fail(block, ty_src, "expected union type, found '{f}'", .{union_ty.fmt(pt)});
1939719386 }
19398 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ .simple = .union_field_name });
19387 const field_name = try sema.resolveConstStringIntern(block, field_src, extra.field_name, .{ .simple = .union_field_names });
1939919388 const init = try sema.resolveInst(extra.init);
1940019389 return sema.unionInit(block, init, init_src, union_ty, ty_src, field_name, field_src);
1940119390}
......@@ -20553,589 +20542,529 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air
2055320542 return block.addUnOp(.tag_name, casted_operand);
2055420543}
2055520544
20556fn zirReify(
20545fn zirReifyInt(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air.Inst.Ref {
20546 const inst_data = sema.code.instructions.items(.data)[@intFromEnum(inst)].pl_node;
20547 const signedness_src = block.builtinCallArgSrc(inst_data.src_node, 0);
20548 const bits_src = block.builtinCallArgSrc(inst_data.src_node, 1);
20549 const extra = sema.code.extraData(Zir.Inst.Bin, inst_data.payload_index).data;
20550 const signedness = try sema.resolveBuiltinEnum(block, signedness_src, extra.lhs, .Signedness, .{ .simple = .int_signedness });
20551 const bits: u16 = @intCast(try sema.resolveInt(block, bits_src, extra.rhs, .u16, .{ .simple = .int_bit_width }));
20552 return .fromType(try sema.pt.intType(signedness, bits));
20553}
20554
20555fn zirReifySliceArgTy(
2055720556 sema: *Sema,
2055820557 block: *Block,
2055920558 extended: Zir.Inst.Extended.InstData,
20560 inst: Zir.Inst.Index,
2056120559) CompileError!Air.Inst.Ref {
2056220560 const pt = sema.pt;
2056320561 const zcu = pt.zcu;
20564 const gpa = sema.gpa;
20565 const ip = &zcu.intern_pool;
20566 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
20567 const extra = sema.code.extraData(Zir.Inst.Reify, extended.operand).data;
20568 const tracked_inst = try block.trackZir(inst);
20569 const src: LazySrcLoc = .{
20570 .base_node_inst = tracked_inst,
20571 .offset = LazySrcLoc.Offset.nodeOffset(.zero),
20572 };
20573 const operand_src: LazySrcLoc = .{
20574 .base_node_inst = tracked_inst,
20575 .offset = .{
20576 .node_offset_builtin_call_arg = .{
20577 .builtin_call_node = .zero, // `tracked_inst` is precisely the `reify` instruction, so offset is 0
20578 .arg_index = 0,
20579 },
20580 },
20562
20563 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
20564 const info: Zir.Inst.ReifySliceArgInfo = @enumFromInt(extended.small);
20565
20566 const src = block.nodeOffset(extra.node);
20567
20568 const comptime_reason: std.zig.SimpleComptimeReason, const in_scalar_ty: Type, const out_scalar_ty: Type = switch (info) {
20569 // zig fmt: off
20570 .type_to_fn_param_attrs => .{ .fn_param_attrs, .type, try sema.getBuiltinType(src, .@"Type.Fn.Param.Attributes") },
20571 .string_to_struct_field_type => .{ .struct_field_types, .slice_const_u8, .type },
20572 .string_to_union_field_type => .{ .union_field_types, .slice_const_u8, .type },
20573 .string_to_struct_field_attrs => .{ .struct_field_attrs, .slice_const_u8, try sema.getBuiltinType(src, .@"Type.StructField.Attributes") },
20574 .string_to_union_field_attrs => .{ .union_field_attrs, .slice_const_u8, try sema.getBuiltinType(src, .@"Type.UnionField.Attributes") },
20575 // zig fmt: on
2058120576 };
20582 const type_info_ty = try sema.getBuiltinType(src, .Type);
20583 const uncasted_operand = try sema.resolveInst(extra.operand);
20584 const type_info = try sema.coerce(block, type_info_ty, uncasted_operand, operand_src);
20585 const val = try sema.resolveConstDefinedValue(block, operand_src, type_info, .{ .simple = .operand_Type });
20586 const union_val = ip.indexToKey(val.toIntern()).un;
20587 if (try sema.anyUndef(block, operand_src, Value.fromInterned(union_val.val))) {
20588 return sema.failWithUseOfUndef(block, operand_src, null);
20589 }
20590 const tag_index = type_info_ty.unionTagFieldIndex(Value.fromInterned(union_val.tag), zcu).?;
20591 switch (@as(std.builtin.TypeId, @enumFromInt(tag_index))) {
20592 .type => return .type_type,
20593 .void => return .void_type,
20594 .bool => return .bool_type,
20595 .noreturn => return .noreturn_type,
20596 .comptime_float => return .comptime_float_type,
20597 .comptime_int => return .comptime_int_type,
20598 .undefined => return .undefined_type,
20599 .null => return .null_type,
20600 .@"anyframe" => return sema.failWithUseOfAsync(block, src),
20601 .enum_literal => return .enum_literal_type,
20602 .int => {
20603 const int = try sema.interpretBuiltinType(block, operand_src, .fromInterned(union_val.val), std.builtin.Type.Int);
20604 const ty = try pt.intType(int.signedness, int.bits);
20605 return Air.internedToRef(ty.toIntern());
20606 },
20607 .vector => {
20608 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
20609 const len_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20610 ip,
20611 try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls),
20612 ).?);
20613 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20614 ip,
20615 try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
20616 ).?);
20617
20618 const len: u32 = @intCast(try len_val.toUnsignedIntSema(pt));
20619 const child_ty = child_val.toType();
20620
20621 try sema.checkVectorElemType(block, src, child_ty);
20622
20623 const ty = try pt.vectorType(.{
20624 .len = len,
20625 .child = child_ty.toIntern(),
20626 });
20627 return Air.internedToRef(ty.toIntern());
20628 },
20629 .float => {
20630 const float = try sema.interpretBuiltinType(block, operand_src, .fromInterned(union_val.val), std.builtin.Type.Float);
20631
20632 const ty: Type = switch (float.bits) {
20633 16 => .f16,
20634 32 => .f32,
20635 64 => .f64,
20636 80 => .f80,
20637 128 => .f128,
20638 else => return sema.fail(block, src, "{d}-bit float unsupported", .{float.bits}),
20639 };
20640 return Air.internedToRef(ty.toIntern());
20641 },
20642 .pointer => {
20643 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
20644 const size_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20645 ip,
20646 try ip.getOrPutString(gpa, pt.tid, "size", .no_embedded_nulls),
20647 ).?);
20648 const is_const_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20649 ip,
20650 try ip.getOrPutString(gpa, pt.tid, "is_const", .no_embedded_nulls),
20651 ).?);
20652 const is_volatile_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20653 ip,
20654 try ip.getOrPutString(gpa, pt.tid, "is_volatile", .no_embedded_nulls),
20655 ).?);
20656 const alignment_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20657 ip,
20658 try ip.getOrPutString(gpa, pt.tid, "alignment", .no_embedded_nulls),
20659 ).?);
20660 const address_space_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20661 ip,
20662 try ip.getOrPutString(gpa, pt.tid, "address_space", .no_embedded_nulls),
20663 ).?);
20664 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20665 ip,
20666 try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
20667 ).?);
20668 const is_allowzero_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20669 ip,
20670 try ip.getOrPutString(gpa, pt.tid, "is_allowzero", .no_embedded_nulls),
20671 ).?);
20672 const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20673 ip,
20674 try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls),
20675 ).?);
20676
20677 if (!try sema.intFitsInType(alignment_val, align_ty, null)) {
20678 return sema.fail(block, src, "alignment must fit in '{f}'", .{align_ty.fmt(pt)});
20679 }
20680 const alignment_val_int = try alignment_val.toUnsignedIntSema(pt);
20681 const abi_align = try sema.validateAlign(block, src, alignment_val_int);
20682
20683 const elem_ty = child_val.toType();
20684 if (abi_align != .none) {
20685 try elem_ty.resolveLayout(pt);
20686 }
20687
20688 const ptr_size = try sema.interpretBuiltinType(block, operand_src, size_val, std.builtin.Type.Pointer.Size);
20689
20690 const actual_sentinel: InternPool.Index = s: {
20691 if (!sentinel_val.isNull(zcu)) {
20692 if (ptr_size == .one or ptr_size == .c) {
20693 return sema.fail(block, src, "sentinels are only allowed on slices and unknown-length pointers", .{});
20694 }
20695 const sentinel_ptr_val = sentinel_val.optionalValue(zcu).?;
20696 const ptr_ty = try pt.singleMutPtrType(elem_ty);
20697 const sent_val = (try sema.pointerDeref(block, src, sentinel_ptr_val, ptr_ty)).?;
20698 try sema.checkSentinelType(block, src, elem_ty);
20699 if (sent_val.canMutateComptimeVarState(zcu)) {
20700 const sentinel_name = try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls);
20701 return sema.failWithContainsReferenceToComptimeVar(block, src, sentinel_name, "sentinel", sent_val);
20702 }
20703 break :s sent_val.toIntern();
20704 }
20705 break :s .none;
20706 };
2070720577
20708 if (elem_ty.zigTypeTag(zcu) == .noreturn) {
20709 return sema.fail(block, src, "pointer to noreturn not allowed", .{});
20710 } else if (elem_ty.zigTypeTag(zcu) == .@"fn") {
20711 if (ptr_size != .one) {
20712 return sema.fail(block, src, "function pointers must be single pointers", .{});
20713 }
20714 } else if (ptr_size != .one and elem_ty.zigTypeTag(zcu) == .@"opaque") {
20715 return sema.fail(block, src, "indexable pointer to opaque type '{f}' not allowed", .{elem_ty.fmt(pt)});
20716 } else if (ptr_size == .c) {
20717 if (!try sema.validateExternType(elem_ty, .other)) {
20718 const msg = msg: {
20719 const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{f}'", .{elem_ty.fmt(pt)});
20720 errdefer msg.destroy(gpa);
20578 const operand_ty = try pt.ptrTypeSema(.{
20579 .child = in_scalar_ty.toIntern(),
20580 .flags = .{ .size = .slice, .is_const = true },
20581 });
2072120582
20722 try sema.explainWhyTypeIsNotExtern(msg, src, elem_ty, .other);
20583 const operand_uncoerced = try sema.resolveInst(extra.operand);
20584 const operand_coerced = try sema.coerce(block, operand_ty, operand_uncoerced, src);
20585 const operand_val = try sema.resolveConstDefinedValue(block, src, operand_coerced, .{ .simple = comptime_reason });
20586 const len_val: Value = .fromInterned(zcu.intern_pool.indexToKey(operand_val.toIntern()).slice.len);
20587 if (len_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, src, null);
20588 const len = try len_val.toUnsignedIntSema(pt);
2072320589
20724 try sema.addDeclaredHereNote(msg, elem_ty);
20725 break :msg msg;
20726 };
20727 return sema.failWithOwnedErrorMsg(block, msg);
20728 }
20729 }
20590 return .fromType(try pt.singleConstPtrType(try pt.arrayType(.{
20591 .len = len,
20592 .child = out_scalar_ty.toIntern(),
20593 })));
20594}
2073020595
20731 const ty = try pt.ptrTypeSema(.{
20732 .child = elem_ty.toIntern(),
20733 .sentinel = actual_sentinel,
20734 .flags = .{
20735 .size = ptr_size,
20736 .is_const = is_const_val.toBool(),
20737 .is_volatile = is_volatile_val.toBool(),
20738 .alignment = abi_align,
20739 .address_space = try sema.interpretBuiltinType(block, operand_src, address_space_val, std.builtin.AddressSpace),
20740 .is_allowzero = is_allowzero_val.toBool(),
20741 },
20742 });
20743 return Air.internedToRef(ty.toIntern());
20744 },
20745 .array => {
20746 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
20747 const len_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20748 ip,
20749 try ip.getOrPutString(gpa, pt.tid, "len", .no_embedded_nulls),
20750 ).?);
20751 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20752 ip,
20753 try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
20754 ).?);
20755 const sentinel_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20756 ip,
20757 try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls),
20758 ).?);
20759
20760 const len = try len_val.toUnsignedIntSema(pt);
20761 const child_ty = child_val.toType();
20762 const sentinel = if (sentinel_val.optionalValue(zcu)) |p| blk: {
20763 const ptr_ty = try pt.singleMutPtrType(child_ty);
20764 try sema.checkSentinelType(block, src, child_ty);
20765 const sentinel = (try sema.pointerDeref(block, src, p, ptr_ty)).?;
20766 if (sentinel.canMutateComptimeVarState(zcu)) {
20767 const sentinel_name = try ip.getOrPutString(gpa, pt.tid, "sentinel_ptr", .no_embedded_nulls);
20768 return sema.failWithContainsReferenceToComptimeVar(block, src, sentinel_name, "sentinel", sentinel);
20769 }
20770 break :blk sentinel;
20771 } else null;
20772
20773 const ty = try pt.arrayType(.{
20774 .len = len,
20775 .sentinel = if (sentinel) |s| s.toIntern() else .none,
20776 .child = child_ty.toIntern(),
20777 });
20778 return Air.internedToRef(ty.toIntern());
20779 },
20780 .optional => {
20781 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
20782 const child_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20783 ip,
20784 try ip.getOrPutString(gpa, pt.tid, "child", .no_embedded_nulls),
20785 ).?);
20596fn zirReifyEnumValueSliceTy(
20597 sema: *Sema,
20598 block: *Block,
20599 extended: Zir.Inst.Extended.InstData,
20600) CompileError!Air.Inst.Ref {
20601 const pt = sema.pt;
20602 const zcu = pt.zcu;
2078620603
20787 const child_ty = child_val.toType();
20604 const extra = sema.code.extraData(Zir.Inst.BinNode, extended.operand).data;
2078820605
20789 const ty = try pt.optionalType(child_ty.toIntern());
20790 return Air.internedToRef(ty.toIntern());
20791 },
20792 .error_union => {
20793 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
20794 const error_set_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20795 ip,
20796 try ip.getOrPutString(gpa, pt.tid, "error_set", .no_embedded_nulls),
20797 ).?);
20798 const payload_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20799 ip,
20800 try ip.getOrPutString(gpa, pt.tid, "payload", .no_embedded_nulls),
20801 ).?);
20606 const int_tag_ty_src = block.builtinCallArgSrc(extra.node, 0);
20607 const field_names_src = block.builtinCallArgSrc(extra.node, 2);
2080220608
20803 const error_set_ty = error_set_val.toType();
20804 const payload_ty = payload_val.toType();
20609 const int_tag_ty = try sema.resolveType(block, int_tag_ty_src, extra.lhs);
2080520610
20806 if (error_set_ty.zigTypeTag(zcu) != .error_set) {
20807 return sema.fail(block, src, "Type.ErrorUnion.error_set must be an error set type", .{});
20808 }
20611 const operand_uncoerced = try sema.resolveInst(extra.rhs);
20612 const operand_coerced = try sema.coerce(block, .slice_const_slice_const_u8, operand_uncoerced, field_names_src);
20613 const operand_val = try sema.resolveConstDefinedValue(block, field_names_src, operand_coerced, .{ .simple = .enum_field_names });
20614 const len_val: Value = .fromInterned(zcu.intern_pool.indexToKey(operand_val.toIntern()).slice.len);
20615 if (len_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, field_names_src, null);
20616 const len = try len_val.toUnsignedIntSema(pt);
2080920617
20810 const ty = try pt.errorUnionType(error_set_ty, payload_ty);
20811 return Air.internedToRef(ty.toIntern());
20812 },
20813 .error_set => {
20814 const payload_val = Value.fromInterned(union_val.val).optionalValue(zcu) orelse
20815 return .anyerror_type;
20618 return .fromType(try pt.singleConstPtrType(try pt.arrayType(.{
20619 .len = len,
20620 .child = int_tag_ty.toIntern(),
20621 })));
20622}
20623
20624fn zirReifyPointerSentinelTy(
20625 sema: *Sema,
20626 block: *Block,
20627 extended: Zir.Inst.Extended.InstData,
20628) CompileError!Air.Inst.Ref {
20629 const pt = sema.pt;
20630 const zcu = pt.zcu;
20631 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
20632 const src = block.nodeOffset(extra.node);
20633 const elem_ty = try sema.resolveType(block, src, extra.operand);
20634 return .fromType(switch (elem_ty.zigTypeTag(zcu)) {
20635 else => try pt.optionalType(elem_ty.toIntern()),
20636 // These types cannot be the child of an optional. To allow reifying pointers to them still,
20637 // we treat the "sentinel" argument to `@Pointer` as `?noreturn` instead of `?T`.
20638 .@"opaque", .null => .optional_noreturn,
20639 });
20640}
2081620641
20817 const names_val = try sema.derefSliceAsArray(block, src, payload_val, .{ .simple = .error_set_contents });
20642fn zirReifyTuple(
20643 sema: *Sema,
20644 block: *Block,
20645 extended: Zir.Inst.Extended.InstData,
20646) CompileError!Air.Inst.Ref {
20647 const pt = sema.pt;
20648 const zcu = pt.zcu;
2081820649
20819 const len = try sema.usizeCast(block, src, names_val.typeOf(zcu).arrayLen(zcu));
20820 var names: InferredErrorSet.NameMap = .{};
20821 try names.ensureUnusedCapacity(sema.arena, len);
20822 for (0..len) |i| {
20823 const elem_val = try names_val.elemValue(pt, i);
20824 const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));
20825 const name_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
20826 ip,
20827 try ip.getOrPutString(gpa, pt.tid, "name", .no_embedded_nulls),
20828 ).?);
20829
20830 const name = try sema.sliceToIpString(block, src, name_val, .{ .simple = .error_set_contents });
20831 _ = try pt.getErrorValue(name);
20832 const gop = names.getOrPutAssumeCapacity(name);
20833 if (gop.found_existing) {
20834 return sema.fail(block, src, "duplicate error '{f}'", .{
20835 name.fmt(ip),
20836 });
20837 }
20838 }
20650 const extra = sema.code.extraData(Zir.Inst.UnNode, extended.operand).data;
20651 const operand_src = block.builtinCallArgSrc(extra.node, 0);
2083920652
20840 const ty = try pt.errorSetFromUnsortedNames(names.keys());
20841 return Air.internedToRef(ty.toIntern());
20842 },
20843 .@"struct" => {
20844 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
20845 const layout_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20846 ip,
20847 try ip.getOrPutString(gpa, pt.tid, "layout", .no_embedded_nulls),
20848 ).?);
20849 const backing_integer_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20850 ip,
20851 try ip.getOrPutString(gpa, pt.tid, "backing_integer", .no_embedded_nulls),
20852 ).?);
20853 const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20854 ip,
20855 try ip.getOrPutString(gpa, pt.tid, "fields", .no_embedded_nulls),
20856 ).?);
20857 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20858 ip,
20859 try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
20860 ).?);
20861 const is_tuple_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20862 ip,
20863 try ip.getOrPutString(gpa, pt.tid, "is_tuple", .no_embedded_nulls),
20864 ).?);
20865
20866 const layout = try sema.interpretBuiltinType(block, operand_src, layout_val, std.builtin.Type.ContainerLayout);
20867
20868 // Decls
20869 if (try decls_val.sliceLen(pt) > 0) {
20870 return sema.fail(block, src, "reified structs must have no decls", .{});
20871 }
20872
20873 if (layout != .@"packed" and !backing_integer_val.isNull(zcu)) {
20874 return sema.fail(block, src, "non-packed struct does not support backing integer type", .{});
20875 }
20876
20877 const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{ .simple = .struct_fields });
20878
20879 if (is_tuple_val.toBool()) {
20880 switch (layout) {
20881 .@"extern" => return sema.fail(block, src, "extern tuples are not supported", .{}),
20882 .@"packed" => return sema.fail(block, src, "packed tuples are not supported", .{}),
20883 .auto => {},
20884 }
20885 return sema.reifyTuple(block, src, fields_arr);
20886 } else {
20887 return sema.reifyStruct(block, inst, src, layout, backing_integer_val, fields_arr, name_strategy);
20888 }
20889 },
20890 .@"enum" => {
20891 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
20892 const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20893 ip,
20894 try ip.getOrPutString(gpa, pt.tid, "tag_type", .no_embedded_nulls),
20895 ).?);
20896 const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20897 ip,
20898 try ip.getOrPutString(gpa, pt.tid, "fields", .no_embedded_nulls),
20899 ).?);
20900 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20901 ip,
20902 try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
20903 ).?);
20904 const is_exhaustive_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20905 ip,
20906 try ip.getOrPutString(gpa, pt.tid, "is_exhaustive", .no_embedded_nulls),
20907 ).?);
20908
20909 if (try decls_val.sliceLen(pt) > 0) {
20910 return sema.fail(block, src, "reified enums must have no decls", .{});
20911 }
20912
20913 const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{ .simple = .enum_fields });
20914
20915 return sema.reifyEnum(block, inst, src, tag_type_val.toType(), is_exhaustive_val.toBool(), fields_arr, name_strategy);
20916 },
20917 .@"opaque" => {
20918 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
20919 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20920 ip,
20921 try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
20922 ).?);
20653 const types_uncoerced = try sema.resolveInst(extra.operand);
20654 const types_coerced = try sema.coerce(block, .slice_const_type, types_uncoerced, operand_src);
20655 const types_slice_val = try sema.resolveConstDefinedValue(block, operand_src, types_coerced, .{ .simple = .tuple_field_types });
20656 const types_array_val = try sema.derefSliceAsArray(block, operand_src, types_slice_val, .{ .simple = .tuple_field_types });
20657 const fields_len: u32 = @intCast(types_array_val.typeOf(zcu).arrayLen(zcu));
2092320658
20924 // Decls
20925 if (try decls_val.sliceLen(pt) > 0) {
20926 return sema.fail(block, src, "reified opaque must have no decls", .{});
20927 }
20659 const field_types = try sema.arena.alloc(InternPool.Index, fields_len);
20660 for (field_types, 0..) |*field_ty, field_idx| {
20661 const field_ty_val = try types_array_val.elemValue(pt, field_idx);
20662 if (field_ty_val.isUndef(zcu)) {
20663 return sema.failWithUseOfUndef(block, operand_src, null);
20664 }
20665 field_ty.* = field_ty_val.toIntern();
20666 }
2092820667
20929 const wip_ty = switch (try ip.getOpaqueType(gpa, pt.tid, .{
20930 .key = .{ .reified = .{
20931 .zir_index = try block.trackZir(inst),
20932 } },
20933 })) {
20934 .existing => |ty| {
20935 try sema.addTypeReferenceEntry(src, ty);
20936 return Air.internedToRef(ty);
20937 },
20938 .wip => |wip| wip,
20939 };
20940 errdefer wip_ty.cancel(ip, pt.tid);
20668 const field_values = try sema.arena.alloc(InternPool.Index, fields_len);
20669 @memset(field_values, .none);
2094120670
20942 const type_name = try sema.createTypeName(
20943 block,
20944 name_strategy,
20945 "opaque",
20946 inst,
20947 wip_ty.index,
20948 );
20949 wip_ty.setName(ip, type_name.name, type_name.nav);
20671 return .fromIntern(try zcu.intern_pool.getTupleType(zcu.gpa, pt.tid, .{
20672 .types = field_types,
20673 .values = field_values,
20674 }));
20675}
2095020676
20951 const new_namespace_index = try pt.createNamespace(.{
20952 .parent = block.namespace.toOptional(),
20953 .owner_type = wip_ty.index,
20954 .file_scope = block.getFileScopeIndex(zcu),
20955 .generation = zcu.generation,
20956 });
20677fn zirReifyPointer(
20678 sema: *Sema,
20679 block: *Block,
20680 extended: Zir.Inst.Extended.InstData,
20681) CompileError!Air.Inst.Ref {
20682 const pt = sema.pt;
20683 const zcu = pt.zcu;
20684 const gpa = zcu.gpa;
20685 const ip = &zcu.intern_pool;
2095720686
20958 try sema.addTypeReferenceEntry(src, wip_ty.index);
20959 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
20960 return Air.internedToRef(wip_ty.finish(ip, new_namespace_index));
20961 },
20962 .@"union" => {
20963 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
20964 const layout_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20965 ip,
20966 try ip.getOrPutString(gpa, pt.tid, "layout", .no_embedded_nulls),
20967 ).?);
20968 const tag_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20969 ip,
20970 try ip.getOrPutString(gpa, pt.tid, "tag_type", .no_embedded_nulls),
20971 ).?);
20972 const fields_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20973 ip,
20974 try ip.getOrPutString(gpa, pt.tid, "fields", .no_embedded_nulls),
20975 ).?);
20976 const decls_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
20977 ip,
20978 try ip.getOrPutString(gpa, pt.tid, "decls", .no_embedded_nulls),
20979 ).?);
20687 const extra = sema.code.extraData(Zir.Inst.ReifyPointer, extended.operand).data;
20688 const src = block.nodeOffset(extra.node);
20689 const size_src = block.builtinCallArgSrc(extra.node, 0);
20690 const attrs_src = block.builtinCallArgSrc(extra.node, 1);
20691 const elem_ty_src = block.builtinCallArgSrc(extra.node, 2);
20692 const sentinel_src = block.builtinCallArgSrc(extra.node, 3);
20693
20694 const size_ty = try sema.getBuiltinType(size_src, .@"Type.Pointer.Size");
20695 const attrs_ty = try sema.getBuiltinType(attrs_src, .@"Type.Pointer.Attributes");
20696
20697 const size_uncoerced = try sema.resolveInst(extra.size);
20698 const size_coerced = try sema.coerce(block, size_ty, size_uncoerced, size_src);
20699 const size_val = try sema.resolveConstDefinedValue(block, size_src, size_coerced, .{ .simple = .pointer_size });
20700 const size = try sema.interpretBuiltinType(block, size_src, size_val, std.builtin.Type.Pointer.Size);
20701
20702 const attrs_uncoerced = try sema.resolveInst(extra.attrs);
20703 const attrs_coerced = try sema.coerce(block, attrs_ty, attrs_uncoerced, attrs_src);
20704 const attrs_val = try sema.resolveConstDefinedValue(block, attrs_src, attrs_coerced, .{ .simple = .pointer_attrs });
20705 const attrs = try sema.interpretBuiltinType(block, attrs_src, attrs_val, std.builtin.Type.Pointer.Attributes);
20706
20707 const @"align": Alignment = if (attrs.@"align") |bytes| a: {
20708 break :a try sema.validateAlign(block, attrs_src, bytes);
20709 } else .none;
2098020710
20981 if (try decls_val.sliceLen(pt) > 0) {
20982 return sema.fail(block, src, "reified unions must have no decls", .{});
20983 }
20984 const layout = try sema.interpretBuiltinType(block, operand_src, layout_val, std.builtin.Type.ContainerLayout);
20711 const elem_ty = try sema.resolveType(block, elem_ty_src, extra.elem_ty);
2098520712
20986 const has_tag = tag_type_val.optionalValue(zcu) != null;
20713 switch (elem_ty.zigTypeTag(zcu)) {
20714 .noreturn => return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{}),
20715 // This needs to be disallowed, because the sentinel parameter would otherwise have type
20716 // `?@TypeOf(null)`, which is not a valid type because you cannot differentiate between
20717 // constructing the "inner" null value and the "outer" null value.
20718 .null => return sema.fail(block, elem_ty_src, "cannot reify pointer to '@TypeOf(null)'", .{}),
20719 .@"fn" => switch (size) {
20720 .one => {},
20721 .many, .c, .slice => return sema.fail(block, src, "function pointers must be single pointers", .{}),
20722 },
20723 .@"opaque" => switch (size) {
20724 .one => {},
20725 .many, .c, .slice => return sema.fail(block, src, "indexable pointer to opaque type '{f}' not allowed", .{elem_ty.fmt(pt)}),
20726 },
20727 else => {},
20728 }
2098720729
20988 if (has_tag) {
20989 switch (layout) {
20990 .@"extern" => return sema.fail(block, src, "extern union does not support enum tag type", .{}),
20991 .@"packed" => return sema.fail(block, src, "packed union does not support enum tag type", .{}),
20992 .auto => {},
20993 }
20994 }
20730 if (size == .c and !try sema.validateExternType(elem_ty, .other)) {
20731 return sema.failWithOwnedErrorMsg(block, msg: {
20732 const msg = try sema.errMsg(src, "C pointers cannot point to non-C-ABI-compatible type '{f}'", .{elem_ty.fmt(pt)});
20733 errdefer msg.destroy(gpa);
20734 try sema.explainWhyTypeIsNotExtern(msg, elem_ty_src, elem_ty, .other);
20735 try sema.addDeclaredHereNote(msg, elem_ty);
20736 break :msg msg;
20737 });
20738 }
2099520739
20996 const fields_arr = try sema.derefSliceAsArray(block, operand_src, fields_val, .{ .simple = .union_fields });
20740 const sentinel_ty = try pt.optionalType(elem_ty.toIntern());
20741 const sentinel_uncoerced = try sema.resolveInst(extra.sentinel);
20742 const sentinel_coerced = try sema.coerce(block, sentinel_ty, sentinel_uncoerced, sentinel_src);
20743 const sentinel_val = try sema.resolveConstDefinedValue(block, sentinel_src, sentinel_coerced, .{ .simple = .pointer_sentinel });
20744 const opt_sentinel = sentinel_val.optionalValue(zcu);
20745 if (opt_sentinel) |sentinel| {
20746 switch (size) {
20747 .many, .slice => {},
20748 .one, .c => return sema.fail(block, sentinel_src, "sentinels are only allowed on slices and unknown-length pointers", .{}),
20749 }
20750 try checkSentinelType(sema, block, sentinel_src, elem_ty);
20751 if (sentinel.canMutateComptimeVarState(zcu)) {
20752 const sentinel_name = try ip.getOrPutString(gpa, pt.tid, "sentinel", .no_embedded_nulls);
20753 return sema.failWithContainsReferenceToComptimeVar(block, sentinel_src, sentinel_name, "sentinel", sentinel);
20754 }
20755 }
2099720756
20998 return sema.reifyUnion(block, inst, src, layout, tag_type_val, fields_arr, name_strategy);
20757 return .fromType(try pt.ptrTypeSema(.{
20758 .child = elem_ty.toIntern(),
20759 .sentinel = if (opt_sentinel) |s| s.toIntern() else .none,
20760 .flags = .{
20761 .size = size,
20762 .is_const = attrs.@"const",
20763 .is_volatile = attrs.@"volatile",
20764 .is_allowzero = attrs.@"allowzero",
20765 .address_space = attrs.@"addrspace" orelse as: {
20766 if (elem_ty.zigTypeTag(zcu) == .@"fn" and zcu.getTarget().cpu.arch == .avr) break :as .flash;
20767 break :as .generic;
20768 },
20769 .alignment = @"align",
2099920770 },
21000 .@"fn" => {
21001 const struct_type = ip.loadStructType(ip.typeOf(union_val.val));
21002 const calling_convention_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21003 ip,
21004 try ip.getOrPutString(gpa, pt.tid, "calling_convention", .no_embedded_nulls),
21005 ).?);
21006 const is_generic_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21007 ip,
21008 try ip.getOrPutString(gpa, pt.tid, "is_generic", .no_embedded_nulls),
21009 ).?);
21010 const is_var_args_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21011 ip,
21012 try ip.getOrPutString(gpa, pt.tid, "is_var_args", .no_embedded_nulls),
21013 ).?);
21014 const return_type_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21015 ip,
21016 try ip.getOrPutString(gpa, pt.tid, "return_type", .no_embedded_nulls),
21017 ).?);
21018 const params_slice_val = try Value.fromInterned(union_val.val).fieldValue(pt, struct_type.nameIndex(
21019 ip,
21020 try ip.getOrPutString(gpa, pt.tid, "params", .no_embedded_nulls),
21021 ).?);
21022
21023 const is_generic = is_generic_val.toBool();
21024 if (is_generic) {
21025 return sema.fail(block, src, "Type.Fn.is_generic must be false for @Type", .{});
21026 }
21027
21028 const is_var_args = is_var_args_val.toBool();
21029 const cc = try sema.analyzeValueAsCallconv(block, src, calling_convention_val);
21030 if (is_var_args) {
21031 try sema.checkCallConvSupportsVarArgs(block, src, cc);
21032 }
21033
21034 const return_type = return_type_val.optionalValue(zcu) orelse
21035 return sema.fail(block, src, "Type.Fn.return_type must be non-null for @Type", .{});
21036
21037 const params_val = try sema.derefSliceAsArray(block, operand_src, params_slice_val, .{ .simple = .function_parameters });
21038
21039 const args_len = try sema.usizeCast(block, src, params_val.typeOf(zcu).arrayLen(zcu));
21040 const param_types = try sema.arena.alloc(InternPool.Index, args_len);
20771 }));
20772}
2104120773
21042 var noalias_bits: u32 = 0;
21043 for (param_types, 0..) |*param_type, i| {
21044 const elem_val = try params_val.elemValue(pt, i);
21045 const elem_struct_type = ip.loadStructType(ip.typeOf(elem_val.toIntern()));
21046 const param_is_generic_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
21047 ip,
21048 try ip.getOrPutString(gpa, pt.tid, "is_generic", .no_embedded_nulls),
21049 ).?);
21050 const param_is_noalias_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
21051 ip,
21052 try ip.getOrPutString(gpa, pt.tid, "is_noalias", .no_embedded_nulls),
21053 ).?);
21054 const opt_param_type_val = try elem_val.fieldValue(pt, elem_struct_type.nameIndex(
21055 ip,
21056 try ip.getOrPutString(gpa, pt.tid, "type", .no_embedded_nulls),
21057 ).?);
21058
21059 if (param_is_generic_val.toBool()) {
21060 return sema.fail(block, src, "Type.Fn.Param.is_generic must be false for @Type", .{});
21061 }
21062
21063 const param_type_val = opt_param_type_val.optionalValue(zcu) orelse
21064 return sema.fail(block, src, "Type.Fn.Param.type must be non-null for @Type", .{});
21065 param_type.* = param_type_val.toIntern();
21066
21067 if (param_is_noalias_val.toBool()) {
21068 if (!Type.fromInterned(param_type.*).isPtrAtRuntime(zcu)) {
21069 return sema.fail(block, src, "non-pointer parameter declared noalias", .{});
21070 }
21071 noalias_bits |= @as(u32, 1) << (std.math.cast(u5, i) orelse
21072 return sema.fail(block, src, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{}));
21073 }
20774fn zirReifyFn(
20775 sema: *Sema,
20776 block: *Block,
20777 extended: Zir.Inst.Extended.InstData,
20778) CompileError!Air.Inst.Ref {
20779 const pt = sema.pt;
20780 const zcu = pt.zcu;
20781 const gpa = zcu.gpa;
20782 const ip = &zcu.intern_pool;
20783
20784 const extra = sema.code.extraData(Zir.Inst.ReifyFn, extended.operand).data;
20785 const param_types_src = block.builtinCallArgSrc(extra.node, 0);
20786 const param_attrs_src = block.builtinCallArgSrc(extra.node, 1);
20787 const ret_ty_src = block.builtinCallArgSrc(extra.node, 2);
20788 const fn_attrs_src = block.builtinCallArgSrc(extra.node, 3);
20789
20790 const single_param_attrs_ty = try sema.getBuiltinType(param_attrs_src, .@"Type.Fn.Param.Attributes");
20791 const fn_attrs_ty = try sema.getBuiltinType(fn_attrs_src, .@"Type.Fn.Attributes");
20792
20793 const param_types_uncoerced = try sema.resolveInst(extra.param_types);
20794 const param_types_coerced = try sema.coerce(block, .slice_const_type, param_types_uncoerced, param_types_src);
20795 const param_types_slice = try sema.resolveConstDefinedValue(block, param_types_src, param_types_coerced, .{ .simple = .fn_param_types });
20796 const param_types_arr = try sema.derefSliceAsArray(block, param_types_src, param_types_slice, .{ .simple = .fn_param_types });
20797
20798 const params_len = param_types_arr.typeOf(zcu).arrayLen(zcu);
20799
20800 const param_attrs_ty = try pt.singleConstPtrType(try pt.arrayType(.{
20801 .len = params_len,
20802 .child = single_param_attrs_ty.toIntern(),
20803 }));
20804 const param_attrs_uncoerced = try sema.resolveInst(extra.param_attrs);
20805 const param_attrs_coerced = try sema.coerce(block, param_attrs_ty, param_attrs_uncoerced, param_attrs_src);
20806 const param_attrs_slice = try sema.resolveConstDefinedValue(block, param_attrs_src, param_attrs_coerced, .{ .simple = .fn_param_attrs });
20807 const param_attrs_arr = try sema.derefSliceAsArray(block, param_attrs_src, param_attrs_slice, .{ .simple = .fn_param_attrs });
20808
20809 const ret_ty = try sema.resolveType(block, ret_ty_src, extra.ret_ty);
20810
20811 const fn_attrs_uncoerced = try sema.resolveInst(extra.fn_attrs);
20812 const fn_attrs_coerced = try sema.coerce(block, fn_attrs_ty, fn_attrs_uncoerced, fn_attrs_src);
20813 const fn_attrs_val = try sema.resolveConstDefinedValue(block, fn_attrs_src, fn_attrs_coerced, .{ .simple = .fn_attrs });
20814 const fn_attrs = try sema.interpretBuiltinType(block, fn_attrs_src, fn_attrs_val, std.builtin.Type.Fn.Attributes);
20815
20816 var noalias_bits: u32 = 0;
20817 const param_types_ip = try sema.arena.alloc(InternPool.Index, @intCast(params_len));
20818 for (param_types_ip, 0..@intCast(params_len)) |*param_ty_ip, param_idx| {
20819 const param_ty: Type = (try param_types_arr.elemValue(pt, param_idx)).toType();
20820 const param_attrs = try sema.interpretBuiltinType(
20821 block,
20822 param_attrs_src,
20823 try param_attrs_arr.elemValue(pt, param_idx),
20824 std.builtin.Type.Fn.Param.Attributes,
20825 );
20826 try sema.checkParamTypeCommon(
20827 block,
20828 @intCast(param_idx),
20829 param_ty,
20830 param_attrs.@"noalias",
20831 param_types_src,
20832 fn_attrs.@"callconv",
20833 );
20834 if (try param_ty.comptimeOnlySema(pt)) {
20835 return sema.fail(block, param_attrs_src, "cannot reify function type with comptime-only parameter type '{f}'", .{param_ty.fmt(pt)});
20836 }
20837 if (param_attrs.@"noalias") {
20838 if (param_idx > 31) {
20839 return sema.fail(block, param_attrs_src, "this compiler implementation only supports 'noalias' on the first 32 parameters", .{});
2107420840 }
20841 noalias_bits |= @as(u32, 1) << @intCast(param_idx);
20842 }
20843 param_ty_ip.* = param_ty.toIntern();
20844 }
2107520845
21076 const ty = try pt.funcType(.{
21077 .param_types = param_types,
21078 .noalias_bits = noalias_bits,
21079 .return_type = return_type.toIntern(),
21080 .cc = cc,
21081 .is_var_args = is_var_args,
21082 });
21083 return Air.internedToRef(ty.toIntern());
21084 },
21085 .frame => return sema.failWithUseOfAsync(block, src),
20846 if (fn_attrs.varargs) {
20847 try sema.checkCallConvSupportsVarArgs(block, fn_attrs_src, fn_attrs.@"callconv");
2108620848 }
20849
20850 try sema.checkReturnTypeAndCallConvCommon(
20851 block,
20852 ret_ty,
20853 ret_ty_src,
20854 fn_attrs.@"callconv",
20855 fn_attrs_src,
20856 if (fn_attrs.varargs) fn_attrs_src else null,
20857 false,
20858 false,
20859 );
20860 if (try ret_ty.comptimeOnlySema(pt)) {
20861 return sema.fail(block, param_attrs_src, "cannot reify function type with comptime-only return type '{f}'", .{ret_ty.fmt(pt)});
20862 }
20863
20864 return .fromIntern(try ip.getFuncType(gpa, pt.tid, .{
20865 .param_types = param_types_ip,
20866 .noalias_bits = noalias_bits,
20867 .comptime_bits = 0,
20868 .return_type = ret_ty.toIntern(),
20869 .cc = fn_attrs.@"callconv",
20870 .is_var_args = fn_attrs.varargs,
20871 .is_generic = false,
20872 .is_noinline = false,
20873 }));
2108720874}
2108820875
21089fn reifyEnum(
20876fn zirReifyStruct(
2109020877 sema: *Sema,
2109120878 block: *Block,
20879 extended: Zir.Inst.Extended.InstData,
2109220880 inst: Zir.Inst.Index,
21093 src: LazySrcLoc,
21094 tag_ty: Type,
21095 is_exhaustive: bool,
21096 fields_val: Value,
21097 name_strategy: Zir.Inst.NameStrategy,
2109820881) CompileError!Air.Inst.Ref {
2109920882 const pt = sema.pt;
2110020883 const zcu = pt.zcu;
2110120884 const gpa = sema.gpa;
2110220885 const ip = &zcu.intern_pool;
2110320886
21104 // This logic must stay in sync with the structure of `std.builtin.Type.Enum` - search for `fieldValue`.
20887 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
20888 const extra = sema.code.extraData(Zir.Inst.ReifyStruct, extended.operand).data;
20889 const tracked_inst = try block.trackZir(inst);
20890 const src: LazySrcLoc = .{
20891 .base_node_inst = tracked_inst,
20892 .offset = .nodeOffset(.zero),
20893 };
20894
20895 const layout_src: LazySrcLoc = .{
20896 .base_node_inst = tracked_inst,
20897 .offset = .{ .node_offset_builtin_call_arg = .{
20898 .builtin_call_node = .zero,
20899 .arg_index = 0,
20900 } },
20901 };
20902 const backing_ty_src: LazySrcLoc = .{
20903 .base_node_inst = tracked_inst,
20904 .offset = .{ .node_offset_builtin_call_arg = .{
20905 .builtin_call_node = .zero,
20906 .arg_index = 1,
20907 } },
20908 };
20909 const field_names_src: LazySrcLoc = .{
20910 .base_node_inst = tracked_inst,
20911 .offset = .{ .node_offset_builtin_call_arg = .{
20912 .builtin_call_node = .zero,
20913 .arg_index = 2,
20914 } },
20915 };
20916 const field_types_src: LazySrcLoc = .{
20917 .base_node_inst = tracked_inst,
20918 .offset = .{ .node_offset_builtin_call_arg = .{
20919 .builtin_call_node = .zero,
20920 .arg_index = 3,
20921 } },
20922 };
20923 const field_attrs_src: LazySrcLoc = .{
20924 .base_node_inst = tracked_inst,
20925 .offset = .{ .node_offset_builtin_call_arg = .{
20926 .builtin_call_node = .zero,
20927 .arg_index = 4,
20928 } },
20929 };
20930
20931 const container_layout_ty = try sema.getBuiltinType(layout_src, .@"Type.ContainerLayout");
20932 const single_field_attrs_ty = try sema.getBuiltinType(field_attrs_src, .@"Type.StructField.Attributes");
20933
20934 const layout_uncoerced = try sema.resolveInst(extra.layout);
20935 const layout_coerced = try sema.coerce(block, container_layout_ty, layout_uncoerced, layout_src);
20936 const layout_val = try sema.resolveConstDefinedValue(block, layout_src, layout_coerced, .{ .simple = .struct_layout });
20937 const layout = try sema.interpretBuiltinType(block, layout_src, layout_val, std.builtin.Type.ContainerLayout);
20938
20939 const backing_int_ty_uncoerced = try sema.resolveInst(extra.backing_ty);
20940 const backing_int_ty_coerced = try sema.coerce(block, .optional_type, backing_int_ty_uncoerced, backing_ty_src);
20941 const backing_int_ty_val = try sema.resolveConstDefinedValue(block, backing_ty_src, backing_int_ty_coerced, .{ .simple = .type });
20942
20943 const field_names_uncoerced = try sema.resolveInst(extra.field_names);
20944 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);
20945 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .struct_field_names });
20946 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .struct_field_names });
20947
20948 const fields_len = try sema.usizeCast(block, src, field_names_arr.typeOf(zcu).arrayLen(zcu));
20949
20950 const field_types_ty = try pt.singleConstPtrType(try pt.arrayType(.{
20951 .len = fields_len,
20952 .child = .type_type,
20953 }));
20954 const field_attrs_ty = try pt.singleConstPtrType(try pt.arrayType(.{
20955 .len = fields_len,
20956 .child = single_field_attrs_ty.toIntern(),
20957 }));
20958
20959 const field_types_uncoerced = try sema.resolveInst(extra.field_types);
20960 const field_types_coerced = try sema.coerce(block, field_types_ty, field_types_uncoerced, field_types_src);
20961 const field_types_slice = try sema.resolveConstDefinedValue(block, field_types_src, field_types_coerced, .{ .simple = .struct_field_types });
20962 const field_types_arr = try sema.derefSliceAsArray(block, field_types_src, field_types_slice, .{ .simple = .struct_field_types });
2110520963
21106 const fields_len: u32 = @intCast(fields_val.typeOf(zcu).arrayLen(zcu));
20964 const field_attrs_uncoerced = try sema.resolveInst(extra.field_attrs);
20965 const field_attrs_coerced = try sema.coerce(block, field_attrs_ty, field_attrs_uncoerced, field_attrs_src);
20966 const field_attrs_slice = try sema.resolveConstDefinedValue(block, field_attrs_src, field_attrs_coerced, .{ .simple = .struct_field_attrs });
20967 const field_attrs_arr = try sema.derefSliceAsArray(block, field_attrs_src, field_attrs_slice, .{ .simple = .struct_field_attrs });
20968
20969 // Before we begin, check for undefs...
20970 if (try sema.anyUndef(block, field_attrs_src, field_attrs_arr)) {
20971 return sema.failWithUseOfUndef(block, field_attrs_src, null);
20972 }
20973 if (try sema.anyUndef(block, field_types_src, field_types_arr)) {
20974 return sema.failWithUseOfUndef(block, field_types_src, null);
20975 }
20976 // We don't need to check `field_names_arr`, because `sliceToIpString` will check that for us.
20977 if (try sema.anyUndef(block, backing_ty_src, backing_int_ty_val)) {
20978 return sema.failWithUseOfUndef(block, backing_ty_src, null);
20979 }
2110720980
2110820981 // The validation work here is non-trivial, and it's possible the type already exists.
2110920982 // So in this first pass, let's just construct a hash to optimize for this case. If the
2111020983 // inputs turn out to be invalid, we can cancel the WIP type later.
2111120984
20985 var any_comptime_fields = false;
20986 var any_default_inits = false;
20987 var any_aligned_fields = false;
20988
2111220989 // For deduplication purposes, we must create a hash including all details of this type.
2111320990 // TODO: use a longer hash!
2111420991 var hasher = std.hash.Wyhash.init(0);
21115 std.hash.autoHash(&hasher, tag_ty.toIntern());
21116 std.hash.autoHash(&hasher, is_exhaustive);
21117 std.hash.autoHash(&hasher, fields_len);
21118
20992 std.hash.autoHash(&hasher, layout);
20993 std.hash.autoHash(&hasher, backing_int_ty_val);
20994 // The field *type* array has already been deduplicated for us thanks to the InternPool!
20995 std.hash.autoHash(&hasher, field_types_arr);
20996 // However, for field names and attributes, we need to actually iterate the individual fields,
20997 // because the presence of pointers (the `[]const u8` for the name and the `*const anyopaque`
20998 // for the default value) means that distinct interned values could ultimately result in the
20999 // same struct type.
2111921000 for (0..fields_len) |field_idx| {
21120 const field_info = try fields_val.elemValue(pt, field_idx);
21001 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
21002 const field_attrs_val = try field_attrs_arr.elemValue(pt, field_idx);
21003
21004 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, .{ .simple = .struct_field_names });
21005
21006 const field_attr_comptime = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
21007 std.builtin.Type.StructField.Attributes,
21008 "comptime",
21009 ).?);
21010 const field_attr_align = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
21011 std.builtin.Type.StructField.Attributes,
21012 "align",
21013 ).?);
21014 const field_attr_default_value_ptr = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
21015 std.builtin.Type.StructField.Attributes,
21016 "default_value_ptr",
21017 ).?);
2112121018
21122 const field_name_val = try field_info.fieldValue(pt, 0);
21123 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 1));
21124
21125 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ .simple = .enum_field_name });
21019 const field_default: InternPool.Index = d: {
21020 const ptr_val = field_attr_default_value_ptr.optionalValue(zcu) orelse break :d .none;
21021 const field_ty = (try field_types_arr.elemValue(pt, field_idx)).toType();
21022 const ptr_ty = try pt.singleConstPtrType(field_ty);
21023 const deref_val = try sema.pointerDeref(block, field_attrs_src, ptr_val, ptr_ty) orelse return sema.failWithNeededComptime(
21024 block,
21025 field_attrs_src,
21026 .{ .simple = .struct_field_default_value },
21027 );
21028 // Resolve the value so that lazy values do not create distinct types.
21029 break :d (try sema.resolveLazyValue(deref_val)).toIntern();
21030 };
2112621031
2112721032 std.hash.autoHash(&hasher, .{
2112821033 field_name,
21129 field_value_val.toIntern(),
21034 field_attr_comptime,
21035 field_attr_align,
21036 field_default,
2113021037 });
21038
21039 if (field_attr_comptime.toBool()) any_comptime_fields = true;
21040 if (field_attr_align.optionalValue(zcu)) |_| any_aligned_fields = true;
21041 if (field_default != .none) any_default_inits = true;
2113121042 }
2113221043
21133 const tracked_inst = try block.trackZir(inst);
21044 // Some basic validation to avoid a bogus `getStructType` call...
21045 const backing_int_ty: ?Type = if (backing_int_ty_val.optionalValue(zcu)) |backing| ty: {
21046 switch (layout) {
21047 .auto, .@"extern" => return sema.fail(block, backing_ty_src, "non-packed struct does not support backing integer type", .{}),
21048 .@"packed" => {},
21049 }
21050 break :ty backing.toType();
21051 } else null;
21052 if (any_aligned_fields and layout == .@"packed") {
21053 return sema.fail(block, field_attrs_src, "packed struct fields cannot be aligned", .{});
21054 }
21055 if (any_comptime_fields and layout != .auto) {
21056 return sema.fail(block, field_attrs_src, "{t} struct fields cannot be marked comptime", .{layout});
21057 }
2113421058
21135 const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{
21136 .has_values = true,
21137 .tag_mode = if (is_exhaustive) .explicit else .nonexhaustive,
21138 .fields_len = fields_len,
21059 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
21060 .layout = layout,
21061 .fields_len = @intCast(fields_len),
21062 .known_non_opv = false,
21063 .requires_comptime = .unknown,
21064 .any_comptime_fields = any_comptime_fields,
21065 .any_default_inits = any_default_inits,
21066 .any_aligned_fields = any_aligned_fields,
21067 .inits_resolved = true,
2113921068 .key = .{ .reified = .{
2114021069 .zir_index = tracked_inst,
2114121070 .type_hash = hasher.final(),
......@@ -21148,79 +21077,144 @@ fn reifyEnum(
2114821077 return Air.internedToRef(ty);
2114921078 },
2115021079 };
21151 var done = false;
21152 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
21153
21154 if (tag_ty.zigTypeTag(zcu) != .int) {
21155 return sema.fail(block, src, "Type.Enum.tag_type must be an integer type", .{});
21156 }
21080 errdefer wip_ty.cancel(ip, pt.tid);
2115721081
2115821082 const type_name = try sema.createTypeName(
2115921083 block,
2116021084 name_strategy,
21161 "enum",
21085 "struct",
2116221086 inst,
2116321087 wip_ty.index,
2116421088 );
2116521089 wip_ty.setName(ip, type_name.name, type_name.nav);
2116621090
21167 const new_namespace_index = try pt.createNamespace(.{
21168 .parent = block.namespace.toOptional(),
21169 .owner_type = wip_ty.index,
21170 .file_scope = block.getFileScopeIndex(zcu),
21171 .generation = zcu.generation,
21172 });
21173
21174 try sema.declareDependency(.{ .interned = wip_ty.index });
21175 try sema.addTypeReferenceEntry(src, wip_ty.index);
21176 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
21177 wip_ty.prepare(ip, new_namespace_index);
21178 wip_ty.setTagTy(ip, tag_ty.toIntern());
21179 done = true;
21091 const wip_struct_type = ip.loadStructType(wip_ty.index);
2118021092
2118121093 for (0..fields_len) |field_idx| {
21182 const field_info = try fields_val.elemValue(pt, field_idx);
21094 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
21095 const field_attrs_val = try field_attrs_arr.elemValue(pt, field_idx);
2118321096
21184 const field_name_val = try field_info.fieldValue(pt, 0);
21185 const field_value_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 1));
21097 const field_ty = (try field_types_arr.elemValue(pt, field_idx)).toType();
2118621098
21187 // Don't pass a reason; first loop acts as an assertion that this is valid.
21188 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
21099 // Don't pass a reason; first loop acts as a check that this is valid.
21100 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, undefined);
21101 if (wip_struct_type.addFieldName(ip, field_name)) |prev_index| {
21102 _ = prev_index; // TODO: better source location
21103 return sema.fail(block, field_names_src, "duplicate struct field name {f}", .{field_name.fmt(ip)});
21104 }
21105
21106 const field_attr_comptime = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
21107 std.builtin.Type.StructField.Attributes,
21108 "comptime",
21109 ).?);
21110 const field_attr_align = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
21111 std.builtin.Type.StructField.Attributes,
21112 "align",
21113 ).?);
21114 const field_attr_default_value_ptr = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex(
21115 std.builtin.Type.StructField.Attributes,
21116 "default_value_ptr",
21117 ).?);
21118
21119 if (field_attr_align.optionalValue(zcu)) |field_align_val| {
21120 assert(layout != .@"packed");
21121 const bytes = try field_align_val.toUnsignedIntSema(pt);
21122 const a = try sema.validateAlign(block, field_attrs_src, bytes);
21123 wip_struct_type.field_aligns.get(ip)[field_idx] = a;
21124 } else if (any_aligned_fields) {
21125 assert(layout != .@"packed");
21126 wip_struct_type.field_aligns.get(ip)[field_idx] = .none;
21127 }
2118921128
21190 if (!try sema.intFitsInType(field_value_val, tag_ty, null)) {
21191 // TODO: better source location
21192 return sema.fail(block, src, "field '{f}' with enumeration value '{f}' is too large for backing int type '{f}'", .{
21193 field_name.fmt(ip),
21194 field_value_val.fmtValueSema(pt, sema),
21195 tag_ty.fmt(pt),
21196 });
21129 const field_default: InternPool.Index = d: {
21130 const ptr_val = field_attr_default_value_ptr.optionalValue(zcu) orelse break :d .none;
21131 assert(any_default_inits);
21132 const ptr_ty = try pt.singleConstPtrType(field_ty);
21133 // The first loop checked that this is comptime-dereferencable.
21134 const deref_val = (try sema.pointerDeref(block, field_attrs_src, ptr_val, ptr_ty)).?;
21135 // ...but we've not checked this yet!
21136 if (deref_val.canMutateComptimeVarState(zcu)) {
21137 return sema.failWithContainsReferenceToComptimeVar(block, field_attrs_src, field_name, "field default value", deref_val);
21138 }
21139 break :d (try sema.resolveLazyValue(deref_val)).toIntern();
21140 };
21141
21142 if (field_attr_comptime.toBool()) {
21143 assert(layout == .auto);
21144 if (field_default == .none) {
21145 return sema.fail(block, field_attrs_src, "comptime field without default initialization value", .{});
21146 }
21147 wip_struct_type.setFieldComptime(ip, field_idx);
2119721148 }
2119821149
21199 const coerced_field_val = try pt.getCoerced(field_value_val, tag_ty);
21200 if (wip_ty.nextField(ip, field_name, coerced_field_val.toIntern())) |conflict| {
21201 return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) {
21202 .name => msg: {
21203 const msg = try sema.errMsg(src, "duplicate enum field '{f}'", .{field_name.fmt(ip)});
21150 wip_struct_type.field_types.get(ip)[field_idx] = field_ty.toIntern();
21151 if (field_default != .none) {
21152 wip_struct_type.field_inits.get(ip)[field_idx] = field_default;
21153 }
21154
21155 switch (field_ty.zigTypeTag(zcu)) {
21156 .@"opaque" => return sema.failWithOwnedErrorMsg(block, msg: {
21157 const msg = try sema.errMsg(field_types_src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
21158 errdefer msg.destroy(gpa);
21159 try sema.addDeclaredHereNote(msg, field_ty);
21160 break :msg msg;
21161 }),
21162 .noreturn => return sema.failWithOwnedErrorMsg(block, msg: {
21163 const msg = try sema.errMsg(field_types_src, "struct fields cannot be 'noreturn'", .{});
21164 errdefer msg.destroy(gpa);
21165 try sema.addDeclaredHereNote(msg, field_ty);
21166 break :msg msg;
21167 }),
21168 else => {},
21169 }
21170
21171 switch (layout) {
21172 .auto => {},
21173 .@"extern" => if (!try sema.validateExternType(field_ty, .struct_field)) {
21174 return sema.failWithOwnedErrorMsg(block, msg: {
21175 const msg = try sema.errMsg(field_types_src, "extern structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
2120421176 errdefer msg.destroy(gpa);
21205 _ = conflict.prev_field_idx; // TODO: this note is incorrect
21206 try sema.errNote(src, msg, "other field here", .{});
21177 try sema.explainWhyTypeIsNotExtern(msg, field_types_src, field_ty, .struct_field);
21178 try sema.addDeclaredHereNote(msg, field_ty);
2120721179 break :msg msg;
21208 },
21209 .value => msg: {
21210 const msg = try sema.errMsg(src, "enum tag value {f} already taken", .{field_value_val.fmtValueSema(pt, sema)});
21180 });
21181 },
21182 .@"packed" => if (!try sema.validatePackedType(field_ty)) {
21183 return sema.failWithOwnedErrorMsg(block, msg: {
21184 const msg = try sema.errMsg(field_types_src, "packed structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
2121121185 errdefer msg.destroy(gpa);
21212 _ = conflict.prev_field_idx; // TODO: this note is incorrect
21213 try sema.errNote(src, msg, "other enum tag value here", .{});
21186 try sema.explainWhyTypeIsNotPacked(msg, field_types_src, field_ty);
21187 try sema.addDeclaredHereNote(msg, field_ty);
2121421188 break :msg msg;
21215 },
21216 });
21189 });
21190 },
2121721191 }
2121821192 }
2121921193
21220 if (!is_exhaustive and fields_len > 1 and std.math.log2_int(u64, fields_len) == tag_ty.bitSize(zcu)) {
21221 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});
21194 if (layout == .@"packed") {
21195 var fields_bit_sum: u64 = 0;
21196 for (0..wip_struct_type.field_types.len) |field_idx| {
21197 const field_ty: Type = .fromInterned(wip_struct_type.field_types.get(ip)[field_idx]);
21198 try field_ty.resolveLayout(pt);
21199 fields_bit_sum += field_ty.bitSize(zcu);
21200 }
21201 if (backing_int_ty) |ty| {
21202 try sema.checkBackingIntType(block, src, ty, fields_bit_sum);
21203 wip_struct_type.setBackingIntType(ip, ty.toIntern());
21204 } else {
21205 const ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
21206 wip_struct_type.setBackingIntType(ip, ty.toIntern());
21207 }
2122221208 }
2122321209
21210 const new_namespace_index = try pt.createNamespace(.{
21211 .parent = block.namespace.toOptional(),
21212 .owner_type = wip_ty.index,
21213 .file_scope = block.getFileScopeIndex(zcu),
21214 .generation = zcu.generation,
21215 });
21216
21217 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
2122421218 codegen_type: {
2122521219 if (zcu.comp.config.use_llvm) break :codegen_type;
2122621220 if (block.ownerModule().strip) break :codegen_type;
......@@ -21228,75 +21222,177 @@ fn reifyEnum(
2122821222 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
2122921223 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
2123021224 }
21231 return Air.internedToRef(wip_ty.index);
21225 try sema.declareDependency(.{ .interned = wip_ty.index });
21226 try sema.addTypeReferenceEntry(src, wip_ty.index);
21227 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
21228 return .fromIntern(wip_ty.finish(ip, new_namespace_index));
2123221229}
2123321230
21234fn reifyUnion(
21231fn zirReifyUnion(
2123521232 sema: *Sema,
2123621233 block: *Block,
21234 extended: Zir.Inst.Extended.InstData,
2123721235 inst: Zir.Inst.Index,
21238 src: LazySrcLoc,
21239 layout: std.builtin.Type.ContainerLayout,
21240 opt_tag_type_val: Value,
21241 fields_val: Value,
21242 name_strategy: Zir.Inst.NameStrategy,
2124321236) CompileError!Air.Inst.Ref {
2124421237 const pt = sema.pt;
2124521238 const zcu = pt.zcu;
2124621239 const gpa = sema.gpa;
2124721240 const ip = &zcu.intern_pool;
2124821241
21249 // This logic must stay in sync with the structure of `std.builtin.Type.Union` - search for `fieldValue`.
21242 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
21243 const extra = sema.code.extraData(Zir.Inst.ReifyUnion, extended.operand).data;
21244 const tracked_inst = try block.trackZir(inst);
21245 const src: LazySrcLoc = .{
21246 .base_node_inst = tracked_inst,
21247 .offset = .nodeOffset(.zero),
21248 };
21249
21250 const layout_src: LazySrcLoc = .{
21251 .base_node_inst = tracked_inst,
21252 .offset = .{ .node_offset_builtin_call_arg = .{
21253 .builtin_call_node = .zero,
21254 .arg_index = 0,
21255 } },
21256 };
21257 const arg_ty_src: LazySrcLoc = .{
21258 .base_node_inst = tracked_inst,
21259 .offset = .{ .node_offset_builtin_call_arg = .{
21260 .builtin_call_node = .zero,
21261 .arg_index = 1,
21262 } },
21263 };
21264 const field_names_src: LazySrcLoc = .{
21265 .base_node_inst = tracked_inst,
21266 .offset = .{ .node_offset_builtin_call_arg = .{
21267 .builtin_call_node = .zero,
21268 .arg_index = 2,
21269 } },
21270 };
21271 const field_types_src: LazySrcLoc = .{
21272 .base_node_inst = tracked_inst,
21273 .offset = .{ .node_offset_builtin_call_arg = .{
21274 .builtin_call_node = .zero,
21275 .arg_index = 3,
21276 } },
21277 };
21278 const field_attrs_src: LazySrcLoc = .{
21279 .base_node_inst = tracked_inst,
21280 .offset = .{ .node_offset_builtin_call_arg = .{
21281 .builtin_call_node = .zero,
21282 .arg_index = 4,
21283 } },
21284 };
21285
21286 const container_layout_ty = try sema.getBuiltinType(layout_src, .@"Type.ContainerLayout");
21287 const single_field_attrs_ty = try sema.getBuiltinType(field_attrs_src, .@"Type.UnionField.Attributes");
21288
21289 const layout_uncoerced = try sema.resolveInst(extra.layout);
21290 const layout_coerced = try sema.coerce(block, container_layout_ty, layout_uncoerced, layout_src);
21291 const layout_val = try sema.resolveConstDefinedValue(block, layout_src, layout_coerced, .{ .simple = .union_layout });
21292 const layout = try sema.interpretBuiltinType(block, layout_src, layout_val, std.builtin.Type.ContainerLayout);
21293
21294 const arg_ty_uncoerced = try sema.resolveInst(extra.arg_ty);
21295 const arg_ty_coerced = try sema.coerce(block, .optional_type, arg_ty_uncoerced, arg_ty_src);
21296 const arg_ty_val = try sema.resolveConstDefinedValue(block, arg_ty_src, arg_ty_coerced, .{ .simple = .type });
21297
21298 const field_names_uncoerced = try sema.resolveInst(extra.field_names);
21299 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);
21300 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .union_field_names });
21301 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .union_field_names });
21302
21303 const fields_len = try sema.usizeCast(block, src, field_names_arr.typeOf(zcu).arrayLen(zcu));
21304
21305 const field_types_ty = try pt.singleConstPtrType(try pt.arrayType(.{
21306 .len = fields_len,
21307 .child = .type_type,
21308 }));
21309 const field_attrs_ty = try pt.singleConstPtrType(try pt.arrayType(.{
21310 .len = fields_len,
21311 .child = single_field_attrs_ty.toIntern(),
21312 }));
21313
21314 const field_types_uncoerced = try sema.resolveInst(extra.field_types);
21315 const field_types_coerced = try sema.coerce(block, field_types_ty, field_types_uncoerced, field_types_src);
21316 const field_types_slice = try sema.resolveConstDefinedValue(block, field_types_src, field_types_coerced, .{ .simple = .union_field_types });
21317 const field_types_arr = try sema.derefSliceAsArray(block, field_types_src, field_types_slice, .{ .simple = .union_field_types });
2125021318
21251 const fields_len: u32 = @intCast(fields_val.typeOf(zcu).arrayLen(zcu));
21319 const field_attrs_uncoerced = try sema.resolveInst(extra.field_attrs);
21320 const field_attrs_coerced = try sema.coerce(block, field_attrs_ty, field_attrs_uncoerced, field_attrs_src);
21321 const field_attrs_slice = try sema.resolveConstDefinedValue(block, field_attrs_src, field_attrs_coerced, .{ .simple = .union_field_attrs });
21322 const field_attrs_arr = try sema.derefSliceAsArray(block, field_attrs_src, field_attrs_slice, .{ .simple = .union_field_attrs });
21323
21324 // Before we begin, check for undefs...
21325 if (try sema.anyUndef(block, field_attrs_src, field_attrs_arr)) {
21326 return sema.failWithUseOfUndef(block, field_attrs_src, null);
21327 }
21328 if (try sema.anyUndef(block, field_types_src, field_types_arr)) {
21329 return sema.failWithUseOfUndef(block, field_types_src, null);
21330 }
21331 // We don't need to check `field_names_arr`, because `sliceToIpString` will check that for us.
21332 if (try sema.anyUndef(block, arg_ty_src, arg_ty_val)) {
21333 return sema.failWithUseOfUndef(block, arg_ty_src, null);
21334 }
2125221335
2125321336 // The validation work here is non-trivial, and it's possible the type already exists.
2125421337 // So in this first pass, let's just construct a hash to optimize for this case. If the
2125521338 // inputs turn out to be invalid, we can cancel the WIP type later.
2125621339
21340 var any_aligned_fields = false;
21341
2125721342 // For deduplication purposes, we must create a hash including all details of this type.
2125821343 // TODO: use a longer hash!
2125921344 var hasher = std.hash.Wyhash.init(0);
2126021345 std.hash.autoHash(&hasher, layout);
21261 std.hash.autoHash(&hasher, opt_tag_type_val.toIntern());
21262 std.hash.autoHash(&hasher, fields_len);
21263
21346 std.hash.autoHash(&hasher, arg_ty_val);
21347 // `field_types_arr` and `field_attrs_arr` are already deduplicated by the InternPool!
21348 std.hash.autoHash(&hasher, field_types_arr);
21349 std.hash.autoHash(&hasher, field_attrs_arr);
21350 // However, for field names, we need to iterate the individual fields, because the pointers (the
21351 // names are slices) mean that distinct values could ultimately result in the same union type.
2126421352 for (0..fields_len) |field_idx| {
21265 const field_info = try fields_val.elemValue(pt, field_idx);
21266
21267 const field_name_val = try field_info.fieldValue(pt, 0);
21268 const field_type_val = try field_info.fieldValue(pt, 1);
21269 const field_align_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 2));
21353 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
21354 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, .{ .simple = .union_field_names });
21355 std.hash.autoHash(&hasher, field_name);
2127021356
21271 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ .simple = .union_field_name });
21272 std.hash.autoHash(&hasher, .{
21273 field_name,
21274 field_type_val.toIntern(),
21275 field_align_val.toIntern(),
21276 });
21357 const field_attrs = try sema.interpretBuiltinType(
21358 block,
21359 field_attrs_src,
21360 try field_attrs_arr.elemValue(pt, field_idx),
21361 std.builtin.Type.UnionField.Attributes,
21362 );
21363 if (field_attrs.@"align" != null) {
21364 any_aligned_fields = true;
21365 }
2127721366 }
2127821367
21279 const tracked_inst = try block.trackZir(inst);
21368 // Some basic validation to avoid a bogus `getUnionType` call...
21369 const explicit_tag_ty: ?Type = if (arg_ty_val.optionalValue(zcu)) |arg_ty| ty: {
21370 switch (layout) {
21371 .@"extern", .@"packed" => return sema.fail(block, arg_ty_src, "{t} union does not support enum tag type", .{layout}),
21372 .auto => {},
21373 }
21374 break :ty arg_ty.toType();
21375 } else null;
21376 if (any_aligned_fields and layout == .@"packed") {
21377 return sema.fail(block, field_attrs_src, "packed union fields cannot be aligned", .{});
21378 }
2128021379
2128121380 const wip_ty = switch (try ip.getUnionType(gpa, pt.tid, .{
2128221381 .flags = .{
2128321382 .layout = layout,
2128421383 .status = .none,
21285 .runtime_tag = if (opt_tag_type_val.optionalValue(zcu) != null)
21286 .tagged
21287 else if (layout != .auto)
21288 .none
21289 else switch (block.wantSafeTypes()) {
21290 true => .safety,
21291 false => .none,
21384 .runtime_tag = rt: {
21385 if (explicit_tag_ty != null) break :rt .tagged;
21386 if (layout == .auto and block.wantSafeTypes()) break :rt .safety;
21387 break :rt .none;
2129221388 },
21293 .any_aligned_fields = layout != .@"packed",
21389 .any_aligned_fields = any_aligned_fields,
2129421390 .requires_comptime = .unknown,
2129521391 .assumed_runtime_bits = false,
2129621392 .assumed_pointer_aligned = false,
2129721393 .alignment = .none,
2129821394 },
21299 .fields_len = fields_len,
21395 .fields_len = @intCast(fields_len),
2130021396 .enum_tag_ty = .none, // set later because not yet validated
2130121397 .field_types = &.{}, // set later
2130221398 .field_aligns = &.{}, // set later
......@@ -21325,128 +21421,117 @@ fn reifyUnion(
2132521421
2132621422 const loaded_union = ip.loadUnionType(wip_ty.index);
2132721423
21328 const enum_tag_ty, const has_explicit_tag = if (opt_tag_type_val.optionalValue(zcu)) |tag_type_val| tag_ty: {
21329 switch (ip.indexToKey(tag_type_val.toIntern())) {
21330 .enum_type => {},
21331 else => return sema.fail(block, src, "Type.Union.tag_type must be an enum type", .{}),
21424 const enum_tag_ty, const has_explicit_tag = if (explicit_tag_ty) |enum_tag_ty| tag: {
21425 if (enum_tag_ty.zigTypeTag(zcu) != .@"enum") {
21426 return sema.fail(block, arg_ty_src, "tag type must be an enum type", .{});
2133221427 }
21333 const enum_tag_ty = tag_type_val.toType();
2133421428
21335 // We simply track which fields of the tag type have been seen.
2133621429 const tag_ty_fields_len = enum_tag_ty.enumFieldCount(zcu);
21337 var seen_tags = try std.DynamicBitSetUnmanaged.initEmpty(sema.arena, tag_ty_fields_len);
2133821430
2133921431 for (0..fields_len) |field_idx| {
21340 const field_info = try fields_val.elemValue(pt, field_idx);
21432 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
21433 // Don't pass a reason; first loop acts as a check that this is valid.
21434 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, undefined);
2134121435
21342 const field_name_val = try field_info.fieldValue(pt, 0);
21343 const field_type_val = try field_info.fieldValue(pt, 1);
21344 const field_alignment_val = try field_info.fieldValue(pt, 2);
21345
21346 // Don't pass a reason; first loop acts as an assertion that this is valid.
21347 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
21348
21349 const enum_index = enum_tag_ty.enumFieldIndex(field_name, zcu) orelse {
21350 // TODO: better source location
21351 return sema.fail(block, src, "no field named '{f}' in enum '{f}'", .{
21436 if (field_idx >= tag_ty_fields_len) {
21437 return sema.fail(block, field_names_src, "no field named '{f}' in enum '{f}'", .{
2135221438 field_name.fmt(ip), enum_tag_ty.fmt(pt),
2135321439 });
21354 };
21355 if (seen_tags.isSet(enum_index)) {
21356 // TODO: better source location
21357 return sema.fail(block, src, "duplicate union field {f}", .{field_name.fmt(ip)});
2135821440 }
21359 seen_tags.set(enum_index);
2136021441
21361 loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern();
21362 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21363 if (layout == .@"packed") {
21364 if (byte_align != 0) return sema.fail(block, src, "alignment of a packed union field must be set to 0", .{});
21365 } else {
21366 loaded_union.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);
21442 const enum_field_name = enum_tag_ty.enumFieldName(field_idx, zcu);
21443 if (enum_field_name != field_name) {
21444 return sema.fail(block, field_names_src, "union field name '{f}' does not match enum field name '{f}'", .{
21445 field_name.fmt(ip), enum_field_name.fmt(ip),
21446 });
2136721447 }
2136821448 }
21369
2137021449 if (tag_ty_fields_len > fields_len) return sema.failWithOwnedErrorMsg(block, msg: {
21371 const msg = try sema.errMsg(src, "enum fields missing in union", .{});
21450 const msg = try sema.errMsg(field_names_src, "{d} enum fields missing in union", .{
21451 tag_ty_fields_len - fields_len,
21452 });
2137221453 errdefer msg.destroy(gpa);
21373 var it = seen_tags.iterator(.{ .kind = .unset });
21374 while (it.next()) |enum_index| {
21375 const field_name = enum_tag_ty.enumFieldName(enum_index, zcu);
21376 try sema.addFieldErrNote(enum_tag_ty, enum_index, msg, "field '{f}' missing, declared here", .{
21377 field_name.fmt(ip),
21454 for (fields_len..tag_ty_fields_len) |enum_field_idx| {
21455 try sema.addFieldErrNote(enum_tag_ty, enum_field_idx, msg, "field '{f}' missing, declared here", .{
21456 enum_tag_ty.enumFieldName(enum_field_idx, zcu).fmt(ip),
2137821457 });
2137921458 }
2138021459 try sema.addDeclaredHereNote(msg, enum_tag_ty);
2138121460 break :msg msg;
2138221461 });
21383
21384 break :tag_ty .{ enum_tag_ty.toIntern(), true };
21385 } else tag_ty: {
21462 break :tag .{ enum_tag_ty.toIntern(), true };
21463 } else tag: {
2138621464 // We must track field names and set up the tag type ourselves.
2138721465 var field_names: std.AutoArrayHashMapUnmanaged(InternPool.NullTerminatedString, void) = .empty;
2138821466 try field_names.ensureTotalCapacity(sema.arena, fields_len);
2138921467
2139021468 for (0..fields_len) |field_idx| {
21391 const field_info = try fields_val.elemValue(pt, field_idx);
21392
21393 const field_name_val = try field_info.fieldValue(pt, 0);
21394 const field_type_val = try field_info.fieldValue(pt, 1);
21395 const field_alignment_val = try field_info.fieldValue(pt, 2);
21396
21397 // Don't pass a reason; first loop acts as an assertion that this is valid.
21398 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
21469 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
21470 // Don't pass a reason; first loop acts as a check that this is valid.
21471 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, undefined);
2139921472 const gop = field_names.getOrPutAssumeCapacity(field_name);
2140021473 if (gop.found_existing) {
2140121474 // TODO: better source location
21402 return sema.fail(block, src, "duplicate union field {f}", .{field_name.fmt(ip)});
21403 }
21404
21405 loaded_union.field_types.get(ip)[field_idx] = field_type_val.toIntern();
21406 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21407 if (layout == .@"packed") {
21408 if (byte_align != 0) return sema.fail(block, src, "alignment of a packed union field must be set to 0", .{});
21409 } else {
21410 loaded_union.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);
21475 return sema.fail(block, field_names_src, "duplicate union field {f}", .{field_name.fmt(ip)});
2141121476 }
2141221477 }
21413
2141421478 const enum_tag_ty = try sema.generateUnionTagTypeSimple(block, field_names.keys(), wip_ty.index, type_name.name);
21415 break :tag_ty .{ enum_tag_ty, false };
21479 break :tag .{ enum_tag_ty, false };
2141621480 };
2141721481 errdefer if (!has_explicit_tag) ip.remove(pt.tid, enum_tag_ty); // remove generated tag type on error
2141821482
21419 for (loaded_union.field_types.get(ip)) |field_ty_ip| {
21420 const field_ty: Type = .fromInterned(field_ty_ip);
21483 for (0..fields_len) |field_idx| {
21484 const field_ty = (try field_types_arr.elemValue(pt, field_idx)).toType();
21485 const field_attrs = try sema.interpretBuiltinType(
21486 block,
21487 field_attrs_src,
21488 try field_attrs_arr.elemValue(pt, field_idx),
21489 std.builtin.Type.UnionField.Attributes,
21490 );
21491
2142121492 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
2142221493 return sema.failWithOwnedErrorMsg(block, msg: {
21423 const msg = try sema.errMsg(src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
21494 const msg = try sema.errMsg(field_types_src, "opaque types have unknown size and therefore cannot be directly embedded in unions", .{});
2142421495 errdefer msg.destroy(gpa);
21425
2142621496 try sema.addDeclaredHereNote(msg, field_ty);
2142721497 break :msg msg;
2142821498 });
2142921499 }
21430 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .union_field)) {
21431 return sema.failWithOwnedErrorMsg(block, msg: {
21432 const msg = try sema.errMsg(src, "extern unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
21433 errdefer msg.destroy(gpa);
2143421500
21435 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .union_field);
21501 switch (layout) {
21502 .auto => {},
21503 .@"extern" => if (!try sema.validateExternType(field_ty, .union_field)) {
21504 return sema.failWithOwnedErrorMsg(block, msg: {
21505 const msg = try sema.errMsg(field_types_src, "extern unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
21506 errdefer msg.destroy(gpa);
21507
21508 try sema.explainWhyTypeIsNotExtern(msg, field_types_src, field_ty, .union_field);
2143621509
21437 try sema.addDeclaredHereNote(msg, field_ty);
21438 break :msg msg;
21439 });
21440 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
21441 return sema.failWithOwnedErrorMsg(block, msg: {
21442 const msg = try sema.errMsg(src, "packed unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
21443 errdefer msg.destroy(gpa);
21510 try sema.addDeclaredHereNote(msg, field_ty);
21511 break :msg msg;
21512 });
21513 },
21514 .@"packed" => if (!try sema.validatePackedType(field_ty)) {
21515 return sema.failWithOwnedErrorMsg(block, msg: {
21516 const msg = try sema.errMsg(field_types_src, "packed unions cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
21517 errdefer msg.destroy(gpa);
2144421518
21445 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);
21519 try sema.explainWhyTypeIsNotPacked(msg, field_types_src, field_ty);
2144621520
21447 try sema.addDeclaredHereNote(msg, field_ty);
21448 break :msg msg;
21449 });
21521 try sema.addDeclaredHereNote(msg, field_ty);
21522 break :msg msg;
21523 });
21524 },
21525 }
21526
21527 loaded_union.field_types.get(ip)[field_idx] = field_ty.toIntern();
21528 if (field_attrs.@"align") |bytes| {
21529 assert(layout != .@"packed");
21530 const a = try sema.validateAlign(block, field_attrs_src, bytes);
21531 loaded_union.field_aligns.get(ip)[field_idx] = a;
21532 } else if (any_aligned_fields) {
21533 assert(layout != .@"packed");
21534 loaded_union.field_aligns.get(ip)[field_idx] = .none;
2145021535 }
2145121536 }
2145221537
......@@ -21471,116 +21556,94 @@ fn reifyUnion(
2147121556 try sema.declareDependency(.{ .interned = wip_ty.index });
2147221557 try sema.addTypeReferenceEntry(src, wip_ty.index);
2147321558 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
21474 return Air.internedToRef(wip_ty.finish(ip, new_namespace_index));
21559 return .fromIntern(wip_ty.finish(ip, new_namespace_index));
2147521560}
2147621561
21477fn reifyTuple(
21562fn zirReifyEnum(
2147821563 sema: *Sema,
2147921564 block: *Block,
21480 src: LazySrcLoc,
21481 fields_val: Value,
21565 extended: Zir.Inst.Extended.InstData,
21566 inst: Zir.Inst.Index,
2148221567) CompileError!Air.Inst.Ref {
2148321568 const pt = sema.pt;
2148421569 const zcu = pt.zcu;
2148521570 const gpa = sema.gpa;
2148621571 const ip = &zcu.intern_pool;
2148721572
21488 const fields_len: u32 = @intCast(fields_val.typeOf(zcu).arrayLen(zcu));
21489
21490 const types = try sema.arena.alloc(InternPool.Index, fields_len);
21491 const inits = try sema.arena.alloc(InternPool.Index, fields_len);
21492
21493 for (types, inits, 0..) |*field_ty, *field_init, field_idx| {
21494 const field_info = try fields_val.elemValue(pt, field_idx);
21495
21496 const field_name_val = try field_info.fieldValue(pt, 0);
21497 const field_type_val = try field_info.fieldValue(pt, 1);
21498 const field_default_value_val = try field_info.fieldValue(pt, 2);
21499 const field_is_comptime_val = try field_info.fieldValue(pt, 3);
21500 const field_alignment_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 4));
21501
21502 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ .simple = .tuple_field_name });
21503 const field_type = field_type_val.toType();
21504 const field_default_value: InternPool.Index = if (field_default_value_val.optionalValue(zcu)) |ptr_val| d: {
21505 const ptr_ty = try pt.singleConstPtrType(field_type_val.toType());
21506 // We need to do this deref here, so we won't check for this error case later on.
21507 const val = try sema.pointerDeref(block, src, ptr_val, ptr_ty) orelse return sema.failWithNeededComptime(
21508 block,
21509 src,
21510 .{ .simple = .tuple_field_default_value },
21511 );
21512 if (val.canMutateComptimeVarState(zcu)) {
21513 return sema.failWithContainsReferenceToComptimeVar(block, src, field_name, "field default value", val);
21514 }
21515 // Resolve the value so that lazy values do not create distinct types.
21516 break :d (try sema.resolveLazyValue(val)).toIntern();
21517 } else .none;
21573 const name_strategy: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
21574 const extra = sema.code.extraData(Zir.Inst.ReifyEnum, extended.operand).data;
21575 const tracked_inst = try block.trackZir(inst);
21576 const src: LazySrcLoc = .{
21577 .base_node_inst = tracked_inst,
21578 .offset = .nodeOffset(.zero),
21579 };
2151821580
21519 const field_name_index = field_name.toUnsigned(ip) orelse return sema.fail(
21520 block,
21521 src,
21522 "tuple cannot have non-numeric field '{f}'",
21523 .{field_name.fmt(ip)},
21524 );
21525 if (field_name_index != field_idx) {
21526 return sema.fail(
21527 block,
21528 src,
21529 "tuple field name '{d}' does not match field index {d}",
21530 .{ field_name_index, field_idx },
21531 );
21532 }
21581 const tag_ty_src: LazySrcLoc = .{
21582 .base_node_inst = tracked_inst,
21583 .offset = .{ .node_offset_builtin_call_arg = .{
21584 .builtin_call_node = .zero,
21585 .arg_index = 0,
21586 } },
21587 };
21588 const mode_src: LazySrcLoc = .{
21589 .base_node_inst = tracked_inst,
21590 .offset = .{ .node_offset_builtin_call_arg = .{
21591 .builtin_call_node = .zero,
21592 .arg_index = 1,
21593 } },
21594 };
21595 const field_names_src: LazySrcLoc = .{
21596 .base_node_inst = tracked_inst,
21597 .offset = .{ .node_offset_builtin_call_arg = .{
21598 .builtin_call_node = .zero,
21599 .arg_index = 2,
21600 } },
21601 };
21602 const field_values_src: LazySrcLoc = .{
21603 .base_node_inst = tracked_inst,
21604 .offset = .{ .node_offset_builtin_call_arg = .{
21605 .builtin_call_node = .zero,
21606 .arg_index = 3,
21607 } },
21608 };
2153321609
21534 try sema.validateTupleFieldType(block, field_type, src);
21610 const enum_mode_ty = try sema.getBuiltinType(mode_src, .@"Type.Enum.Mode");
2153521611
21536 {
21537 const alignment_ok = ok: {
21538 if (field_alignment_val.toIntern() == .zero) break :ok true;
21539 const given_align = try field_alignment_val.getUnsignedIntSema(pt) orelse break :ok false;
21540 const abi_align = (try field_type.abiAlignmentSema(pt)).toByteUnits() orelse 0;
21541 break :ok abi_align == given_align;
21542 };
21543 if (!alignment_ok) {
21544 return sema.fail(block, src, "tuple fields cannot specify alignment", .{});
21545 }
21546 }
21612 const tag_ty = try sema.resolveType(block, tag_ty_src, extra.tag_ty);
21613 if (tag_ty.zigTypeTag(zcu) != .int) {
21614 return sema.fail(block, tag_ty_src, "tag type must be an integer type", .{});
21615 }
2154721616
21548 if (field_is_comptime_val.toBool() and field_default_value == .none) {
21549 return sema.fail(block, src, "comptime field without default initialization value", .{});
21550 }
21617 const mode_uncoerced = try sema.resolveInst(extra.mode);
21618 const mode_coerced = try sema.coerce(block, enum_mode_ty, mode_uncoerced, mode_src);
21619 const mode_val = try sema.resolveConstDefinedValue(block, mode_src, mode_coerced, .{ .simple = .type });
21620 const nonexhaustive = switch (try sema.interpretBuiltinType(block, mode_src, mode_val, std.builtin.Type.Enum.Mode)) {
21621 .exhaustive => false,
21622 .nonexhaustive => true,
21623 };
2155121624
21552 if (!field_is_comptime_val.toBool() and field_default_value != .none) {
21553 return sema.fail(block, src, "non-comptime tuple fields cannot specify default initialization value", .{});
21554 }
21625 const field_names_uncoerced = try sema.resolveInst(extra.field_names);
21626 const field_names_coerced = try sema.coerce(block, .slice_const_slice_const_u8, field_names_uncoerced, field_names_src);
21627 const field_names_slice = try sema.resolveConstDefinedValue(block, field_names_src, field_names_coerced, .{ .simple = .enum_field_names });
21628 const field_names_arr = try sema.derefSliceAsArray(block, field_names_src, field_names_slice, .{ .simple = .enum_field_names });
2155521629
21556 field_ty.* = field_type.toIntern();
21557 field_init.* = field_default_value;
21558 }
21630 const fields_len = try sema.usizeCast(block, src, field_names_arr.typeOf(zcu).arrayLen(zcu));
2155921631
21560 return Air.internedToRef(try zcu.intern_pool.getTupleType(gpa, pt.tid, .{
21561 .types = types,
21562 .values = inits,
21632 const field_values_ty = try pt.singleConstPtrType(try pt.arrayType(.{
21633 .len = fields_len,
21634 .child = tag_ty.toIntern(),
2156321635 }));
21564}
21565
21566fn reifyStruct(
21567 sema: *Sema,
21568 block: *Block,
21569 inst: Zir.Inst.Index,
21570 src: LazySrcLoc,
21571 layout: std.builtin.Type.ContainerLayout,
21572 opt_backing_int_val: Value,
21573 fields_val: Value,
21574 name_strategy: Zir.Inst.NameStrategy,
21575) CompileError!Air.Inst.Ref {
21576 const pt = sema.pt;
21577 const zcu = pt.zcu;
21578 const gpa = sema.gpa;
21579 const ip = &zcu.intern_pool;
2158021636
21581 // This logic must stay in sync with the structure of `std.builtin.Type.Struct` - search for `fieldValue`.
21637 const field_values_uncoerced = try sema.resolveInst(extra.field_values);
21638 const field_values_coerced = try sema.coerce(block, field_values_ty, field_values_uncoerced, field_values_src);
21639 const field_values_slice = try sema.resolveConstDefinedValue(block, field_values_src, field_values_coerced, .{ .simple = .enum_field_values });
21640 const field_values_arr = try sema.derefSliceAsArray(block, field_values_src, field_values_slice, .{ .simple = .enum_field_values });
2158221641
21583 const fields_len: u32 = @intCast(fields_val.typeOf(zcu).arrayLen(zcu));
21642 // Before we begin, check for undefs...
21643 if (try sema.anyUndef(block, field_values_src, field_values_arr)) {
21644 return sema.failWithUseOfUndef(block, field_values_src, null);
21645 }
21646 // We don't need to check `field_names_arr`, because `sliceToIpString` will check that for us.
2158421647
2158521648 // The validation work here is non-trivial, and it's possible the type already exists.
2158621649 // So in this first pass, let's just construct a hash to optimize for this case. If the
......@@ -21589,62 +21652,23 @@ fn reifyStruct(
2158921652 // For deduplication purposes, we must create a hash including all details of this type.
2159021653 // TODO: use a longer hash!
2159121654 var hasher = std.hash.Wyhash.init(0);
21592 std.hash.autoHash(&hasher, layout);
21593 std.hash.autoHash(&hasher, opt_backing_int_val.toIntern());
21655 std.hash.autoHash(&hasher, tag_ty.toIntern());
21656 std.hash.autoHash(&hasher, nonexhaustive);
2159421657 std.hash.autoHash(&hasher, fields_len);
21595
21596 var any_comptime_fields = false;
21597 var any_default_inits = false;
21598
21658 // `field_values_arr` is already deduplicated by the InternPool!
21659 std.hash.autoHash(&hasher, field_values_arr);
21660 // However, for field names, we need to iterate the individual fields, because the pointers (the
21661 // names are slices) mean that distinct values could ultimately result in the same enum type.
2159921662 for (0..fields_len) |field_idx| {
21600 const field_info = try fields_val.elemValue(pt, field_idx);
21601
21602 const field_name_val = try field_info.fieldValue(pt, 0);
21603 const field_type_val = try field_info.fieldValue(pt, 1);
21604 const field_default_value_val = try field_info.fieldValue(pt, 2);
21605 const field_is_comptime_val = try field_info.fieldValue(pt, 3);
21606 const field_alignment_val = try sema.resolveLazyValue(try field_info.fieldValue(pt, 4));
21607
21608 const field_name = try sema.sliceToIpString(block, src, field_name_val, .{ .simple = .struct_field_name });
21609 const field_is_comptime = field_is_comptime_val.toBool();
21610 const field_default_value: InternPool.Index = if (field_default_value_val.optionalValue(zcu)) |ptr_val| d: {
21611 const ptr_ty = try pt.singleConstPtrType(field_type_val.toType());
21612 // We need to do this deref here, so we won't check for this error case later on.
21613 const val = try sema.pointerDeref(block, src, ptr_val, ptr_ty) orelse return sema.failWithNeededComptime(
21614 block,
21615 src,
21616 .{ .simple = .struct_field_default_value },
21617 );
21618 if (val.canMutateComptimeVarState(zcu)) {
21619 return sema.failWithContainsReferenceToComptimeVar(block, src, field_name, "field default value", val);
21620 }
21621 // Resolve the value so that lazy values do not create distinct types.
21622 break :d (try sema.resolveLazyValue(val)).toIntern();
21623 } else .none;
21624
21625 std.hash.autoHash(&hasher, .{
21626 field_name,
21627 field_type_val.toIntern(),
21628 field_default_value,
21629 field_is_comptime,
21630 field_alignment_val.toIntern(),
21631 });
21632
21633 if (field_is_comptime) any_comptime_fields = true;
21634 if (field_default_value != .none) any_default_inits = true;
21663 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
21664 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, .{ .simple = .enum_field_names });
21665 std.hash.autoHash(&hasher, field_name);
2163521666 }
2163621667
21637 const tracked_inst = try block.trackZir(inst);
21638
21639 const wip_ty = switch (try ip.getStructType(gpa, pt.tid, .{
21640 .layout = layout,
21641 .fields_len = fields_len,
21642 .known_non_opv = false,
21643 .requires_comptime = .unknown,
21644 .any_comptime_fields = any_comptime_fields,
21645 .any_default_inits = any_default_inits,
21646 .any_aligned_fields = layout != .@"packed",
21647 .inits_resolved = true,
21668 const wip_ty = switch (try ip.getEnumType(gpa, pt.tid, .{
21669 .has_values = true,
21670 .tag_mode = if (nonexhaustive) .nonexhaustive else .explicit,
21671 .fields_len = @intCast(fields_len),
2164821672 .key = .{ .reified = .{
2164921673 .zir_index = tracked_inst,
2165021674 .type_hash = hasher.final(),
......@@ -21654,152 +21678,66 @@ fn reifyStruct(
2165421678 .existing => |ty| {
2165521679 try sema.declareDependency(.{ .interned = ty });
2165621680 try sema.addTypeReferenceEntry(src, ty);
21657 return Air.internedToRef(ty);
21681 return .fromIntern(ty);
2165821682 },
2165921683 };
21660 errdefer wip_ty.cancel(ip, pt.tid);
21684 var done = false;
21685 errdefer if (!done) wip_ty.cancel(ip, pt.tid);
2166121686
2166221687 const type_name = try sema.createTypeName(
2166321688 block,
2166421689 name_strategy,
21665 "struct",
21690 "enum",
2166621691 inst,
2166721692 wip_ty.index,
2166821693 );
2166921694 wip_ty.setName(ip, type_name.name, type_name.nav);
2167021695
21671 const struct_type = ip.loadStructType(wip_ty.index);
21672
21673 for (0..fields_len) |field_idx| {
21674 const field_info = try fields_val.elemValue(pt, field_idx);
21675
21676 const field_name_val = try field_info.fieldValue(pt, 0);
21677 const field_type_val = try field_info.fieldValue(pt, 1);
21678 const field_default_value_val = try field_info.fieldValue(pt, 2);
21679 const field_is_comptime_val = try field_info.fieldValue(pt, 3);
21680 const field_alignment_val = try field_info.fieldValue(pt, 4);
21681
21682 const field_ty = field_type_val.toType();
21683 // Don't pass a reason; first loop acts as an assertion that this is valid.
21684 const field_name = try sema.sliceToIpString(block, src, field_name_val, undefined);
21685 if (struct_type.addFieldName(ip, field_name)) |prev_index| {
21686 _ = prev_index; // TODO: better source location
21687 return sema.fail(block, src, "duplicate struct field name {f}", .{field_name.fmt(ip)});
21688 }
21689
21690 if (!try sema.intFitsInType(field_alignment_val, align_ty, null)) {
21691 return sema.fail(block, src, "alignment must fit in '{f}'", .{align_ty.fmt(pt)});
21692 }
21693 const byte_align = try field_alignment_val.toUnsignedIntSema(pt);
21694 if (layout == .@"packed") {
21695 if (byte_align != 0) return sema.fail(block, src, "alignment of a packed struct field must be set to 0", .{});
21696 } else {
21697 struct_type.field_aligns.get(ip)[field_idx] = try sema.validateAlign(block, src, byte_align);
21698 }
21699
21700 const field_is_comptime = field_is_comptime_val.toBool();
21701 if (field_is_comptime) {
21702 assert(any_comptime_fields);
21703 switch (layout) {
21704 .@"extern" => return sema.fail(block, src, "extern struct fields cannot be marked comptime", .{}),
21705 .@"packed" => return sema.fail(block, src, "packed struct fields cannot be marked comptime", .{}),
21706 .auto => struct_type.setFieldComptime(ip, field_idx),
21707 }
21708 }
21709
21710 const field_default: InternPool.Index = d: {
21711 if (!any_default_inits) break :d .none;
21712 const ptr_val = field_default_value_val.optionalValue(zcu) orelse break :d .none;
21713 const ptr_ty = try pt.singleConstPtrType(field_ty);
21714 // Asserted comptime-dereferencable above.
21715 const val = (try sema.pointerDeref(block, src, ptr_val, ptr_ty)).?;
21716 // We already resolved this for deduplication, so we may as well do it now.
21717 break :d (try sema.resolveLazyValue(val)).toIntern();
21718 };
21719
21720 if (field_is_comptime and field_default == .none) {
21721 return sema.fail(block, src, "comptime field without default initialization value", .{});
21722 }
21723
21724 struct_type.field_types.get(ip)[field_idx] = field_type_val.toIntern();
21725 if (field_default != .none) {
21726 struct_type.field_inits.get(ip)[field_idx] = field_default;
21727 }
21728
21729 if (field_ty.zigTypeTag(zcu) == .@"opaque") {
21730 return sema.failWithOwnedErrorMsg(block, msg: {
21731 const msg = try sema.errMsg(src, "opaque types have unknown size and therefore cannot be directly embedded in structs", .{});
21732 errdefer msg.destroy(gpa);
21733
21734 try sema.addDeclaredHereNote(msg, field_ty);
21735 break :msg msg;
21736 });
21737 }
21738 if (field_ty.zigTypeTag(zcu) == .noreturn) {
21739 return sema.failWithOwnedErrorMsg(block, msg: {
21740 const msg = try sema.errMsg(src, "struct fields cannot be 'noreturn'", .{});
21741 errdefer msg.destroy(gpa);
21742
21743 try sema.addDeclaredHereNote(msg, field_ty);
21744 break :msg msg;
21745 });
21746 }
21747 if (layout == .@"extern" and !try sema.validateExternType(field_ty, .struct_field)) {
21748 return sema.failWithOwnedErrorMsg(block, msg: {
21749 const msg = try sema.errMsg(src, "extern structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
21750 errdefer msg.destroy(gpa);
21696 const new_namespace_index = try pt.createNamespace(.{
21697 .parent = block.namespace.toOptional(),
21698 .owner_type = wip_ty.index,
21699 .file_scope = block.getFileScopeIndex(zcu),
21700 .generation = zcu.generation,
21701 });
2175121702
21752 try sema.explainWhyTypeIsNotExtern(msg, src, field_ty, .struct_field);
21703 try sema.declareDependency(.{ .interned = wip_ty.index });
21704 try sema.addTypeReferenceEntry(src, wip_ty.index);
21705 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
21706 wip_ty.prepare(ip, new_namespace_index);
21707 wip_ty.setTagTy(ip, tag_ty.toIntern());
21708 done = true;
2175321709
21754 try sema.addDeclaredHereNote(msg, field_ty);
21755 break :msg msg;
21756 });
21757 } else if (layout == .@"packed" and !try sema.validatePackedType(field_ty)) {
21758 return sema.failWithOwnedErrorMsg(block, msg: {
21759 const msg = try sema.errMsg(src, "packed structs cannot contain fields of type '{f}'", .{field_ty.fmt(pt)});
21760 errdefer msg.destroy(gpa);
21710 for (0..fields_len) |field_idx| {
21711 const field_name_val = try field_names_arr.elemValue(pt, field_idx);
21712 // Don't pass a reason; first loop acts as a check that this is valid.
21713 const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, undefined);
2176121714
21762 try sema.explainWhyTypeIsNotPacked(msg, src, field_ty);
21715 const field_val = try field_values_arr.elemValue(pt, field_idx);
2176321716
21764 try sema.addDeclaredHereNote(msg, field_ty);
21765 break :msg msg;
21717 if (wip_ty.nextField(ip, field_name, field_val.toIntern())) |conflict| {
21718 return sema.failWithOwnedErrorMsg(block, switch (conflict.kind) {
21719 .name => msg: {
21720 const msg = try sema.errMsg(field_names_src, "duplicate enum field '{f}'", .{field_name.fmt(ip)});
21721 errdefer msg.destroy(gpa);
21722 _ = conflict.prev_field_idx; // TODO: this note is incorrect
21723 try sema.errNote(field_names_src, msg, "other field here", .{});
21724 break :msg msg;
21725 },
21726 .value => msg: {
21727 const msg = try sema.errMsg(field_values_src, "enum tag value {f} already taken", .{field_val.fmtValueSema(pt, sema)});
21728 errdefer msg.destroy(gpa);
21729 _ = conflict.prev_field_idx; // TODO: this note is incorrect
21730 try sema.errNote(field_values_src, msg, "other enum tag value here", .{});
21731 break :msg msg;
21732 },
2176621733 });
2176721734 }
2176821735 }
2176921736
21770 if (layout == .@"packed") {
21771 var fields_bit_sum: u64 = 0;
21772 for (0..struct_type.field_types.len) |field_idx| {
21773 const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_idx]);
21774 field_ty.resolveLayout(pt) catch |err| switch (err) {
21775 error.AnalysisFail => {
21776 const msg = sema.err orelse return err;
21777 try sema.errNote(src, msg, "while checking a field of this struct", .{});
21778 return err;
21779 },
21780 else => return err,
21781 };
21782 fields_bit_sum += field_ty.bitSize(zcu);
21783 }
21784
21785 if (opt_backing_int_val.optionalValue(zcu)) |backing_int_val| {
21786 const backing_int_ty = backing_int_val.toType();
21787 try sema.checkBackingIntType(block, src, backing_int_ty, fields_bit_sum);
21788 struct_type.setBackingIntType(ip, backing_int_ty.toIntern());
21789 } else {
21790 const backing_int_ty = try pt.intType(.unsigned, @intCast(fields_bit_sum));
21791 struct_type.setBackingIntType(ip, backing_int_ty.toIntern());
21792 }
21737 if (nonexhaustive and fields_len > 1 and std.math.log2_int(u64, fields_len) == tag_ty.bitSize(zcu)) {
21738 return sema.fail(block, src, "non-exhaustive enum specified every value", .{});
2179321739 }
2179421740
21795 const new_namespace_index = try pt.createNamespace(.{
21796 .parent = block.namespace.toOptional(),
21797 .owner_type = wip_ty.index,
21798 .file_scope = block.getFileScopeIndex(zcu),
21799 .generation = zcu.generation,
21800 });
21801
21802 try zcu.comp.queueJob(.{ .resolve_type_fully = wip_ty.index });
2180321741 codegen_type: {
2180421742 if (zcu.comp.config.use_llvm) break :codegen_type;
2180521743 if (block.ownerModule().strip) break :codegen_type;
......@@ -21807,10 +21745,7 @@ fn reifyStruct(
2180721745 zcu.comp.link_prog_node.increaseEstimatedTotalItems(1);
2180821746 try zcu.comp.queueJob(.{ .link_type = wip_ty.index });
2180921747 }
21810 try sema.declareDependency(.{ .interned = wip_ty.index });
21811 try sema.addTypeReferenceEntry(src, wip_ty.index);
21812 if (zcu.comp.debugIncremental()) try zcu.incremental_debug_state.newType(zcu, wip_ty.index);
21813 return Air.internedToRef(wip_ty.finish(ip, new_namespace_index));
21748 return Air.internedToRef(wip_ty.index);
2181421749}
2181521750
2181621751fn resolveVaListRef(sema: *Sema, block: *Block, src: LazySrcLoc, zir_ref: Zir.Inst.Ref) CompileError!Air.Inst.Ref {
......@@ -23969,7 +23904,7 @@ fn analyzeShuffle(
2396923904 const b_src = block.builtinCallArgSrc(src_node, 2);
2397023905 const mask_src = block.builtinCallArgSrc(src_node, 3);
2397123906
23972 // If the type of `a` is `@Type(.undefined)`, i.e. the argument is untyped,
23907 // If the type of `a` is `@TypeOf(undefined)`, i.e. the argument is untyped,
2397323908 // this is 0, because it is an error to index into this vector.
2397423909 const a_len: u32 = switch (sema.typeOf(a_uncoerced).zigTypeTag(zcu)) {
2397523910 .array, .vector => @intCast(sema.typeOf(a_uncoerced).arrayLen(zcu)),
......@@ -23981,7 +23916,7 @@ fn analyzeShuffle(
2398123916 const a_ty = try pt.vectorType(.{ .len = a_len, .child = elem_ty.toIntern() });
2398223917 const a_coerced = try sema.coerce(block, a_ty, a_uncoerced, a_src);
2398323918
23984 // If the type of `b` is `@Type(.undefined)`, i.e. the argument is untyped, this is 0, because it is an error to index into this vector.
23919 // If the type of `b` is `@TypeOf(undefined)`, i.e. the argument is untyped, this is 0, because it is an error to index into this vector.
2398523920 const b_len: u32 = switch (sema.typeOf(b_uncoerced).zigTypeTag(zcu)) {
2398623921 .array, .vector => @intCast(sema.typeOf(b_uncoerced).arrayLen(zcu)),
2398723922 .undefined => 0,
......@@ -25541,7 +25476,7 @@ fn zirFuncFancy(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A
2554125476 extra_index += body.len;
2554225477 if (extra.data.bits.ret_ty_is_generic) break :blk .generic_poison;
2554325478
25544 const val = try sema.resolveGenericBody(block, ret_src, body, inst, .type, .{ .simple = .function_ret_ty });
25479 const val = try sema.resolveGenericBody(block, ret_src, body, inst, .type, .{ .simple = .fn_ret_ty });
2554525480 const ty = val.toType();
2554625481 break :blk ty;
2554725482 } else if (extra.data.bits.has_ret_ty_ref) blk: {
......@@ -25968,21 +25903,26 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2596825903 const src = block.nodeOffset(src_node);
2596925904 const value: Zir.Inst.BuiltinValue = @enumFromInt(extended.small);
2597025905
25971 const ty = switch (value) {
25906 const builtin_type: Zcu.BuiltinDecl = switch (value) {
2597225907 // zig fmt: off
25973 .atomic_order => try sema.getBuiltinType(src, .AtomicOrder),
25974 .atomic_rmw_op => try sema.getBuiltinType(src, .AtomicRmwOp),
25975 .calling_convention => try sema.getBuiltinType(src, .CallingConvention),
25976 .address_space => try sema.getBuiltinType(src, .AddressSpace),
25977 .float_mode => try sema.getBuiltinType(src, .FloatMode),
25978 .reduce_op => try sema.getBuiltinType(src, .ReduceOp),
25979 .call_modifier => try sema.getBuiltinType(src, .CallModifier),
25980 .prefetch_options => try sema.getBuiltinType(src, .PrefetchOptions),
25981 .export_options => try sema.getBuiltinType(src, .ExportOptions),
25982 .extern_options => try sema.getBuiltinType(src, .ExternOptions),
25983 .type_info => try sema.getBuiltinType(src, .Type),
25984 .branch_hint => try sema.getBuiltinType(src, .BranchHint),
25985 .clobbers => try sema.getBuiltinType(src, .@"assembly.Clobbers"),
25908 .atomic_order => .AtomicOrder,
25909 .atomic_rmw_op => .AtomicRmwOp,
25910 .calling_convention => .CallingConvention,
25911 .address_space => .AddressSpace,
25912 .float_mode => .FloatMode,
25913 .signedness => .Signedness,
25914 .reduce_op => .ReduceOp,
25915 .call_modifier => .CallModifier,
25916 .prefetch_options => .PrefetchOptions,
25917 .export_options => .ExportOptions,
25918 .extern_options => .ExternOptions,
25919 .branch_hint => .BranchHint,
25920 .clobbers => .@"assembly.Clobbers",
25921 .pointer_size => .@"Type.Pointer.Size",
25922 .pointer_attributes => .@"Type.Pointer.Attributes",
25923 .fn_attributes, => .@"Type.Fn.Attributes",
25924 .container_layout => .@"Type.ContainerLayout",
25925 .enum_mode => .@"Type.Enum.Mode",
2598625926 // zig fmt: on
2598725927
2598825928 // Values are handled here.
......@@ -26009,7 +25949,7 @@ fn zirBuiltinValue(sema: *Sema, block: *Block, extended: Zir.Inst.Extended.InstD
2600925949 return sema.coerce(block, callconv_ty, Air.internedToRef(inline_tag_val.toIntern()), src);
2601025950 },
2601125951 };
26012 return Air.internedToRef(ty.toIntern());
25952 return .fromType(try sema.getBuiltinType(src, builtin_type));
2601325953}
2601425954
2601525955fn zirInplaceArithResultTy(sema: *Sema, extended: Zir.Inst.Extended.InstData) CompileError!Air.Inst.Ref {
......@@ -35259,7 +35199,7 @@ fn structFields(
3525935199 .base_node_inst = struct_type.zir_index,
3526035200 .offset = .nodeOffset(.zero),
3526135201 },
35262 .r = .{ .simple = .struct_fields },
35202 .r = .{ .simple = .type },
3526335203 } },
3526435204 .src_base_inst = struct_type.zir_index,
3526535205 .type_name_ctx = struct_type.name,
......@@ -35614,7 +35554,7 @@ fn unionFields(
3561435554 .inlining = null,
3561535555 .comptime_reason = .{ .reason = .{
3561635556 .src = src,
35617 .r = .{ .simple = .union_fields },
35557 .r = .{ .simple = .type },
3561835558 } },
3561935559 .src_base_inst = union_type.zir_index,
3562035560 .type_name_ctx = union_type.name,
......@@ -36077,8 +36017,13 @@ pub fn typeHasOnePossibleValue(sema: *Sema, ty: Type) CompileError!?Value {
3607736017 .manyptr_u8_type,
3607836018 .manyptr_const_u8_type,
3607936019 .manyptr_const_u8_sentinel_0_type,
36020 .manyptr_const_slice_const_u8_type,
3608036021 .slice_const_u8_type,
3608136022 .slice_const_u8_sentinel_0_type,
36023 .slice_const_slice_const_u8_type,
36024 .optional_type_type,
36025 .manyptr_const_type_type,
36026 .slice_const_type_type,
3608236027 .vector_8_i8_type,
3608336028 .vector_16_i8_type,
3608436029 .vector_32_i8_type,
......@@ -37230,7 +37175,7 @@ fn sliceToIpString(
3723037175
3723137176/// Given a slice value, attempts to dereference it into a comptime-known array.
3723237177/// Emits a compile error if the contents of the slice are not comptime-known.
37233/// Asserts that `slice_val` is a slice.
37178/// Asserts that `slice_val` is a slice or a pointer to an array.
3723437179fn derefSliceAsArray(
3723537180 sema: *Sema,
3723637181 block: *Block,
......@@ -37247,7 +37192,7 @@ fn derefSliceAsArray(
3724737192
3724837193/// Given a slice value, attempts to dereference it into a comptime-known array.
3724937194/// Returns `null` if the contents of the slice are not comptime-known.
37250/// Asserts that `slice_val` is a slice.
37195/// Asserts that `slice_val` is a slice or a pointer to an array.
3725137196fn maybeDerefSliceAsArray(
3725237197 sema: *Sema,
3725337198 block: *Block,
......@@ -37257,7 +37202,13 @@ fn maybeDerefSliceAsArray(
3725737202 const pt = sema.pt;
3725837203 const zcu = pt.zcu;
3725937204 const ip = &zcu.intern_pool;
37260 assert(slice_val.typeOf(zcu).isSlice(zcu));
37205 const slice_ty = slice_val.typeOf(zcu);
37206 assert(slice_ty.zigTypeTag(zcu) == .pointer);
37207 switch (slice_ty.ptrInfo(zcu).flags.size) {
37208 .slice => {},
37209 .one => return sema.pointerDeref(block, src, slice_val, slice_ty),
37210 .many, .c => unreachable,
37211 }
3726137212 const slice = switch (ip.indexToKey(slice_val.toIntern())) {
3726237213 .undef => return sema.failWithUseOfUndef(block, src, null),
3726337214 .slice => |slice| slice,
......@@ -37393,7 +37344,7 @@ pub fn resolveDeclaredEnum(
3739337344 .inlining = null,
3739437345 .comptime_reason = .{ .reason = .{
3739537346 .src = src,
37396 .r = .{ .simple = .enum_fields },
37347 .r = .{ .simple = .enum_field_values },
3739737348 } },
3739837349 .src_base_inst = tracked_inst,
3739937350 .type_name_ctx = type_name,
src/Type.zig+8-2
......@@ -317,7 +317,7 @@ pub fn print(ty: Type, writer: *std.Io.Writer, pt: Zcu.PerThread, ctx: ?*Compari
317317 .undefined,
318318 => try writer.print("@TypeOf({s})", .{@tagName(s)}),
319319
320 .enum_literal => try writer.writeAll("@Type(.enum_literal)"),
320 .enum_literal => try writer.writeAll("@EnumLiteral()"),
321321
322322 .generic_poison => unreachable,
323323 },
......@@ -3509,7 +3509,9 @@ pub fn typeDeclSrcLine(ty: Type, zcu: *Zcu) ?u32 {
35093509 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_line,
35103510 .enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_line,
35113511 .opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_line,
3512 .reify => zir.extraData(Zir.Inst.Reify, inst.data.extended.operand).data.src_line,
3512 .reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.src_line,
3513 .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.src_line,
3514 .reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.src_line,
35133515 else => unreachable,
35143516 },
35153517 else => unreachable,
......@@ -4280,6 +4282,10 @@ pub const manyptr_const_u8: Type = .{ .ip_index = .manyptr_const_u8_type };
42804282pub const manyptr_const_u8_sentinel_0: Type = .{ .ip_index = .manyptr_const_u8_sentinel_0_type };
42814283pub const slice_const_u8: Type = .{ .ip_index = .slice_const_u8_type };
42824284pub const slice_const_u8_sentinel_0: Type = .{ .ip_index = .slice_const_u8_sentinel_0_type };
4285pub const slice_const_slice_const_u8: Type = .{ .ip_index = .slice_const_slice_const_u8_type };
4286pub const slice_const_type: Type = .{ .ip_index = .slice_const_type_type };
4287pub const optional_type: Type = .{ .ip_index = .optional_type_type };
4288pub const optional_noreturn: Type = .{ .ip_index = .optional_noreturn_type };
42834289
42844290pub const vector_8_i8: Type = .{ .ip_index = .vector_8_i8_type };
42854291pub const vector_16_i8: Type = .{ .ip_index = .vector_16_i8_type };
src/Value.zig+23
......@@ -2824,6 +2824,29 @@ pub fn resolveLazy(
28242824 .val = resolved_val,
28252825 }));
28262826 },
2827 .error_union => |eu| switch (eu.val) {
2828 .err_name => return val,
2829 .payload => |payload| {
2830 const resolved_payload = try Value.fromInterned(payload).resolveLazy(arena, pt);
2831 if (resolved_payload.toIntern() == payload) return val;
2832 return .fromInterned(try pt.intern(.{ .error_union = .{
2833 .ty = eu.ty,
2834 .val = .{ .payload = resolved_payload.toIntern() },
2835 } }));
2836 },
2837 },
2838 .opt => |opt| switch (opt.val) {
2839 .none => return val,
2840 else => |payload| {
2841 const resolved_payload = try Value.fromInterned(payload).resolveLazy(arena, pt);
2842 if (resolved_payload.toIntern() == payload) return val;
2843 return .fromInterned(try pt.intern(.{ .opt = .{
2844 .ty = opt.ty,
2845 .val = resolved_payload.toIntern(),
2846 } }));
2847 },
2848 },
2849
28272850 else => return val,
28282851 }
28292852}
src/Zcu.zig+19-5
......@@ -416,10 +416,13 @@ pub const BuiltinDecl = enum {
416416 Type,
417417 @"Type.Fn",
418418 @"Type.Fn.Param",
419 @"Type.Fn.Param.Attributes",
420 @"Type.Fn.Attributes",
419421 @"Type.Int",
420422 @"Type.Float",
421423 @"Type.Pointer",
422424 @"Type.Pointer.Size",
425 @"Type.Pointer.Attributes",
423426 @"Type.Array",
424427 @"Type.Vector",
425428 @"Type.Optional",
......@@ -427,10 +430,13 @@ pub const BuiltinDecl = enum {
427430 @"Type.ErrorUnion",
428431 @"Type.EnumField",
429432 @"Type.Enum",
433 @"Type.Enum.Mode",
430434 @"Type.Union",
431435 @"Type.UnionField",
436 @"Type.UnionField.Attributes",
432437 @"Type.Struct",
433438 @"Type.StructField",
439 @"Type.StructField.Attributes",
434440 @"Type.ContainerLayout",
435441 @"Type.Opaque",
436442 @"Type.Declaration",
......@@ -495,10 +501,13 @@ pub const BuiltinDecl = enum {
495501 .Type,
496502 .@"Type.Fn",
497503 .@"Type.Fn.Param",
504 .@"Type.Fn.Param.Attributes",
505 .@"Type.Fn.Attributes",
498506 .@"Type.Int",
499507 .@"Type.Float",
500508 .@"Type.Pointer",
501509 .@"Type.Pointer.Size",
510 .@"Type.Pointer.Attributes",
502511 .@"Type.Array",
503512 .@"Type.Vector",
504513 .@"Type.Optional",
......@@ -506,10 +515,13 @@ pub const BuiltinDecl = enum {
506515 .@"Type.ErrorUnion",
507516 .@"Type.EnumField",
508517 .@"Type.Enum",
518 .@"Type.Enum.Mode",
509519 .@"Type.Union",
510520 .@"Type.UnionField",
521 .@"Type.UnionField.Attributes",
511522 .@"Type.Struct",
512523 .@"Type.StructField",
524 .@"Type.StructField.Attributes",
513525 .@"Type.ContainerLayout",
514526 .@"Type.Opaque",
515527 .@"Type.Declaration",
......@@ -1745,28 +1757,28 @@ pub const SrcLoc = struct {
17451757 const node = node_off.toAbsolute(src_loc.base_node);
17461758 var buf: [1]Ast.Node.Index = undefined;
17471759 const full = tree.fullFnProto(&buf, node).?;
1748 return tree.nodeToSpan(full.ast.align_expr.unwrap().?);
1760 return tree.nodeToSpan(full.ast.align_expr.unwrap() orelse node);
17491761 },
17501762 .node_offset_fn_type_addrspace => |node_off| {
17511763 const tree = try src_loc.file_scope.getTree(zcu);
17521764 const node = node_off.toAbsolute(src_loc.base_node);
17531765 var buf: [1]Ast.Node.Index = undefined;
17541766 const full = tree.fullFnProto(&buf, node).?;
1755 return tree.nodeToSpan(full.ast.addrspace_expr.unwrap().?);
1767 return tree.nodeToSpan(full.ast.addrspace_expr.unwrap() orelse node);
17561768 },
17571769 .node_offset_fn_type_section => |node_off| {
17581770 const tree = try src_loc.file_scope.getTree(zcu);
17591771 const node = node_off.toAbsolute(src_loc.base_node);
17601772 var buf: [1]Ast.Node.Index = undefined;
17611773 const full = tree.fullFnProto(&buf, node).?;
1762 return tree.nodeToSpan(full.ast.section_expr.unwrap().?);
1774 return tree.nodeToSpan(full.ast.section_expr.unwrap() orelse node);
17631775 },
17641776 .node_offset_fn_type_cc => |node_off| {
17651777 const tree = try src_loc.file_scope.getTree(zcu);
17661778 const node = node_off.toAbsolute(src_loc.base_node);
17671779 var buf: [1]Ast.Node.Index = undefined;
17681780 const full = tree.fullFnProto(&buf, node).?;
1769 return tree.nodeToSpan(full.ast.callconv_expr.unwrap().?);
1781 return tree.nodeToSpan(full.ast.callconv_expr.unwrap() orelse node);
17701782 },
17711783
17721784 .node_offset_fn_type_ret_ty => |node_off| {
......@@ -2684,7 +2696,9 @@ pub const LazySrcLoc = struct {
26842696 .union_decl => zir.extraData(Zir.Inst.UnionDecl, inst.data.extended.operand).data.src_node,
26852697 .enum_decl => zir.extraData(Zir.Inst.EnumDecl, inst.data.extended.operand).data.src_node,
26862698 .opaque_decl => zir.extraData(Zir.Inst.OpaqueDecl, inst.data.extended.operand).data.src_node,
2687 .reify => zir.extraData(Zir.Inst.Reify, inst.data.extended.operand).data.node,
2699 .reify_enum => zir.extraData(Zir.Inst.ReifyEnum, inst.data.extended.operand).data.node,
2700 .reify_struct => zir.extraData(Zir.Inst.ReifyStruct, inst.data.extended.operand).data.node,
2701 .reify_union => zir.extraData(Zir.Inst.ReifyUnion, inst.data.extended.operand).data.node,
26882702 else => unreachable,
26892703 },
26902704 else => unreachable,
src/codegen/aarch64/Assemble.zig+11-21
......@@ -120,23 +120,13 @@ const matchers = matchers: {
120120 );
121121 var symbols: Symbols: {
122122 const symbols = @typeInfo(@TypeOf(instruction.symbols)).@"struct".fields;
123 var symbol_fields: [symbols.len]std.builtin.Type.StructField = undefined;
124 for (&symbol_fields, symbols) |*symbol_field, symbol| {
125 const Storage = zonCast(SymbolSpec, @field(instruction.symbols, symbol.name), .{}).Storage();
126 symbol_field.* = .{
127 .name = symbol.name,
128 .type = Storage,
129 .default_value_ptr = null,
130 .is_comptime = false,
131 .alignment = @alignOf(Storage),
132 };
123 var field_names: [symbols.len][]const u8 = undefined;
124 var field_types: [symbols.len]type = undefined;
125 for (symbols, &field_names, &field_types) |symbol, *field_name, *FieldType| {
126 field_name.* = symbol.name;
127 FieldType.* = zonCast(SymbolSpec, @field(instruction.symbols, symbol.name), .{}).Storage();
133128 }
134 break :Symbols @Type(.{ .@"struct" = .{
135 .layout = .auto,
136 .fields = &symbol_fields,
137 .decls = &.{},
138 .is_tuple = false,
139 } });
129 break :Symbols @Struct(.auto, null, &field_names, &field_types, &@splat(.{}));
140130 } = undefined;
141131 const Symbol = std.meta.FieldEnum(@TypeOf(instruction.symbols));
142132 comptime var unused_symbols: std.enums.EnumSet(Symbol) = .initFull();
......@@ -334,7 +324,7 @@ const SymbolSpec = union(enum) {
334324 .reg => aarch64.encoding.Register,
335325 .arrangement => aarch64.encoding.Register.Arrangement,
336326 .systemreg => aarch64.encoding.Register.System,
337 .imm => |imm_spec| @Type(.{ .int = imm_spec.type }),
327 .imm => |imm_spec| @Int(imm_spec.type.signedness, imm_spec.type.bits),
338328 .fimm => f16,
339329 .extend => Instruction.DataProcessingRegister.AddSubtractExtendedRegister.Option,
340330 .shift => Instruction.DataProcessingRegister.Shift.Op,
......@@ -413,13 +403,13 @@ const SymbolSpec = union(enum) {
413403 return systemreg;
414404 },
415405 .imm => |imm_spec| {
416 const imm = std.fmt.parseInt(@Type(.{ .int = .{
417 .signedness = imm_spec.type.signedness,
418 .bits = switch (imm_spec.adjust) {
406 const imm = std.fmt.parseInt(@Int(
407 imm_spec.type.signedness,
408 switch (imm_spec.adjust) {
419409 .none, .neg_wrap => imm_spec.type.bits,
420410 .dec => imm_spec.type.bits + 1,
421411 },
422 } }), token, 0) catch {
412 ), token, 0) catch {
423413 log.debug("invalid immediate: \"{f}\"", .{std.zig.fmtString(token)});
424414 return null;
425415 };
src/codegen/aarch64/Select.zig+22-14
......@@ -8928,12 +8928,16 @@ pub const Value = struct {
89288928 constant: Constant,
89298929
89308930 pub const Tag = @typeInfo(Parent).@"union".tag_type.?;
8931 pub const Payload = @Type(.{ .@"union" = .{
8932 .layout = .auto,
8933 .tag_type = null,
8934 .fields = @typeInfo(Parent).@"union".fields,
8935 .decls = &.{},
8936 } });
8931 pub const Payload = Payload: {
8932 const fields = @typeInfo(Parent).@"union".fields;
8933 var types: [fields.len]type = undefined;
8934 var names: [fields.len][]const u8 = undefined;
8935 for (fields, &types, &names) |f, *ty, *name| {
8936 ty.* = f.type;
8937 name.* = f.name;
8938 }
8939 break :Payload @Union(.auto, null, &names, &types, &@splat(.{}));
8940 };
89378941 };
89388942
89398943 pub const Location = union(enum(u1)) {
......@@ -8949,12 +8953,16 @@ pub const Value = struct {
89498953 },
89508954
89518955 pub const Tag = @typeInfo(Location).@"union".tag_type.?;
8952 pub const Payload = @Type(.{ .@"union" = .{
8953 .layout = .auto,
8954 .tag_type = null,
8955 .fields = @typeInfo(Location).@"union".fields,
8956 .decls = &.{},
8957 } });
8956 pub const Payload = Payload: {
8957 const fields = @typeInfo(Location).@"union".fields;
8958 var types: [fields.len]type = undefined;
8959 var names: [fields.len][]const u8 = undefined;
8960 for (fields, &types, &names) |f, *ty, *name| {
8961 ty.* = f.type;
8962 name.* = f.name;
8963 }
8964 break :Payload @Union(.auto, null, &names, &types, &@splat(.{}));
8965 };
89588966 };
89598967
89608968 pub const Indirect = packed struct(u32) {
......@@ -11210,7 +11218,7 @@ pub const Value = struct {
1121011218 .storage = .{ .u64 = switch (size) {
1121111219 else => unreachable,
1121211220 inline 1...8 => |ct_size| std.mem.readInt(
11213 @Type(.{ .int = .{ .signedness = .unsigned, .bits = 8 * ct_size } }),
11221 @Int(.unsigned, 8 * ct_size),
1121411222 buffer[@intCast(offset)..][0..ct_size],
1121511223 isel.target.cpu.arch.endian(),
1121611224 ),
......@@ -11438,7 +11446,7 @@ fn writeKeyToMemory(isel: *Select, constant_key: InternPool.Key, buffer: []u8) e
1143811446 switch (buffer.len) {
1143911447 else => unreachable,
1144011448 inline 1...4 => |size| std.mem.writeInt(
11441 @Type(.{ .int = .{ .signedness = .unsigned, .bits = 8 * size } }),
11449 @Int(.unsigned, 8 * size),
1144211450 buffer[0..size],
1144311451 @intCast(error_int),
1144411452 isel.target.cpu.arch.endian(),
src/codegen/c/Type.zig+70
......@@ -1416,6 +1416,9 @@ pub const Pool = struct {
14161416 .null_type,
14171417 .undefined_type,
14181418 .enum_literal_type,
1419 .optional_type_type,
1420 .manyptr_const_type_type,
1421 .slice_const_type_type,
14191422 => return .void,
14201423 .u1_type, .u8_type => return .u8,
14211424 .i8_type => return .i8,
......@@ -1525,6 +1528,73 @@ pub const Pool = struct {
15251528 return pool.fromFields(allocator, .@"struct", &fields, kind);
15261529 },
15271530
1531 .manyptr_const_slice_const_u8_type => {
1532 const target = &mod.resolved_target.result;
1533 var fields: [2]Info.Field = .{
1534 .{
1535 .name = .{ .index = .ptr },
1536 .ctype = try pool.getPointer(allocator, .{
1537 .elem_ctype = .u8,
1538 .@"const" = true,
1539 .nonstring = true,
1540 }),
1541 .alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
1542 },
1543 .{
1544 .name = .{ .index = .len },
1545 .ctype = .usize,
1546 .alignas = AlignAs.fromAbiAlignment(
1547 .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
1548 ),
1549 },
1550 };
1551 const slice_const_u8 = try pool.fromFields(allocator, .@"struct", &fields, kind);
1552 return pool.getPointer(allocator, .{
1553 .elem_ctype = slice_const_u8,
1554 .@"const" = true,
1555 });
1556 },
1557 .slice_const_slice_const_u8_type => {
1558 const target = &mod.resolved_target.result;
1559 var fields: [2]Info.Field = .{
1560 .{
1561 .name = .{ .index = .ptr },
1562 .ctype = try pool.getPointer(allocator, .{
1563 .elem_ctype = .u8,
1564 .@"const" = true,
1565 .nonstring = true,
1566 }),
1567 .alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
1568 },
1569 .{
1570 .name = .{ .index = .len },
1571 .ctype = .usize,
1572 .alignas = AlignAs.fromAbiAlignment(
1573 .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
1574 ),
1575 },
1576 };
1577 const slice_const_u8 = try pool.fromFields(allocator, .@"struct", &fields, .forward);
1578 fields = .{
1579 .{
1580 .name = .{ .index = .ptr },
1581 .ctype = try pool.getPointer(allocator, .{
1582 .elem_ctype = slice_const_u8,
1583 .@"const" = true,
1584 }),
1585 .alignas = AlignAs.fromAbiAlignment(Type.ptrAbiAlignment(target)),
1586 },
1587 .{
1588 .name = .{ .index = .len },
1589 .ctype = .usize,
1590 .alignas = AlignAs.fromAbiAlignment(
1591 .fromByteUnits(std.zig.target.intAlignment(target, target.ptrBitWidth())),
1592 ),
1593 },
1594 };
1595 return pool.fromFields(allocator, .@"struct", &fields, kind);
1596 },
1597
15281598 .vector_8_i8_type => {
15291599 const vector_ctype = try pool.getVector(allocator, .{
15301600 .elem_ctype = .i8,
src/codegen/x86_64/CodeGen.zig+5-7
......@@ -189867,9 +189867,7 @@ const Select = struct {
189867189867 }
189868189868
189869189869 fn adjustedImm(op: Select.Operand, comptime SignedImm: type, s: *const Select) SignedImm {
189870 const UnsignedImm = @Type(.{
189871 .int = .{ .signedness = .unsigned, .bits = @typeInfo(SignedImm).int.bits },
189872 });
189870 const UnsignedImm = @Int(.unsigned, @typeInfo(SignedImm).int.bits);
189873189871 const lhs: SignedImm = lhs: switch (op.flags.adjust.lhs) {
189874189872 .none => 0,
189875189873 .ptr_size => @divExact(s.cg.target.ptrBitWidth(), 8),
......@@ -189934,10 +189932,10 @@ const Select = struct {
189934189932 const RefImm = switch (size) {
189935189933 else => comptime unreachable,
189936189934 .none => Imm,
189937 .byte, .word, .dword, .qword => @Type(comptime .{ .int = .{
189938 .signedness = @typeInfo(Imm).int.signedness,
189939 .bits = size.bitSize(undefined),
189940 } }),
189935 .byte, .word, .dword, .qword => @Int(
189936 @typeInfo(Imm).int.signedness,
189937 size.bitSize(undefined),
189938 ),
189941189939 };
189942189940 break :lhs @bitCast(@as(Imm, @intCast(@as(RefImm, switch (adjust) {
189943189941 else => comptime unreachable,
src/codegen/x86_64/Emit.zig+1-1
......@@ -708,7 +708,7 @@ pub fn emitMir(emit: *Emit) Error!void {
708708 switch (reloc.source_length) {
709709 else => unreachable,
710710 inline 1, 4 => |source_length| std.mem.writeInt(
711 @Type(.{ .int = .{ .signedness = .signed, .bits = @as(u16, 8) * source_length } }),
711 @Int(.signed, @as(u16, 8) * source_length),
712712 inst_bytes[reloc.source_offset..][0..source_length],
713713 @intCast(disp),
714714 .little,
src/link.zig+1-4
......@@ -51,10 +51,7 @@ pub const Diags = struct {
5151
5252 const Int = blk: {
5353 const bits = @typeInfo(@This()).@"struct".fields.len;
54 break :blk @Type(.{ .int = .{
55 .signedness = .unsigned,
56 .bits = bits,
57 } });
54 break :blk @Int(.unsigned, bits);
5855 };
5956
6057 pub fn anySet(ef: Flags) bool {
src/link/Dwarf.zig+19-14
......@@ -4490,7 +4490,12 @@ fn updateContainerTypeWriterError(
44904490 .enum_decl => @as(Zir.Inst.EnumDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
44914491 .union_decl => @as(Zir.Inst.UnionDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
44924492 .opaque_decl => @as(Zir.Inst.OpaqueDecl.Small, @bitCast(decl_inst.data.extended.small)).name_strategy,
4493 .reify => @as(Zir.Inst.NameStrategy, @enumFromInt(decl_inst.data.extended.small)),
4493
4494 .reify_enum,
4495 .reify_struct,
4496 .reify_union,
4497 => @enumFromInt(decl_inst.data.extended.small),
4498
44944499 else => unreachable,
44954500 },
44964501 else => unreachable,
......@@ -5125,25 +5130,23 @@ pub fn resolveRelocs(dwarf: *Dwarf) RelocError!void {
51255130
51265131fn DeclValEnum(comptime T: type) type {
51275132 const decls = @typeInfo(T).@"struct".decls;
5128 @setEvalBranchQuota(7 * decls.len);
5129 var fields: [decls.len]std.builtin.Type.EnumField = undefined;
5133 @setEvalBranchQuota(10 * decls.len);
5134 var field_names: [decls.len][]const u8 = undefined;
51305135 var fields_len = 0;
51315136 var min_value: ?comptime_int = null;
51325137 var max_value: ?comptime_int = null;
51335138 for (decls) |decl| {
51345139 if (std.mem.startsWith(u8, decl.name, "HP_") or std.mem.endsWith(u8, decl.name, "_user")) continue;
51355140 const value = @field(T, decl.name);
5136 fields[fields_len] = .{ .name = decl.name, .value = value };
5141 field_names[fields_len] = decl.name;
51375142 fields_len += 1;
51385143 if (min_value == null or min_value.? > value) min_value = value;
51395144 if (max_value == null or max_value.? < value) max_value = value;
51405145 }
5141 return @Type(.{ .@"enum" = .{
5142 .tag_type = std.math.IntFittingRange(min_value orelse 0, max_value orelse 0),
5143 .fields = fields[0..fields_len],
5144 .decls = &.{},
5145 .is_exhaustive = true,
5146 } });
5146 const TagInt = std.math.IntFittingRange(min_value orelse 0, max_value orelse 0);
5147 var field_vals: [fields_len]TagInt = undefined;
5148 for (field_names[0..fields_len], &field_vals) |name, *val| val.* = @field(T, name);
5149 return @Enum(TagInt, .exhaustive, field_names[0..fields_len], &field_vals);
51475150}
51485151
51495152const AbbrevCode = enum {
......@@ -6377,10 +6380,12 @@ fn freeCommonEntry(
63776380
63786381fn writeInt(dwarf: *Dwarf, buf: []u8, int: u64) void {
63796382 switch (buf.len) {
6380 inline 0...8 => |len| std.mem.writeInt(@Type(.{ .int = .{
6381 .signedness = .unsigned,
6382 .bits = len * 8,
6383 } }), buf[0..len], @intCast(int), dwarf.endian),
6383 inline 0...8 => |len| std.mem.writeInt(
6384 @Int(.unsigned, len * 8),
6385 buf[0..len],
6386 @intCast(int),
6387 dwarf.endian,
6388 ),
63846389 else => unreachable,
63856390 }
63866391}
src/link/MappedFile.zig+6-14
......@@ -108,10 +108,7 @@ pub const Node = extern struct {
108108 has_content: bool,
109109 /// Whether a moved event on this node bubbles down to children.
110110 bubbles_moved: bool,
111 unused: @Type(.{ .int = .{
112 .signedness = .unsigned,
113 .bits = 32 - @bitSizeOf(std.mem.Alignment) - 6,
114 } }) = 0,
111 unused: @Int(.unsigned, 32 - @bitSizeOf(std.mem.Alignment) - 6) = 0,
115112 };
116113
117114 pub const Location = union(enum(u1)) {
......@@ -122,19 +119,14 @@ pub const Node = extern struct {
122119 },
123120 large: extern struct {
124121 index: usize,
125 unused: @Type(.{ .int = .{
126 .signedness = .unsigned,
127 .bits = 64 - @bitSizeOf(usize),
128 } }) = 0,
122 unused: @Int(.unsigned, 64 - @bitSizeOf(usize)) = 0,
129123 },
130124
131125 pub const Tag = @typeInfo(Location).@"union".tag_type.?;
132 pub const Payload = @Type(.{ .@"union" = .{
133 .layout = .@"extern",
134 .tag_type = null,
135 .fields = @typeInfo(Location).@"union".fields,
136 .decls = &.{},
137 } });
126 pub const Payload = extern union {
127 small: @FieldType(Location, "small"),
128 large: @FieldType(Location, "large"),
129 };
138130
139131 pub fn resolve(loc: Location, mf: *const MappedFile) [2]u64 {
140132 return switch (loc) {
src/main.zig+1-1
......@@ -136,7 +136,7 @@ var log_scopes: std.ArrayList([]const u8) = .empty;
136136
137137pub fn log(
138138 comptime level: std.log.Level,
139 comptime scope: @Type(.enum_literal),
139 comptime scope: @EnumLiteral(),
140140 comptime format: []const u8,
141141 args: anytype,
142142) void {
src/print_zir.zig+93-11
......@@ -399,6 +399,7 @@ const Writer = struct {
399399 .splat,
400400 .reduce,
401401 .bitcast,
402 .reify_int,
402403 .vector_type,
403404 .max,
404405 .min,
......@@ -568,6 +569,8 @@ const Writer = struct {
568569 .work_group_id,
569570 .branch_hint,
570571 .float_op_result_ty,
572 .reify_tuple,
573 .reify_pointer_sentinel_ty,
571574 => {
572575 const inst_data = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
573576 try self.writeInstRef(stream, inst_data.operand);
......@@ -575,23 +578,13 @@ const Writer = struct {
575578 try self.writeSrcNode(stream, inst_data.node);
576579 },
577580
578 .reify => {
579 const inst_data = self.code.extraData(Zir.Inst.Reify, extended.operand).data;
580 try stream.print("line({d}), ", .{inst_data.src_line});
581 try self.writeInstRef(stream, inst_data.operand);
582 try stream.writeAll(")) ");
583 const prev_parent_decl_node = self.parent_decl_node;
584 self.parent_decl_node = inst_data.node;
585 defer self.parent_decl_node = prev_parent_decl_node;
586 try self.writeSrcNode(stream, .zero);
587 },
588
589581 .builtin_extern,
590582 .c_define,
591583 .error_cast,
592584 .wasm_memory_grow,
593585 .prefetch,
594586 .c_va_arg,
587 .reify_enum_value_slice_ty,
595588 => {
596589 const inst_data = self.code.extraData(Zir.Inst.BinNode, extended.operand).data;
597590 try self.writeInstRef(stream, inst_data.lhs);
......@@ -601,6 +594,95 @@ const Writer = struct {
601594 try self.writeSrcNode(stream, inst_data.node);
602595 },
603596
597 .reify_slice_arg_ty => {
598 const reify_slice_arg_info: Zir.Inst.ReifySliceArgInfo = @enumFromInt(extended.operand);
599 const extra = self.code.extraData(Zir.Inst.UnNode, extended.operand).data;
600 try stream.print("{t}, ", .{reify_slice_arg_info});
601 try self.writeInstRef(stream, extra.operand);
602 try stream.writeAll(")) ");
603 try self.writeSrcNode(stream, extra.node);
604 },
605
606 .reify_pointer => {
607 const extra = self.code.extraData(Zir.Inst.ReifyPointer, extended.operand).data;
608 try self.writeInstRef(stream, extra.size);
609 try stream.writeAll(", ");
610 try self.writeInstRef(stream, extra.attrs);
611 try stream.writeAll(", ");
612 try self.writeInstRef(stream, extra.elem_ty);
613 try stream.writeAll(", ");
614 try self.writeInstRef(stream, extra.sentinel);
615 try stream.writeAll(")) ");
616 try self.writeSrcNode(stream, extra.node);
617 },
618 .reify_fn => {
619 const extra = self.code.extraData(Zir.Inst.ReifyFn, extended.operand).data;
620 try self.writeInstRef(stream, extra.param_types);
621 try stream.writeAll(", ");
622 try self.writeInstRef(stream, extra.param_attrs);
623 try stream.writeAll(", ");
624 try self.writeInstRef(stream, extra.ret_ty);
625 try stream.writeAll(", ");
626 try self.writeInstRef(stream, extra.fn_attrs);
627 try stream.writeAll(")) ");
628 try self.writeSrcNode(stream, extra.node);
629 },
630 .reify_struct => {
631 const extra = self.code.extraData(Zir.Inst.ReifyStruct, extended.operand).data;
632 const name_strat: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
633 try stream.print("line({d}), {t}, ", .{ extra.src_line, name_strat });
634 try self.writeInstRef(stream, extra.layout);
635 try stream.writeAll(", ");
636 try self.writeInstRef(stream, extra.backing_ty);
637 try stream.writeAll(", ");
638 try self.writeInstRef(stream, extra.field_names);
639 try stream.writeAll(", ");
640 try self.writeInstRef(stream, extra.field_types);
641 try stream.writeAll(", ");
642 try self.writeInstRef(stream, extra.field_attrs);
643 try stream.writeAll(")) ");
644 const prev_parent_decl_node = self.parent_decl_node;
645 self.parent_decl_node = extra.node;
646 defer self.parent_decl_node = prev_parent_decl_node;
647 try self.writeSrcNode(stream, .zero);
648 },
649 .reify_union => {
650 const extra = self.code.extraData(Zir.Inst.ReifyUnion, extended.operand).data;
651 const name_strat: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
652 try stream.print("line({d}), {t}, ", .{ extra.src_line, name_strat });
653 try self.writeInstRef(stream, extra.layout);
654 try stream.writeAll(", ");
655 try self.writeInstRef(stream, extra.arg_ty);
656 try stream.writeAll(", ");
657 try self.writeInstRef(stream, extra.field_names);
658 try stream.writeAll(", ");
659 try self.writeInstRef(stream, extra.field_types);
660 try stream.writeAll(", ");
661 try self.writeInstRef(stream, extra.field_attrs);
662 try stream.writeAll(")) ");
663 const prev_parent_decl_node = self.parent_decl_node;
664 self.parent_decl_node = extra.node;
665 defer self.parent_decl_node = prev_parent_decl_node;
666 try self.writeSrcNode(stream, .zero);
667 },
668 .reify_enum => {
669 const extra = self.code.extraData(Zir.Inst.ReifyEnum, extended.operand).data;
670 const name_strat: Zir.Inst.NameStrategy = @enumFromInt(extended.small);
671 try stream.print("line({d}), {t}, ", .{ extra.src_line, name_strat });
672 try self.writeInstRef(stream, extra.tag_ty);
673 try stream.writeAll(", ");
674 try self.writeInstRef(stream, extra.mode);
675 try stream.writeAll(", ");
676 try self.writeInstRef(stream, extra.field_names);
677 try stream.writeAll(", ");
678 try self.writeInstRef(stream, extra.field_values);
679 try stream.writeAll(")) ");
680 const prev_parent_decl_node = self.parent_decl_node;
681 self.parent_decl_node = extra.node;
682 defer self.parent_decl_node = prev_parent_decl_node;
683 try self.writeSrcNode(stream, .zero);
684 },
685
604686 .cmpxchg => try self.writeCmpxchg(stream, extended),
605687 .ptr_cast_full => try self.writePtrCastFull(stream, extended),
606688 .ptr_cast_no_dest => try self.writePtrCastNoDest(stream, extended),
stage1/zig1.wasm
Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ
test/behavior/basic.zig+2-5
......@@ -1264,12 +1264,9 @@ test "reference to inferred local variable works as expected" {
12641264 try expect(crasher_local.lets_crash != a.lets_crash);
12651265}
12661266
1267test "@Type returned from block" {
1267test "@Int returned from block" {
12681268 const T = comptime b: {
1269 break :b @Type(.{ .int = .{
1270 .signedness = .unsigned,
1271 .bits = 8,
1272 } });
1269 break :b @Int(.unsigned, 8);
12731270 };
12741271 try std.testing.expect(T == u8);
12751272}
test/behavior/bit_shifting.zig+1-10
......@@ -119,21 +119,12 @@ test "Saturating Shift Left where lhs is of a computed type" {
119119 if (builtin.zig_backend == .stage2_riscv64) return error.SkipZigTest;
120120
121121 const S = struct {
122 fn getIntShiftType(comptime T: type) type {
123 var unsigned_shift_type = @typeInfo(std.math.Log2Int(T)).int;
124 unsigned_shift_type.signedness = .signed;
125
126 return @Type(.{
127 .int = unsigned_shift_type,
128 });
129 }
130
131122 pub fn FixedPoint(comptime ValueType: type) type {
132123 return struct {
133124 value: ValueType,
134125 exponent: ShiftType,
135126
136 const ShiftType: type = getIntShiftType(ValueType);
127 const ShiftType = @Int(.signed, @typeInfo(std.math.Log2Int(ValueType)).int.bits);
137128
138129 pub fn shiftExponent(self: @This(), shift: ShiftType) @This() {
139130 const shiftAbs = @abs(shift);
test/behavior/call.zig+1-1
......@@ -355,7 +355,7 @@ test "inline call doesn't re-evaluate non generic struct" {
355355 try comptime @call(.always_inline, S.foo, ArgTuple{.{ .a = 123, .b = 45 }});
356356}
357357
358test "Enum constructed by @Type passed as generic argument" {
358test "Enum constructed by @Enum passed as generic argument" {
359359 const S = struct {
360360 const E = std.meta.FieldEnum(struct {
361361 prev_pos: bool,
test/behavior/cast.zig+8-3
......@@ -2446,9 +2446,14 @@ test "peer type resolution: pointer attributes are combined correctly" {
24462446 };
24472447
24482448 const NonAllowZero = comptime blk: {
2449 var ti = @typeInfo(@TypeOf(r1, r2, r3, r4));
2450 ti.pointer.is_allowzero = false;
2451 break :blk @Type(ti);
2449 const ptr = @typeInfo(@TypeOf(r1, r2, r3, r4)).pointer;
2450 break :blk @Pointer(ptr.size, .{
2451 .@"const" = ptr.is_const,
2452 .@"volatile" = ptr.is_volatile,
2453 .@"allowzero" = false,
2454 .@"align" = ptr.alignment,
2455 .@"addrspace" = ptr.address_space,
2456 }, ptr.child, ptr.sentinel());
24522457 };
24532458 try expectEqualSlices(u8, std.mem.span(@volatileCast(@as(NonAllowZero, @ptrCast(r1)))), "foo");
24542459 try expectEqualSlices(u8, std.mem.span(@volatileCast(@as(NonAllowZero, @ptrCast(r2)))), "bar");
test/behavior/enum.zig+1-4
......@@ -1283,10 +1283,7 @@ test "Non-exhaustive enum backed by comptime_int" {
12831283test "matching captures causes enum equivalence" {
12841284 const S = struct {
12851285 fn Nonexhaustive(comptime I: type) type {
1286 const UTag = @Type(.{ .int = .{
1287 .signedness = .unsigned,
1288 .bits = @typeInfo(I).int.bits,
1289 } });
1286 const UTag = @Int(.unsigned, @typeInfo(I).int.bits);
12901287 return enum(UTag) { _ };
12911288 }
12921289 };
test/behavior/fn.zig+2-2
......@@ -556,10 +556,10 @@ test "lazy values passed to anytype parameter" {
556556
557557test "pass and return comptime-only types" {
558558 const S = struct {
559 fn returnNull(comptime x: @Type(.null)) @Type(.null) {
559 fn returnNull(comptime x: @TypeOf(null)) @TypeOf(null) {
560560 return x;
561561 }
562 fn returnUndefined(comptime x: @Type(.undefined)) @Type(.undefined) {
562 fn returnUndefined(comptime x: @TypeOf(undefined)) @TypeOf(undefined) {
563563 return x;
564564 }
565565 };
test/behavior/generics.zig+1-9
......@@ -263,15 +263,7 @@ test "generic function instantiation turns into comptime call" {
263263
264264 pub fn FieldEnum(comptime T: type) type {
265265 _ = T;
266 var enumFields: [1]std.builtin.Type.EnumField = .{.{ .name = "A", .value = 0 }};
267 return @Type(.{
268 .@"enum" = .{
269 .tag_type = u0,
270 .fields = &enumFields,
271 .decls = &.{},
272 .is_exhaustive = true,
273 },
274 });
266 return @Enum(u0, .exhaustive, &.{"A"}, &.{0});
275267 }
276268 };
277269 try S.doTheTest();
test/behavior/sizeof_and_typeof.zig+6-6
......@@ -338,14 +338,14 @@ test "peer type resolution with @TypeOf doesn't trigger dependency loop check" {
338338
339339test "@sizeOf reified union zero-size payload fields" {
340340 comptime {
341 try std.testing.expect(0 == @sizeOf(@Type(@typeInfo(union {}))));
342 try std.testing.expect(0 == @sizeOf(@Type(@typeInfo(union { a: void }))));
341 try std.testing.expect(0 == @sizeOf(@Union(.auto, null, &.{}, &.{}, &.{})));
342 try std.testing.expect(0 == @sizeOf(@Union(.auto, null, &.{"a"}, &.{void}, &.{.{}})));
343343 if (builtin.mode == .Debug or builtin.mode == .ReleaseSafe) {
344 try std.testing.expect(1 == @sizeOf(@Type(@typeInfo(union { a: void, b: void }))));
345 try std.testing.expect(1 == @sizeOf(@Type(@typeInfo(union { a: void, b: void, c: void }))));
344 try std.testing.expect(1 == @sizeOf(@Union(.auto, null, &.{ "a", "b" }, &.{ void, void }, &.{ .{}, .{} })));
345 try std.testing.expect(1 == @sizeOf(@Union(.auto, null, &.{ "a", "b", "c" }, &.{ void, void, void }, &.{ .{}, .{}, .{} })));
346346 } else {
347 try std.testing.expect(0 == @sizeOf(@Type(@typeInfo(union { a: void, b: void }))));
348 try std.testing.expect(0 == @sizeOf(@Type(@typeInfo(union { a: void, b: void, c: void }))));
347 try std.testing.expect(0 == @sizeOf(@Union(.auto, null, &.{ "a", "b" }, &.{ void, void }, &.{ .{}, .{} })));
348 try std.testing.expect(0 == @sizeOf(@Union(.auto, null, &.{ "a", "b", "c" }, &.{ void, void, void }, &.{ .{}, .{}, .{} })));
349349 }
350350 }
351351}
test/behavior/struct.zig+1-4
......@@ -2034,10 +2034,7 @@ test "matching captures causes struct equivalence" {
20342034 fn UnsignedWrapper(comptime I: type) type {
20352035 const bits = @typeInfo(I).int.bits;
20362036 return struct {
2037 x: @Type(.{ .int = .{
2038 .signedness = .unsigned,
2039 .bits = bits,
2040 } }),
2037 x: @Int(.unsigned, bits),
20412038 };
20422039 }
20432040 };
test/behavior/switch.zig+4-2
......@@ -843,7 +843,8 @@ test "switch capture peer type resolution for in-memory coercible payloads" {
843843 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
844844
845845 const T1 = c_int;
846 const T2 = @Type(@typeInfo(T1));
846 const t1_info = @typeInfo(T1).int;
847 const T2 = @Int(t1_info.signedness, t1_info.bits);
847848
848849 comptime assert(T1 != T2);
849850
......@@ -865,7 +866,8 @@ test "switch pointer capture peer type resolution" {
865866 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
866867
867868 const T1 = c_int;
868 const T2 = @Type(@typeInfo(T1));
869 const t1_info = @typeInfo(T1).int;
870 const T2 = @Int(t1_info.signedness, t1_info.bits);
869871
870872 comptime assert(T1 != T2);
871873
test/behavior/switch_loop.zig+1-4
......@@ -230,10 +230,7 @@ test "switch loop on larger than pointer integer" {
230230 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
231231 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
232232
233 var entry: @Type(.{ .int = .{
234 .signedness = .unsigned,
235 .bits = @bitSizeOf(usize) + 1,
236 } }) = undefined;
233 var entry: @Int(.unsigned, @bitSizeOf(usize) + 1) = undefined;
237234 entry = 0;
238235 loop: switch (entry) {
239236 0 => {
test/behavior/tuple.zig+4-55
......@@ -130,29 +130,7 @@ test "array-like initializer for tuple types" {
130130 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
131131 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
132132
133 const T = @Type(.{
134 .@"struct" = .{
135 .is_tuple = true,
136 .layout = .auto,
137 .decls = &.{},
138 .fields = &.{
139 .{
140 .name = "0",
141 .type = i32,
142 .default_value_ptr = null,
143 .is_comptime = false,
144 .alignment = @alignOf(i32),
145 },
146 .{
147 .name = "1",
148 .type = u8,
149 .default_value_ptr = null,
150 .is_comptime = false,
151 .alignment = @alignOf(u8),
152 },
153 },
154 },
155 });
133 const T = @Tuple(&.{ i32, u8 });
156134 const S = struct {
157135 fn doTheTest() !void {
158136 var obj: T = .{ -1234, 128 };
......@@ -320,20 +298,7 @@ test "zero sized struct in tuple handled correctly" {
320298 const Self = @This();
321299 const Inner = struct {};
322300
323 data: @Type(.{
324 .@"struct" = .{
325 .is_tuple = true,
326 .layout = .auto,
327 .decls = &.{},
328 .fields = &.{.{
329 .name = "0",
330 .type = Inner,
331 .default_value_ptr = null,
332 .is_comptime = false,
333 .alignment = @alignOf(Inner),
334 }},
335 },
336 }),
301 data: @Tuple(&.{Inner}),
337302
338303 pub fn do(this: Self) usize {
339304 return @sizeOf(@TypeOf(this));
......@@ -470,12 +435,7 @@ test "coerce anon tuple to tuple" {
470435}
471436
472437test "empty tuple type" {
473 const S = @Type(.{ .@"struct" = .{
474 .layout = .auto,
475 .fields = &.{},
476 .decls = &.{},
477 .is_tuple = true,
478 } });
438 const S = @Tuple(&.{});
479439
480440 const s: S = .{};
481441 try expect(s.len == 0);
......@@ -616,18 +576,7 @@ test "OPV tuple fields aren't comptime" {
616576 const t_info = @typeInfo(T);
617577 try expect(!t_info.@"struct".fields[0].is_comptime);
618578
619 const T2 = @Type(.{ .@"struct" = .{
620 .layout = .auto,
621 .fields = &.{.{
622 .name = "0",
623 .type = void,
624 .default_value_ptr = null,
625 .is_comptime = false,
626 .alignment = @alignOf(void),
627 }},
628 .decls = &.{},
629 .is_tuple = true,
630 } });
579 const T2 = @Tuple(&.{void});
631580 const t2_info = @typeInfo(T2);
632581 try expect(!t2_info.@"struct".fields[0].is_comptime);
633582}
test/behavior/type.zig+93-477
......@@ -4,63 +4,17 @@ const Type = std.builtin.Type;
44const testing = std.testing;
55const assert = std.debug.assert;
66
7fn testTypes(comptime types: []const type) !void {
8 inline for (types) |testType| {
9 try testing.expect(testType == @Type(@typeInfo(testType)));
10 }
11}
12
13test "Type.MetaType" {
14 try testing.expect(type == @Type(.{ .type = {} }));
15 try testTypes(&[_]type{type});
16}
17
18test "Type.Void" {
19 try testing.expect(void == @Type(.{ .void = {} }));
20 try testTypes(&[_]type{void});
21}
22
23test "Type.Bool" {
24 try testing.expect(bool == @Type(.{ .bool = {} }));
25 try testTypes(&[_]type{bool});
26}
27
28test "Type.NoReturn" {
29 try testing.expect(noreturn == @Type(.{ .noreturn = {} }));
30 try testTypes(&[_]type{noreturn});
31}
32
337test "Type.Int" {
34 try testing.expect(u1 == @Type(.{ .int = .{ .signedness = .unsigned, .bits = 1 } }));
35 try testing.expect(i1 == @Type(.{ .int = .{ .signedness = .signed, .bits = 1 } }));
36 try testing.expect(u8 == @Type(.{ .int = .{ .signedness = .unsigned, .bits = 8 } }));
37 try testing.expect(i8 == @Type(.{ .int = .{ .signedness = .signed, .bits = 8 } }));
38 try testing.expect(u64 == @Type(.{ .int = .{ .signedness = .unsigned, .bits = 64 } }));
39 try testing.expect(i64 == @Type(.{ .int = .{ .signedness = .signed, .bits = 64 } }));
40 try testTypes(&[_]type{ u8, u32, i64 });
41}
42
43test "Type.ComptimeFloat" {
44 try testTypes(&[_]type{comptime_float});
45}
46test "Type.ComptimeInt" {
47 try testTypes(&[_]type{comptime_int});
48}
49test "Type.Undefined" {
50 try testTypes(&[_]type{@TypeOf(undefined)});
51}
52test "Type.Null" {
53 try testTypes(&[_]type{@TypeOf(null)});
54}
55
56test "Type.EnumLiteral" {
57 try testTypes(&[_]type{
58 @TypeOf(.Dummy),
59 });
8 try testing.expect(u1 == @Int(.unsigned, 1));
9 try testing.expect(i1 == @Int(.signed, 1));
10 try testing.expect(u8 == @Int(.unsigned, 8));
11 try testing.expect(i8 == @Int(.signed, 8));
12 try testing.expect(u64 == @Int(.unsigned, 64));
13 try testing.expect(i64 == @Int(.signed, 64));
6014}
6115
6216test "Type.Pointer" {
63 try testTypes(&[_]type{
17 inline for (&[_]type{
6418 // One Value Pointer Types
6519 *u8, *const u8,
6620 *volatile u8, *const volatile u8,
......@@ -101,62 +55,30 @@ test "Type.Pointer" {
10155 [*c]align(4) volatile u8, [*c]align(4) const volatile u8,
10256 [*c]align(8) u8, [*c]align(8) const u8,
10357 [*c]align(8) volatile u8, [*c]align(8) const volatile u8,
104 });
58 }) |testType| {
59 const ptr = @typeInfo(testType).pointer;
60 try testing.expect(testType == @Pointer(ptr.size, .{
61 .@"const" = ptr.is_const,
62 .@"volatile" = ptr.is_volatile,
63 .@"allowzero" = ptr.is_allowzero,
64 .@"align" = ptr.alignment,
65 .@"addrspace" = ptr.address_space,
66 }, ptr.child, ptr.sentinel()));
67 }
10568}
10669
107test "Type.Float" {
108 try testing.expect(f16 == @Type(.{ .float = .{ .bits = 16 } }));
109 try testing.expect(f32 == @Type(.{ .float = .{ .bits = 32 } }));
110 try testing.expect(f64 == @Type(.{ .float = .{ .bits = 64 } }));
111 try testing.expect(f80 == @Type(.{ .float = .{ .bits = 80 } }));
112 try testing.expect(f128 == @Type(.{ .float = .{ .bits = 128 } }));
113 try testTypes(&[_]type{ f16, f32, f64, f80, f128 });
70test "@Pointer create slice without sentinel" {
71 const Slice = @Pointer(.slice, .{ .@"const" = true, .@"align" = 8 }, ?*i32, null);
72 try testing.expect(Slice == []align(8) const ?*i32);
11473}
11574
116test "Type.Array" {
117 try testing.expect([123]u8 == @Type(.{
118 .array = .{
119 .len = 123,
120 .child = u8,
121 .sentinel_ptr = null,
122 },
123 }));
124 try testing.expect([2]u32 == @Type(.{
125 .array = .{
126 .len = 2,
127 .child = u32,
128 .sentinel_ptr = null,
129 },
130 }));
131 try testing.expect([2:0]u32 == @Type(.{
132 .array = .{
133 .len = 2,
134 .child = u32,
135 .sentinel_ptr = &@as(u32, 0),
136 },
137 }));
138 try testTypes(&[_]type{ [1]u8, [30]usize, [7]bool });
75test "@Pointer create slice with null sentinel" {
76 const Slice = @Pointer(.slice, .{ .@"const" = true, .@"align" = 8 }, ?*i32, @as(?*i32, null));
77 try testing.expect(Slice == [:null]align(8) const ?*i32);
13978}
14079
141test "@Type create slice with null sentinel" {
142 const Slice = @Type(.{
143 .pointer = .{
144 .size = .slice,
145 .is_const = true,
146 .is_volatile = false,
147 .is_allowzero = false,
148 .alignment = 8,
149 .address_space = .generic,
150 .child = *i32,
151 .sentinel_ptr = null,
152 },
153 });
154 try testing.expect(Slice == []align(8) const *i32);
155}
156
157test "@Type picks up the sentinel value from Type" {
158 try testTypes(&[_]type{
159 [11:0]u8, [4:10]u8,
80test "@Pointer on @typeInfo round-trips sentinels" {
81 inline for (&[_]type{
16082 [*:0]u8, [*:0]const u8,
16183 [*:0]volatile u8, [*:0]const volatile u8,
16284 [*:0]align(4) u8, [*:0]align(4) const u8,
......@@ -179,24 +101,16 @@ test "@Type picks up the sentinel value from Type" {
179101 [:0]allowzero align(4) u8, [:0]allowzero align(4) const u8,
180102 [:0]allowzero align(4) volatile u8, [:0]allowzero align(4) const volatile u8,
181103 [:4]allowzero align(4) volatile u8, [:4]allowzero align(4) const volatile u8,
182 });
183}
184
185test "Type.Optional" {
186 try testTypes(&[_]type{
187 ?u8,
188 ?*u8,
189 ?[]u8,
190 ?[*]u8,
191 ?[*c]u8,
192 });
193}
194
195test "Type.ErrorUnion" {
196 try testTypes(&[_]type{
197 error{}!void,
198 error{Error}!void,
199 });
104 }) |TestType| {
105 const ptr = @typeInfo(TestType).pointer;
106 try testing.expect(TestType == @Pointer(ptr.size, .{
107 .@"const" = ptr.is_const,
108 .@"volatile" = ptr.is_volatile,
109 .@"allowzero" = ptr.is_allowzero,
110 .@"align" = ptr.alignment,
111 .@"addrspace" = ptr.address_space,
112 }, ptr.child, ptr.sentinel()));
113 }
200114}
201115
202116test "Type.Opaque" {
......@@ -205,11 +119,7 @@ test "Type.Opaque" {
205119 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
206120 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
207121
208 const Opaque = @Type(.{
209 .@"opaque" = .{
210 .decls = &.{},
211 },
212 });
122 const Opaque = opaque {};
213123 try testing.expect(Opaque != opaque {});
214124 try testing.expectEqualSlices(
215125 Type.Declaration,
......@@ -218,52 +128,17 @@ test "Type.Opaque" {
218128 );
219129}
220130
221test "Type.Vector" {
222 try testTypes(&[_]type{
223 @Vector(0, u8),
224 @Vector(4, u8),
225 @Vector(8, *u8),
226 @Vector(0, u8),
227 @Vector(4, u8),
228 @Vector(8, *u8),
229 });
230}
231
232test "Type.AnyFrame" {
233 if (true) {
234 // https://github.com/ziglang/zig/issues/6025
235 return error.SkipZigTest;
236 }
237
238 try testTypes(&[_]type{
239 anyframe,
240 anyframe->u8,
241 anyframe->anyframe->u8,
242 });
243}
244
245131fn add(a: i32, b: i32) i32 {
246132 return a + b;
247133}
248134
249test "Type.ErrorSet" {
250 try testing.expect(@Type(.{ .error_set = null }) == anyerror);
251
252 // error sets don't compare equal so just check if they compile
253 inline for (.{ error{}, error{A}, error{ A, B, C } }) |T| {
254 const info = @typeInfo(T);
255 const T2 = @Type(info);
256 try testing.expect(T == T2);
257 }
258}
259
260135test "Type.Struct" {
261136 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
262137 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
263138 if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
264139 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
265140
266 const A = @Type(@typeInfo(struct { x: u8, y: u32 }));
141 const A = @Struct(.auto, null, &.{ "x", "y" }, &.{ u8, u32 }, &@splat(.{}));
267142 const infoA = @typeInfo(A).@"struct";
268143 try testing.expectEqual(Type.ContainerLayout.auto, infoA.layout);
269144 try testing.expectEqualSlices(u8, "x", infoA.fields[0].name);
......@@ -281,7 +156,13 @@ test "Type.Struct" {
281156 a.y += 1;
282157 try testing.expectEqual(@as(u32, 2), a.y);
283158
284 const B = @Type(@typeInfo(extern struct { x: u8, y: u32 = 5 }));
159 const B = @Struct(
160 .@"extern",
161 null,
162 &.{ "x", "y" },
163 &.{ u8, u32 },
164 &.{ .{}, .{ .default_value_ptr = &@as(u32, 5) } },
165 );
285166 const infoB = @typeInfo(B).@"struct";
286167 try testing.expectEqual(Type.ContainerLayout.@"extern", infoB.layout);
287168 try testing.expectEqualSlices(u8, "x", infoB.fields[0].name);
......@@ -293,7 +174,16 @@ test "Type.Struct" {
293174 try testing.expectEqual(@as(usize, 0), infoB.decls.len);
294175 try testing.expectEqual(@as(bool, false), infoB.is_tuple);
295176
296 const C = @Type(@typeInfo(packed struct { x: u8 = 3, y: u32 = 5 }));
177 const C = @Struct(
178 .@"packed",
179 null,
180 &.{ "x", "y" },
181 &.{ u8, u32 },
182 &.{
183 .{ .default_value_ptr = &@as(u8, 3) },
184 .{ .default_value_ptr = &@as(u32, 5) },
185 },
186 );
297187 const infoC = @typeInfo(C).@"struct";
298188 try testing.expectEqual(Type.ContainerLayout.@"packed", infoC.layout);
299189 try testing.expectEqualSlices(u8, "x", infoC.fields[0].name);
......@@ -305,76 +195,23 @@ test "Type.Struct" {
305195 try testing.expectEqual(@as(usize, 0), infoC.decls.len);
306196 try testing.expectEqual(@as(bool, false), infoC.is_tuple);
307197
308 // anon structs
309 const D = @Type(@typeInfo(@TypeOf(.{ .x = 3, .y = 5 })));
310 const infoD = @typeInfo(D).@"struct";
311 try testing.expectEqual(Type.ContainerLayout.auto, infoD.layout);
312 try testing.expectEqualSlices(u8, "x", infoD.fields[0].name);
313 try testing.expectEqual(comptime_int, infoD.fields[0].type);
314 try testing.expectEqual(@as(comptime_int, 3), infoD.fields[0].defaultValue().?);
315 try testing.expectEqualSlices(u8, "y", infoD.fields[1].name);
316 try testing.expectEqual(comptime_int, infoD.fields[1].type);
317 try testing.expectEqual(@as(comptime_int, 5), infoD.fields[1].defaultValue().?);
318 try testing.expectEqual(@as(usize, 0), infoD.decls.len);
319 try testing.expectEqual(@as(bool, false), infoD.is_tuple);
320
321 // tuples
322 const E = @Type(@typeInfo(@TypeOf(.{ 1, 2 })));
323 const infoE = @typeInfo(E).@"struct";
324 try testing.expectEqual(Type.ContainerLayout.auto, infoE.layout);
325 try testing.expectEqualSlices(u8, "0", infoE.fields[0].name);
326 try testing.expectEqual(comptime_int, infoE.fields[0].type);
327 try testing.expectEqual(@as(comptime_int, 1), infoE.fields[0].defaultValue().?);
328 try testing.expectEqualSlices(u8, "1", infoE.fields[1].name);
329 try testing.expectEqual(comptime_int, infoE.fields[1].type);
330 try testing.expectEqual(@as(comptime_int, 2), infoE.fields[1].defaultValue().?);
331 try testing.expectEqual(@as(usize, 0), infoE.decls.len);
332 try testing.expectEqual(@as(bool, true), infoE.is_tuple);
333
334198 // empty struct
335 const F = @Type(@typeInfo(struct {}));
199 const F = @Struct(.auto, null, &.{}, &.{}, &.{});
336200 const infoF = @typeInfo(F).@"struct";
337201 try testing.expectEqual(Type.ContainerLayout.auto, infoF.layout);
338202 try testing.expect(infoF.fields.len == 0);
339203 try testing.expectEqual(@as(bool, false), infoF.is_tuple);
340
341 // empty tuple
342 const G = @Type(@typeInfo(@TypeOf(.{})));
343 const infoG = @typeInfo(G).@"struct";
344 try testing.expectEqual(Type.ContainerLayout.auto, infoG.layout);
345 try testing.expect(infoG.fields.len == 0);
346 try testing.expectEqual(@as(bool, true), infoG.is_tuple);
347204}
348205
349206test "Type.Enum" {
350207 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
351208 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
352209
353 const Foo = @Type(.{
354 .@"enum" = .{
355 .tag_type = u8,
356 .fields = &.{
357 .{ .name = "a", .value = 1 },
358 .{ .name = "b", .value = 5 },
359 },
360 .decls = &.{},
361 .is_exhaustive = true,
362 },
363 });
210 const Foo = @Enum(u8, .exhaustive, &.{ "a", "b" }, &.{ 1, 5 });
364211 try testing.expectEqual(true, @typeInfo(Foo).@"enum".is_exhaustive);
365212 try testing.expectEqual(@as(u8, 1), @intFromEnum(Foo.a));
366213 try testing.expectEqual(@as(u8, 5), @intFromEnum(Foo.b));
367 const Bar = @Type(.{
368 .@"enum" = .{
369 .tag_type = u32,
370 .fields = &.{
371 .{ .name = "a", .value = 1 },
372 .{ .name = "b", .value = 5 },
373 },
374 .decls = &.{},
375 .is_exhaustive = false,
376 },
377 });
214 const Bar = @Enum(u32, .nonexhaustive, &.{ "a", "b" }, &.{ 1, 5 });
378215 try testing.expectEqual(false, @typeInfo(Bar).@"enum".is_exhaustive);
379216 try testing.expectEqual(@as(u32, 1), @intFromEnum(Bar.a));
380217 try testing.expectEqual(@as(u32, 5), @intFromEnum(Bar.b));
......@@ -382,12 +219,7 @@ test "Type.Enum" {
382219
383220 { // from https://github.com/ziglang/zig/issues/19985
384221 { // enum with single field can be initialized.
385 const E = @Type(.{ .@"enum" = .{
386 .tag_type = u0,
387 .is_exhaustive = true,
388 .fields = &.{.{ .name = "foo", .value = 0 }},
389 .decls = &.{},
390 } });
222 const E = @Enum(u0, .exhaustive, &.{"foo"}, &.{0});
391223 const s: struct { E } = .{.foo};
392224 try testing.expectEqual(.foo, s[0]);
393225 }
......@@ -411,60 +243,20 @@ test "Type.Union" {
411243 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
412244 if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest;
413245
414 const Untagged = @Type(.{
415 .@"union" = .{
416 .layout = .@"extern",
417 .tag_type = null,
418 .fields = &.{
419 .{ .name = "int", .type = i32, .alignment = @alignOf(f32) },
420 .{ .name = "float", .type = f32, .alignment = @alignOf(f32) },
421 },
422 .decls = &.{},
423 },
424 });
246 const Untagged = @Union(.@"extern", null, &.{ "int", "float" }, &.{ i32, f32 }, &.{ .{}, .{} });
425247 var untagged = Untagged{ .int = 1 };
426248 untagged.float = 2.0;
427249 untagged.int = 3;
428250 try testing.expectEqual(@as(i32, 3), untagged.int);
429251
430 const PackedUntagged = @Type(.{
431 .@"union" = .{
432 .layout = .@"packed",
433 .tag_type = null,
434 .fields = &.{
435 .{ .name = "signed", .type = i32, .alignment = 0 },
436 .{ .name = "unsigned", .type = u32, .alignment = 0 },
437 },
438 .decls = &.{},
439 },
440 });
252 const PackedUntagged = @Union(.@"packed", null, &.{ "signed", "unsigned" }, &.{ i32, u32 }, &.{ .{}, .{} });
441253 var packed_untagged: PackedUntagged = .{ .signed = -1 };
442254 _ = &packed_untagged;
443255 try testing.expectEqual(@as(i32, -1), packed_untagged.signed);
444256 try testing.expectEqual(~@as(u32, 0), packed_untagged.unsigned);
445257
446 const Tag = @Type(.{
447 .@"enum" = .{
448 .tag_type = u1,
449 .fields = &.{
450 .{ .name = "signed", .value = 0 },
451 .{ .name = "unsigned", .value = 1 },
452 },
453 .decls = &.{},
454 .is_exhaustive = true,
455 },
456 });
457 const Tagged = @Type(.{
458 .@"union" = .{
459 .layout = .auto,
460 .tag_type = Tag,
461 .fields = &.{
462 .{ .name = "signed", .type = i32, .alignment = @alignOf(i32) },
463 .{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) },
464 },
465 .decls = &.{},
466 },
467 });
258 const Tag = @Enum(u1, .exhaustive, &.{ "signed", "unsigned" }, &.{ 0, 1 });
259 const Tagged = @Union(.auto, Tag, &.{ "signed", "unsigned" }, &.{ i32, u32 }, &.{ .{}, .{} });
468260 var tagged = Tagged{ .signed = -1 };
469261 try testing.expectEqual(Tag.signed, @as(Tag, tagged));
470262 tagged = .{ .unsigned = 1 };
......@@ -472,74 +264,26 @@ test "Type.Union" {
472264}
473265
474266test "Type.Union from Type.Enum" {
475 const Tag = @Type(.{
476 .@"enum" = .{
477 .tag_type = u0,
478 .fields = &.{
479 .{ .name = "working_as_expected", .value = 0 },
480 },
481 .decls = &.{},
482 .is_exhaustive = true,
483 },
484 });
485 const T = @Type(.{
486 .@"union" = .{
487 .layout = .auto,
488 .tag_type = Tag,
489 .fields = &.{
490 .{ .name = "working_as_expected", .type = u32, .alignment = @alignOf(u32) },
491 },
492 .decls = &.{},
493 },
494 });
267 const Tag = @Enum(u0, .exhaustive, &.{"working_as_expected"}, &.{0});
268 const T = @Union(.auto, Tag, &.{"working_as_expected"}, &.{u32}, &.{.{}});
495269 _ = @typeInfo(T).@"union";
496270}
497271
498272test "Type.Union from regular enum" {
499273 const E = enum { working_as_expected };
500 const T = @Type(.{
501 .@"union" = .{
502 .layout = .auto,
503 .tag_type = E,
504 .fields = &.{
505 .{ .name = "working_as_expected", .type = u32, .alignment = @alignOf(u32) },
506 },
507 .decls = &.{},
508 },
509 });
274 const T = @Union(.auto, E, &.{"working_as_expected"}, &.{u32}, &.{.{}});
510275 _ = @typeInfo(T).@"union";
511276}
512277
513278test "Type.Union from empty regular enum" {
514279 const E = enum {};
515 const U = @Type(.{
516 .@"union" = .{
517 .layout = .auto,
518 .tag_type = E,
519 .fields = &.{},
520 .decls = &.{},
521 },
522 });
280 const U = @Union(.auto, E, &.{}, &.{}, &.{});
523281 try testing.expectEqual(@sizeOf(U), 0);
524282}
525283
526284test "Type.Union from empty Type.Enum" {
527 const E = @Type(.{
528 .@"enum" = .{
529 .tag_type = u0,
530 .fields = &.{},
531 .decls = &.{},
532 .is_exhaustive = true,
533 },
534 });
535 const U = @Type(.{
536 .@"union" = .{
537 .layout = .auto,
538 .tag_type = E,
539 .fields = &.{},
540 .decls = &.{},
541 },
542 });
285 const E = @Enum(u0, .exhaustive, &.{}, &.{});
286 const U = @Union(.auto, E, &.{}, &.{}, &.{});
543287 try testing.expectEqual(@sizeOf(U), 0);
544288}
545289
......@@ -548,47 +292,22 @@ test "Type.Fn" {
548292
549293 const some_opaque = opaque {};
550294 const some_ptr = *some_opaque;
551 const T = fn (c_int, some_ptr) callconv(.c) void;
552
553 {
554 const fn_info = std.builtin.Type{ .@"fn" = .{
555 .calling_convention = .c,
556 .is_generic = false,
557 .is_var_args = false,
558 .return_type = void,
559 .params = &.{
560 .{ .is_generic = false, .is_noalias = false, .type = c_int },
561 .{ .is_generic = false, .is_noalias = false, .type = some_ptr },
562 },
563 } };
564
565 const fn_type = @Type(fn_info);
566 try std.testing.expectEqual(T, fn_type);
567 }
568295
569 {
570 const fn_info = @typeInfo(T);
571 const fn_type = @Type(fn_info);
572 try std.testing.expectEqual(T, fn_type);
573 }
296 const A = @Fn(&.{ c_int, some_ptr }, &@splat(.{}), void, .{ .@"callconv" = .c });
297 comptime assert(A == fn (c_int, some_ptr) callconv(.c) void);
298
299 const B = @Fn(&.{ c_int, some_ptr, u32 }, &.{ .{}, .{ .@"noalias" = true }, .{} }, u64, .{});
300 comptime assert(B == fn (c_int, noalias some_ptr, u32) u64);
301
302 const C = @Fn(&.{?[*]u8}, &.{.{}}, *const anyopaque, .{ .@"callconv" = .c, .varargs = true });
303 comptime assert(C == fn (?[*]u8, ...) callconv(.c) *const anyopaque);
574304}
575305
576306test "reified struct field name from optional payload" {
577307 comptime {
578308 const m_name: ?[1:0]u8 = "a".*;
579309 if (m_name) |*name| {
580 const T = @Type(.{ .@"struct" = .{
581 .layout = .auto,
582 .fields = &.{.{
583 .name = name,
584 .type = u8,
585 .default_value_ptr = null,
586 .is_comptime = false,
587 .alignment = 1,
588 }},
589 .decls = &.{},
590 .is_tuple = false,
591 } });
310 const T = @Struct(.auto, null, &.{name}, &.{u8}, &.{.{}});
592311 const t: T = .{ .a = 123 };
593312 try std.testing.expect(t.a == 123);
594313 }
......@@ -598,20 +317,7 @@ test "reified struct field name from optional payload" {
598317test "reified union uses @alignOf" {
599318 const S = struct {
600319 fn CreateUnion(comptime T: type) type {
601 return @Type(.{
602 .@"union" = .{
603 .layout = .auto,
604 .tag_type = null,
605 .fields = &[_]std.builtin.Type.UnionField{
606 .{
607 .name = "field",
608 .type = T,
609 .alignment = @alignOf(T),
610 },
611 },
612 .decls = &.{},
613 },
614 });
320 return @Union(.auto, null, &.{"field"}, &.{T}, &.{.{}});
615321 }
616322 };
617323 _ = S.CreateUnion(struct {});
......@@ -620,22 +326,13 @@ test "reified union uses @alignOf" {
620326test "reified struct uses @alignOf" {
621327 const S = struct {
622328 fn NamespacedGlobals(comptime modules: anytype) type {
623 return @Type(.{
624 .@"struct" = .{
625 .layout = .auto,
626 .is_tuple = false,
627 .fields = &.{
628 .{
629 .name = "globals",
630 .type = modules.mach.globals,
631 .default_value_ptr = null,
632 .is_comptime = false,
633 .alignment = @alignOf(modules.mach.globals),
634 },
635 },
636 .decls = &.{},
637 },
638 });
329 return @Struct(
330 .auto,
331 null,
332 &.{"globals"},
333 &.{modules.mach.globals},
334 &.{.{ .@"align" = @alignOf(modules.mach.globals) }},
335 );
639336 }
640337 };
641338 _ = S.NamespacedGlobals(.{
......@@ -645,56 +342,10 @@ test "reified struct uses @alignOf" {
645342 });
646343}
647344
648test "reified error set initialized with field pointer" {
649 const S = struct {
650 const info = .{
651 .args = [_]Type.Error{
652 .{ .name = "bar" },
653 },
654 };
655 const Foo = @Type(.{
656 .error_set = &info.args,
657 });
658 };
659 try testing.expect(S.Foo == error{bar});
660}
661test "reified function type params initialized with field pointer" {
662 const S = struct {
663 const fn_info = .{
664 .params = [_]Type.Fn.Param{
665 .{ .is_generic = false, .is_noalias = false, .type = u8 },
666 },
667 };
668 const Bar = @Type(.{
669 .@"fn" = .{
670 .calling_convention = .auto,
671 .is_generic = false,
672 .is_var_args = false,
673 .return_type = void,
674 .params = &fn_info.params,
675 },
676 });
677 };
678 try testing.expect(@typeInfo(S.Bar) == .@"fn");
679}
680
681345test "empty struct assigned to reified struct field" {
682346 const S = struct {
683347 fn NamespacedComponents(comptime modules: anytype) type {
684 return @Type(.{
685 .@"struct" = .{
686 .layout = .auto,
687 .is_tuple = false,
688 .fields = &.{.{
689 .name = "components",
690 .type = @TypeOf(modules.components),
691 .default_value_ptr = null,
692 .is_comptime = false,
693 .alignment = @alignOf(@TypeOf(modules.components)),
694 }},
695 .decls = &.{},
696 },
697 });
348 return @Struct(.auto, null, &.{"components"}, &.{@TypeOf(modules.components)}, &.{.{}});
698349 }
699350
700351 fn namespacedComponents(comptime modules: anytype) NamespacedComponents(modules) {
......@@ -710,16 +361,6 @@ test "empty struct assigned to reified struct field" {
710361 });
711362}
712363
713test "@Type should resolve its children types" {
714 const sparse = enum(u2) { a, b, c };
715 const dense = enum(u2) { a, b, c, d };
716
717 comptime var sparse_info = @typeInfo(anyerror!sparse);
718 sparse_info.error_union.payload = dense;
719 const B = @Type(sparse_info);
720 try testing.expectEqual(anyerror!dense, B);
721}
722
723364test "struct field names sliced at comptime from larger string" {
724365 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
725366
......@@ -729,28 +370,14 @@ test "struct field names sliced at comptime from larger string" {
729370 \\f3
730371 ;
731372 comptime {
732 var fields: []const Type.StructField = &[0]Type.StructField{};
373 var field_names: []const []const u8 = &.{};
733374
734375 var it = std.mem.tokenizeScalar(u8, text, '\n');
735376 while (it.next()) |name| {
736 fields = fields ++ &[_]Type.StructField{.{
737 .alignment = @alignOf(usize),
738 .name = name ++ "",
739 .type = usize,
740 .default_value_ptr = null,
741 .is_comptime = false,
742 }};
377 field_names = field_names ++ @as([]const []const u8, &.{name});
743378 }
744379
745 const T = @Type(.{
746 .@"struct" = .{
747 .layout = .auto,
748 .is_tuple = false,
749 .fields = fields,
750 .decls = &.{},
751 },
752 });
753
380 const T = @Struct(.auto, null, field_names, &@splat(usize), &@splat(.{}));
754381 const gen_fields = @typeInfo(T).@"struct".fields;
755382 try testing.expectEqual(3, gen_fields.len);
756383 try testing.expectEqualStrings("f1", gen_fields[0].name);
......@@ -762,10 +389,7 @@ test "struct field names sliced at comptime from larger string" {
762389test "matching captures causes opaque equivalence" {
763390 const S = struct {
764391 fn UnsignedId(comptime I: type) type {
765 const U = @Type(.{ .int = .{
766 .signedness = .unsigned,
767 .bits = @typeInfo(I).int.bits,
768 } });
392 const U = @Int(.unsigned, @typeInfo(I).int.bits);
769393 return opaque {
770394 fn id(x: U) U {
771395 return x;
......@@ -785,17 +409,9 @@ test "matching captures causes opaque equivalence" {
785409}
786410
787411test "reify enum where fields refers to part of array" {
788 const fields: [3]std.builtin.Type.EnumField = .{
789 .{ .name = "foo", .value = 0 },
790 .{ .name = "bar", .value = 1 },
791 undefined,
792 };
793 const E = @Type(.{ .@"enum" = .{
794 .tag_type = u8,
795 .fields = fields[0..2],
796 .decls = &.{},
797 .is_exhaustive = true,
798 } });
412 const field_names: [3][]const u8 = .{ "foo", "bar", undefined };
413 const field_values: [3]u8 = .{ undefined, 0, 1 };
414 const E = @Enum(u8, .exhaustive, field_names[0..2], field_values[1..3]);
799415 var a: E = undefined;
800416 var b: E = undefined;
801417 a = .foo;
test/behavior/union.zig+2-8
......@@ -2198,14 +2198,8 @@ test "matching captures causes union equivalence" {
21982198 fn SignedUnsigned(comptime I: type) type {
21992199 const bits = @typeInfo(I).int.bits;
22002200 return union {
2201 u: @Type(.{ .int = .{
2202 .signedness = .unsigned,
2203 .bits = bits,
2204 } }),
2205 i: @Type(.{ .int = .{
2206 .signedness = .signed,
2207 .bits = bits,
2208 } }),
2201 u: @Int(.unsigned, bits),
2202 i: @Int(.signed, bits),
22092203 };
22102204 }
22112205 };
test/behavior/x86_64/math.zig+5-14
......@@ -36,34 +36,28 @@ pub fn ChangeScalar(comptime Type: type, comptime NewScalar: type) type {
3636}
3737pub fn AsSignedness(comptime Type: type, comptime signedness: std.builtin.Signedness) type {
3838 return switch (@typeInfo(Scalar(Type))) {
39 .int => |int| ChangeScalar(Type, @Type(.{ .int = .{
40 .signedness = signedness,
41 .bits = int.bits,
42 } })),
39 .int => |int| ChangeScalar(Type, @Int(signedness, int.bits)),
4340 .float => Type,
4441 else => @compileError(@typeName(Type)),
4542 };
4643}
4744pub fn AddOneBit(comptime Type: type) type {
4845 return ChangeScalar(Type, switch (@typeInfo(Scalar(Type))) {
49 .int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = 1 + int.bits } }),
46 .int => |int| @Int(int.signedness, 1 + int.bits),
5047 .float => Scalar(Type),
5148 else => @compileError(@typeName(Type)),
5249 });
5350}
5451pub fn DoubleBits(comptime Type: type) type {
5552 return ChangeScalar(Type, switch (@typeInfo(Scalar(Type))) {
56 .int => |int| @Type(.{ .int = .{ .signedness = int.signedness, .bits = int.bits * 2 } }),
53 .int => |int| @Int(int.signedness, int.bits * 2),
5754 .float => Scalar(Type),
5855 else => @compileError(@typeName(Type)),
5956 });
6057}
6158pub fn RoundBitsUp(comptime Type: type, comptime multiple: u16) type {
6259 return ChangeScalar(Type, switch (@typeInfo(Scalar(Type))) {
63 .int => |int| @Type(.{ .int = .{
64 .signedness = int.signedness,
65 .bits = std.mem.alignForward(u16, int.bits, multiple),
66 } }),
60 .int => |int| @Int(int.signedness, std.mem.alignForward(u16, int.bits, multiple)),
6761 .float => Scalar(Type),
6862 else => @compileError(@typeName(Type)),
6963 });
......@@ -83,10 +77,7 @@ pub fn splat(comptime Type: type, scalar: Scalar(Type)) Type {
8377pub fn sign(rhs: anytype) ChangeScalar(@TypeOf(rhs), bool) {
8478 const Int = ChangeScalar(@TypeOf(rhs), switch (@typeInfo(Scalar(@TypeOf(rhs)))) {
8579 .int, .comptime_int => Scalar(@TypeOf(rhs)),
86 .float => |float| @Type(.{ .int = .{
87 .signedness = .signed,
88 .bits = float.bits,
89 } }),
80 .float => |float| @Int(.signed, float.bits),
9081 else => @compileError(@typeName(@TypeOf(rhs))),
9182 });
9283 return @as(Int, @bitCast(rhs)) < splat(Int, 0);
test/cases/compile_errors/@import_zon_bad_type.zig+1-1
......@@ -116,7 +116,7 @@ export fn testMutablePointer() void {
116116// tmp.zig:85:26: note: ZON does not allow nested optionals
117117// tmp.zig:90:29: error: type '*i32' is not available in ZON
118118// tmp.zig:90:29: note: ZON does not allow mutable pointers
119// neg_inf.zon:1:1: error: expected type '@Type(.enum_literal)'
119// neg_inf.zon:1:1: error: expected type '@EnumLiteral()'
120120// tmp.zig:37:38: note: imported here
121121// neg_inf.zon:1:1: error: expected type '?u8'
122122// tmp.zig:57:28: note: imported here
test/cases/compile_errors/@import_zon_opt_in_err.zig+1-1
......@@ -70,7 +70,7 @@ export fn testVector() void {
7070// tmp.zig:22:29: note: imported here
7171// vec2.zon:1:2: error: expected type '?tmp.Enum'
7272// tmp.zig:28:30: note: imported here
73// vec2.zon:1:2: error: expected type '?@Type(.enum_literal)'
73// vec2.zon:1:2: error: expected type '?@EnumLiteral()'
7474// tmp.zig:33:39: note: imported here
7575// vec2.zon:1:2: error: expected type '?[1]u8'
7676// tmp.zig:38:31: note: imported here
test/cases/compile_errors/align_zero.zig+4-24
......@@ -38,31 +38,11 @@ export fn i() void {
3838}
3939
4040export fn j() void {
41 _ = @Type(.{ .@"struct" = .{
42 .layout = .auto,
43 .fields = &.{.{
44 .name = "test",
45 .type = u32,
46 .default_value_ptr = null,
47 .is_comptime = false,
48 .alignment = 0,
49 }},
50 .decls = &.{},
51 .is_tuple = false,
52 } });
41 _ = @Struct(.auto, null, &.{"test"}, &.{u32}, &.{.{ .@"align" = 0 }});
5342}
5443
5544export fn k() void {
56 _ = @Type(.{ .pointer = .{
57 .size = .one,
58 .is_const = false,
59 .is_volatile = false,
60 .alignment = 0,
61 .address_space = .generic,
62 .child = u32,
63 .is_allowzero = false,
64 .sentinel_ptr = null,
65 } });
45 _ = @Pointer(.one, .{ .@"align" = 0 }, u32, null);
6646}
6747
6848// error
......@@ -76,5 +56,5 @@ export fn k() void {
7656// :29:17: error: alignment must be >= 1
7757// :33:35: error: alignment must be >= 1
7858// :37:34: error: alignment must be >= 1
79// :41:9: error: alignment must be >= 1
80// :56:9: error: alignment must be >= 1
59// :41:51: error: alignment must be >= 1
60// :45:25: error: alignment must be >= 1
test/cases/compile_errors/attempt_to_cast_enum_literal_to_error.zig+1-1
......@@ -6,4 +6,4 @@ export fn entry() void {
66
77// error
88//
9// :3:10: error: expected type 'error{Hi}', found '@Type(.enum_literal)'
9// :3:10: error: expected type 'error{Hi}', found '@EnumLiteral()'
test/cases/compile_errors/attempt_to_create_17_bit_float_type.zig deleted-8
......@@ -1,8 +0,0 @@
1const builtin = @import("std").builtin;
2comptime {
3 _ = @Type(.{ .float = .{ .bits = 17 } });
4}
5
6// error
7//
8// :3:9: error: 17-bit float unsupported
test/cases/compile_errors/enum_with_declarations_unavailable_for_reify_type.zig deleted-10
......@@ -1,10 +0,0 @@
1export fn entry() void {
2 _ = @Type(@typeInfo(enum {
3 foo,
4 pub const bar = 1;
5 }));
6}
7
8// error
9//
10// :2:9: error: reified enums must have no decls
test/cases/compile_errors/error_set_decl_literal.zig+1-1
......@@ -6,4 +6,4 @@ export fn entry() void {
66
77// error
88//
9// :3:19: error: expected type 'error{Foo}', found '@Type(.enum_literal)'
9// :3:19: error: expected type 'error{Foo}', found '@EnumLiteral()'
test/cases/compile_errors/invalid_pointer_to_opaque.zig+5-32
......@@ -9,40 +9,13 @@ export fn c() void {
99}
1010
1111export fn d() void {
12 _ = @Type(.{ .pointer = .{
13 .size = .slice,
14 .is_const = false,
15 .is_volatile = false,
16 .alignment = 1,
17 .address_space = .generic,
18 .child = anyopaque,
19 .is_allowzero = false,
20 .sentinel_ptr = null,
21 } });
12 _ = @Pointer(.slice, .{}, anyopaque, null);
2213}
2314export fn e() void {
24 _ = @Type(.{ .pointer = .{
25 .size = .many,
26 .is_const = false,
27 .is_volatile = false,
28 .alignment = 1,
29 .address_space = .generic,
30 .child = anyopaque,
31 .is_allowzero = false,
32 .sentinel_ptr = null,
33 } });
15 _ = @Pointer(.many, .{}, anyopaque, null);
3416}
3517export fn f() void {
36 _ = @Type(.{ .pointer = .{
37 .size = .c,
38 .is_const = false,
39 .is_volatile = false,
40 .alignment = 1,
41 .address_space = .generic,
42 .child = anyopaque,
43 .is_allowzero = false,
44 .sentinel_ptr = null,
45 } });
18 _ = @Pointer(.c, .{}, anyopaque, null);
4619}
4720
4821// error
......@@ -51,5 +24,5 @@ export fn f() void {
5124// :5:12: error: indexable pointer to opaque type 'anyopaque' not allowed
5225// :8:13: error: indexable pointer to opaque type 'anyopaque' not allowed
5326// :12:9: error: indexable pointer to opaque type 'anyopaque' not allowed
54// :24:9: error: indexable pointer to opaque type 'anyopaque' not allowed
55// :36:9: error: indexable pointer to opaque type 'anyopaque' not allowed
27// :15:9: error: indexable pointer to opaque type 'anyopaque' not allowed
28// :18:9: error: indexable pointer to opaque type 'anyopaque' not allowed
test/cases/compile_errors/invalid_pointer_with_reify_type.zig+2-11
......@@ -1,16 +1,7 @@
11export fn entry() void {
2 _ = @Type(.{ .pointer = .{
3 .size = .one,
4 .is_const = false,
5 .is_volatile = false,
6 .alignment = 1,
7 .address_space = .generic,
8 .child = u8,
9 .is_allowzero = false,
10 .sentinel_ptr = &@as(u8, 0),
11 } });
2 _ = @Pointer(.one, .{}, u8, 0);
123}
134
145// error
156//
16// :2:9: error: sentinels are only allowed on slices and unknown-length pointers
7// :2:33: error: sentinels are only allowed on slices and unknown-length pointers
test/cases/compile_errors/minmax_nonnumeric_operand.zig+1-1
......@@ -36,4 +36,4 @@ const Union = union { foo: void };
3636// :13:29: error: expected number, found 'tmp.Union'
3737// :19:15: note: union declared here
3838// :14:61: error: expected number, found 'fn () u8'
39// :15:25: error: expected number, found '@Type(.enum_literal)'
39// :15:25: error: expected number, found '@EnumLiteral()'
test/cases/compile_errors/nested_vectors.zig+2-2
......@@ -1,10 +1,10 @@
11export fn entry() void {
22 const V1 = @Vector(4, u8);
3 const V2 = @Type(.{ .vector = .{ .len = 4, .child = V1 } });
3 const V2 = @Vector(4, V1);
44 const v: V2 = undefined;
55 _ = v;
66}
77
88// error
99//
10// :3:16: error: expected integer, float, bool, or pointer for the vector element type; found '@Vector(4, u8)'
10// :3:27: error: expected integer, float, bool, or pointer for the vector element type; found '@Vector(4, u8)'
test/cases/compile_errors/non_constant_expression_in_array_size.zig+1-1
......@@ -14,4 +14,4 @@ export fn entry() usize {
1414//
1515// :6:12: error: unable to resolve comptime value
1616// :2:12: note: called at comptime from here
17// :1:13: note: struct fields must be comptime-known
17// :1:13: note: types must be comptime-known
test/cases/compile_errors/non_scalar_sentinel.zig+4-27
......@@ -12,31 +12,10 @@ comptime {
1212}
1313
1414comptime {
15 _ = @Type(.{ .array = .{ .child = S, .len = 0, .sentinel_ptr = &sentinel } });
15 _ = @Pointer(.slice, .{}, S, sentinel);
1616}
1717comptime {
18 _ = @Type(.{ .pointer = .{
19 .size = .slice,
20 .is_const = false,
21 .is_volatile = false,
22 .alignment = @alignOf(S),
23 .address_space = .generic,
24 .child = S,
25 .is_allowzero = false,
26 .sentinel_ptr = &sentinel,
27 } });
28}
29comptime {
30 _ = @Type(.{ .pointer = .{
31 .size = .many,
32 .is_const = false,
33 .is_volatile = false,
34 .alignment = @alignOf(S),
35 .address_space = .generic,
36 .child = S,
37 .is_allowzero = false,
38 .sentinel_ptr = &sentinel,
39 } });
18 _ = @Pointer(.many, .{}, S, sentinel);
4019}
4120
4221// error
......@@ -47,9 +26,7 @@ comptime {
4726// :1:11: note: struct declared here
4827// :11:12: error: non-scalar sentinel type 'tmp.S'
4928// :1:11: note: struct declared here
50// :15:9: error: non-scalar sentinel type 'tmp.S'
51// :1:11: note: struct declared here
52// :18:9: error: non-scalar sentinel type 'tmp.S'
29// :15:34: error: non-scalar sentinel type 'tmp.S'
5330// :1:11: note: struct declared here
54// :30:9: error: non-scalar sentinel type 'tmp.S'
31// :18:33: error: non-scalar sentinel type 'tmp.S'
5532// :1:11: note: struct declared here
test/cases/compile_errors/reified_enum_field_value_overflow.zig+2-11
......@@ -1,17 +1,8 @@
11comptime {
2 const E = @Type(.{ .@"enum" = .{
3 .tag_type = u1,
4 .fields = &.{
5 .{ .name = "f0", .value = 0 },
6 .{ .name = "f1", .value = 1 },
7 .{ .name = "f2", .value = 2 },
8 },
9 .decls = &.{},
10 .is_exhaustive = true,
11 } });
2 const E = @Enum(u1, .exhaustive, &.{ "f0", "f1", "f2" }, &.{ 0, 1, 2 });
123 _ = E;
134}
145
156// error
167//
17// :2:15: error: field 'f2' with enumeration value '2' is too large for backing int type 'u1'
8// :2:72: error: type 'u1' cannot represent integer value '2'
test/cases/compile_errors/reify_enum_with_duplicate_field.zig+3-13
......@@ -1,18 +1,8 @@
11export fn entry() void {
2 _ = @Type(.{
3 .@"enum" = .{
4 .tag_type = u32,
5 .fields = &.{
6 .{ .name = "A", .value = 0 },
7 .{ .name = "A", .value = 1 },
8 },
9 .decls = &.{},
10 .is_exhaustive = false,
11 },
12 });
2 _ = @Enum(u32, .nonexhaustive, &.{ "A", "A" }, &.{ 0, 1 });
133}
144
155// error
166//
17// :2:9: error: duplicate enum field 'A'
18// :2:9: note: other field here
7// :2:36: error: duplicate enum field 'A'
8// :2:36: note: other field here
test/cases/compile_errors/reify_enum_with_duplicate_tag_value.zig+3-13
......@@ -1,18 +1,8 @@
11export fn entry() void {
2 _ = @Type(.{
3 .@"enum" = .{
4 .tag_type = u32,
5 .fields = &.{
6 .{ .name = "A", .value = 10 },
7 .{ .name = "B", .value = 10 },
8 },
9 .decls = &.{},
10 .is_exhaustive = false,
11 },
12 });
2 _ = @Enum(u32, .nonexhaustive, &.{ "A", "B" }, &.{ 10, 10 });
133}
144
155// error
166//
17// :2:9: error: enum tag value 10 already taken
18// :2:9: note: other enum tag value here
7// :2:52: error: enum tag value 10 already taken
8// :2:52: note: other enum tag value here
test/cases/compile_errors/reify_struct.zig+6-69
......@@ -1,79 +1,16 @@
11comptime {
2 @Type(.{ .@"struct" = .{
3 .layout = .auto,
4 .fields = &.{.{
5 .name = "foo",
6 .type = u32,
7 .default_value_ptr = null,
8 .is_comptime = false,
9 .alignment = 4,
10 }},
11 .decls = &.{},
12 .is_tuple = true,
13 } });
2 @Struct(.auto, null, &.{"foo"}, &.{u32}, &.{.{ .@"comptime" = true }});
143}
154comptime {
16 @Type(.{ .@"struct" = .{
17 .layout = .auto,
18 .fields = &.{.{
19 .name = "3",
20 .type = u32,
21 .default_value_ptr = null,
22 .is_comptime = false,
23 .alignment = 4,
24 }},
25 .decls = &.{},
26 .is_tuple = true,
27 } });
5 @Struct(.@"extern", null, &.{"foo"}, &.{u32}, &.{.{ .@"comptime" = true, .default_value_ptr = &@as(u32, 10) }});
286}
297comptime {
30 @Type(.{ .@"struct" = .{
31 .layout = .auto,
32 .fields = &.{.{
33 .name = "0",
34 .type = u32,
35 .default_value_ptr = null,
36 .is_comptime = true,
37 .alignment = 4,
38 }},
39 .decls = &.{},
40 .is_tuple = true,
41 } });
42}
43comptime {
44 @Type(.{ .@"struct" = .{
45 .layout = .@"extern",
46 .fields = &.{.{
47 .name = "0",
48 .type = u32,
49 .default_value_ptr = null,
50 .is_comptime = true,
51 .alignment = 4,
52 }},
53 .decls = &.{},
54 .is_tuple = false,
55 } });
56}
57comptime {
58 @Type(.{ .@"struct" = .{
59 .layout = .@"packed",
60 .fields = &.{.{
61 .name = "0",
62 .type = u32,
63 .default_value_ptr = null,
64 .is_comptime = true,
65 .alignment = 4,
66 }},
67 .decls = &.{},
68 .is_tuple = false,
69 } });
8 @Struct(.@"packed", null, &.{"foo"}, &.{u32}, &.{.{ .@"align" = 4 }});
709}
7110
7211// error
7312//
74// :2:5: error: tuple cannot have non-numeric field 'foo'
75// :16:5: error: tuple field name '3' does not match field index 0
76// :30:5: error: comptime field without default initialization value
77// :44:5: error: extern struct fields cannot be marked comptime
78// :58:5: error: alignment of a packed struct field must be set to 0
13// :2:46: error: comptime field without default initialization value
14// :5:51: error: extern struct fields cannot be marked comptime
15// :8:51: error: packed struct fields cannot be aligned
7916
test/cases/compile_errors/reify_type.Fn_with_is_generic_true.zig deleted-16
......@@ -1,16 +0,0 @@
1const Foo = @Type(.{
2 .@"fn" = .{
3 .calling_convention = .auto,
4 .is_generic = true,
5 .is_var_args = false,
6 .return_type = u0,
7 .params = &.{},
8 },
9});
10comptime {
11 _ = Foo;
12}
13
14// error
15//
16// :1:13: error: Type.Fn.is_generic must be false for @Type
test/cases/compile_errors/reify_type.Fn_with_is_var_args_true_and_non-C_callconv.zig+3-12
......@@ -1,18 +1,9 @@
1const Foo = @Type(.{
2 .@"fn" = .{
3 .calling_convention = .auto,
4 .is_generic = false,
5 .is_var_args = true,
6 .return_type = u0,
7 .params = &.{},
8 },
9});
101comptime {
11 _ = Foo;
2 _ = @Fn(&.{u32}, &.{.{}}, u8, .{ .varargs = true });
123}
134
145// error
156// target=x86_64-linux
167//
17// :1:13: error: variadic function does not support 'auto' calling convention
18// :1:13: note: supported calling conventions: 'x86_64_sysv', 'x86_64_x32', 'x86_64_win'
8// :2:36: error: variadic function does not support 'auto' calling convention
9// :2:36: note: supported calling conventions: 'x86_64_sysv', 'x86_64_x32', 'x86_64_win'
test/cases/compile_errors/reify_type.Fn_with_return_type_null.zig deleted-16
......@@ -1,16 +0,0 @@
1const Foo = @Type(.{
2 .@"fn" = .{
3 .calling_convention = .auto,
4 .is_generic = false,
5 .is_var_args = false,
6 .return_type = null,
7 .params = &.{},
8 },
9});
10comptime {
11 _ = Foo;
12}
13
14// error
15//
16// :1:13: error: Type.Fn.return_type must be non-null for @Type
test/cases/compile_errors/reify_type_for_exhaustive_enum_with_non-integer_tag_type.zig+2-9
......@@ -1,15 +1,8 @@
1const Tag = @Type(.{
2 .@"enum" = .{
3 .tag_type = bool,
4 .fields = &.{},
5 .decls = &.{},
6 .is_exhaustive = false,
7 },
8});
1const Tag = @Enum(bool, .nonexhaustive, &.{}, &.{});
92export fn entry() void {
103 _ = @as(Tag, @enumFromInt(0));
114}
125
136// error
147//
15// :1:13: error: Type.Enum.tag_type must be an integer type
8// :1:19: error: tag type must be an integer type
test/cases/compile_errors/reify_type_for_exhaustive_enum_with_undefined_tag_type.zig+2-9
......@@ -1,15 +1,8 @@
1const Tag = @Type(.{
2 .@"enum" = .{
3 .tag_type = undefined,
4 .fields = &.{},
5 .decls = &.{},
6 .is_exhaustive = false,
7 },
8});
1const Tag = @Enum(undefined, .exhaustive, &.{}, &.{});
92export fn entry() void {
103 _ = @as(Tag, @enumFromInt(0));
114}
125
136// error
147//
15// :1:20: error: use of undefined value here causes illegal behavior
8// :1:19: error: use of undefined value here causes illegal behavior
test/cases/compile_errors/reify_type_for_tagged_extern_union.zig+3-24
......@@ -1,26 +1,5 @@
1const Tag = @Type(.{
2 .@"enum" = .{
3 .tag_type = u2,
4 .fields = &.{
5 .{ .name = "signed", .value = 0 },
6 .{ .name = "unsigned", .value = 1 },
7 },
8 .decls = &.{},
9 .is_exhaustive = true,
10 },
11});
12
13const Extern = @Type(.{
14 .@"union" = .{
15 .layout = .@"extern",
16 .tag_type = Tag,
17 .fields = &.{
18 .{ .name = "signed", .type = i32, .alignment = @alignOf(i32) },
19 .{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) },
20 },
21 .decls = &.{},
22 },
23});
1const Tag = @Enum(u2, .exhaustive, &.{ "signed", "unsigned" }, &.{ 0, 1 });
2const Extern = @Union(.@"extern", Tag, &.{ "signed", "unsigned" }, &.{ i32, u32 }, &@splat(.{}));
243
254export fn entry() void {
265 const tagged: Extern = .{ .signed = -1 };
......@@ -29,4 +8,4 @@ export fn entry() void {
298
309// error
3110//
32// :13:16: error: extern union does not support enum tag type
11// :2:35: error: extern union does not support enum tag type
test/cases/compile_errors/reify_type_for_tagged_packed_union.zig+3-24
......@@ -1,26 +1,5 @@
1const Tag = @Type(.{
2 .@"enum" = .{
3 .tag_type = u2,
4 .fields = &.{
5 .{ .name = "signed", .value = 0 },
6 .{ .name = "unsigned", .value = 1 },
7 },
8 .decls = &.{},
9 .is_exhaustive = true,
10 },
11});
12
13const Packed = @Type(.{
14 .@"union" = .{
15 .layout = .@"packed",
16 .tag_type = Tag,
17 .fields = &.{
18 .{ .name = "signed", .type = i32, .alignment = @alignOf(i32) },
19 .{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) },
20 },
21 .decls = &.{},
22 },
23});
1const Tag = @Enum(u2, .exhaustive, &.{ "signed", "unsigned" }, &.{ 0, 1 });
2const Packed = @Union(.@"packed", Tag, &.{ "signed", "unsigned" }, &.{ i32, u32 }, &@splat(.{}));
243
254export fn entry() void {
265 const tagged: Packed = .{ .signed = -1 };
......@@ -29,4 +8,4 @@ export fn entry() void {
298
309// error
3110//
32// :13:16: error: packed union does not support enum tag type
11// :2:35: error: packed union does not support enum tag type
test/cases/compile_errors/reify_type_for_tagged_union_with_extra_enum_field.zig+3-24
......@@ -1,26 +1,5 @@
1const Tag = @Type(.{
2 .@"enum" = .{
3 .tag_type = u2,
4 .fields = &.{
5 .{ .name = "signed", .value = 0 },
6 .{ .name = "unsigned", .value = 1 },
7 .{ .name = "arst", .value = 2 },
8 },
9 .decls = &.{},
10 .is_exhaustive = true,
11 },
12});
13const Tagged = @Type(.{
14 .@"union" = .{
15 .layout = .auto,
16 .tag_type = Tag,
17 .fields = &.{
18 .{ .name = "signed", .type = i32, .alignment = @alignOf(i32) },
19 .{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) },
20 },
21 .decls = &.{},
22 },
23});
1const Tag = @Enum(u2, .exhaustive, &.{ "signed", "unsigned", "arst" }, &.{ 0, 1, 2 });
2const Tagged = @Union(.auto, Tag, &.{ "signed", "unsigned" }, &.{ i32, u32 }, &@splat(.{}));
243export fn entry() void {
254 var tagged = Tagged{ .signed = -1 };
265 tagged = .{ .unsigned = 1 };
......@@ -28,6 +7,6 @@ export fn entry() void {
287
298// error
309//
31// :13:16: error: enum fields missing in union
10// :2:35: error: 1 enum fields missing in union
3211// :1:13: note: field 'arst' missing, declared here
3312// :1:13: note: enum declared here
test/cases/compile_errors/reify_type_for_tagged_union_with_extra_union_field.zig+3-24
......@@ -1,26 +1,5 @@
1const Tag = @Type(.{
2 .@"enum" = .{
3 .tag_type = u1,
4 .fields = &.{
5 .{ .name = "signed", .value = 0 },
6 .{ .name = "unsigned", .value = 1 },
7 },
8 .decls = &.{},
9 .is_exhaustive = true,
10 },
11});
12const Tagged = @Type(.{
13 .@"union" = .{
14 .layout = .auto,
15 .tag_type = Tag,
16 .fields = &.{
17 .{ .name = "signed", .type = i32, .alignment = @alignOf(i32) },
18 .{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) },
19 .{ .name = "arst", .type = f32, .alignment = @alignOf(f32) },
20 },
21 .decls = &.{},
22 },
23});
1const Tag = @Enum(u1, .exhaustive, &.{ "signed", "unsigned" }, &.{ 0, 1 });
2const Tagged = @Union(.auto, Tag, &.{ "signed", "unsigned", "arst" }, &.{ i32, u32, f32 }, &@splat(.{}));
243export fn entry() void {
254 var tagged = Tagged{ .signed = -1 };
265 tagged = .{ .unsigned = 1 };
......@@ -28,5 +7,5 @@ export fn entry() void {
287
298// error
309//
31// :12:16: error: no field named 'arst' in enum 'tmp.Tag'
10// :2:35: error: no field named 'arst' in enum 'tmp.Tag'
3211// :1:13: note: enum declared here
test/cases/compile_errors/reify_type_for_tagged_union_with_no_enum_fields.zig+3-20
......@@ -1,22 +1,5 @@
1const Tag = @Type(.{
2 .@"enum" = .{
3 .tag_type = u0,
4 .fields = &.{},
5 .decls = &.{},
6 .is_exhaustive = true,
7 },
8});
9const Tagged = @Type(.{
10 .@"union" = .{
11 .layout = .auto,
12 .tag_type = Tag,
13 .fields = &.{
14 .{ .name = "signed", .type = i32, .alignment = @alignOf(i32) },
15 .{ .name = "unsigned", .type = u32, .alignment = @alignOf(u32) },
16 },
17 .decls = &.{},
18 },
19});
1const Tag = @Enum(u0, .exhaustive, &.{}, &.{});
2const Tagged = @Union(.auto, Tag, &.{ "signed", "unsigned" }, &.{ i32, u32 }, &@splat(.{}));
203export fn entry() void {
214 const tagged: Tagged = undefined;
225 _ = tagged;
......@@ -24,5 +7,5 @@ export fn entry() void {
247
258// error
269//
27// :9:16: error: no field named 'signed' in enum 'tmp.Tag'
10// :2:35: error: no field named 'signed' in enum 'tmp.Tag'
2811// :1:13: note: enum declared here
test/cases/compile_errors/reify_type_for_tagged_union_with_no_union_fields.zig+3-20
......@@ -1,22 +1,5 @@
1const Tag = @Type(.{
2 .@"enum" = .{
3 .tag_type = u1,
4 .fields = &.{
5 .{ .name = "signed", .value = 0 },
6 .{ .name = "unsigned", .value = 1 },
7 },
8 .decls = &.{},
9 .is_exhaustive = true,
10 },
11});
12const Tagged = @Type(.{
13 .@"union" = .{
14 .layout = .auto,
15 .tag_type = Tag,
16 .fields = &.{},
17 .decls = &.{},
18 },
19});
1const Tag = @Enum(u1, .exhaustive, &.{ "signed", "unsigned" }, &.{ 0, 1 });
2const Tagged = @Union(.auto, Tag, &.{}, &.{}, &.{});
203export fn entry() void {
214 const tagged: Tagged = undefined;
225 _ = tagged;
......@@ -24,7 +7,7 @@ export fn entry() void {
247
258// error
269//
27// :12:16: error: enum fields missing in union
10// :2:35: error: 2 enum fields missing in union
2811// :1:13: note: field 'signed' missing, declared here
2912// :1:13: note: field 'unsigned' missing, declared here
3013// :1:13: note: enum declared here
test/cases/compile_errors/reify_type_for_union_with_opaque_field.zig+3-12
......@@ -1,18 +1,9 @@
1const Untagged = @Type(.{
2 .@"union" = .{
3 .layout = .auto,
4 .tag_type = null,
5 .fields = &.{
6 .{ .name = "foo", .type = opaque {}, .alignment = 1 },
7 },
8 .decls = &.{},
9 },
10});
1const Untagged = @Union(.auto, null, &.{"foo"}, &.{opaque {}}, &.{.{}});
112export fn entry() usize {
123 return @sizeOf(Untagged);
134}
145
156// error
167//
17// :1:18: error: opaque types have unknown size and therefore cannot be directly embedded in unions
18// :6:39: note: opaque declared here
8// :1:49: error: opaque types have unknown size and therefore cannot be directly embedded in unions
9// :1:52: note: opaque declared here
test/cases/compile_errors/reify_type_union_payload_is_undefined.zig deleted-10
......@@ -1,10 +0,0 @@
1const Foo = @Type(.{
2 .@"struct" = undefined,
3});
4comptime {
5 _ = Foo;
6}
7
8// error
9//
10// :1:20: error: use of undefined value here causes illegal behavior
test/cases/compile_errors/reify_type_with_Type.Int.zig deleted-13
......@@ -1,13 +0,0 @@
1const builtin = @import("std").builtin;
2export fn entry() void {
3 _ = @Type(builtin.Type.Int{
4 .signedness = .signed,
5 .bits = 8,
6 });
7}
8
9// error
10//
11// :3:31: error: expected type 'builtin.Type', found 'builtin.Type.Int'
12// :?:?: note: struct declared here
13// :?:?: note: union declared here
test/cases/compile_errors/reify_type_with_invalid_field_alignment.zig+6-39
......@@ -1,48 +1,15 @@
11comptime {
2 _ = @Type(.{
3 .@"union" = .{
4 .layout = .auto,
5 .tag_type = null,
6 .fields = &.{
7 .{ .name = "foo", .type = usize, .alignment = 3 },
8 },
9 .decls = &.{},
10 },
11 });
2 _ = @Union(.auto, null, &.{"foo"}, &.{usize}, &.{.{ .@"align" = 3 }});
123}
134comptime {
14 _ = @Type(.{
15 .@"struct" = .{
16 .layout = .auto,
17 .fields = &.{.{
18 .name = "0",
19 .type = u32,
20 .default_value_ptr = null,
21 .is_comptime = true,
22 .alignment = 5,
23 }},
24 .decls = &.{},
25 .is_tuple = false,
26 },
27 });
5 _ = @Struct(.auto, null, &.{"a"}, &.{u32}, &.{.{ .@"comptime" = true, .@"align" = 5 }});
286}
297comptime {
30 _ = @Type(.{
31 .pointer = .{
32 .size = .many,
33 .is_const = true,
34 .is_volatile = false,
35 .alignment = 7,
36 .address_space = .generic,
37 .child = u8,
38 .is_allowzero = false,
39 .sentinel_ptr = null,
40 },
41 });
8 _ = @Pointer(.many, .{ .@"align" = 7 }, u8, null);
429}
4310
4411// error
4512//
46// :2:9: error: alignment value '3' is not a power of two
47// :14:9: error: alignment value '5' is not a power of two
48// :30:9: error: alignment value '7' is not a power of two
13// :2:51: error: alignment value '3' is not a power of two
14// :5:48: error: alignment value '5' is not a power of two
15// :8:26: error: alignment value '7' is not a power of two
test/cases/compile_errors/reify_type_with_undefined.zig+4-24
......@@ -1,31 +1,11 @@
11comptime {
2 _ = @Type(.{ .array = .{ .len = 0, .child = u8, .sentinel_ptr = undefined } });
2 _ = @Struct(.auto, null, &.{}, &.{}, undefined);
33}
44comptime {
5 _ = @Type(.{
6 .@"struct" = .{
7 .fields = undefined,
8 .decls = undefined,
9 .is_tuple = false,
10 .layout = .auto,
11 },
12 });
13}
14comptime {
15 const std = @import("std");
16 const fields: [1]std.builtin.Type.StructField = undefined;
17 _ = @Type(.{
18 .@"struct" = .{
19 .layout = .auto,
20 .fields = &fields,
21 .decls = &.{},
22 .is_tuple = false,
23 },
24 });
5 _ = @Struct(.auto, null, &.{"foo"}, &.{undefined}, &.{.{}});
256}
267
278// error
289//
29// :2:16: error: use of undefined value here causes illegal behavior
30// :5:16: error: use of undefined value here causes illegal behavior
31// :17:16: error: use of undefined value here causes illegal behavior
10// :2:42: error: use of undefined value here causes illegal behavior
11// :5:41: error: use of undefined value here causes illegal behavior
test/cases/compile_errors/runtime_condition_comptime_type_in_destructure.zig+1-1
......@@ -7,4 +7,4 @@ export fn foobar() void {
77
88// error
99//
10// :4:5: error: value with comptime-only type '@Type(.enum_literal)' depends on runtime control flow
10// :4:5: error: value with comptime-only type '@EnumLiteral()' depends on runtime control flow
test/cases/compile_errors/struct_with_declarations_unavailable_for_reify_type.zig deleted-9
......@@ -1,9 +0,0 @@
1export fn entry() void {
2 _ = @Type(@typeInfo(struct {
3 pub const foo = 1;
4 }));
5}
6
7// error
8//
9// :2:9: error: reified structs must have no decls
test/cases/compile_errors/tagName_on_undef_enum_literal.zig+1-1
......@@ -1,5 +1,5 @@
11comptime {
2 const undef: @Type(.enum_literal) = undefined;
2 const undef: @EnumLiteral() = undefined;
33 _ = @tagName(undef);
44}
55
test/cases/compile_errors/unable_to_evaluate_comptime_expr.zig+1-1
......@@ -42,4 +42,4 @@ pub export fn entry3() void {
4242// :13:13: note: initializer of container-level variable must be comptime-known
4343// :22:9: error: unable to evaluate comptime expression
4444// :22:21: note: operation is runtime due to this operand
45// :21:13: note: enum fields must be comptime-known
45// :21:13: note: enum field values must be comptime-known
test/cases/compile_errors/wrong_type_for_reify_type.zig+21-4
......@@ -1,8 +1,25 @@
1export fn entry() void {
2 _ = @Type(0);
1export fn entryI() void {
2 _ = @Int(0, 0);
3}
4
5export fn entryE() void {
6 _ = @Enum(0, 0, 0, 0);
7}
8
9export fn entryS() void {
10 _ = @Struct(0, 0, &.{}, &.{}, &.{});
11}
12
13export fn entryU() void {
14 _ = @Union(0, 0, &.{}, &.{}, &.{});
315}
416
517// error
618//
7// :2:15: error: expected type 'builtin.Type', found 'comptime_int'
8// :?:?: note: union declared here
19// :2:14: error: expected type 'builtin.Signedness', found 'comptime_int'
20// :?:?: note: enum declared here
21// :6:15: error: expected type 'type', found 'comptime_int'
22// :10:17: error: expected type 'builtin.Type.ContainerLayout', found 'comptime_int'
23// :?:?: enum declared here
24// :14:16: error: expected type 'builtin.Type.ContainerLayout', found 'comptime_int'
25// :?:?: enum declared here
test/cases/default_value_references_comptime_var.zig+13-35
......@@ -2,49 +2,27 @@ export fn foo() void {
22 comptime var a: u8 = 0;
33 _ = struct { comptime *u8 = &a };
44}
5export fn bar() void {
6 comptime var a: u8 = 0;
7 _ = @Type(.{ .@"struct" = .{
8 .layout = .auto,
9 .fields = &.{.{
10 .name = "0",
11 .type = *u8,
12 .default_value_ptr = @ptrCast(&&a),
13 .is_comptime = true,
14 .alignment = @alignOf(*u8),
15 }},
16 .decls = &.{},
17 .is_tuple = true,
18 } });
19}
205
21export fn baz() void {
6export fn bar() void {
227 comptime var a: u8 = 0;
238 _ = struct { foo: *u8 = &a };
249}
25export fn qux() void {
10export fn baz() void {
2611 comptime var a: u8 = 0;
27 _ = @Type(.{ .@"struct" = .{
28 .layout = .auto,
29 .fields = &.{.{
30 .name = "foo",
31 .type = *u8,
32 .default_value_ptr = @ptrCast(&&a),
33 .is_comptime = false,
34 .alignment = @alignOf(*u8),
35 }},
36 .decls = &.{},
37 .is_tuple = false,
38 } });
12 _ = @Struct(
13 .auto,
14 null,
15 &.{"foo"},
16 &.{*u8},
17 &.{.{ .default_value_ptr = @ptrCast(&&a) }},
18 );
3919}
4020
4121// error
4222//
4323// :3:33: error: field default value contains reference to comptime var
4424// :2:14: note: '0' points to comptime var declared here
45// :7:9: error: field default value contains reference to comptime var
46// :6:14: note: '0' points to comptime var declared here
47// :23:9: error: captured value contains reference to comptime var
48// :22:14: note: 'a' points to comptime var declared here
49// :27:9: error: field default value contains reference to comptime var
50// :26:14: note: 'foo' points to comptime var declared here
25// :8:9: error: captured value contains reference to comptime var
26// :7:14: note: 'a' points to comptime var declared here
27// :17:9: error: field default value contains reference to comptime var
28// :11:14: note: 'foo' points to comptime var declared here
test/cases/sentinel_references_comptime_var.zig+5-24
......@@ -2,14 +2,6 @@ export fn foo() void {
22 comptime var a: u8 = 0;
33 _ = [0:&a]*u8;
44}
5export fn bar() void {
6 comptime var a: u8 = 0;
7 _ = @Type(.{ .array = .{
8 .child = *u8,
9 .len = 0,
10 .sentinel_ptr = @ptrCast(&&a),
11 } });
12}
135
146export fn baz() void {
157 comptime var a: u8 = 0;
......@@ -17,25 +9,14 @@ export fn baz() void {
179}
1810export fn qux() void {
1911 comptime var a: u8 = 0;
20 _ = @Type(.{ .pointer = .{
21 .size = .many,
22 .is_const = false,
23 .is_volatile = false,
24 .alignment = @alignOf(u8),
25 .address_space = .generic,
26 .child = *u8,
27 .is_allowzero = false,
28 .sentinel_ptr = @ptrCast(&&a),
29 } });
12 _ = @Pointer(.many, .{}, *u8, &a);
3013}
3114
3215// error
3316//
3417// :3:12: error: sentinel contains reference to comptime var
3518// :2:14: note: 'sentinel' points to comptime var declared here
36// :7:9: error: sentinel contains reference to comptime var
37// :6:14: note: 'sentinel_ptr' points to comptime var declared here
38// :16:11: error: sentinel contains reference to comptime var
39// :15:14: note: 'sentinel' points to comptime var declared here
40// :20:9: error: sentinel contains reference to comptime var
41// :19:14: note: 'sentinel_ptr' points to comptime var declared here
19// :8:11: error: sentinel contains reference to comptime var
20// :7:14: note: 'sentinel' points to comptime var declared here
21// :12:35: error: sentinel contains reference to comptime var
22// :11:14: note: 'sentinel' points to comptime var declared here
test/standalone/simple/issue_7030.zig+1-1
......@@ -6,7 +6,7 @@ pub const std_options: std.Options = .{
66
77pub fn log(
88 comptime message_level: std.log.Level,
9 comptime scope: @Type(.enum_literal),
9 comptime scope: @EnumLiteral(),
1010 comptime format: []const u8,
1111 args: anytype,
1212) void {
test/standalone/simple/std_enums_big_enums.zig+14-15
......@@ -3,20 +3,18 @@ const std = @import("std");
33// big enums should not hit the eval branch quota
44pub fn main() void {
55 const big = struct {
6 const Big = @Type(.{ .@"enum" = .{
7 .tag_type = u16,
8 .fields = make_fields: {
9 @setEvalBranchQuota(500000);
10 var fields: [1001]std.builtin.Type.EnumField = undefined;
11 for (&fields, 0..) |*field, i| {
12 field.* = .{ .name = std.fmt.comptimePrint("field_{d}", .{i}), .value = i };
13 }
14 fields[1000] = .{ .name = "field_9999", .value = 9999 };
15 break :make_fields &fields;
16 },
17 .decls = &.{},
18 .is_exhaustive = true,
19 } });
6 const Big = Big: {
7 @setEvalBranchQuota(500000);
8 var names: [1001][]const u8 = undefined;
9 var values: [1001]u16 = undefined;
10 for (values[0..1000], names[0..1000], 0..1000) |*val, *name, i| {
11 name.* = std.fmt.comptimePrint("field_{d}", .{i});
12 val.* = i;
13 }
14 names[1000] = "field_9999";
15 values[1000] = 9999;
16 break :Big @Enum(u16, .exhaustive, &names, &values);
17 };
2018 };
2119
2220 var set = std.enums.EnumSet(big.Big).init(.{});
......@@ -29,10 +27,11 @@ pub fn main() void {
2927 var multiset = std.enums.EnumMultiset(big.Big).init(.{});
3028 _ = &multiset;
3129
30 @setEvalBranchQuota(4000);
31
3232 var bounded_multiset = std.enums.BoundedEnumMultiset(big.Big, u8).init(.{});
3333 _ = &bounded_multiset;
3434
35 @setEvalBranchQuota(3000);
3635 var array = std.enums.EnumArray(big.Big, u8).init(undefined);
3736 array = std.enums.EnumArray(big.Big, u8).initDefault(123, .{});
3837}
tools/lldb_pretty_printers.py+1-1
......@@ -559,7 +559,7 @@ type_tag_handlers = {
559559 'extern_options': lambda payload: 'std.builtin.ExternOptions',
560560 'type_info': lambda payload: 'std.builtin.Type',
561561
562 'enum_literal': lambda payload: '@TypeOf(.enum_literal)',
562 'enum_literal': lambda payload: '@EnumLiteral()',
563563 'null': lambda payload: '@TypeOf(null)',
564564 'undefined': lambda payload: '@TypeOf(undefined)',
565565 'empty_struct_literal': lambda payload: '@TypeOf(.{})',