diff --git a/doc/langref.html.in b/doc/langref.html.in index 17f3be04a0..84a4bba774 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -5752,7 +5752,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val {#header_open|@Fn#}
{#syntax#}@Fn(
     comptime param_types: []const type,
-    comptime param_attrs: *const [param_types.len]std.lang.Type.Fn.Param.Attributes,
+    comptime param_attrs: *const [param_types.len]std.lang.Type.Fn.ParamAttributes,
     comptime ReturnType: type,
     comptime attrs: std.lang.Type.Fn.Attributes,
 ) type{#endsyntax#}
@@ -5765,7 +5765,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val comptime BackingInt: ?type, comptime field_names: []const []const u8, comptime field_types: *const [field_names.len]type, - comptime field_attrs: *const [field_names.len]std.lang.Type.StructField.Attributes, + comptime field_attrs: *const [field_names.len]std.lang.Type.Struct.FieldAttributes, ) type{#endsyntax#}

Returns a {#link|struct#} type with the properties specified by the arguments.

{#header_close#} @@ -5777,7 +5777,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val comptime ArgType: ?type, comptime field_names: []const []const u8, comptime field_types: *const [field_names.len]type, - comptime field_attrs: *const [field_names.len]std.lang.Type.UnionField.Attributes, + comptime field_attrs: *const [field_names.len]std.lang.Type.Union.FieldAttributes, ) type{#endsyntax#}

Returns a {#link|union#} type with the properties specified by the arguments.

{#header_close#} diff --git a/doc/langref/inline_prong_range.zig b/doc/langref/inline_prong_range.zig index 3d68324c56..4c195d6bfd 100644 --- a/doc/langref/inline_prong_range.zig +++ b/doc/langref/inline_prong_range.zig @@ -1,7 +1,7 @@ fn isFieldOptional(comptime T: type, field_index: usize) !bool { - const fields = @typeInfo(T).@"struct".fields; + const field_types = @typeInfo(T).@"struct".field_types; return switch (field_index) { - inline 0...fields.len - 1 => |idx| @typeInfo(fields[idx].type) == .optional, + inline 0...field_types.len - 1 => |idx| @typeInfo(field_types[idx]) == .optional, else => return error.IndexOutOfBounds, }; } diff --git a/doc/langref/test_enums.zig b/doc/langref/test_enums.zig index 55a4f87d3b..9502e7ae74 100644 --- a/doc/langref/test_enums.zig +++ b/doc/langref/test_enums.zig @@ -102,8 +102,8 @@ test "std.meta.Tag" { // @typeInfo tells us the field count and the fields names: test "@typeInfo" { - try expectEqual(4, @typeInfo(Small).@"enum".fields.len); - try expectEqualStrings(@typeInfo(Small).@"enum".fields[1].name, "two"); + try expectEqual(4, @typeInfo(Small).@"enum".field_names.len); + try expectEqualStrings(@typeInfo(Small).@"enum".field_names[1], "two"); } // @tagName gives a [:0]const u8 representation of an enum value: diff --git a/doc/langref/test_fn_reflection.zig b/doc/langref/test_fn_reflection.zig index 7c462bbfc5..42b89c72e9 100644 --- a/doc/langref/test_fn_reflection.zig +++ b/doc/langref/test_fn_reflection.zig @@ -3,7 +3,7 @@ const math = std.math; const testing = std.testing; test "fn reflection" { - try testing.expectEqual(bool, @typeInfo(@TypeOf(testing.expect)).@"fn".params[0].type.?); + try testing.expectEqual(bool, @typeInfo(@TypeOf(testing.expect)).@"fn".param_types[0].?); try testing.expectEqual(testing.TmpDir, @typeInfo(@TypeOf(testing.tmpDir)).@"fn".return_type.?); try testing.expect(@typeInfo(@TypeOf(math.Log2Int)).@"fn".is_generic); diff --git a/doc/langref/test_inline_else.zig b/doc/langref/test_inline_else.zig index 8972bd8c6b..c500bd685d 100644 --- a/doc/langref/test_inline_else.zig +++ b/doc/langref/test_inline_else.zig @@ -18,12 +18,13 @@ const AnySlice = union(enum) { fn withFor(any: AnySlice) usize { const Tag = @typeInfo(AnySlice).@"union".tag_type.?; - inline for (@typeInfo(Tag).@"enum".fields) |field| { + const info = @typeInfo(Tag).@"enum"; + inline for (info.field_names, info.field_values) |field_name, field_value| { // With `inline for` the function gets generated as // a series of `if` statements relying on the optimizer // to convert it to a switch. - if (field.value == @intFromEnum(any)) { - return @field(any, field.name).len; + if (field_value == @intFromEnum(any)) { + return @field(any, field_name).len; } } // When using `inline for` the compiler doesn't know that every diff --git a/doc/langref/test_inline_switch.zig b/doc/langref/test_inline_switch.zig index b19c467ef5..1dde085124 100644 --- a/doc/langref/test_inline_switch.zig +++ b/doc/langref/test_inline_switch.zig @@ -3,11 +3,11 @@ const expect = std.testing.expect; const expectError = std.testing.expectError; fn isFieldOptional(comptime T: type, field_index: usize) !bool { - const fields = @typeInfo(T).@"struct".fields; + const field_types = @typeInfo(T).@"struct".field_types; return switch (field_index) { // This prong is analyzed twice with `idx` being a // comptime-known value each time. - inline 0, 1 => |idx| @typeInfo(fields[idx].type) == .optional, + inline 0, 1 => |idx| @typeInfo(field_types[idx]) == .optional, else => return error.IndexOutOfBounds, }; } diff --git a/doc/langref/test_variable_func_alignment.zig b/doc/langref/test_variable_func_alignment.zig index bd97756c45..1b93aa295a 100644 --- a/doc/langref/test_variable_func_alignment.zig +++ b/doc/langref/test_variable_func_alignment.zig @@ -3,7 +3,7 @@ const expectEqual = @import("std").testing.expectEqual; var foo: u8 align(4) = 100; test "global variable alignment" { - try expectEqual(4, @typeInfo(@TypeOf(&foo)).pointer.alignment); + try expectEqual(4, @typeInfo(@TypeOf(&foo)).pointer.attrs.@"align"); try expectEqual(*align(4) u8, @TypeOf(&foo)); const as_pointer_to_array: *align(4) [1]u8 = &foo; const as_slice: []align(4) u8 = as_pointer_to_array; diff --git a/doc/langref/test_variadic_function.zig b/doc/langref/test_variadic_function.zig index a47e7fa18e..ab9fa84b51 100644 --- a/doc/langref/test_variadic_function.zig +++ b/doc/langref/test_variadic_function.zig @@ -5,7 +5,7 @@ pub extern "c" fn printf(format: [*:0]const u8, ...) c_int; test "variadic function" { try testing.expectEqual(14, printf("Hello, world!\n")); - try testing.expect(@typeInfo(@TypeOf(printf)).@"fn".is_var_args); + try testing.expect(@typeInfo(@TypeOf(printf)).@"fn".attrs.varargs); } // test diff --git a/lib/compiler/Maker/ScannedConfig.zig b/lib/compiler/Maker/ScannedConfig.zig index e9345f001f..1e36ff0d51 100644 --- a/lib/compiler/Maker/ScannedConfig.zig +++ b/lib/compiler/Maker/ScannedConfig.zig @@ -49,9 +49,10 @@ pub fn print(sc: *const ScannedConfig, w: *Writer) Writer.Error!void { } fn printStruct(sc: *const ScannedConfig, s: *Serializer.Struct, comptime S: type, v: S) !void { - inline for (@typeInfo(S).@"struct".fields) |field| { - try s.fieldPrefix(field.name); - try printValue(sc, s.container.serializer, field.type, @field(v, field.name)); + const info = @typeInfo(S).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + try s.fieldPrefix(field_name); + try printValue(sc, s.container.serializer, field_type, @field(v, field_name)); } } diff --git a/lib/compiler/Maker/Step/FindProgram.zig b/lib/compiler/Maker/Step/FindProgram.zig index b3396cc5c8..48eb678223 100644 --- a/lib/compiler/Maker/Step/FindProgram.zig +++ b/lib/compiler/Maker/Step/FindProgram.zig @@ -113,8 +113,8 @@ fn checkCandidate( } fn supportedWindowsProgramExtension(ext: []const u8) bool { - inline for (@typeInfo(std.process.WindowsExtension).@"enum".fields) |field| { - if (std.ascii.eqlIgnoreCase(ext, "." ++ field.name)) return true; + inline for (@typeInfo(std.process.WindowsExtension).@"enum".field_names) |field_name| { + if (std.ascii.eqlIgnoreCase(ext, "." ++ field_name)) return true; } return false; } diff --git a/lib/compiler/Maker/Watch/FsEvents.zig b/lib/compiler/Maker/Watch/FsEvents.zig index 04833b2644..6fc0bdbb57 100644 --- a/lib/compiler/Maker/Watch/FsEvents.zig +++ b/lib/compiler/Maker/Watch/FsEvents.zig @@ -87,8 +87,9 @@ pub fn init(cwd_path: []const u8) error{ OpenFrameworkFailed, MissingCoreService errdefer core_services.close(); var resolved_symbols: ResolvedSymbols = undefined; - inline for (@typeInfo(ResolvedSymbols).@"struct".fields) |f| { - @field(resolved_symbols, f.name) = core_services.lookup(f.type, f.name) orelse return error.MissingCoreServicesSymbol; + const info = @typeInfo(ResolvedSymbols).@"struct"; + inline for (info.field_names, info.field_types) |f_name, f_type| { + @field(resolved_symbols, f_name) = core_services.lookup(f_type, f_name) orelse return error.MissingCoreServicesSymbol; } return .{ diff --git a/lib/compiler/aro/aro/Attribute.zig b/lib/compiler/aro/aro/Attribute.zig index 389b390d23..b517792498 100644 --- a/lib/compiler/aro/aro/Attribute.zig +++ b/lib/compiler/aro/aro/Attribute.zig @@ -89,9 +89,9 @@ pub fn requiredArgCount(attr: Tag) u32 { inline else => |tag| { comptime var needed = 0; comptime { - const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; - for (fields) |arg_field| { - if (!mem.eql(u8, arg_field.name, "__name_tok") and @typeInfo(arg_field.type) != .optional) needed += 1; + const info = @typeInfo(@field(attributes, @tagName(tag))).@"struct"; + for (info.field_names, info.field_types) |arg_field_name, arg_field_type| { + if (!mem.eql(u8, arg_field_name, "__name_tok") and @typeInfo(arg_field_type) != .optional) needed += 1; } } return needed; @@ -105,9 +105,9 @@ pub fn maxArgCount(attr: Tag) u32 { inline else => |tag| { comptime var max = 0; comptime { - const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; - for (fields) |arg_field| { - if (!mem.eql(u8, arg_field.name, "__name_tok")) max += 1; + const field_names = @typeInfo(@field(attributes, @tagName(tag))).@"struct".field_names; + for (field_names) |arg_field_name| { + if (!mem.eql(u8, arg_field_name, "__name_tok")) max += 1; } } return max; @@ -130,10 +130,10 @@ pub const Formatting = struct { switch (attr) { .calling_convention => unreachable, inline else => |tag| { - const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; + const field_types = @typeInfo(@field(attributes, @tagName(tag))).@"struct".field_types; - if (fields.len == 0) unreachable; - const Unwrapped = UnwrapOptional(fields[0].type); + if (field_types.len == 0) unreachable; + const Unwrapped = UnwrapOptional(field_types[0]); if (@typeInfo(Unwrapped) != .@"enum") unreachable; return if (Unwrapped.opts.enum_kind == .identifier) "'" else "\""; @@ -147,18 +147,18 @@ pub const Formatting = struct { switch (attr) { .calling_convention => unreachable, inline else => |tag| { - const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; + const field_types = @typeInfo(@field(attributes, @tagName(tag))).@"struct".field_types; - if (fields.len == 0) unreachable; - const Unwrapped = UnwrapOptional(fields[0].type); + if (field_types.len == 0) unreachable; + const Unwrapped = UnwrapOptional(field_types[0]); if (@typeInfo(Unwrapped) != .@"enum") unreachable; - const enum_fields = @typeInfo(Unwrapped).@"enum".fields; + const enum_field_names = @typeInfo(Unwrapped).@"enum".field_names; const quote = comptime quoteChar(@enumFromInt(@intFromEnum(tag))); - comptime var values: []const u8 = quote ++ enum_fields[0].name ++ quote; - inline for (enum_fields[1..]) |enum_field| { + comptime var values: []const u8 = quote ++ enum_field_names[0] ++ quote; + inline for (enum_field_names[1..]) |enum_field_name| { values = values ++ ", "; - values = values ++ quote ++ enum_field.name ++ quote; + values = values ++ quote ++ enum_field_name ++ quote; } return values; }, @@ -171,10 +171,10 @@ pub fn wantsIdentEnum(attr: Tag) bool { switch (attr) { .calling_convention => return false, inline else => |tag| { - const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; + const field_types = @typeInfo(@field(attributes, @tagName(tag))).@"struct".field_types; - if (fields.len == 0) return false; - const Unwrapped = UnwrapOptional(fields[0].type); + if (field_types.len == 0) return false; + const Unwrapped = UnwrapOptional(field_types[0]); if (@typeInfo(Unwrapped) != .@"enum") return false; return Unwrapped.opts.enum_kind == .identifier; @@ -185,12 +185,12 @@ pub fn wantsIdentEnum(attr: Tag) bool { pub fn diagnoseIdent(attr: Tag, arguments: *Arguments, ident: TokenIndex, p: *Parser) !bool { switch (attr) { inline else => |tag| { - const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; - if (fields.len == 0) unreachable; - const Unwrapped = UnwrapOptional(fields[0].type); + const info = @typeInfo(@field(attributes, @tagName(tag))).@"struct"; + if (info.field_names.len == 0) unreachable; + const Unwrapped = UnwrapOptional(info.field_types[0]); if (@typeInfo(Unwrapped) != .@"enum") unreachable; if (std.meta.stringToEnum(Unwrapped, normalize(p.tokSlice(ident)))) |enum_val| { - @field(@field(arguments, @tagName(tag)), fields[0].name) = enum_val; + @field(@field(arguments, @tagName(tag)), info.field_names[0]) = enum_val; return false; } @@ -203,11 +203,11 @@ pub fn diagnoseIdent(attr: Tag, arguments: *Arguments, ident: TokenIndex, p: *Pa pub fn wantsAlignment(attr: Tag, idx: usize) bool { switch (attr) { inline else => |tag| { - const fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; - if (fields.len == 0) return false; + const field_types = @typeInfo(@field(attributes, @tagName(tag))).@"struct".field_types; + if (field_types.len == 0) return false; return switch (idx) { - inline 0...fields.len - 1 => |i| UnwrapOptional(fields[i].type) == Alignment, + inline 0...field_types.len - 1 => |i| UnwrapOptional(field_types[i]) == Alignment, else => false, }; }, @@ -217,12 +217,12 @@ pub fn wantsAlignment(attr: Tag, idx: usize) bool { pub fn diagnoseAlignment(attr: Tag, arguments: *Arguments, arg_idx: u32, res: Parser.Result, arg_start: TokenIndex, p: *Parser) !bool { switch (attr) { inline else => |tag| { - const arg_fields = @typeInfo(@field(attributes, @tagName(tag))).@"struct".fields; - if (arg_fields.len == 0) unreachable; + const arg_info = @typeInfo(@field(attributes, @tagName(tag))).@"struct"; + if (arg_info.field_names.len == 0) unreachable; switch (arg_idx) { - inline 0...arg_fields.len - 1 => |arg_i| { - if (UnwrapOptional(arg_fields[arg_i].type) != Alignment) unreachable; + inline 0...arg_info.field_names.len - 1 => |arg_i| { + if (UnwrapOptional(arg_info.field_types[arg_i]) != Alignment) unreachable; if (!res.val.is(.int, p.comp)) { try p.err(arg_start, .alignas_unavailable, .{}); @@ -241,7 +241,7 @@ pub fn diagnoseAlignment(attr: Tag, arguments: *Arguments, arg_idx: u32, res: Pa return true; } - @field(@field(arguments, @tagName(tag)), arg_fields[arg_i].name) = .{ .requested = requested }; + @field(@field(arguments, @tagName(tag)), arg_info.field_names[arg_i]) = .{ .requested = requested }; return false; }, else => unreachable, @@ -251,8 +251,8 @@ pub fn diagnoseAlignment(attr: Tag, arguments: *Arguments, arg_idx: u32, res: Pa } fn diagnoseField( - comptime decl: ZigType.Declaration, - comptime field: ZigType.StructField, + comptime decl_name: []const u8, + comptime field_name: []const u8, comptime Wanted: type, arguments: *Arguments, res: Parser.Result, @@ -283,7 +283,7 @@ fn diagnoseField( if (res.val.opt_ref == .none) { if (Wanted == Identifier and node == .decl_ref_expr) { - @field(@field(arguments, decl.name), field.name) = .{ .tok = node.decl_ref_expr.name_tok }; + @field(@field(arguments, decl_name), field_name) = .{ .tok = node.decl_ref_expr.name_tok }; return false; } @@ -294,7 +294,7 @@ fn diagnoseField( switch (key) { .int => { if (@typeInfo(Wanted) == .int) { - @field(@field(arguments, decl.name), field.name) = res.val.toInt(Wanted, p.comp) orelse { + @field(@field(arguments, decl_name), field_name) = res.val.toInt(Wanted, p.comp) orelse { try p.err(arg_start, .attribute_int_out_of_range, .{res}); return true; }; @@ -310,20 +310,20 @@ fn diagnoseField( .char, .uchar, .schar => {}, else => break :validate, } - @field(@field(arguments, decl.name), field.name) = try p.removeNull(res.val); + @field(@field(arguments, decl_name), field_name) = try p.removeNull(res.val); return false; } - try p.err(arg_start, .attribute_requires_string, .{decl.name}); + try p.err(arg_start, .attribute_requires_string, .{decl_name}); return true; } else if (@typeInfo(Wanted) == .@"enum" and @hasDecl(Wanted, "opts") and Wanted.opts.enum_kind == .string) { const str = bytes[0 .. bytes.len - 1]; if (std.meta.stringToEnum(Wanted, str)) |enum_val| { - @field(@field(arguments, decl.name), field.name) = enum_val; + @field(@field(arguments, decl_name), field_name) = enum_val; return false; } - try p.err(arg_start, .unknown_attr_enum, .{ decl.name, Formatting.choices(@field(Tag, decl.name)) }); + try p.err(arg_start, .unknown_attr_enum, .{ decl_name, Formatting.choices(@field(Tag, decl_name)) }); return true; } }, @@ -344,17 +344,18 @@ fn diagnoseField( pub fn diagnose(attr: Tag, arguments: *Arguments, arg_idx: u32, res: Parser.Result, arg_start: TokenIndex, node: Tree.Node, p: *Parser) !bool { switch (attr) { inline else => |tag| { - const decl = @typeInfo(attributes).@"struct".decls[@intFromEnum(tag)]; + const decl_name = @typeInfo(attributes).@"struct".decl_names[@intFromEnum(tag)]; const max_arg_count = comptime maxArgCount(tag); if (arg_idx >= max_arg_count) { try p.err(arg_start, .attribute_too_many_args, .{ @tagName(attr), max_arg_count }); return true; } - const arg_fields = @typeInfo(@field(attributes, decl.name)).@"struct".fields; + const arg_field_names = @typeInfo(@field(attributes, decl_name)).@"struct".field_names; + const arg_field_types = @typeInfo(@field(attributes, decl_name)).@"struct".field_types; switch (arg_idx) { - inline 0...arg_fields.len - 1 => |arg_i| { - return diagnoseField(decl, arg_fields[arg_i], UnwrapOptional(arg_fields[arg_i].type), arguments, res, arg_start, node, p); + inline 0...arg_field_names.len - 1 => |arg_i| { + return diagnoseField(decl_name, arg_field_names[arg_i], UnwrapOptional(arg_field_types[arg_i]), arguments, res, arg_start, node, p); }, else => unreachable, } @@ -722,20 +723,20 @@ const attributes = struct { pub const Tag = std.meta.DeclEnum(attributes); pub const Arguments = blk: { - const decls = @typeInfo(attributes).@"struct".decls; - var names: [decls.len][]const u8 = undefined; - var types: [decls.len]type = undefined; - for (decls, &names, &types) |decl, *name, *T| { - name.* = decl.name; - T.* = @field(attributes, decl.name); + const decl_names = @typeInfo(attributes).@"struct".decl_names; + var names: [decl_names.len][]const u8 = undefined; + var types: [decl_names.len]type = undefined; + for (decl_names, &names, &types) |decl_name, *name, *T| { + name.* = decl_name; + T.* = @field(attributes, decl_name); } break :blk @Union(.auto, null, &names, &types, &@splat(.{})); }; pub fn ArgumentsForTag(comptime tag: Tag) type { - const decl = @typeInfo(attributes).@"struct".decls[@intFromEnum(tag)]; - return @field(attributes, decl.name); + const decl_name = @typeInfo(attributes).@"struct".decl_names[@intFromEnum(tag)]; + return @field(attributes, decl_name); } pub fn initArguments(tag: Tag, name_tok: TokenIndex) Arguments { diff --git a/lib/compiler/aro/aro/Compilation.zig b/lib/compiler/aro/aro/Compilation.zig index bf3670a033..978bbcffc8 100644 --- a/lib/compiler/aro/aro/Compilation.zig +++ b/lib/compiler/aro/aro/Compilation.zig @@ -78,12 +78,12 @@ pub const Environment = struct { pub fn loadAll(environ_map: *const std.process.Environ.Map) Environment { var env: Environment = .{}; - inline for (@typeInfo(@TypeOf(env)).@"struct".fields) |field| { - std.debug.assert(@field(env, field.name) == null); + inline for (@typeInfo(@TypeOf(env)).@"struct".field_names) |field_name| { + std.debug.assert(@field(env, field_name) == null); - var env_var_buf: [field.name.len]u8 = undefined; - const env_var_name = std.ascii.upperString(&env_var_buf, field.name); - @field(env, field.name) = environ_map.get(env_var_name); + var env_var_buf: [field_name.len]u8 = undefined; + const env_var_name = std.ascii.upperString(&env_var_buf, field_name); + @field(env, field_name) = environ_map.get(env_var_name); } return env; } diff --git a/lib/compiler/aro/aro/Diagnostics.zig b/lib/compiler/aro/aro/Diagnostics.zig index 9443c876d5..78284de142 100644 --- a/lib/compiler/aro/aro/Diagnostics.zig +++ b/lib/compiler/aro/aro/Diagnostics.zig @@ -333,8 +333,8 @@ pub fn deinit(d: *Diagnostics) void { /// Used by the __has_warning builtin macro. pub fn warningExists(name: []const u8) bool { if (std.mem.eql(u8, name, "pedantic")) return true; - inline for (comptime std.meta.declarations(Option)) |group| { - if (std.mem.eql(u8, name, group.name)) return true; + inline for (comptime std.meta.declarations(Option)) |group_name| { + if (std.mem.eql(u8, name, group_name)) return true; } return std.meta.stringToEnum(Option, name) != null; } @@ -349,9 +349,9 @@ pub fn set(d: *Diagnostics, name: []const u8, to: Message.Kind) Compilation.Erro return; } - inline for (comptime std.meta.declarations(Option)) |group| { - if (std.mem.eql(u8, name, group.name)) { - for (@field(Option, group.name)) |option| { + inline for (comptime std.meta.declarations(Option)) |group_name| { + if (std.mem.eql(u8, name, group_name)) { + for (@field(Option, group_name)) |option| { d.state.options.put(option, to); } return; @@ -494,8 +494,8 @@ pub fn addWithLocation( pub fn formatArgs(w: *std.Io.Writer, fmt: []const u8, args: anytype) std.Io.Writer.Error!void { var i: usize = 0; - inline for (std.meta.fields(@TypeOf(args))) |arg_info| { - const arg = @field(args, arg_info.name); + inline for (comptime std.meta.fieldNames(@TypeOf(args))) |arg_name| { + const arg = @field(args, arg_name); i += switch (@TypeOf(arg)) { []const u8 => try formatString(w, fmt[i..], arg), else => switch (@typeInfo(@TypeOf(arg))) { diff --git a/lib/compiler/aro/aro/Parser.zig b/lib/compiler/aro/aro/Parser.zig index 53c7273538..3388150e1f 100644 --- a/lib/compiler/aro/aro/Parser.zig +++ b/lib/compiler/aro/aro/Parser.zig @@ -456,8 +456,8 @@ pub fn err(p: *Parser, tok_i: TokenIndex, diagnostic: Diagnostic, args: anytype) fn formatArgs(p: *Parser, w: *std.Io.Writer, fmt: []const u8, args: anytype) !void { var i: usize = 0; - inline for (std.meta.fields(@TypeOf(args))) |arg_info| { - const arg = @field(args, arg_info.name); + inline for (comptime std.meta.fieldNames(@TypeOf(args))) |arg_name| { + const arg = @field(args, arg_name); i += switch (@TypeOf(arg)) { []const u8 => try Diagnostics.formatString(w, fmt[i..], arg), Tree.Token.Id => try formatTokenId(w, fmt[i..], arg), diff --git a/lib/compiler/aro/aro/Tree.zig b/lib/compiler/aro/aro/Tree.zig index fec719106c..1bd854b43f 100644 --- a/lib/compiler/aro/aro/Tree.zig +++ b/lib/compiler/aro/aro/Tree.zig @@ -3048,25 +3048,25 @@ fn dumpAttribute(tree: *const Tree, attr: Attribute, w: *std.Io.Writer) !void { switch (attr.tag) { inline else => |tag| { const args = @field(attr.args, @tagName(tag)); - const fields = @typeInfo(@TypeOf(args)).@"struct".fields; - if (fields.len == 0) { + const args_info = @typeInfo(@TypeOf(args)).@"struct"; + if (args_info.field_names.len == 0) { try w.writeByte('\n'); return; } try w.writeByte(' '); - inline for (fields, 0..) |f, i| { - if (comptime std.mem.eql(u8, f.name, "__name_tok")) continue; + inline for (args_info.field_names, args_info.field_types, 0..) |f_name, f_type, i| { + if (comptime std.mem.eql(u8, f_name, "__name_tok")) continue; if (i != 0) { try w.writeAll(", "); } - try w.writeAll(f.name); + try w.writeAll(f_name); try w.writeAll(": "); - switch (f.type) { - Interner.Ref => try w.print("\"{s}\"", .{tree.interner.get(@field(args, f.name)).bytes}), - ?Interner.Ref => try w.print("\"{?s}\"", .{if (@field(args, f.name)) |str| tree.interner.get(str).bytes else null}), - else => switch (@typeInfo(f.type)) { - .@"enum" => try w.writeAll(@tagName(@field(args, f.name))), - else => try w.print("{any}", .{@field(args, f.name)}), + switch (f_type) { + Interner.Ref => try w.print("\"{s}\"", .{tree.interner.get(@field(args, f_name)).bytes}), + ?Interner.Ref => try w.print("\"{?s}\"", .{if (@field(args, f_name)) |str| tree.interner.get(str).bytes else null}), + else => switch (@typeInfo(f_type)) { + .@"enum" => try w.writeAll(@tagName(@field(args, f_name))), + else => try w.print("{any}", .{@field(args, f_name)}), }, } } diff --git a/lib/compiler/aro/aro/features.zig b/lib/compiler/aro/aro/features.zig index 0b6d0e2e93..d8a93fba6d 100644 --- a/lib/compiler/aro/aro/features.zig +++ b/lib/compiler/aro/aro/features.zig @@ -46,8 +46,8 @@ pub fn hasFeature(comp: *Compilation, ext: []const u8) bool { .c_thread_local = comp.langopts.standard.atLeast(.c11) and comp.target.isTlsSupported(), .bounds_attributes = comp.langopts.bounds_safety == .clang, }; - inline for (@typeInfo(@TypeOf(list)).@"struct".fields) |f| { - if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name); + inline for (@typeInfo(@TypeOf(list)).@"struct".field_names) |f_name| { + if (std.mem.eql(u8, f_name, ext)) return @field(list, f_name); } return false; } @@ -70,8 +70,8 @@ pub fn hasExtension(comp: *Compilation, ext: []const u8) bool { .matrix_types = false, // TODO .matrix_types_scalar_division = false, // TODO }; - inline for (@typeInfo(@TypeOf(list)).@"struct".fields) |f| { - if (std.mem.eql(u8, f.name, ext)) return @field(list, f.name); + inline for (@typeInfo(@TypeOf(list)).@"struct".field_names) |f_name| { + if (std.mem.eql(u8, f_name, ext)) return @field(list, f_name); } return false; } diff --git a/lib/compiler/aro/aro/text_literal.zig b/lib/compiler/aro/aro/text_literal.zig index 73efc5d262..5d186167b1 100644 --- a/lib/compiler/aro/aro/text_literal.zig +++ b/lib/compiler/aro/aro/text_literal.zig @@ -335,8 +335,8 @@ pub const Parser = struct { fn formatArgs(w: *std.Io.Writer, fmt: []const u8, args: anytype) !void { var i: usize = 0; - inline for (std.meta.fields(@TypeOf(args))) |arg_info| { - const arg = @field(args, arg_info.name); + inline for (comptime std.meta.fieldNames(@TypeOf(args))) |arg_name| { + const arg = @field(args, arg_name); i += switch (@TypeOf(arg)) { []const u8 => try Diagnostics.formatString(w, fmt[i..], arg), Ascii => try arg.format(w, fmt[i..]), diff --git a/lib/compiler/aro/backend/Interner.zig b/lib/compiler/aro/backend/Interner.zig index f43d518f5c..027c411d63 100644 --- a/lib/compiler/aro/backend/Interner.zig +++ b/lib/compiler/aro/backend/Interner.zig @@ -733,7 +733,7 @@ pub fn put(i: *Interner, gpa: Allocator, key: Key) !Ref { }); }, .record_ty => |elems| { - try i.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.Record).@"struct".fields.len + + try i.extra.ensureUnusedCapacity(gpa, @typeInfo(Tag.Record).@"struct".field_names.len + elems.len); i.items.appendAssumeCapacity(.{ .tag = .record_ty, @@ -755,18 +755,19 @@ pub fn put(i: *Interner, gpa: Allocator, key: Key) !Ref { } fn addExtra(i: *Interner, gpa: Allocator, extra: anytype) Allocator.Error!u32 { - const fields = @typeInfo(@TypeOf(extra)).@"struct".fields; - try i.extra.ensureUnusedCapacity(gpa, fields.len); + const field_count = @typeInfo(@TypeOf(extra)).@"struct".field_names.len; + try i.extra.ensureUnusedCapacity(gpa, field_count); return i.addExtraAssumeCapacity(extra); } fn addExtraAssumeCapacity(i: *Interner, extra: anytype) u32 { const result = @as(u32, @intCast(i.extra.items.len)); - inline for (@typeInfo(@TypeOf(extra)).@"struct".fields) |field| { - i.extra.appendAssumeCapacity(switch (field.type) { - Ref => @intFromEnum(@field(extra, field.name)), - u32 => @field(extra, field.name), - else => @compileError("bad field type: " ++ @typeName(field.type)), + const info = @typeInfo(@TypeOf(extra)).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + i.extra.appendAssumeCapacity(switch (field_type) { + Ref => @intFromEnum(@field(extra, field_name)), + u32 => @field(extra, field_name), + else => @compileError("bad field type: " ++ @typeName(field_type)), }); } return result; @@ -891,17 +892,17 @@ fn extraData(i: *const Interner, comptime T: type, index: usize) T { fn extraDataTrail(i: *const Interner, comptime T: type, index: usize) struct { data: T, end: u32 } { var result: T = undefined; - const fields = @typeInfo(T).@"struct".fields; - inline for (fields, 0..) |field, field_i| { + const info = @typeInfo(T).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, field_i| { const int32 = i.extra.items[field_i + index]; - @field(result, field.name) = switch (field.type) { + @field(result, field_name) = switch (field_type) { Ref => @enumFromInt(int32), u32 => int32, - else => @compileError("bad field type: " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ @typeName(field_type)), }; } return .{ .data = result, - .end = @intCast(index + fields.len), + .end = @intCast(index + info.field_names.len), }; } diff --git a/lib/compiler/configurer.zig b/lib/compiler/configurer.zig index b88c410b22..cdd86f87d4 100644 --- a/lib/compiler/configurer.zig +++ b/lib/compiler/configurer.zig @@ -601,8 +601,8 @@ const Serialize = struct { dest_module.* = try addModule(s, src_module); } - comptime assert(std.mem.eql(u8, @typeInfo(Configuration.Module).@"struct".fields[2].name, "import_table")); - comptime assert(@typeInfo(Configuration.Module).@"struct".fields[2].type == Configuration.ImportTable.Index); + comptime assert(std.mem.eql(u8, @typeInfo(Configuration.Module).@"struct".field_names[2], "import_table")); + comptime assert(@typeInfo(Configuration.Module).@"struct".field_types[2] == Configuration.ImportTable.Index); assert(wc.extra.items[@intFromEnum(module_index) + 2] == @intFromEnum(Configuration.ImportTable.Index.invalid)); const import_table_index = try wc.addDeduped(Configuration.ImportTable, .{ .imports = .{ .mal = imports }, diff --git a/lib/compiler/resinator/bmp.zig b/lib/compiler/resinator/bmp.zig index 651be2e450..d4ec0ba886 100644 --- a/lib/compiler/resinator/bmp.zig +++ b/lib/compiler/resinator/bmp.zig @@ -241,8 +241,9 @@ pub const Compression = enum(u32) { }; fn structFieldsLittleToNative(comptime T: type, x: *T) void { - inline for (@typeInfo(T).@"struct".fields) |field| { - @field(x, field.name) = std.mem.littleToNative(field.type, @field(x, field.name)); + const info = @typeInfo(T).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(x, field_name) = std.mem.littleToNative(field_type, @field(x, field_name)); } } diff --git a/lib/compiler/resinator/code_pages.zig b/lib/compiler/resinator/code_pages.zig index 4f4544ff02..7907f6e173 100644 --- a/lib/compiler/resinator/code_pages.zig +++ b/lib/compiler/resinator/code_pages.zig @@ -178,19 +178,20 @@ pub const UnsupportedCodePage = enum(u16) { }; pub const CodePage = blk: { - const fields = @typeInfo(SupportedCodePage).@"enum".fields ++ @typeInfo(UnsupportedCodePage).@"enum".fields; - var field_names: [fields.len][]const u8 = undefined; - var field_values: [fields.len]u16 = undefined; - for (fields, &field_names, &field_values) |field, *name, *val| { - name.* = field.name; - val.* = field.value; + const field_names = @typeInfo(SupportedCodePage).@"enum".field_names ++ @typeInfo(UnsupportedCodePage).@"enum".field_names; + const field_values = @typeInfo(SupportedCodePage).@"enum".field_values ++ @typeInfo(UnsupportedCodePage).@"enum".field_values; + var cp_field_names: [field_names.len][]const u8 = undefined; + var cp_field_values: [field_names.len]u16 = undefined; + for (field_names, field_values, &cp_field_names, &cp_field_values) |field_name, field_value, *name, *val| { + name.* = field_name; + val.* = field_value; } - break :blk @Enum(u16, .exhaustive, &field_names, &field_values); + break :blk @Enum(u16, .exhaustive, &cp_field_names, &cp_field_values); }; pub fn isSupported(code_page: CodePage) bool { - inline for (@typeInfo(SupportedCodePage).@"enum".fields) |enumField| { - if (@intFromEnum(code_page) == @intFromEnum(@field(SupportedCodePage, enumField.name))) { + inline for (@typeInfo(SupportedCodePage).@"enum".field_names) |field_name| { + if (@intFromEnum(code_page) == @intFromEnum(@field(SupportedCodePage, field_name))) { return true; } } @@ -200,9 +201,10 @@ pub fn isSupported(code_page: CodePage) bool { pub fn getByIdentifier(identifier: u16) !CodePage { // There's probably a more efficient way to do this (e.g. ComptimeHashMap?) but // this should be fine, especially since this function likely won't be called much. - inline for (@typeInfo(CodePage).@"enum".fields) |enumField| { - if (identifier == enumField.value) { - return @field(CodePage, enumField.name); + const info = @typeInfo(CodePage).@"enum"; + inline for (info.field_names, info.field_values) |field_name, field_value| { + if (identifier == field_value) { + return @field(CodePage, field_name); } } return error.InvalidCodePage; diff --git a/lib/compiler/resinator/cvtres.zig b/lib/compiler/resinator/cvtres.zig index f496eec890..84364cea9f 100644 --- a/lib/compiler/resinator/cvtres.zig +++ b/lib/compiler/resinator/cvtres.zig @@ -1054,17 +1054,18 @@ pub const supported_targets = struct { .ebc, }; comptime { - for (@typeInfo(Arch).@"enum".fields) |enum_field| { - _ = std.mem.indexOfScalar(Arch, ordered_for_display, @enumFromInt(enum_field.value)) orelse { - @compileError(std.fmt.comptimePrint("'{s}' missing from ordered_for_display", .{enum_field.name})); + const info = @typeInfo(Arch).@"enum"; + for (info.field_names, info.field_values) |field_name, field_value| { + _ = std.mem.indexOfScalar(Arch, ordered_for_display, @enumFromInt(field_value)) orelse { + @compileError(std.fmt.comptimePrint("'{s}' missing from ordered_for_display", .{field_name})); }; } } pub const longest_name = blk: { var len = 0; - for (@typeInfo(Arch).@"enum".fields) |field| { - if (field.name.len > len) len = field.name.len; + for (@typeInfo(Arch).@"enum".field_names) |field_name| { + if (field_name.len > len) len = field_name.len; } break :blk len; }; @@ -1106,14 +1107,14 @@ pub const supported_targets = struct { // Enforce two things: // 1. Arch enum field names are all lowercase (necessary for how fromStringIgnoreCase is implemented) // 2. All enum fields in Arch have an associated RVA relocation type when converted to a coff.IMAGE.FILE.MACHINE - for (@typeInfo(Arch).@"enum".fields) |enum_field| { - const all_lower = all_lower: for (enum_field.name) |c| { + for (@typeInfo(Arch).@"enum".field_names) |field_name| { + const all_lower = all_lower: for (field_name) |c| { if (std.ascii.isUpper(c)) break :all_lower false; } else break :all_lower true; - if (!all_lower) @compileError(std.fmt.comptimePrint("Arch field is not all lowercase: {s}", .{enum_field.name})); - const coff_machine = @field(Arch, enum_field.name).toCoffMachineType(); + if (!all_lower) @compileError(std.fmt.comptimePrint("Arch field is not all lowercase: {s}", .{field_name})); + const coff_machine = @field(Arch, field_name).toCoffMachineType(); _ = rvaRelocationTypeIndicator(coff_machine) orelse { - @compileError(std.fmt.comptimePrint("No RVA relocation for Arch: {s}", .{enum_field.name})); + @compileError(std.fmt.comptimePrint("No RVA relocation for Arch: {s}", .{field_name})); }; } } diff --git a/lib/compiler/resinator/errors.zig b/lib/compiler/resinator/errors.zig index d4b6e25d2f..3fda3d3c52 100644 --- a/lib/compiler/resinator/errors.zig +++ b/lib/compiler/resinator/errors.zig @@ -145,8 +145,8 @@ pub const ErrorDetails = struct { comptime { // all fields in the extra union should be 32 bits or less - for (std.meta.fields(Extra)) |field| { - std.debug.assert(@bitSizeOf(field.type) <= 32); + for (std.meta.fieldTypes(Extra)) |field_type| { + std.debug.assert(@bitSizeOf(field_type) <= 32); } } @@ -257,18 +257,18 @@ pub const ErrorDetails = struct { pub fn writeCommaSeparated(self: ExpectedTypes, writer: *std.Io.Writer) !void { const struct_info = @typeInfo(ExpectedTypes).@"struct"; - const num_real_fields = struct_info.fields.len - 1; + const num_real_fields = struct_info.field_names.len - 1; const num_padding_bits = @bitSizeOf(ExpectedTypes) - num_real_fields; const mask = std.math.maxInt(struct_info.backing_integer.?) >> num_padding_bits; const relevant_bits_only = @as(struct_info.backing_integer.?, @bitCast(self)) & mask; const num_set_bits = @popCount(relevant_bits_only); var i: usize = 0; - inline for (struct_info.fields) |field_info| { - if (field_info.type != bool) continue; + inline for (struct_info.field_names, struct_info.field_types) |field_name, field_type| { + if (field_type != bool) continue; if (i == num_set_bits) return; - if (@field(self, field_info.name)) { - try writer.writeAll(strings.get(field_info.name).?); + if (@field(self, field_name)) { + try writer.writeAll(strings.get(field_name).?); i += 1; if (num_set_bits > 2 and i != num_set_bits) { try writer.writeAll(", "); @@ -857,24 +857,20 @@ pub const ErrorDetails = struct { /// Convenience struct only useful when the code page can be inferred from the token pub const ErrorDetailsWithoutCodePage = blk: { - const details_info = @typeInfo(ErrorDetails); - const fields = details_info.@"struct".fields; - var field_names: [fields.len - 1][]const u8 = undefined; - var field_types: [fields.len - 1]type = undefined; - var field_attrs: [fields.len - 1]std.builtin.Type.StructField.Attributes = undefined; + const details_info = @typeInfo(ErrorDetails).@"struct"; + const field_count = details_info.field_names.len; + var field_names: [field_count - 1][]const u8 = undefined; + var field_types: [field_count - 1]type = undefined; + var field_attrs: [field_count - 1]std.builtin.Type.Struct.FieldAttributes = undefined; var i: usize = 0; - for (fields) |field| { - if (std.mem.eql(u8, field.name, "code_page")) continue; - field_names[i] = field.name; - field_types[i] = field.type; - field_attrs[i] = .{ - .@"comptime" = field.is_comptime, - .@"align" = field.alignment, - .default_value_ptr = field.default_value_ptr, - }; + for (details_info.field_names, details_info.field_types, details_info.field_attrs) |field_name, field_type, field_attr| { + if (std.mem.eql(u8, field_name, "code_page")) continue; + field_names[i] = field_name; + field_types[i] = field_type; + field_attrs[i] = field_attr; i += 1; } - std.debug.assert(i == fields.len - 1); + std.debug.assert(i == field_count - 1); break :blk @Struct(.auto, null, &field_names, &field_types, &field_attrs); }; diff --git a/lib/compiler/resinator/lang.zig b/lib/compiler/resinator/lang.zig index c3ddc32fb2..625462cf47 100644 --- a/lib/compiler/resinator/lang.zig +++ b/lib/compiler/resinator/lang.zig @@ -87,8 +87,8 @@ pub fn tagToId(tag: []const u8) error{InvalidLanguageTag}!?LanguageId { if (parsed.multiple_suffixes) return null; const longest_known_tag = comptime blk: { var len = 0; - for (@typeInfo(LanguageId).@"enum".fields) |field| { - if (field.name.len > len) len = field.name.len; + for (@typeInfo(LanguageId).@"enum".field_names) |field_name| { + if (field_name.len > len) len = field_name.len; } break :blk len; }; @@ -120,13 +120,13 @@ test tagToId { test "exhaustive tagToId" { @setEvalBranchQuota(2000); - inline for (@typeInfo(LanguageId).@"enum".fields) |field| { - const id = tagToId(field.name) catch |err| { - std.debug.print("tag: {s}\n", .{field.name}); + inline for (@typeInfo(LanguageId).@"enum".field_names) |field_name| { + const id = tagToId(field_name) catch |err| { + std.debug.print("tag: {s}\n", .{field_name}); return err; }; - try std.testing.expectEqual(@field(LanguageId, field.name), id orelse { - std.debug.print("tag: {s}, got null\n", .{field.name}); + try std.testing.expectEqual(@field(LanguageId, field_name), id orelse { + std.debug.print("tag: {s}, got null\n", .{field_name}); return error.TestExpectedEqual; }); } diff --git a/lib/compiler/resinator/parse.zig b/lib/compiler/resinator/parse.zig index 1d54887a54..c884e0510a 100644 --- a/lib/compiler/resinator/parse.zig +++ b/lib/compiler/resinator/parse.zig @@ -137,7 +137,7 @@ pub const Parser = struct { fn parseOptionalStatements(self: *Self, resource: ResourceType) ![]*Node { var optional_statements: std.ArrayList(*Node) = .empty; - const num_statement_types = @typeInfo(rc.OptionalStatements).@"enum".fields.len; + const num_statement_types = @typeInfo(rc.OptionalStatements).@"enum".field_names.len; var statement_type_has_duplicates: [num_statement_types]bool = @splat(false); var last_statement_per_type: [num_statement_types]?*Node = @splat(null); diff --git a/lib/compiler/translate-c/ast.zig b/lib/compiler/translate-c/ast.zig index b1b6631ad0..ebe9e7b201 100644 --- a/lib/compiler/translate-c/ast.zig +++ b/lib/compiler/translate-c/ast.zig @@ -925,18 +925,18 @@ const Context = struct { } fn addExtra(c: *Context, extra: anytype) Allocator.Error!std.zig.Ast.ExtraIndex { - const fields = std.meta.fields(@TypeOf(extra)); - try c.extra_data.ensureUnusedCapacity(c.gpa, fields.len); + const info = @typeInfo(@TypeOf(extra)).@"struct"; + try c.extra_data.ensureUnusedCapacity(c.gpa, info.field_names.len); const result: std.zig.Ast.ExtraIndex = @enumFromInt(c.extra_data.items.len); - inline for (fields) |field| { - const data: u32 = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + const data: u32 = switch (field_type) { NodeIndex, std.zig.Ast.Node.OptionalIndex, std.zig.Ast.OptionalTokenIndex, std.zig.Ast.ExtraIndex, - => @intFromEnum(@field(extra, field.name)), + => @intFromEnum(@field(extra, field_name)), TokenIndex, - => @field(extra, field.name), + => @field(extra, field_name), else => @compileError("unexpected field type"), }; c.extra_data.appendAssumeCapacity(data); diff --git a/lib/docs/wasm/markdown/Document.zig b/lib/docs/wasm/markdown/Document.zig index 59a40135d6..0cf00556fb 100644 --- a/lib/docs/wasm/markdown/Document.zig +++ b/lib/docs/wasm/markdown/Document.zig @@ -170,11 +170,11 @@ pub fn ExtraData(comptime T: type) type { } pub fn extraData(doc: Document, comptime T: type, index: ExtraIndex) ExtraData(T) { - const fields = @typeInfo(T).@"struct".fields; + const info = @typeInfo(T).@"struct"; var i: usize = @intFromEnum(index); var result: T = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => doc.extra[i], else => @compileError("bad field type"), }; diff --git a/lib/docs/wasm/markdown/Parser.zig b/lib/docs/wasm/markdown/Parser.zig index cb1800ff16..9d1bc1f46d 100644 --- a/lib/docs/wasm/markdown/Parser.zig +++ b/lib/docs/wasm/markdown/Parser.zig @@ -1574,11 +1574,11 @@ fn parseInlines(p: *Parser, content: []const u8) !ExtraIndex { } pub fn extraData(p: Parser, comptime T: type, index: ExtraIndex) ExtraData(T) { - const fields = @typeInfo(T).@"struct".fields; + const info = @typeInfo(T).@"struct"; var i: usize = @intFromEnum(index); var result: T = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => p.extra.items[i], else => @compileError("bad field type"), }; diff --git a/lib/std/Build.zig b/lib/std/Build.zig index cebc691fad..c5bf7d889d 100644 --- a/lib/std/Build.zig +++ b/lib/std/Build.zig @@ -389,9 +389,10 @@ fn createChild( fn userInputOptionsFromArgs(arena: Allocator, args: anytype) UserInputOptionsMap { var map = UserInputOptionsMap.init(arena); - inline for (@typeInfo(@TypeOf(args)).@"struct".fields) |field| { - if (field.type == @TypeOf(null)) continue; - addUserInputOptionFromArg(arena, &map, field, field.type, @field(args, field.name)); + const args_info = @typeInfo(@TypeOf(args)).@"struct"; + inline for (args_info.field_names, args_info.field_types) |field_name, field_type| { + if (field_type == @TypeOf(null)) continue; + addUserInputOptionFromArg(arena, &map, field_name, field_type, @field(args, field_name)); } return map; } @@ -399,15 +400,15 @@ fn userInputOptionsFromArgs(arena: Allocator, args: anytype) UserInputOptionsMap fn addUserInputOptionFromArg( arena: Allocator, map: *UserInputOptionsMap, - field: std.builtin.Type.StructField, + field_name: [:0]const u8, comptime T: type, /// If null, the value won't be added, but `T` will still be type-checked. maybe_value: ?T, ) void { switch (T) { Target.Query => return if (maybe_value) |v| { - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .scalar = v.zigTriple(arena) catch @panic("OOM") }, .used = false, }) catch @panic("OOM"); @@ -418,8 +419,8 @@ fn addUserInputOptionFromArg( }) catch @panic("OOM"); }, ResolvedTarget => return if (maybe_value) |v| { - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .scalar = v.query.zigTriple(arena) catch @panic("OOM") }, .used = false, }) catch @panic("OOM"); @@ -430,15 +431,15 @@ fn addUserInputOptionFromArg( }) catch @panic("OOM"); }, std.zig.BuildId => return if (maybe_value) |v| { - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .scalar = std.fmt.allocPrint(arena, "{f}", .{v}) catch @panic("OOM") }, .used = false, }) catch @panic("OOM"); }, LazyPath => return if (maybe_value) |v| { - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .lazy_path = v.dupeInner(arena) }, .used = false, }) catch @panic("OOM"); @@ -446,15 +447,15 @@ fn addUserInputOptionFromArg( []const LazyPath => return if (maybe_value) |v| { var list = std.array_list.Managed(LazyPath).initCapacity(arena, v.len) catch @panic("OOM"); for (v) |lp| list.appendAssumeCapacity(lp.dupeInner(arena)); - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .lazy_path_list = list }, .used = false, }) catch @panic("OOM"); }, []const u8 => return if (maybe_value) |v| { - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .scalar = arena.dupe(u8, v) catch @panic("OOM") }, .used = false, }) catch @panic("OOM"); @@ -462,37 +463,37 @@ fn addUserInputOptionFromArg( []const []const u8 => return if (maybe_value) |v| { var list = std.array_list.Managed([]const u8).initCapacity(arena, v.len) catch @panic("OOM"); for (v) |s| list.appendAssumeCapacity(arena.dupe(u8, s) catch @panic("OOM")); - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .list = list }, .used = false, }) catch @panic("OOM"); }, else => switch (@typeInfo(T)) { .bool => return if (maybe_value) |v| { - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .scalar = if (v) "true" else "false" }, .used = false, }) catch @panic("OOM"); }, .@"enum", .enum_literal => return if (maybe_value) |v| { - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .scalar = @tagName(v) }, .used = false, }) catch @panic("OOM"); }, .comptime_int, .int => return if (maybe_value) |v| { - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .scalar = std.fmt.allocPrint(arena, "{d}", .{v}) catch @panic("OOM") }, .used = false, }) catch @panic("OOM"); }, .comptime_float, .float => return if (maybe_value) |v| { - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .scalar = std.fmt.allocPrint(arena, "{x}", .{v}) catch @panic("OOM") }, .used = false, }) catch @panic("OOM"); @@ -503,7 +504,7 @@ fn addUserInputOptionFromArg( addUserInputOptionFromArg( arena, map, - field, + field_name, @Pointer(.slice, .{ .@"const" = true }, array_info.child, null), maybe_value orelse null, ); @@ -515,8 +516,8 @@ fn addUserInputOptionFromArg( .@"enum" => return if (maybe_value) |v| { var list = std.array_list.Managed([]const u8).initCapacity(arena, v.len) catch @panic("OOM"); for (v) |tag| list.appendAssumeCapacity(@tagName(tag)); - map.put(field.name, .{ - .name = field.name, + map.put(field_name, .{ + .name = field_name, .value = .{ .list = list }, .used = false, }) catch @panic("OOM"); @@ -525,7 +526,7 @@ fn addUserInputOptionFromArg( addUserInputOptionFromArg( arena, map, - field, + field_name, @Pointer(ptr_info.size, .{ .@"const" = true }, ptr_info.child, null), maybe_value orelse null, ); @@ -541,7 +542,7 @@ fn addUserInputOptionFromArg( addUserInputOptionFromArg( arena, map, - field, + field_name, info.child, maybe_value orelse null, ); @@ -551,7 +552,7 @@ fn addUserInputOptionFromArg( else => {}, }, } - @compileError("option '" ++ field.name ++ "' has unsupported type: " ++ @typeName(field.type)); + @compileError("option '" ++ field_name ++ "' has unsupported type: " ++ @typeName(T)); } const OrderedUserValue = union(enum) { @@ -1114,11 +1115,11 @@ pub fn option(b: *Build, comptime T: type, name_raw: []const u8, description_raw const type_id = comptime typeToEnum(T); const enum_options = if (type_id == .@"enum" or type_id == .enum_list) blk: { const EnumType = if (type_id == .enum_list) @typeInfo(T).pointer.child else T; - const fields = comptime std.meta.fields(EnumType); - var options = std.array_list.Managed([]const u8).initCapacity(arena, fields.len) catch @panic("OOM"); + const field_names = comptime std.meta.fieldNames(EnumType); + var options = std.array_list.Managed([]const u8).initCapacity(b.allocator, field_names.len) catch @panic("OOM"); - inline for (fields) |field| { - options.appendAssumeCapacity(field.name); + inline for (field_names) |field_name| { + options.appendAssumeCapacity(field_name); } break :blk options.toOwnedSlice() catch @panic("OOM"); @@ -1407,8 +1408,8 @@ pub fn parseTargetQuery(options: std.Target.Query.ParseOptions) error{ParseFaile \\available operating systems: \\ , .{diags.os_name.?}); - inline for (std.meta.fields(Target.Os.Tag)) |field| { - std.debug.print(" {s}\n", .{field.name}); + inline for (comptime std.meta.fieldNames(Target.Os.Tag)) |field_name| { + std.debug.print(" {s}\n", .{field_name}); } return error.ParseFailed; }, @@ -1811,8 +1812,8 @@ pub fn findProgram(b: *Build, options: FindProgramOptions) ?[]const u8 { } fn supportedWindowsProgramExtension(ext: []const u8) bool { - inline for (@typeInfo(std.process.WindowsExtension).@"enum".fields) |field| { - if (std.ascii.eqlIgnoreCase(ext, "." ++ field.name)) return true; + inline for (@typeInfo(std.process.WindowsExtension).@"enum".field_names) |field_name| { + if (std.ascii.eqlIgnoreCase(ext, "." ++ field_name)) return true; } return false; } @@ -2072,8 +2073,7 @@ inline fn findImportPkgHashOrFatal(b: *Build, comptime asking_build_zig: type, c const deps = build_runner.dependencies; const arena = b.graph.arena; - const b_pkg_hash, const b_pkg_deps = comptime for (@typeInfo(deps.packages).@"struct".decls) |decl| { - const pkg_hash = decl.name; + const b_pkg_hash, const b_pkg_deps = comptime for (@typeInfo(deps.packages).@"struct".decl_names) |pkg_hash| { const pkg = @field(deps.packages, pkg_hash); if (@hasDecl(pkg, "build_zig") and pkg.build_zig == asking_build_zig) break .{ pkg_hash, pkg.deps }; } else .{ "", deps.root_deps }; @@ -2116,9 +2116,9 @@ pub fn lazyDependency(b: *Build, name: []const u8, args: anytype) ?*Dependency { const deps = build_runner.dependencies; const pkg_hash = findPkgHashOrFatal(b, name); - inline for (@typeInfo(deps.packages).@"struct".decls) |decl| { - if (mem.eql(u8, decl.name, pkg_hash)) { - const pkg = @field(deps.packages, decl.name); + inline for (@typeInfo(deps.packages).@"struct".decl_names) |decl_name| { + if (mem.eql(u8, decl_name, pkg_hash)) { + const pkg = @field(deps.packages, decl_name); const available = !@hasDecl(pkg, "available") or pkg.available; if (!available) { markNeededLazyDep(b, pkg_hash); @@ -2136,9 +2136,9 @@ pub fn dependency(b: *Build, name: []const u8, args: anytype) *Dependency { const deps = build_runner.dependencies; const pkg_hash = findPkgHashOrFatal(b, name); - inline for (@typeInfo(deps.packages).@"struct".decls) |decl| { - if (mem.eql(u8, decl.name, pkg_hash)) { - const pkg = @field(deps.packages, decl.name); + inline for (@typeInfo(deps.packages).@"struct".decl_names) |decl_name| { + if (mem.eql(u8, decl_name, pkg_hash)) { + const pkg = @field(deps.packages, decl_name); if (@hasDecl(pkg, "available")) { panic("dependency '{s}{s}' is marked as lazy in build.zig.zon which means it must use the lazyDependency function instead", .{ b.dep_prefix, name }); } @@ -2166,9 +2166,9 @@ pub inline fn lazyImport( const deps = build_runner.dependencies; const pkg_hash = findImportPkgHashOrFatal(b, asking_build_zig, dep_name); - inline for (@typeInfo(deps.packages).@"struct".decls) |decl| { - if (comptime mem.eql(u8, decl.name, pkg_hash)) { - const pkg = @field(deps.packages, decl.name); + inline for (@typeInfo(deps.packages).@"struct".decl_names) |decl_name| { + if (comptime mem.eql(u8, decl_name, pkg_hash)) { + const pkg = @field(deps.packages, decl_name); const available = !@hasDecl(pkg, "available") or pkg.available; if (!available) { markNeededLazyDep(b, pkg_hash); @@ -2197,8 +2197,7 @@ pub fn dependencyFromBuildZig( const arena = graph.arena; find_dep: { - const pkg, const pkg_hash = inline for (@typeInfo(deps.packages).@"struct".decls) |decl| { - const pkg_hash = decl.name; + const pkg, const pkg_hash = inline for (@typeInfo(deps.packages).@"struct".decl_names) |pkg_hash| { const pkg = @field(deps.packages, pkg_hash); if (@hasDecl(pkg, "build_zig") and pkg.build_zig == build_zig) break .{ pkg, pkg_hash }; } else break :find_dep; diff --git a/lib/std/Build/Cache.zig b/lib/std/Build/Cache.zig index f6d158be55..fe40251590 100644 --- a/lib/std/Build/Cache.zig +++ b/lib/std/Build/Cache.zig @@ -1241,7 +1241,7 @@ pub const Manifest = struct { } pub fn populateFileSystemInputs(man: *Manifest, buf: *std.ArrayList(u8)) Allocator.Error!void { - assert(@typeInfo(std.zig.Server.Message.PathPrefix).@"enum".fields.len == man.cache.prefixes_len); + assert(@typeInfo(std.zig.Server.Message.PathPrefix).@"enum".field_names.len == man.cache.prefixes_len); buf.clearRetainingCapacity(); const gpa = man.cache.gpa; const files = man.files.keys(); @@ -1259,7 +1259,7 @@ pub const Manifest = struct { pub fn populateOtherManifest(man: *Manifest, other: *Manifest, prefix_map: [4]u8) Allocator.Error!void { const gpa = other.cache.gpa; - assert(@typeInfo(std.zig.Server.Message.PathPrefix).@"enum".fields.len == man.cache.prefixes_len); + assert(@typeInfo(std.zig.Server.Message.PathPrefix).@"enum".field_names.len == man.cache.prefixes_len); assert(man.cache.prefixes_len == 4); for (man.files.keys()) |file| { const prefixed_path: PrefixedPath = .{ diff --git a/lib/std/Build/Configuration.zig b/lib/std/Build/Configuration.zig index eda3a73e5e..d01ad0c897 100644 --- a/lib/std/Build/Configuration.zig +++ b/lib/std/Build/Configuration.zig @@ -2884,7 +2884,10 @@ pub const Storage = enum { } pub fn cast(this: @This(), c: *const Configuration, comptime S: type) ?S { - const wanted_tag = @typeInfo(S.Flags).@"struct".fields[0].defaultValue().?; + const wanted_tag = blk: { + const info = @typeInfo(S.Flags).@"struct"; + break :blk info.field_attrs[0].defaultValue(info.field_types[0]).?; + }; const base_flags: BaseFlags = @bitCast(c.extra[@intFromEnum(this)]); if (base_flags.tag != wanted_tag) return null; var i: usize = @intFromEnum(this); @@ -3047,8 +3050,8 @@ pub const Storage = enum { switch (@typeInfo(T)) { .@"struct" => |info| { var result: T = undefined; - inline for (info.fields) |field| { - @field(result, field.name) = dataField(buffer, i, &result, field.type); + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = dataField(buffer, i, &result, field_type); } return result; }, @@ -3058,7 +3061,7 @@ pub const Storage = enum { inline else => |comptime_tag| @unionInit( T, @tagName(comptime_tag), - data(buffer, i, info.fields[@intFromEnum(comptime_tag)].type), + data(buffer, i, info.field_types[@intFromEnum(comptime_tag)]), ), }; }, @@ -3125,7 +3128,7 @@ pub const Storage = enum { buffer, i, container, - @typeInfo(Field.Union).@"union".fields[@intFromEnum(comptime_tag)].type, + @typeInfo(Field.Union).@"union".field_types[@intFromEnum(comptime_tag)], ), ), }, @@ -3167,7 +3170,7 @@ pub const Storage = enum { .multi_list => { const data_start = i.* + 1; const len = buffer[data_start - 1]; - defer i.* = data_start + len * @typeInfo(Field.Elem).@"struct".fields.len; + defer i.* = data_start + len * @typeInfo(Field.Elem).@"struct".field_names.len; return .{ .mal = .{ .bytes = @ptrCast(@constCast(buffer[data_start..][0..len])), .len = len, @@ -3205,10 +3208,10 @@ pub const Storage = enum { /// Returns new end index. fn setExtra(buffer: []u32, index: usize, extra: anytype) usize { - const fields = @typeInfo(@TypeOf(extra)).@"struct".fields; + const info = @typeInfo(@TypeOf(extra)).@"struct"; var i = index; - inline for (fields) |field| { - i += setExtraField(buffer, i, field.type, @field(extra, field.name)); + inline for (info.field_names, info.field_types) |field_name, field_type| { + i += setExtraField(buffer, i, field_type, @field(extra, field_name)); } return i; } @@ -3236,7 +3239,7 @@ pub const Storage = enum { .flag_length_prefixed_list, .flag_list, => 1 + @divExact(@sizeOf(Field.Elem), @sizeOf(u32)) * field.slice.len, - .multi_list => 1 + field.mal.len * @typeInfo(Field.Elem).@"struct".fields.len, + .multi_list => 1 + field.mal.len * @typeInfo(Field.Elem).@"struct".field_names.len, .union_list => Field.extraLen(field.len), .flag_union => switch (field.u) { inline else => |v| extraFieldLen(v), @@ -3249,10 +3252,10 @@ pub const Storage = enum { } fn extraLen(extra: anytype) usize { - const fields = @typeInfo(@TypeOf(extra)).@"struct".fields; + const field_names = @typeInfo(@TypeOf(extra)).@"struct".field_names; var i: usize = 0; - inline for (fields) |field| { - i += Storage.extraFieldLen(@field(extra, field.name)); + inline for (field_names) |name| { + i += Storage.extraFieldLen(@field(extra, name)); } return i; } @@ -3324,12 +3327,12 @@ pub const Storage = enum { .multi_list => { const len: u32 = @intCast(value.mal.len); buffer[i] = len; - const fields = @typeInfo(Field.Elem).@"struct".fields; - inline for (0..fields.len) |field_i| @memcpy( + const field_names = @typeInfo(Field.Elem).@"struct".field_names; + inline for (0..field_names.len) |field_i| @memcpy( buffer[i + 1 + field_i * len ..][0..len], @as([]const u32, @ptrCast(value.mal.items(@enumFromInt(field_i)))), ); - return 1 + fields.len * len; + return 1 + field_names.len * len; }, .union_list => { if (value.len == 0) return 0; diff --git a/lib/std/Build/Step/ConfigHeader.zig b/lib/std/Build/Step/ConfigHeader.zig index 291e83975e..c16d6273ab 100644 --- a/lib/std/Build/Step/ConfigHeader.zig +++ b/lib/std/Build/Step/ConfigHeader.zig @@ -173,8 +173,9 @@ fn addValueInner(config_header: *ConfigHeader, name: []const u8, comptime T: typ } pub fn addValues(config_header: *ConfigHeader, values: anytype) void { - inline for (@typeInfo(@TypeOf(values)).@"struct".fields) |field| { - addValue(config_header, field.name, field.type, @field(values, field.name)); + const info = @typeInfo(@TypeOf(values)).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + addValue(config_header, field_name, field_type, @field(values, field_name)); } } diff --git a/lib/std/Build/Step/Options.zig b/lib/std/Build/Step/Options.zig index c8a490cfae..a377bcf704 100644 --- a/lib/std/Build/Step/Options.zig +++ b/lib/std/Build/Step/Options.zig @@ -299,14 +299,14 @@ fn printEnum( try out.appendNTimes(gpa, ' ', indent); try out.print(gpa, "pub const {f} = enum ({s}) {{\n", .{ std.zig.fmtId(@typeName(T)), @typeName(val.tag_type) }); - inline for (val.fields) |field| { + inline for (val.field_names, val.field_values) |field_name, field_value| { try out.appendNTimes(gpa, ' ', indent); try out.print(gpa, " {f} = {d},\n", .{ - std.zig.fmtIdFlags(field.name, .{ .allow_primitive = true }), field.value, + std.zig.fmtIdFlags(field_name, .{ .allow_primitive = true }), field_value, }); } - if (!val.is_exhaustive) { + if (val.mode == .nonexhaustive) { try out.appendNTimes(gpa, ' ', indent); try out.appendSlice(gpa, " _,\n"); } @@ -315,7 +315,13 @@ fn printEnum( try out.appendSlice(gpa, "};\n"); } -fn printStruct(options: *Options, out: *std.ArrayList(u8), comptime T: type, comptime val: std.builtin.Type.Struct, indent: u8) !void { +fn printStruct( + options: *Options, + out: *std.ArrayList(u8), + comptime T: type, + comptime val: std.builtin.Type.Struct, + indent: u8, +) !void { const gpa = options.step.owner.allocator; const gop = try options.encountered_types.getOrPut(gpa, @typeName(T)); if (gop.found_existing) return; @@ -331,32 +337,32 @@ fn printStruct(options: *Options, out: *std.ArrayList(u8), comptime T: type, com try out.appendSlice(gpa, " {\n"); - inline for (val.fields) |field| { + inline for (val.field_names, val.field_types, val.field_attrs) |field_name, field_type, field_attrs| { try out.appendNTimes(gpa, ' ', indent); - const type_name = @typeName(field.type); + const type_name = @typeName(field_type); // If the type name doesn't contains a '.' the type is from zig builtins. if (std.mem.containsAtLeast(u8, type_name, 1, ".")) { try out.print(gpa, " {f}: {f}", .{ - std.zig.fmtIdFlags(field.name, .{ .allow_underscore = true, .allow_primitive = true }), + std.zig.fmtIdFlags(field_name, .{ .allow_underscore = true, .allow_primitive = true }), std.zig.fmtId(type_name), }); } else { try out.print(gpa, " {f}: {s}", .{ - std.zig.fmtIdFlags(field.name, .{ .allow_underscore = true, .allow_primitive = true }), + std.zig.fmtIdFlags(field_name, .{ .allow_underscore = true, .allow_primitive = true }), type_name, }); } - if (field.defaultValue()) |default_value| { + if (field_attrs.defaultValue(field_type)) |default_value| { try out.appendSlice(gpa, " = "); - switch (@typeInfo(@TypeOf(default_value))) { + switch (@typeInfo(field_type)) { .@"enum" => try out.print(gpa, ".{s},\n", .{@tagName(default_value)}), .@"struct" => |info| { try printStructValue(options, out, info, default_value, indent + 4); }, - else => try printType(options, out, @TypeOf(default_value), default_value, indent, null), + else => try printType(options, out, field_type, default_value, indent, null), } } else { try out.appendSlice(gpa, ",\n"); @@ -368,8 +374,8 @@ fn printStruct(options: *Options, out: *std.ArrayList(u8), comptime T: type, com try out.appendNTimes(gpa, ' ', indent); try out.appendSlice(gpa, "};\n"); - inline for (val.fields) |field| { - try printUserDefinedType(options, out, field.type, 0); + inline for (val.field_types) |field_type| { + try printUserDefinedType(options, out, field_type, 0); } } @@ -384,24 +390,24 @@ fn printStructValue( try out.appendSlice(gpa, ".{\n"); if (struct_val.is_tuple) { - inline for (struct_val.fields) |field| { + inline for (struct_val.field_names) |field_name| { try out.appendNTimes(gpa, ' ', indent); - try printType(options, out, @TypeOf(@field(val, field.name)), @field(val, field.name), indent, null); + try printType(options, out, @TypeOf(@field(val, field_name)), @field(val, field_name), indent, null); } } else { - inline for (struct_val.fields) |field| { + inline for (struct_val.field_names) |field_name| { try out.appendNTimes(gpa, ' ', indent); try out.print(gpa, " .{f} = ", .{ - std.zig.fmtIdFlags(field.name, .{ .allow_primitive = true, .allow_underscore = true }), + std.zig.fmtIdFlags(field_name, .{ .allow_primitive = true, .allow_underscore = true }), }); - const field_name = @field(val, field.name); - switch (@typeInfo(@TypeOf(field_name))) { - .@"enum" => try out.print(gpa, ".{s},\n", .{@tagName(field_name)}), + const field_val = @field(val, field_name); + switch (@typeInfo(@TypeOf(field_val))) { + .@"enum" => try out.print(gpa, ".{s},\n", .{@tagName(field_val)}), .@"struct" => |struct_info| { - try printStructValue(options, out, struct_info, field_name, indent + 4); + try printStructValue(options, out, struct_info, field_val, indent + 4); }, - else => try printType(options, out, @TypeOf(field_name), field_name, indent, null), + else => try printType(options, out, @TypeOf(field_val), field_val, indent, null), } } } diff --git a/lib/std/Io.zig b/lib/std/Io.zig index 226de91cf7..50d1ebc21c 100644 --- a/lib/std/Io.zig +++ b/lib/std/Io.zig @@ -396,12 +396,13 @@ pub const Operation = union(enum) { }; pub const Result = Result: { - const operation_fields = @typeInfo(Operation).@"union".fields; - var field_names: [operation_fields.len][]const u8 = undefined; - var field_types: [operation_fields.len]type = undefined; - for (operation_fields, &field_names, &field_types) |field, *field_name, *field_type| { - field_name.* = field.name; - field_type.* = if (field.type == noreturn) noreturn else field.type.Result; + const operation_info = @typeInfo(Operation).@"union"; + const operation_count = operation_info.field_names.len; + var field_names: [operation_count][]const u8 = undefined; + var field_types: [operation_count]type = undefined; + for (operation_info.field_names, operation_info.field_types, &field_names, &field_types) |f_name, f_type, *field_name, *field_type| { + field_name.* = f_name; + field_type.* = if (f_type == noreturn) noreturn else f_type.Result; } break :Result @Union(.auto, Tag, &field_names, &field_types, &@splat(.{})); }; diff --git a/lib/std/Io/Reader.zig b/lib/std/Io/Reader.zig index 0be1fb1fbf..456c0f3470 100644 --- a/lib/std/Io/Reader.zig +++ b/lib/std/Io/Reader.zig @@ -1277,7 +1277,7 @@ pub fn takeEnum(r: *Reader, comptime Enum: type, endian: std.builtin.Endian) Tak /// Asserts the buffer was initialized with a capacity at least `@sizeOf(Enum)`. pub fn takeEnumNonexhaustive(r: *Reader, comptime Enum: type, endian: std.builtin.Endian) Error!Enum { const info = @typeInfo(Enum).@"enum"; - comptime assert(!info.is_exhaustive); + comptime assert(info.mode != .exhaustive); comptime assert(@bitSizeOf(info.tag_type) == @sizeOf(info.tag_type) * 8); return takeEnum(r, Enum, endian) catch |err| switch (err) { error.InvalidEnumTag => unreachable, diff --git a/lib/std/Io/Threaded.zig b/lib/std/Io/Threaded.zig index 69995da839..bbe8822dde 100644 --- a/lib/std/Io/Threaded.zig +++ b/lib/std/Io/Threaded.zig @@ -332,8 +332,8 @@ pub const Environ = struct { .flags = .{ .nonblocking = true }, }; }; - } else inline for (@typeInfo(String).@"struct".fields) |field| { - if (std.mem.eql(u8, key, field.name)) @field(environ.string, field.name) = value; + } else inline for (@typeInfo(String).@"struct".field_names) |field_name| { + if (std.mem.eql(u8, key, field_name)) @field(environ.string, field_name) = value; } } } @@ -11785,8 +11785,8 @@ fn sleepWasi(t: *Threaded, timeout: Io.Timeout) Io.Cancelable!void { fn sleepNanosleep(t: *Threaded, timeout: Io.Timeout) Io.Cancelable!void { const t_io = io(t); - const sec_type = @typeInfo(posix.timespec).@"struct".fields[0].type; - const nsec_type = @typeInfo(posix.timespec).@"struct".fields[1].type; + const sec_type = @typeInfo(posix.timespec).@"struct".field_types[0]; + const nsec_type = @typeInfo(posix.timespec).@"struct".field_types[1]; var timespec: posix.timespec = t: { const d = timeout.toDurationFromNow(t_io) orelse break :t .{ @@ -14923,9 +14923,9 @@ const WindowsEnvironStrings = struct { i += 1; // skip over null byte - inline for (@typeInfo(WindowsEnvironStrings).@"struct".fields) |field| { - const field_name_w = comptime std.unicode.wtf8ToWtf16LeStringLiteral(field.name); - if (windows.eqlIgnoreCaseWtf16(key_w, field_name_w)) @field(result, field.name) = value_w; + inline for (@typeInfo(WindowsEnvironStrings).@"struct".field_names) |field_name| { + const field_name_w = comptime std.unicode.wtf8ToWtf16LeStringLiteral(field_name); + if (windows.eqlIgnoreCaseWtf16(key_w, field_name_w)) @field(result, field_name) = value_w; } } @@ -16190,7 +16190,7 @@ fn windowsCreateProcessPathExt( } var io_status: windows.IO_STATUS_BLOCK = undefined; - const num_supported_pathext = @typeInfo(process.WindowsExtension).@"enum".fields.len; + const num_supported_pathext = @typeInfo(process.WindowsExtension).@"enum".field_names.len; var pathext_seen: [num_supported_pathext]bool = @splat(false); var any_pathext_seen = false; var unappended_exists = false; @@ -16435,8 +16435,8 @@ fn windowsCreateProcess( fn windowsCreateProcessSupportsExtension(ext: []const u16) ?process.WindowsExtension { comptime { // Ensures keeping this function in sync with the enum. - const fields = @typeInfo(process.WindowsExtension).@"enum".fields; - assert(fields.len == 4); + const field_names = @typeInfo(process.WindowsExtension).@"enum".field_names; + assert(field_names.len == 4); assert(@intFromEnum(process.WindowsExtension.bat) == 0); assert(@intFromEnum(process.WindowsExtension.cmd) == 1); assert(@intFromEnum(process.WindowsExtension.com) == 2); diff --git a/lib/std/Io/Writer.zig b/lib/std/Io/Writer.zig index 2aef4f8826..1c2f5f46e6 100644 --- a/lib/std/Io/Writer.zig +++ b/lib/std/Io/Writer.zig @@ -620,14 +620,14 @@ pub fn print(w: *Writer, comptime fmt: []const u8, args: anytype) Error!void { @compileError("expected tuple or struct argument, found " ++ @typeName(ArgsType)); } - const fields_info = args_type_info.@"struct".fields; + const field_names = args_type_info.@"struct".field_names; const max_format_args = @typeInfo(std.fmt.ArgSetType).int.bits; - if (fields_info.len > max_format_args) { + if (field_names.len > max_format_args) { @compileError("32 arguments max are supported per format call"); } @setEvalBranchQuota(@as(comptime_int, fmt.len) * 1000); // NOTE: We're upcasting as 16-bit usize overflows. - comptime var arg_state: std.fmt.ArgState = .{ .args_len = fields_info.len }; + comptime var arg_state: std.fmt.ArgState = .{ .args_len = field_names.len }; comptime var i = 0; comptime var literal: []const u8 = ""; inline while (true) { @@ -728,7 +728,7 @@ pub fn print(w: *Writer, comptime fmt: []const u8, args: anytype) Error!void { .width = width, .precision = precision, }, - @field(args, fields_info[arg_to_print].name), + @field(args, field_names[arg_to_print]), std.options.fmt_max_depth, ); } @@ -1290,7 +1290,7 @@ pub fn printValue( .@"enum" => |info| { if (!is_any and fmt.len != 0) invalidFmtError(fmt, value); optionsForbidden(options); - if (info.is_exhaustive) { + if (info.mode == .exhaustive) { return printEnumExhaustive(w, value); } else { return printEnumNonexhaustive(w, value); @@ -1309,9 +1309,9 @@ pub fn printValue( try w.writeAll(".{ ."); try w.writeAll(@tagName(@as(UnionTagType, value))); try w.writeAll(" = "); - inline for (info.fields) |u_field| { - if (value == @field(UnionTagType, u_field.name)) { - try w.printValue(ANY, options, @field(value, u_field.name), max_depth - 1); + inline for (info.field_names) |u_field_name| { + if (value == @field(UnionTagType, u_field_name)) { + try w.printValue(ANY, options, @field(value, u_field_name), max_depth - 1); } } try w.writeAll(" }"); @@ -1320,14 +1320,14 @@ pub fn printValue( return w.writeAll(".{ ... }"); }, .@"extern", .@"packed" => { - if (info.fields.len == 0) return w.writeAll(".{}"); + if (info.field_names.len == 0) return w.writeAll(".{}"); try w.writeAll(".{ "); - inline for (info.fields, 1..) |field, i| { + inline for (info.field_names, 1..) |field_name, i| { try w.writeByte('.'); - try w.writeAll(field.name); + try w.writeAll(field_name); try w.writeAll(" = "); - try w.printValue(ANY, options, @field(value, field.name), max_depth - 1); - try w.writeAll(if (i < info.fields.len) ", " else " }"); + try w.printValue(ANY, options, @field(value, field_name), max_depth - 1); + try w.writeAll(if (i < info.field_names.len) ", " else " }"); } }, } @@ -1344,13 +1344,13 @@ pub fn printValue( return; } try w.writeAll(".{"); - inline for (info.fields, 0..) |f, i| { + inline for (info.field_names, 0..) |f_name, i| { if (i == 0) { try w.writeAll(" "); } else { try w.writeAll(", "); } - try w.printValue(ANY, options, @field(value, f.name), max_depth - 1); + try w.printValue(ANY, options, @field(value, f_name), max_depth - 1); } try w.writeAll(" }"); return; @@ -1360,15 +1360,15 @@ pub fn printValue( return; } try w.writeAll(".{"); - inline for (info.fields, 0..) |f, i| { + inline for (info.field_names, 0..) |f_name, i| { if (i == 0) { try w.writeAll(" ."); } else { try w.writeAll(", ."); } - try w.writeAll(f.name); + try w.writeAll(f_name); try w.writeAll(" = "); - try w.printValue(ANY, options, @field(value, f.name), max_depth - 1); + try w.printValue(ANY, options, @field(value, f_name), max_depth - 1); } try w.writeAll(" }"); }, diff --git a/lib/std/Progress.zig b/lib/std/Progress.zig index aa9c9f54be..70c61f27e2 100644 --- a/lib/std/Progress.zig +++ b/lib/std/Progress.zig @@ -867,8 +867,8 @@ const TreeSymbol = enum { fn maxByteLen(symbol: TreeSymbol) usize { var max: usize = 0; - inline for (@typeInfo(Encoding).@"enum".fields) |field| { - const len = symbol.bytes(@field(Encoding, field.name)).len; + inline for (@typeInfo(Encoding).@"enum".field_names) |field_name| { + const len = symbol.bytes(@field(Encoding, field_name)).len; max = @max(max, len); } return max; diff --git a/lib/std/Target.zig b/lib/std/Target.zig index 4cac876835..fdeacdd719 100644 --- a/lib/std/Target.zig +++ b/lib/std/Target.zig @@ -1764,10 +1764,10 @@ pub const Cpu = struct { fn allCpusFromDecls(comptime cpus: type) []const *const Cpu.Model { @setEvalBranchQuota(2000); - const decls = @typeInfo(cpus).@"struct".decls; - var array: [decls.len]*const Cpu.Model = undefined; - for (decls, 0..) |decl, i| { - array[i] = &@field(cpus, decl.name); + const decl_names = @typeInfo(cpus).@"struct".decl_names; + var array: [decl_names.len]*const Cpu.Model = undefined; + for (decl_names, 0..) |decl_name, i| { + array[i] = &@field(cpus, decl_name); } const finalized = array; return &finalized; diff --git a/lib/std/Target/aarch64.zig b/lib/std/Target/aarch64.zig index 59dc81cfd2..dbd1b5273f 100644 --- a/lib/std/Target/aarch64.zig +++ b/lib/std/Target/aarch64.zig @@ -291,7 +291,7 @@ pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { @setEvalBranchQuota(2000); - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.a320)] = .{ @@ -2019,7 +2019,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/alpha.zig b/lib/std/Target/alpha.zig index 5dd097e690..9403735aa9 100644 --- a/lib/std/Target/alpha.zig +++ b/lib/std/Target/alpha.zig @@ -17,7 +17,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.bwx)] = .{ @@ -43,7 +43,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/amdgcn.zig b/lib/std/Target/amdgcn.zig index 924fc44359..7f7355daca 100644 --- a/lib/std/Target/amdgcn.zig +++ b/lib/std/Target/amdgcn.zig @@ -268,7 +268,7 @@ pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { @setEvalBranchQuota(2000); - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.@"1024_addressable_vgprs")] = .{ @@ -1877,7 +1877,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/arc.zig b/lib/std/Target/arc.zig index 7cd4e005f1..40e8577473 100644 --- a/lib/std/Target/arc.zig +++ b/lib/std/Target/arc.zig @@ -14,7 +14,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.norm)] = .{ @@ -25,7 +25,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/arm.zig b/lib/std/Target/arm.zig index 4037341cc7..39a9fbbbf7 100644 --- a/lib/std/Target/arm.zig +++ b/lib/std/Target/arm.zig @@ -215,7 +215,7 @@ pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { @setEvalBranchQuota(10000); - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.@"32bit")] = .{ @@ -1736,7 +1736,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/avr.zig b/lib/std/Target/avr.zig index 1afe2d4434..85b15bb636 100644 --- a/lib/std/Target/avr.zig +++ b/lib/std/Target/avr.zig @@ -52,7 +52,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.addsubiw)] = .{ @@ -388,7 +388,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/bpf.zig b/lib/std/Target/bpf.zig index 0c5ffad8e1..a5e34bb0d0 100644 --- a/lib/std/Target/bpf.zig +++ b/lib/std/Target/bpf.zig @@ -17,7 +17,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.allows_misaligned_mem_access)] = .{ @@ -43,7 +43,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/csky.zig b/lib/std/Target/csky.zig index 74cef9e595..4b40098a9c 100644 --- a/lib/std/Target/csky.zig +++ b/lib/std/Target/csky.zig @@ -76,7 +76,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.@"10e60")] = .{ @@ -418,7 +418,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/hexagon.zig b/lib/std/Target/hexagon.zig index 1ea2679708..9de1e04b5d 100644 --- a/lib/std/Target/hexagon.zig +++ b/lib/std/Target/hexagon.zig @@ -60,7 +60,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.audio)] = .{ @@ -334,7 +334,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/hppa.zig b/lib/std/Target/hppa.zig index fce6e3b31d..881b17db06 100644 --- a/lib/std/Target/hppa.zig +++ b/lib/std/Target/hppa.zig @@ -18,7 +18,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.@"64bit")] = .{ @@ -56,7 +56,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/kvx.zig b/lib/std/Target/kvx.zig index a5cb7a24f5..121ec5799d 100644 --- a/lib/std/Target/kvx.zig +++ b/lib/std/Target/kvx.zig @@ -16,7 +16,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.v3_1)] = .{ @@ -41,7 +41,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/lanai.zig b/lib/std/Target/lanai.zig index f4a83d610b..0ba921c539 100644 --- a/lib/std/Target/lanai.zig +++ b/lib/std/Target/lanai.zig @@ -12,13 +12,13 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/loongarch.zig b/lib/std/Target/loongarch.zig index 63dc829408..20a02568cc 100644 --- a/lib/std/Target/loongarch.zig +++ b/lib/std/Target/loongarch.zig @@ -34,7 +34,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.@"32bit")] = .{ @@ -153,7 +153,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/m68k.zig b/lib/std/Target/m68k.zig index fd4a8029c3..0a65c1a2da 100644 --- a/lib/std/Target/m68k.zig +++ b/lib/std/Target/m68k.zig @@ -36,7 +36,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.isa_68000)] = .{ @@ -170,7 +170,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/mips.zig b/lib/std/Target/mips.zig index b8a268702b..02ff2f6a9d 100644 --- a/lib/std/Target/mips.zig +++ b/lib/std/Target/mips.zig @@ -70,7 +70,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.abs2008)] = .{ @@ -425,7 +425,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/msp430.zig b/lib/std/Target/msp430.zig index 36f2dde126..4e4bc288c8 100644 --- a/lib/std/Target/msp430.zig +++ b/lib/std/Target/msp430.zig @@ -17,7 +17,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.ext)] = .{ @@ -43,7 +43,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/nvptx.zig b/lib/std/Target/nvptx.zig index 8573c18c89..8ba60697e3 100644 --- a/lib/std/Target/nvptx.zig +++ b/lib/std/Target/nvptx.zig @@ -84,7 +84,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.ptx32)] = .{ @@ -445,7 +445,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/powerpc.zig b/lib/std/Target/powerpc.zig index 8e36d87f97..897eb69a94 100644 --- a/lib/std/Target/powerpc.zig +++ b/lib/std/Target/powerpc.zig @@ -93,7 +93,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.@"64bit")] = .{ @@ -595,7 +595,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/propeller.zig b/lib/std/Target/propeller.zig index b05b98bc47..8e0b6e8580 100644 --- a/lib/std/Target/propeller.zig +++ b/lib/std/Target/propeller.zig @@ -14,7 +14,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.p2)] = .{ @@ -25,7 +25,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/riscv.zig b/lib/std/Target/riscv.zig index c935a90490..d7da10033c 100644 --- a/lib/std/Target/riscv.zig +++ b/lib/std/Target/riscv.zig @@ -361,7 +361,7 @@ pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { @setEvalBranchQuota(2000); - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.@"32bit")] = .{ @@ -2675,7 +2675,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/s390x.zig b/lib/std/Target/s390x.zig index b05669126e..086e427075 100644 --- a/lib/std/Target/s390x.zig +++ b/lib/std/Target/s390x.zig @@ -62,7 +62,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.backchain)] = .{ @@ -313,7 +313,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/sparc.zig b/lib/std/Target/sparc.zig index d7a0f8f746..c5d1d24615 100644 --- a/lib/std/Target/sparc.zig +++ b/lib/std/Target/sparc.zig @@ -72,7 +72,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.@"64bit")] = .{ @@ -395,7 +395,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/spirv.zig b/lib/std/Target/spirv.zig index cc9aee91b2..04b4530978 100644 --- a/lib/std/Target/spirv.zig +++ b/lib/std/Target/spirv.zig @@ -29,7 +29,7 @@ pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { @setEvalBranchQuota(2000); - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.arbitrary_precision_integers)] = .{ @@ -138,7 +138,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/ve.zig b/lib/std/Target/ve.zig index 454a02a0d7..ef02c8439b 100644 --- a/lib/std/Target/ve.zig +++ b/lib/std/Target/ve.zig @@ -14,7 +14,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.vpu)] = .{ @@ -25,7 +25,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/wasm.zig b/lib/std/Target/wasm.zig index d9b171408f..b72b66361f 100644 --- a/lib/std/Target/wasm.zig +++ b/lib/std/Target/wasm.zig @@ -32,7 +32,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.atomics)] = .{ @@ -139,7 +139,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/x86.zig b/lib/std/Target/x86.zig index eb5dcc0b20..ca5f4b2300 100644 --- a/lib/std/Target/x86.zig +++ b/lib/std/Target/x86.zig @@ -215,7 +215,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.@"16bit_mode")] = .{ @@ -1374,7 +1374,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/xcore.zig b/lib/std/Target/xcore.zig index 7064aef4fd..e30381131e 100644 --- a/lib/std/Target/xcore.zig +++ b/lib/std/Target/xcore.zig @@ -12,13 +12,13 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/Target/xtensa.zig b/lib/std/Target/xtensa.zig index 9009a7640d..c2c2b4005c 100644 --- a/lib/std/Target/xtensa.zig +++ b/lib/std/Target/xtensa.zig @@ -50,7 +50,7 @@ pub const featureSetHasAny = CpuFeature.FeatureSetFns(Feature).featureSetHasAny; pub const featureSetHasAll = CpuFeature.FeatureSetFns(Feature).featureSetHasAll; pub const all_features = blk: { - const len = @typeInfo(Feature).@"enum".fields.len; + const len = @typeInfo(Feature).@"enum".field_names.len; std.debug.assert(len <= CpuFeature.Set.needed_bit_count); var result: [len]CpuFeature = undefined; result[@intFromEnum(Feature.bool)] = .{ @@ -251,7 +251,7 @@ pub const all_features = blk: { const ti = @typeInfo(Feature); for (&result, 0..) |*elem, i| { elem.index = i; - elem.name = ti.@"enum".fields[i].name; + elem.name = ti.@"enum".field_names[i]; } break :blk result; }; diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index 452411c52e..7b10e7900a 100644 --- a/lib/std/c/darwin.zig +++ b/lib/std/c/darwin.zig @@ -54,7 +54,7 @@ pub const EXC = enum(exception_type_t) { _, - pub const TYPES_COUNT = @typeInfo(EXC).@"enum".fields.len; + pub const TYPES_COUNT = @typeInfo(EXC).@"enum".field_names.len; pub const SOFT_SIGNAL = 0x10003; pub const MASK = packed struct(u32) { diff --git a/lib/std/coff.zig b/lib/std/coff.zig index 7dea0f4344..6286ad5657 100644 --- a/lib/std/coff.zig +++ b/lib/std/coff.zig @@ -1386,7 +1386,7 @@ pub const IMAGE = struct { RESERVED = 15, _, - pub const len = @typeInfo(IMAGE.DIRECTORY_ENTRY).@"enum".fields.len; + pub const len = @typeInfo(IMAGE.DIRECTORY_ENTRY).@"enum".field_names.len; }; pub const FILE = struct { diff --git a/lib/std/crypto/codecs/asn1/Oid.zig b/lib/std/crypto/codecs/asn1/Oid.zig index 6ec52d9abc..3a8c45cb3e 100644 --- a/lib/std/crypto/codecs/asn1/Oid.zig +++ b/lib/std/crypto/codecs/asn1/Oid.zig @@ -177,27 +177,27 @@ pub fn StaticMap(comptime Enum: type) type { pub fn initComptime(comptime key_pairs: anytype) ReturnType { const struct_info = @typeInfo(@TypeOf(key_pairs)).@"struct"; const error_msg = "Each field of '" ++ @typeName(Enum) ++ "' must map to exactly one OID"; - if (!enum_info.is_exhaustive or enum_info.fields.len != struct_info.fields.len) { + if (enum_info.mode == .nonexhaustive or enum_info.field_names.len != struct_info.field_names.len) { @compileError(error_msg); } comptime var enum_to_oid = EnumToOid.initUndefined(); const KeyPair = struct { []const u8, Enum }; - comptime var static_key_pairs: [enum_info.fields.len]KeyPair = undefined; + comptime var static_key_pairs: [enum_info.field_names.len]KeyPair = undefined; - comptime for (enum_info.fields, 0..) |f, i| { - if (!@hasField(@TypeOf(key_pairs), f.name)) { - @compileError("Field '" ++ f.name ++ "' missing Oid.StaticMap entry"); + comptime for (enum_info.field_names, enum_info.field_values, 0..) |f_name, f_value, i| { + if (!@hasField(@TypeOf(key_pairs), f_name)) { + @compileError("Field '" ++ f_name ++ "' missing Oid.StaticMap entry"); } - const encoded = &encodeComptime(@field(key_pairs, f.name)); - const tag: Enum = @enumFromInt(f.value); + const encoded = &encodeComptime(@field(key_pairs, f_name)); + const tag: Enum = @enumFromInt(f_value); static_key_pairs[i] = .{ encoded, tag }; enum_to_oid.set(tag, encoded); }; const oid_to_enum = std.StaticStringMap(Enum).initComptime(static_key_pairs); - if (oid_to_enum.values().len != enum_info.fields.len) @compileError(error_msg); + if (oid_to_enum.values().len != enum_info.field_names.len) @compileError(error_msg); return ReturnType{ .oid_to_enum = oid_to_enum, .enum_to_oid = enum_to_oid }; } diff --git a/lib/std/crypto/codecs/asn1/der/Decoder.zig b/lib/std/crypto/codecs/asn1/der/Decoder.zig index 333e52cdf3..25a4139d6e 100644 --- a/lib/std/crypto/codecs/asn1/der/Decoder.zig +++ b/lib/std/crypto/codecs/asn1/der/Decoder.zig @@ -19,14 +19,14 @@ pub fn any(self: *Decoder, comptime T: type) !T { const tag = Tag.fromZig(T).toExpected(); switch (@typeInfo(T)) { - .@"struct" => { + .@"struct" => |info| { const ele = try self.element(tag); defer self.index = ele.slice.end; // don't force parsing all fields var res: T = undefined; - inline for (std.meta.fields(T)) |f| { - self.field_tag = FieldTag.fromContainer(T, f.name); + inline for (info.field_names, info.field_types, info.field_attrs) |f_name, f_type, f_attrs| { + self.field_tag = FieldTag.fromContainer(T, f_name); if (self.field_tag) |ft| { if (ft.explicit) { @@ -36,15 +36,15 @@ pub fn any(self: *Decoder, comptime T: type) !T { } } - @field(res, f.name) = self.any(f.type) catch |err| brk: { - if (f.defaultValue()) |d| { + @field(res, f_name) = self.any(f_type) catch |err| brk: { + if (f_attrs.defaultValue(f_type)) |d| { break :brk d; } return err; }; // DER encodes null values by skipping them. - if (@typeInfo(f.type) == .optional and @field(res, f.name) == null) { - if (f.defaultValue()) |d| @field(res, f.name) = d; + if (@typeInfo(f_type) == .optional and @field(res, f_name) == null) { + if (f_attrs.defaultValue(f_type)) |d| @field(res, f_name) = d; } } diff --git a/lib/std/crypto/codecs/asn1/der/Encoder.zig b/lib/std/crypto/codecs/asn1/der/Encoder.zig index 0000a0660f..f5a9553faa 100644 --- a/lib/std/crypto/codecs/asn1/der/Encoder.zig +++ b/lib/std/crypto/codecs/asn1/der/Encoder.zig @@ -29,16 +29,18 @@ fn anyTag(self: *Encoder, tag_: Tag, val: anytype) !void { switch (@typeInfo(T)) { .@"struct" => |info| { - inline for (0..info.fields.len) |i| { - const f = info.fields[info.fields.len - i - 1]; - const field_val = @field(val, f.name); - const field_tag = FieldTag.fromContainer(T, f.name); + inline for (0..info.field_names.len) |i| { + const f_idx = info.field_names.len - i - 1; + const f_name = info.field_names[f_idx]; + const f_type = info.field_types[f_idx]; + const f_attrs = info.field_attrs[f_idx]; + const field_val = @field(val, f_name); + const field_tag = FieldTag.fromContainer(T, f_name); // > The encoding of a set value or sequence value shall not include an encoding for any // > component value which is equal to its default value. - const is_default = if (f.is_comptime) false else if (f.default_value_ptr) |v| brk: { - const default_val: *const f.type = @ptrCast(@alignCast(v)); - break :brk std.mem.eql(u8, std.mem.asBytes(default_val), std.mem.asBytes(&field_val)); + const is_default = if (f_attrs.@"comptime") false else if (f_attrs.defaultValue(f_type)) |default_val| brk: { + break :brk std.mem.eql(u8, std.mem.asBytes(&default_val), std.mem.asBytes(&field_val)); } else false; if (!is_default) { @@ -46,7 +48,7 @@ fn anyTag(self: *Encoder, tag_: Tag, val: anytype) !void { self.field_tag = field_tag; // will merge with self.field_tag. // may mutate self.field_tag. - try self.anyTag(Tag.fromZig(f.type), field_val); + try self.anyTag(Tag.fromZig(f_type), field_val); if (field_tag) |ft| { if (ft.explicit) { try self.length(self.buffer.data.len - start2); diff --git a/lib/std/crypto/phc_encoding.zig b/lib/std/crypto/phc_encoding.zig index 44651464f1..70f1f52bfb 100644 --- a/lib/std/crypto/phc_encoding.zig +++ b/lib/std/crypto/phc_encoding.zig @@ -115,22 +115,23 @@ pub fn deserialize(comptime HashResult: type, str: []const u8) Error!HashResult while (it_params.next()) |params| { const param = kvSplit(params) catch break; var found = false; - inline for (comptime meta.fields(HashResult)) |p| { - if (mem.eql(u8, p.name, param.key)) { - switch (@typeInfo(p.type)) { - .int => @field(out, p.name) = fmt.parseUnsigned( - p.type, + const info = @typeInfo(HashResult).@"struct"; + inline for (info.field_names, info.field_types) |p_name, p_type| { + if (mem.eql(u8, p_name, param.key)) { + switch (@typeInfo(p_type)) { + .int => @field(out, p_name) = fmt.parseUnsigned( + p_type, param.value, 10, ) catch return Error.InvalidEncoding, .pointer => |ptr| { - if (!ptr.is_const) @compileError("Value slice must be constant"); - @field(out, p.name) = param.value; + if (!ptr.attrs.@"const") @compileError("Value slice must be constant"); + @field(out, p_name) = param.value; }, - .@"struct" => try @field(out, p.name).fromB64(param.value), + .@"struct" => try @field(out, p_name).fromB64(param.value), else => std.debug.panic( "Value for [{s}] must be an integer, a constant slice or a BinValue", - .{p.name}, + .{p_name}, ), } set_fields += 1; @@ -167,8 +168,9 @@ pub fn deserialize(comptime HashResult: type, str: []const u8) Error!HashResult // Check that all the required fields have been set, excluding optional values and parameters // with default values var expected_fields: usize = 0; - inline for (comptime meta.fields(HashResult)) |p| { - if (@typeInfo(p.type) != .optional and p.default_value_ptr == null) { + const info = @typeInfo(HashResult).@"struct"; + inline for (info.field_types, info.field_attrs) |p_type, p_attrs| { + if (@typeInfo(p_type) != .optional and p_attrs.default_value_ptr == null) { expected_fields += 1; } } @@ -228,21 +230,22 @@ fn serializeTo(params: anytype, out: *std.Io.Writer) !void { } var has_params = false; - inline for (comptime meta.fields(HashResult)) |p| { - if (comptime !(mem.eql(u8, p.name, "alg_id") or - mem.eql(u8, p.name, "alg_version") or - mem.eql(u8, p.name, "hash") or - mem.eql(u8, p.name, "salt"))) + const info = @typeInfo(HashResult).@"struct"; + inline for (info.field_names, info.field_types) |p_name, p_type| { + if (comptime !(mem.eql(u8, p_name, "alg_id") or + mem.eql(u8, p_name, "alg_version") or + mem.eql(u8, p_name, "hash") or + mem.eql(u8, p_name, "salt"))) { - const value = @field(params, p.name); + const value = @field(params, p_name); try out.writeAll(if (has_params) params_delimiter else fields_delimiter); - if (@typeInfo(p.type) == .@"struct") { + if (@typeInfo(p_type) == .@"struct") { var buf: [@TypeOf(value).max_encoded_length]u8 = undefined; - try out.print("{s}{s}{s}", .{ p.name, kv_delimiter, try value.toB64(&buf) }); + try out.print("{s}{s}{s}", .{ p_name, kv_delimiter, try value.toB64(&buf) }); } else { try out.print( if (@typeInfo(@TypeOf(value)) == .pointer) "{s}{s}{s}" else "{s}{s}{}", - .{ p.name, kv_delimiter, value }, + .{ p_name, kv_delimiter, value }, ); } has_params = true; diff --git a/lib/std/crypto/timing_safe.zig b/lib/std/crypto/timing_safe.zig index 4aeb4ba003..db76f39a55 100644 --- a/lib/std/crypto/timing_safe.zig +++ b/lib/std/crypto/timing_safe.zig @@ -135,7 +135,7 @@ fn markSecret(ptr: anytype, comptime action: enum { classify, declassify }) void const t = @typeInfo(@TypeOf(ptr)); if (t != .pointer) @compileError("Pointer expected - Found: " ++ @typeName(@TypeOf(ptr))); const p = t.pointer; - if (p.is_allowzero) @compileError("A nullable pointer is always assumed to leak information via side channels"); + if (p.attrs.@"allowzero") @compileError("A nullable pointer is always assumed to leak information via side channels"); const child = @typeInfo(p.child); switch (child) { diff --git a/lib/std/crypto/tls.zig b/lib/std/crypto/tls.zig index e28abc1e46..1d18e7a995 100644 --- a/lib/std/crypto/tls.zig +++ b/lib/std/crypto/tls.zig @@ -710,7 +710,7 @@ pub const Decoder = struct { else => @compileError("unsupported int type: " ++ @typeName(T)), }, .@"enum" => |info| { - if (info.is_exhaustive) @compileError("exhaustive enum cannot be used"); + if (info.mode == .exhaustive) @compileError("exhaustive enum cannot be used"); return @enumFromInt(d.decode(info.tag_type)); }, else => @compileError("unsupported type: " ++ @typeName(T)), diff --git a/lib/std/crypto/tls/Client.zig b/lib/std/crypto/tls/Client.zig index d8eafaed61..3f96531e94 100644 --- a/lib/std/crypto/tls/Client.zig +++ b/lib/std/crypto/tls/Client.zig @@ -1338,11 +1338,11 @@ fn failRead(c: *Client, err: ReadError) error{ReadFailed} { } fn logSecrets(w: *Writer, context: anytype, secrets: anytype) void { - inline for (@typeInfo(@TypeOf(secrets)).@"struct".fields) |field| w.print("{s}" ++ - (if (@hasField(@TypeOf(context), "counter")) "_{d}" else "") ++ " {x} {x}\n", .{field.name} ++ + inline for (@typeInfo(@TypeOf(secrets)).@"struct".field_names) |field_name| w.print("{s}" ++ + (if (@hasField(@TypeOf(context), "counter")) "_{d}" else "") ++ " {x} {x}\n", .{field_name} ++ (if (@hasField(@TypeOf(context), "counter")) .{context.counter} else .{}) ++ .{ context.client_random, - @field(secrets, field.name), + @field(secrets, field_name), }) catch {}; } diff --git a/lib/std/debug/ElfFile.zig b/lib/std/debug/ElfFile.zig index 8925106015..22ea71af44 100644 --- a/lib/std/debug/ElfFile.zig +++ b/lib/std/debug/ElfFile.zig @@ -219,9 +219,10 @@ pub fn load( break :dwarf null; // debug info not present } var sections: Dwarf.SectionArray = @splat(null); - inline for (@typeInfo(Dwarf.Section.Id).@"enum".fields) |f| { - if (result.sections.get(@field(Section.Id, f.name))) |s| { - sections[f.value] = .{ .data = s.bytes, .owned = false }; + const info = @typeInfo(Dwarf.Section.Id).@"enum"; + inline for (info.field_names, info.field_values) |f_name, f_value| { + if (result.sections.get(@field(Section.Id, f_name))) |s| { + sections[f_value] = .{ .data = s.bytes, .owned = false }; } } break :dwarf .{ .sections = sections }; @@ -408,8 +409,8 @@ fn loadSeparateDebugFile( return null; } - inline for (@typeInfo(Dwarf.Section.Id).@"enum".fields) |f| { - const id = @field(Section.Id, f.name); + inline for (@typeInfo(Dwarf.Section.Id).@"enum".field_names) |f_name| { + const id = @field(Section.Id, f_name); if (main_loaded.sections.get(id) == null) { main_loaded.sections.set(id, result.sections.get(id)); } @@ -498,9 +499,12 @@ fn loadInner( if (shdr.sh_name > shstrtab.len) return error.TruncatedElfFile; const name = std.mem.sliceTo(shstrtab[@intCast(shdr.sh_name)..], 0); - const section_id: Section.Id = inline for (@typeInfo(Section.Id).@"enum".fields) |s| { - if (std.mem.eql(u8, "." ++ s.name, name)) { - break @enumFromInt(s.value); + const section_id: Section.Id = inline for ( + @typeInfo(Section.Id).@"enum".field_names, + @typeInfo(Section.Id).@"enum".field_values, + ) |s_name, s_value| { + if (std.mem.eql(u8, "." ++ s_name, name)) { + break @enumFromInt(s_value); } } else continue; diff --git a/lib/std/debug/MachOFile.zig b/lib/std/debug/MachOFile.zig index b561821969..4b2fb524bc 100644 --- a/lib/std/debug/MachOFile.zig +++ b/lib/std/debug/MachOFile.zig @@ -504,8 +504,8 @@ fn loadOFile(gpa: Allocator, io: Io, o_file_name: []const u8) !OFile { if (!std.mem.eql(u8, "__DWARF", sect.segName())) continue; - const section_index: usize = inline for (@typeInfo(Dwarf.Section.Id).@"enum".fields, 0..) |section, i| { - if (mem.eql(u8, "__" ++ section.name, sect.sectName())) break i; + const section_index: usize = inline for (@typeInfo(Dwarf.Section.Id).@"enum".field_names, 0..) |section_name, i| { + if (mem.eql(u8, "__" ++ section_name, sect.sectName())) break i; } else continue; if (mapped_ofile.len < sect.offset + sect.size) return error.InvalidMachO; diff --git a/lib/std/debug/SelfInfo/MachO.zig b/lib/std/debug/SelfInfo/MachO.zig index 91c8cd41dc..c35ae03e9b 100644 --- a/lib/std/debug/SelfInfo/MachO.zig +++ b/lib/std/debug/SelfInfo/MachO.zig @@ -408,8 +408,8 @@ fn unwindFrameInner(si: *SelfInfo, io: Io, context: *UnwindContext) !usize { const ip_ptr = fp + @sizeOf(usize); var reg_addr = fp - @sizeOf(usize); - inline for (@typeInfo(@TypeOf(frame.x_reg_pairs)).@"struct".fields, 0..) |field, i| { - if (@field(frame.x_reg_pairs, field.name) != 0) { + inline for (@typeInfo(@TypeOf(frame.x_reg_pairs)).@"struct".field_names, 0..) |field_name, i| { + if (@field(frame.x_reg_pairs, field_name) != 0) { (try dwarfRegNative(&context.cpu_state, 19 + i)).* = @as(*const usize, @ptrFromInt(reg_addr)).*; reg_addr += @sizeOf(usize); (try dwarfRegNative(&context.cpu_state, 20 + i)).* = @as(*const usize, @ptrFromInt(reg_addr)).*; diff --git a/lib/std/debug/SelfInfo/Windows.zig b/lib/std/debug/SelfInfo/Windows.zig index 5bc770003a..ae81cccae4 100644 --- a/lib/std/debug/SelfInfo/Windows.zig +++ b/lib/std/debug/SelfInfo/Windows.zig @@ -513,8 +513,8 @@ const Module = struct { if (coff_obj.getSectionByName(".debug_info") == null) break :dwarf null; var sections: Dwarf.SectionArray = undefined; - inline for (@typeInfo(Dwarf.Section.Id).@"enum".fields, 0..) |section, i| { - sections[i] = if (coff_obj.getSectionByName("." ++ section.name)) |section_header| .{ + inline for (@typeInfo(Dwarf.Section.Id).@"enum".field_names, 0..) |section_name, i| { + sections[i] = if (coff_obj.getSectionByName("." ++ section_name)) |section_header| .{ .data = try coff_obj.getSectionDataAlloc(section_header, arena), .owned = false, } else null; diff --git a/lib/std/elf.zig b/lib/std/elf.zig index afcf236c28..81de3f7f50 100644 --- a/lib/std/elf.zig +++ b/lib/std/elf.zig @@ -484,7 +484,7 @@ pub const PT = enum(Word) { _, /// Number of defined types - pub const NUM = @typeInfo(PT).@"enum".fields.len; + pub const NUM = @typeInfo(PT).@"enum".field_names.len; /// Start of OS-specific pub const LOOS: PT = @enumFromInt(0x60000000); @@ -552,7 +552,7 @@ pub const SHT = enum(Word) { _, /// Number of defined types - pub const NUM = @typeInfo(SHT).@"enum".fields.len; + pub const NUM = @typeInfo(SHT).@"enum".field_names.len; /// Start of OS-specific pub const LOOS: SHT = @enumFromInt(0x60000000); @@ -595,7 +595,7 @@ pub const STB = enum(u4) { _, /// Number of defined types - pub const NUM = @typeInfo(STB).@"enum".fields.len; + pub const NUM = @typeInfo(STB).@"enum".field_names.len; /// Start of OS-specific pub const LOOS: STB = @enumFromInt(10); @@ -631,7 +631,7 @@ pub const STT = enum(u4) { _, /// Number of defined types - pub const NUM = @typeInfo(STT).@"enum".fields.len; + pub const NUM = @typeInfo(STT).@"enum".field_names.len; /// Start of OS-specific pub const LOOS: STT = @enumFromInt(10); @@ -815,7 +815,7 @@ pub const Header = struct { pub fn init(hdr: anytype, endian: Endian) Header { // Converting integers to exhaustive enums using `@enumFromInt` could cause a panic. - comptime assert(!@typeInfo(OSABI).@"enum".is_exhaustive); + comptime assert(@typeInfo(OSABI).@"enum".mode == .nonexhaustive); return .{ .is_64 = switch (@TypeOf(hdr)) { Elf32_Ehdr => false, @@ -1642,7 +1642,7 @@ pub const CLASS = enum(u8) { @"64" = 2, _, - pub const NUM = @typeInfo(CLASS).@"enum".fields.len; + pub const NUM = @typeInfo(CLASS).@"enum".field_names.len; pub fn ElfN(comptime class: CLASS) type { return switch (class) { @@ -1667,7 +1667,7 @@ pub const DATA = enum(u8) { @"2MSB" = 2, _, - pub const NUM = @typeInfo(DATA).@"enum".fields.len; + pub const NUM = @typeInfo(DATA).@"enum".field_names.len; }; pub const OSABI = enum(u8) { diff --git a/lib/std/enums.zig b/lib/std/enums.zig index fbd1f9111e..10b85ddeeb 100644 --- a/lib/std/enums.zig +++ b/lib/std/enums.zig @@ -3,14 +3,13 @@ const std = @import("std"); const assert = std.debug.assert; const testing = std.testing; -const EnumField = std.builtin.Type.EnumField; /// Increment this value when adding APIs that add single backwards branches. const eval_branch_quota_cushion = 10; pub fn fromInt(comptime E: type, integer: anytype) ?E { const enum_info = @typeInfo(E).@"enum"; - if (!enum_info.is_exhaustive) { + if (enum_info.mode == .nonexhaustive) { if (std.math.cast(enum_info.tag_type, integer)) |tag| { return @enumFromInt(tag); } @@ -32,20 +31,19 @@ pub fn fromInt(comptime E: type, integer: anytype) ?E { /// the first name is used. Each field is of type Data and has the provided /// default, which may be undefined. pub fn EnumFieldStruct(comptime E: type, comptime Data: type, comptime field_default: ?Data) type { - @setEvalBranchQuota(@typeInfo(E).@"enum".fields.len + eval_branch_quota_cushion); + @setEvalBranchQuota(@typeInfo(E).@"enum".field_names.len + eval_branch_quota_cushion); const default_ptr: ?*const anyopaque = if (field_default) |d| @ptrCast(&d) else null; return @Struct(.auto, null, std.meta.fieldNames(E), &@splat(Data), &@splat(.{ .default_value_ptr = default_ptr })); } -/// Looks up the supplied fields in the given enum type. -/// Uses only the field names, field values are ignored. +/// Looks up the supplied field values in the given enum type. /// The result array is in the same order as the input. -pub inline fn valuesFromFields(comptime E: type, comptime fields: []const EnumField) []const E { +pub inline fn valuesFromFields(comptime E: type, comptime field_values: []const comptime_int) []const E { comptime { - @setEvalBranchQuota(@typeInfo(E).@"enum".fields.len + eval_branch_quota_cushion); - var result: [fields.len]E = undefined; - for (&result, fields) |*r, f| { - r.* = @enumFromInt(f.value); + @setEvalBranchQuota(@typeInfo(E).@"enum".field_names.len + eval_branch_quota_cushion); + var result: [field_values.len]E = undefined; + for (&result, field_values) |*r, f_value| { + r.* = @enumFromInt(f_value); } const final = result; return &final; @@ -55,17 +53,18 @@ pub inline fn valuesFromFields(comptime E: type, comptime fields: []const EnumFi /// Returns the set of all named values in the given enum, in /// declaration order. pub inline fn values(comptime E: type) []const E { - return comptime valuesFromFields(E, @typeInfo(E).@"enum".fields); + return comptime valuesFromFields(E, @typeInfo(E).@"enum".field_values); } /// A safe alternative to @tagName() for non-exhaustive enums that doesn't /// panic when `e` has no tagged value. /// Returns the tag name for `e` or null if no tag exists. pub fn tagName(comptime E: type, e: E) ?[:0]const u8 { - const fields = @typeInfo(E).@"enum".fields; - @setEvalBranchQuota(fields.len); - return inline for (fields) |f| { - if (@intFromEnum(e) == f.value) break f.name; + const field_names = @typeInfo(E).@"enum".field_names; + const field_values = @typeInfo(E).@"enum".field_values; + @setEvalBranchQuota(field_names.len); + return inline for (field_names, field_values) |f_name, f_value| { + if (@intFromEnum(e) == f_value) break f_name; } else null; } @@ -88,20 +87,20 @@ test tagName { pub fn directEnumArrayLen(comptime E: type, comptime max_unused_slots: comptime_int) comptime_int { var max_value: comptime_int = -1; const max_usize: comptime_int = ~@as(usize, 0); - const fields = @typeInfo(E).@"enum".fields; - for (fields) |f| { - if (f.value < 0) { - @compileError("Cannot create a direct enum array for " ++ @typeName(E) ++ ", field ." ++ f.name ++ " has a negative value."); + const info = @typeInfo(E).@"enum"; + for (info.field_names, info.field_values) |f_name, f_value| { + if (f_value < 0) { + @compileError("Cannot create a direct enum array for " ++ @typeName(E) ++ ", field ." ++ f_name ++ " has a negative value."); } - if (f.value > max_value) { - if (f.value > max_usize) { - @compileError("Cannot create a direct enum array for " ++ @typeName(E) ++ ", field ." ++ f.name ++ " is larger than the max value of usize."); + if (f_value > max_value) { + if (f_value > max_usize) { + @compileError("Cannot create a direct enum array for " ++ @typeName(E) ++ ", field ." ++ f_name ++ " is larger than the max value of usize."); } - max_value = f.value; + max_value = f_value; } } - const unused_slots = max_value + 1 - fields.len; + const unused_slots = max_value + 1 - info.field_names.len; if (unused_slots > max_unused_slots) { const unused_str = std.fmt.comptimePrint("{d}", .{unused_slots}); const allowed_str = std.fmt.comptimePrint("{d}", .{max_unused_slots}); @@ -167,10 +166,10 @@ pub fn directEnumArrayDefault( ) [directEnumArrayLen(E, max_unused_slots)]Data { const len = comptime directEnumArrayLen(E, max_unused_slots); var result: [len]Data = @splat(default orelse undefined); - inline for (@typeInfo(@TypeOf(init_values)).@"struct".fields) |f| { - const enum_value = @field(E, f.name); + inline for (@typeInfo(@TypeOf(init_values)).@"struct".field_names) |f_name| { + const enum_value = @field(E, f_name); const index = @as(usize, @intCast(@intFromEnum(enum_value))); - result[index] = @field(init_values, f.name); + result[index] = @field(init_values, f_name); } return result; } @@ -256,9 +255,9 @@ pub fn EnumSet(comptime E: type) type { /// Initializes the set using a struct of bools pub fn init(init_values: EnumFieldStruct(E, bool, false)) Self { - @setEvalBranchQuota(2 * @typeInfo(E).@"enum".fields.len); + @setEvalBranchQuota(2 * @typeInfo(E).@"enum".field_names.len); var result: Self = .{}; - if (@typeInfo(E).@"enum".is_exhaustive) { + if (@typeInfo(E).@"enum".mode == .exhaustive) { inline for (0..Self.len) |i| { const key = comptime Indexer.keyForIndex(i); const tag = @tagName(key); @@ -267,9 +266,9 @@ pub fn EnumSet(comptime E: type) type { } } } else { - inline for (std.meta.fields(E)) |field| { - const key = @field(E, field.name); - if (@field(init_values, field.name)) { + inline for (@typeInfo(E).@"enum".field_names) |field_name| { + const key = @field(E, field_name); + if (@field(init_values, field_name)) { const i = comptime Indexer.indexOf(key); result.bits.set(i); } @@ -443,9 +442,9 @@ pub fn EnumMap(comptime E: type, comptime V: type) type { /// Initializes the map using a sparse struct of optionals pub fn init(init_values: EnumFieldStruct(E, ?Value, @as(?Value, null))) Self { - @setEvalBranchQuota(2 * @typeInfo(E).@"enum".fields.len); + @setEvalBranchQuota(2 * @typeInfo(E).@"enum".field_names.len); var result: Self = .{}; - if (@typeInfo(E).@"enum".is_exhaustive) { + if (@typeInfo(E).@"enum".mode == .exhaustive) { inline for (0..Self.len) |i| { const key = comptime Indexer.keyForIndex(i); const tag = @tagName(key); @@ -455,9 +454,9 @@ pub fn EnumMap(comptime E: type, comptime V: type) type { } } } else { - inline for (std.meta.fields(E)) |field| { - const key = @field(E, field.name); - if (@field(init_values, field.name)) |*v| { + inline for (std.meta.fieldNames(E)) |field_name| { + const key = @field(E, field_name); + if (@field(init_values, field_name)) |*v| { const i = comptime Indexer.indexOf(key); result.bits.set(i); result.values[i] = v.*; @@ -487,7 +486,7 @@ pub fn EnumMap(comptime E: type, comptime V: type) type { /// Initializes a full mapping with a provided default. /// Consider using EnumArray instead if the map will remain full. pub fn initFullWithDefault(comptime default: ?Value, init_values: EnumFieldStruct(E, Value, default)) Self { - @setEvalBranchQuota(2 * @typeInfo(E).@"enum".fields.len); + @setEvalBranchQuota(2 * @typeInfo(E).@"enum".field_names.len); var result: Self = .{ .bits = .full, .values = undefined, @@ -673,11 +672,12 @@ pub fn BoundedEnumMultiset(comptime E: type, comptime CountSize: type) type { /// Initializes the multiset using a struct of counts. pub fn init(init_counts: EnumFieldStruct(E, CountSize, 0)) Self { - @setEvalBranchQuota(2 * @typeInfo(E).@"enum".fields.len); + @setEvalBranchQuota(2 * @typeInfo(E).@"enum".field_names.len); var self = initWithCount(0); - inline for (@typeInfo(E).@"enum".fields) |field| { - const c = @field(init_counts, field.name); - const key = @as(E, @enumFromInt(field.value)); + const info = @typeInfo(E).@"enum"; + inline for (info.field_names, info.field_values) |field_name, field_value| { + const c = @field(init_counts, field_name); + const key: E = @enumFromInt(field_value); self.counts.set(key, c); } return self; @@ -745,16 +745,16 @@ pub fn BoundedEnumMultiset(comptime E: type, comptime CountSize: type) type { /// Increases the all key counts by given multiset. Caller /// asserts operation will not overflow any key. pub fn addSetAssertSafe(self: *Self, other: Self) void { - inline for (@typeInfo(E).@"enum".fields) |field| { - const key = @as(E, @enumFromInt(field.value)); + inline for (@typeInfo(E).@"enum".field_values) |field_value| { + const key = @as(E, @enumFromInt(field_value)); self.addAssertSafe(key, other.getCount(key)); } } /// Increases the all key counts by given multiset. pub fn addSet(self: *Self, other: Self) error{Overflow}!void { - inline for (@typeInfo(E).@"enum".fields) |field| { - const key = @as(E, @enumFromInt(field.value)); + inline for (@typeInfo(E).@"enum".field_values) |field_value| { + const key = @as(E, @enumFromInt(field_value)); try self.add(key, other.getCount(key)); } } @@ -763,8 +763,8 @@ pub fn BoundedEnumMultiset(comptime E: type, comptime CountSize: type) type { /// the given multiset has more key counts than this, /// then that key will have a key count of zero. pub fn removeSet(self: *Self, other: Self) void { - inline for (@typeInfo(E).@"enum".fields) |field| { - const key = @as(E, @enumFromInt(field.value)); + inline for (@typeInfo(E).@"enum".field_values) |field_value| { + const key = @as(E, @enumFromInt(field_value)); self.remove(key, other.getCount(key)); } } @@ -772,8 +772,8 @@ pub fn BoundedEnumMultiset(comptime E: type, comptime CountSize: type) type { /// Returns true iff all key counts are the same as /// given multiset. pub fn eql(self: Self, other: Self) bool { - inline for (@typeInfo(E).@"enum".fields) |field| { - const key = @as(E, @enumFromInt(field.value)); + inline for (@typeInfo(E).@"enum".field_values) |field_value| { + const key = @as(E, @enumFromInt(field_value)); if (self.getCount(key) != other.getCount(key)) { return false; } @@ -784,8 +784,8 @@ pub fn BoundedEnumMultiset(comptime E: type, comptime CountSize: type) type { /// Returns true iff all key counts less than or /// equal to the given multiset. pub fn subsetOf(self: Self, other: Self) bool { - inline for (@typeInfo(E).@"enum".fields) |field| { - const key = @as(E, @enumFromInt(field.value)); + inline for (@typeInfo(E).@"enum".field_values) |field_value| { + const key = @as(E, @enumFromInt(field_value)); if (self.getCount(key) > other.getCount(key)) { return false; } @@ -796,8 +796,8 @@ pub fn BoundedEnumMultiset(comptime E: type, comptime CountSize: type) type { /// Returns true iff all key counts greater than or /// equal to the given multiset. pub fn supersetOf(self: Self, other: Self) bool { - inline for (@typeInfo(E).@"enum".fields) |field| { - const key = @as(E, @enumFromInt(field.value)); + inline for (@typeInfo(E).@"enum".field_values) |field_value| { + const key = @as(E, @enumFromInt(field_value)); if (self.getCount(key) < other.getCount(key)) { return false; } @@ -1075,7 +1075,7 @@ pub fn EnumArray(comptime E: type, comptime V: type) type { /// Initializes values in the enum array, with the specified default. pub fn initDefault(comptime default: ?Value, init_values: EnumFieldStruct(E, Value, default)) Self { - @setEvalBranchQuota(2 * @typeInfo(E).@"enum".fields.len); + @setEvalBranchQuota(2 * @typeInfo(E).@"enum".field_names.len); var result: Self = .{ .values = undefined }; inline for (0..Self.len) |i| { const key = comptime Indexer.keyForIndex(i); @@ -1264,10 +1264,10 @@ test "EnumSet non-exhaustive" { pub fn EnumIndexer(comptime E: type) type { // n log n for `std.mem.sortUnstable` call below. - const fields_len = @typeInfo(E).@"enum".fields.len; + const fields_len = @typeInfo(E).@"enum".field_names.len; @setEvalBranchQuota(3 * fields_len * std.math.log2(@max(fields_len, 1)) + eval_branch_quota_cushion); - if (!@typeInfo(E).@"enum".is_exhaustive) { + if (@typeInfo(E).@"enum".mode == .nonexhaustive) { const BackingInt = @typeInfo(E).@"enum".tag_type; if (@bitSizeOf(BackingInt) > @bitSizeOf(usize)) @compileError("Cannot create an enum indexer for a given non-exhaustive enum, tag_type is larger than usize."); @@ -1315,18 +1315,17 @@ pub fn EnumIndexer(comptime E: type) type { }; } - var fields: [fields_len]EnumField = @typeInfo(E).@"enum".fields[0..].*; + var field_values = @typeInfo(E).@"enum".field_values[0..fields_len].*; - std.mem.sortUnstable(EnumField, &fields, {}, struct { - fn lessThan(ctx: void, lhs: EnumField, rhs: EnumField) bool { - ctx; - return lhs.value < rhs.value; + std.mem.sortUnstable(comptime_int, &field_values, {}, struct { + fn lessThan(_: void, a: comptime_int, b: comptime_int) bool { + return a < b; } }.lessThan); - const min = fields[0].value; - const max = fields[fields_len - 1].value; - if (max - min == fields.len - 1) { + const min = field_values[0]; + const max = field_values[fields_len - 1]; + if (max - min == field_values.len - 1) { return struct { pub const Key = E; pub const count: comptime_int = fields_len; @@ -1343,7 +1342,7 @@ pub fn EnumIndexer(comptime E: type) type { }; } - const keys = valuesFromFields(E, &fields); + const keys = valuesFromFields(E, &field_values); return struct { pub const Key = E; diff --git a/lib/std/gpu.zig b/lib/std/gpu.zig index 057ef4bd0b..0e00eccb62 100644 --- a/lib/std/gpu.zig +++ b/lib/std/gpu.zig @@ -58,7 +58,7 @@ pub const ExecutionMode = union(Tag) { /// Declare the mode entry point executes in. pub fn executionMode(comptime entry_point: anytype, comptime mode: ExecutionMode) void { - const cc = @typeInfo(@TypeOf(entry_point)).@"fn".calling_convention; + const cc = @typeInfo(@TypeOf(entry_point)).@"fn".attrs.@"callconv"; switch (mode) { .origin_upper_left, .origin_lower_left, diff --git a/lib/std/hash/auto_hash.zig b/lib/std/hash/auto_hash.zig index a4fa8054e6..edfe870f27 100644 --- a/lib/std/hash/auto_hash.zig +++ b/lib/std/hash/auto_hash.zig @@ -127,10 +127,10 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void { }, .@"struct" => |info| { - inline for (info.fields) |field| { + inline for (info.field_names) |field_name| { // We reuse the hash of the previous field as the seed for the // next one so that they're dependant. - hash(hasher, @field(key, field.name), strat); + hash(hasher, @field(key, field_name), strat); } }, @@ -138,10 +138,10 @@ pub fn hash(hasher: anytype, key: anytype, comptime strat: HashStrategy) void { if (info.tag_type) |tag_type| { const tag = std.meta.activeTag(key); hash(hasher, tag, strat); - inline for (info.fields) |field| { - if (@field(tag_type, field.name) == tag) { - if (field.type != void) { - hash(hasher, @field(key, field.name), strat); + inline for (info.field_names, info.field_types) |field_name, field_type| { + if (@field(tag_type, field_name) == tag) { + if (field_type != void) { + hash(hasher, @field(key, field_name), strat); } break :blk; } @@ -165,8 +165,8 @@ inline fn typeContainsSlice(comptime K: type) bool { .pointer => |info| info.size == .slice, inline .@"struct", .@"union" => |info| { - inline for (info.fields) |field| { - if (typeContainsSlice(field.type)) { + inline for (info.field_types) |field_type| { + if (typeContainsSlice(field_type)) { return true; } } diff --git a/lib/std/hash/verify.zig b/lib/std/hash/verify.zig index a96a36c050..6ff3f0e6b2 100644 --- a/lib/std/hash/verify.zig +++ b/lib/std/hash/verify.zig @@ -2,8 +2,8 @@ const std = @import("std"); fn hashMaybeSeed(comptime hash_fn: anytype, seed: anytype, buf: []const u8) @typeInfo(@TypeOf(hash_fn)).@"fn".return_type.? { const HashFn = @typeInfo(@TypeOf(hash_fn)).@"fn"; - if (HashFn.params.len > 1) { - if (@typeInfo(HashFn.params[0].type.?) == .int) { + if (HashFn.param_types.len > 1) { + if (@typeInfo(HashFn.param_types[0].?) == .int) { return hash_fn(@intCast(seed), buf); } else { return hash_fn(buf, @intCast(seed)); @@ -15,7 +15,7 @@ fn hashMaybeSeed(comptime hash_fn: anytype, seed: anytype, buf: []const u8) @typ fn initMaybeSeed(comptime Hash: anytype, seed: anytype) Hash { const HashFn = @typeInfo(@TypeOf(Hash.init)).@"fn"; - if (HashFn.params.len == 1) { + if (HashFn.param_types.len == 1) { return Hash.init(@intCast(seed)); } else { return Hash.init(); diff --git a/lib/std/http/Client.zig b/lib/std/http/Client.zig index a77d30770c..1dd8bb6579 100644 --- a/lib/std/http/Client.zig +++ b/lib/std/http/Client.zig @@ -823,8 +823,8 @@ pub const Request = struct { /// Externally-owned; must outlive the Request. privileged_headers: []const http.Header, - pub const default_accept_encoding: [@typeInfo(http.ContentEncoding).@"enum".fields.len]bool = b: { - var result: [@typeInfo(http.ContentEncoding).@"enum".fields.len]bool = @splat(false); + pub const default_accept_encoding: [@typeInfo(http.ContentEncoding).@"enum".field_names.len]bool = b: { + var result: [@typeInfo(http.ContentEncoding).@"enum".field_names.len]bool = @splat(false); result[@intFromEnum(http.ContentEncoding.gzip)] = true; result[@intFromEnum(http.ContentEncoding.deflate)] = true; result[@intFromEnum(http.ContentEncoding.identity)] = true; diff --git a/lib/std/json/Stringify.zig b/lib/std/json/Stringify.zig index 893378b899..2030024375 100644 --- a/lib/std/json/Stringify.zig +++ b/lib/std/json/Stringify.zig @@ -401,9 +401,9 @@ pub fn write(self: *Stringify, v: anytype) Error!void { return v.jsonStringify(self); } - if (!enum_info.is_exhaustive) { - inline for (enum_info.fields) |field| { - if (v == @field(T, field.name)) { + if (enum_info.mode == .nonexhaustive) { + inline for (enum_info.field_names) |field_name| { + if (v == @field(T, field_name)) { break; } } else { @@ -424,15 +424,15 @@ pub fn write(self: *Stringify, v: anytype) Error!void { const info = @typeInfo(T).@"union"; if (info.tag_type) |UnionTagType| { try self.beginObject(); - inline for (info.fields) |u_field| { - if (v == @field(UnionTagType, u_field.name)) { - try self.objectField(u_field.name); - if (u_field.type == void) { + inline for (info.field_names, info.field_types) |u_field_name, u_field_type| { + if (v == @field(UnionTagType, u_field_name)) { + try self.objectField(u_field_name); + if (u_field_type == void) { // void v is {} try self.beginObject(); try self.endObject(); } else { - try self.write(@field(v, u_field.name)); + try self.write(@field(v, u_field_name)); } break; } @@ -455,16 +455,16 @@ pub fn write(self: *Stringify, v: anytype) Error!void { } else { try self.beginObject(); } - inline for (S.fields) |Field| { + inline for (S.field_names, S.field_types) |field_name, field_type| { // don't include void fields - if (Field.type == void) continue; + if (field_type == void) continue; var emit_field = true; // don't include optional fields that are null when emit_null_optional_fields is set to false - if (@typeInfo(Field.type) == .optional) { + if (@typeInfo(field_type) == .optional) { if (self.options.emit_null_optional_fields == false) { - if (@field(v, Field.name) == null) { + if (@field(v, field_name) == null) { emit_field = false; } } @@ -472,9 +472,9 @@ pub fn write(self: *Stringify, v: anytype) Error!void { if (emit_field) { if (!S.is_tuple) { - try self.objectField(Field.name); + try self.objectField(field_name); } - try self.write(@field(v, Field.name)); + try self.write(@field(v, field_name)); } } if (S.is_tuple) { diff --git a/lib/std/json/static.zig b/lib/std/json/static.zig index 55f002728a..d177237842 100644 --- a/lib/std/json/static.zig +++ b/lib/std/json/static.zig @@ -286,20 +286,20 @@ pub fn innerParse( }, }; - inline for (unionInfo.fields) |u_field| { - if (std.mem.eql(u8, u_field.name, field_name)) { + inline for (unionInfo.field_names, unionInfo.field_types) |u_field_name, u_field_type| { + if (std.mem.eql(u8, u_field_name, field_name)) { // Free the name token now in case we're using an allocator that optimizes freeing the last allocated object. // (Recursing into innerParse() might trigger more allocations.) freeAllocated(allocator, name_token.?); name_token = null; - if (u_field.type == void) { + if (u_field_type == void) { // void isn't really a json type, but we can support void payload union tags with {} as a value. if (.object_begin != try source.next()) return error.UnexpectedToken; if (.object_end != try source.next()) return error.UnexpectedToken; - result = @unionInit(T, u_field.name, {}); + result = @unionInit(T, u_field_name, {}); } else { // Recurse. - result = @unionInit(T, u_field.name, try innerParse(u_field.type, allocator, source, options)); + result = @unionInit(T, u_field_name, try innerParse(u_field_type, allocator, source, options)); } break; } @@ -318,8 +318,8 @@ pub fn innerParse( if (.array_begin != try source.next()) return error.UnexpectedToken; var r: T = undefined; - inline for (0..structInfo.fields.len) |i| { - r[i] = try innerParse(structInfo.fields[i].type, allocator, source, options); + inline for (structInfo.field_types, 0..) |field_type, i| { + r[i] = try innerParse(field_type, allocator, source, options); } if (.array_end != try source.next()) return error.UnexpectedToken; @@ -334,7 +334,7 @@ pub fn innerParse( if (.object_begin != try source.next()) return error.UnexpectedToken; var r: T = undefined; - var fields_seen: [structInfo.fields.len]bool = @splat(false); + var fields_seen: [structInfo.field_names.len]bool = @splat(false); while (true) { var name_token: ?Token = try source.nextAllocMax(allocator, .alloc_if_needed, options.max_value_len.?); @@ -348,9 +348,14 @@ pub fn innerParse( }, }; - inline for (structInfo.fields, 0..) |field, i| { - if (field.is_comptime) @compileError("comptime fields are not supported: " ++ @typeName(T) ++ "." ++ field.name); - if (std.mem.eql(u8, field.name, field_name)) { + inline for ( + structInfo.field_names, + structInfo.field_types, + structInfo.field_attrs, + 0.., + ) |f_name, f_type, f_attrs, i| { + if (f_attrs.@"comptime") @compileError("comptime fields are not supported: " ++ @typeName(T) ++ "." ++ f_name); + if (std.mem.eql(u8, f_name, field_name)) { // Free the name token now in case we're using an allocator that optimizes freeing the last allocated object. // (Recursing into innerParse() might trigger more allocations.) freeAllocated(allocator, name_token.?); @@ -360,14 +365,14 @@ pub fn innerParse( .use_first => { // Parse and ignore the redundant value. // We don't want to skip the value, because we want type checking. - _ = try innerParse(field.type, allocator, source, options); + _ = try innerParse(f_type, allocator, source, options); break; }, .@"error" => return error.DuplicateField, .use_last => {}, } } - @field(r, field.name) = try innerParse(field.type, allocator, source, options); + @field(r, f_name) = try innerParse(f_type, allocator, source, options); fields_seen[i] = true; break; } @@ -493,7 +498,7 @@ pub fn innerParse( _ = try source.allocNextIntoArrayList(&value_list, .alloc_always); return try value_list.toOwnedSliceSentinel(s); } - if (ptrInfo.is_const) { + if (ptrInfo.attrs.@"const") { switch (try source.nextAllocMax(allocator, options.allocate.?, options.max_value_len.?)) { inline .string, .allocated_string => |slice| return slice, else => unreachable, @@ -613,16 +618,16 @@ pub fn innerParseFromValue( const kv = it.next().?; const field_name = kv.key_ptr.*; - inline for (unionInfo.fields) |u_field| { - if (std.mem.eql(u8, u_field.name, field_name)) { - if (u_field.type == void) { + inline for (unionInfo.field_names, unionInfo.field_types) |u_field_name, u_field_type| { + if (std.mem.eql(u8, u_field_name, field_name)) { + if (u_field_type == void) { // void isn't really a json type, but we can support void payload union tags with {} as a value. if (kv.value_ptr.* != .object) return error.UnexpectedToken; if (kv.value_ptr.*.object.count() != 0) return error.UnexpectedToken; - return @unionInit(T, u_field.name, {}); + return @unionInit(T, u_field_name, {}); } // Recurse. - return @unionInit(T, u_field.name, try innerParseFromValue(u_field.type, allocator, kv.value_ptr.*, options)); + return @unionInit(T, u_field_name, try innerParseFromValue(u_field_type, allocator, kv.value_ptr.*, options)); } } // Didn't match anything. @@ -632,11 +637,11 @@ pub fn innerParseFromValue( .@"struct" => |structInfo| { if (structInfo.is_tuple) { if (source != .array) return error.UnexpectedToken; - if (source.array.items.len != structInfo.fields.len) return error.UnexpectedToken; + if (source.array.items.len != structInfo.field_names.len) return error.UnexpectedToken; var r: T = undefined; - inline for (0..structInfo.fields.len, source.array.items) |i, item| { - r[i] = try innerParseFromValue(structInfo.fields[i].type, allocator, item, options); + inline for (0..structInfo.field_names.len, source.array.items) |i, item| { + r[i] = try innerParseFromValue(structInfo.field_types[i], allocator, item, options); } return r; @@ -649,17 +654,22 @@ pub fn innerParseFromValue( if (source != .object) return error.UnexpectedToken; var r: T = undefined; - var fields_seen: [structInfo.fields.len]bool = @splat(false); + var fields_seen: [structInfo.field_names.len]bool = @splat(false); var it = source.object.iterator(); while (it.next()) |kv| { const field_name = kv.key_ptr.*; - inline for (structInfo.fields, 0..) |field, i| { - if (field.is_comptime) @compileError("comptime fields are not supported: " ++ @typeName(T) ++ "." ++ field.name); - if (std.mem.eql(u8, field.name, field_name)) { + inline for ( + structInfo.field_names, + structInfo.field_types, + structInfo.field_attrs, + 0.., + ) |f_name, f_type, f_attrs, i| { + if (f_attrs.@"comptime") @compileError("comptime fields are not supported: " ++ @typeName(T) ++ "." ++ f_name); + if (std.mem.eql(u8, f_name, field_name)) { assert(!fields_seen[i]); // Can't have duplicate keys in a Value.object. - @field(r, field.name) = try innerParseFromValue(field.type, allocator, kv.value_ptr.*, options); + @field(r, f_name) = try innerParseFromValue(f_type, allocator, kv.value_ptr.*, options); fields_seen[i] = true; break; } @@ -782,11 +792,17 @@ fn sliceToEnum(comptime T: type, slice: []const u8) !T { return std.enums.fromInt(T, n) orelse return error.InvalidEnumTag; } -fn fillDefaultStructValues(comptime T: type, r: *T, fields_seen: *[@typeInfo(T).@"struct".fields.len]bool) !void { - inline for (@typeInfo(T).@"struct".fields, 0..) |field, i| { +fn fillDefaultStructValues(comptime T: type, r: *T, fields_seen: *[@typeInfo(T).@"struct".field_names.len]bool) !void { + const info = @typeInfo(T).@"struct"; + inline for ( + info.field_names, + info.field_types, + info.field_attrs, + 0.., + ) |field_name, field_type, field_attrs, i| { if (!fields_seen[i]) { - if (field.defaultValue()) |default| { - @field(r, field.name) = default; + if (field_attrs.defaultValue(field_type)) |default| { + @field(r, field_name) = default; } else { return error.MissingField; } diff --git a/lib/std/lang.zig b/lib/std/lang.zig index 811e506e53..9fdf35ae3f 100644 --- a/lib/std/lang.zig +++ b/lib/std/lang.zig @@ -596,13 +596,8 @@ pub const Type = union(enum) { /// therefore must be kept in sync with the compiler implementation. pub const Pointer = struct { size: Size, - is_const: bool, - is_volatile: bool, - /// `null` means implicit alignment, which is equivalent to `@alignOf(child)`. - alignment: ?usize, - address_space: AddressSpace, + attrs: Attributes, child: type, - is_allowzero: bool, /// The type of the sentinel is the element type of the pointer, which is /// the value of the `child` field in this struct. However there is no way @@ -665,46 +660,42 @@ pub const Type = union(enum) { @"packed", }; - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. - pub const StructField = struct { - name: [:0]const u8, - type: type, - /// The type of the default value is the type of this struct field, which - /// is the value of the `type` field in this struct. However there is no - /// way to refer to that type here, so we use `*const anyopaque`. - /// See also: `defaultValue`. - default_value_ptr: ?*const anyopaque, - is_comptime: bool, - /// `null` means the field alignment was not explicitly specified. The - /// field will still be aligned to at least `@alignOf` its `type`. - alignment: ?usize, - - /// Loads the field's default value from `default_value_ptr`. - /// Returns `null` if the field has no default value. - pub inline fn defaultValue(comptime sf: StructField) ?sf.type { - const dp: *const sf.type = @ptrCast(@alignCast(sf.default_value_ptr orelse return null)); - return dp.*; - } - - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. - pub const Attributes = struct { - @"comptime": bool = false, - @"align": ?usize = null, - default_value_ptr: ?*const anyopaque = null, - }; - }; - /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const Struct = struct { - layout: ContainerLayout, - /// Only valid if layout is .@"packed" - backing_integer: ?type = null, - fields: []const StructField, - decls: []const Declaration, is_tuple: bool, + layout: ContainerLayout, + /// Always `null` if `layout != .@"packed"`. + backing_integer: ?type, + + field_names: []const [:0]const u8, + /// Guaranteed to have the same length as `field_names`. + field_types: []const type, + /// Guaranteed to have the same length as `field_names`. + field_attrs: []const FieldAttributes, + + decl_names: []const [:0]const u8, + + pub const FieldAttributes = struct { + @"comptime": bool = false, + /// `null` means the field alignment is not explicitly specified. The field will still + /// be aligned to at least `@alignOf` the field type. + @"align": ?usize = null, + /// The type of the default value is the type of this struct field. However, that type + /// is not known here, so we use a type-erased pointer instead, which must be cast to + /// a pointer to the field type. + /// + /// See also: `defaultValue`. + default_value_ptr: ?*const anyopaque = null, + + /// Loads the field's default value from `default_value_ptr`. + /// `FieldType` must exactly match the corresponding element of `Struct.field_types`. + /// Returns `null` if the field has no default value. + pub inline fn defaultValue(comptime attrs: FieldAttributes, comptime FieldType: type) ?FieldType { + const dp: *const FieldType = @ptrCast(@alignCast(attrs.default_value_ptr orelse return null)); + return dp.*; + } + }; }; /// This data structure is used by the Zig language code generation and @@ -722,28 +713,21 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const Error = struct { - name: [:0]const u8, - }; - - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. - pub const ErrorSet = ?[]const Error; - - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. - pub const EnumField = struct { - name: [:0]const u8, - value: comptime_int, + pub const ErrorSet = struct { + error_names: ?[]const [:0]const u8, }; /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const Enum = struct { tag_type: type, - fields: []const EnumField, - decls: []const Declaration, - is_exhaustive: bool, + mode: Mode, + + field_names: []const [:0]const u8, + /// Guaranteed to have the same length as `field_names`. + field_values: []const comptime_int, + + decl_names: []const [:0]const u8, /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. @@ -752,55 +736,45 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. - pub const UnionField = struct { - name: [:0]const u8, - type: type, - /// `null` means the field alignment was not explicitly specified. The - /// field will still be aligned to at least `@alignOf` its `type`. - alignment: ?usize, + pub const Union = struct { + layout: ContainerLayout, + tag_type: ?type, + /// Always `null` if `layout != .@"packed"`. + backing_integer: ?type, - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. - pub const Attributes = struct { + field_names: []const [:0]const u8, + /// Guaranteed to have the same length as `field_names`. + field_types: []const type, + /// Guaranteed to have the same length as `field_names`. + field_attrs: []const FieldAttributes, + + decl_names: []const [:0]const u8, + + pub const FieldAttributes = struct { + /// `null` means the field alignment is not explicitly specified. The field will still + /// be aligned to at least `@alignOf` the field type. @"align": ?usize = null, }; }; - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. - pub const Union = struct { - layout: ContainerLayout, - tag_type: ?type, - fields: []const UnionField, - decls: []const Declaration, - }; - /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const Fn = struct { - calling_convention: CallingConvention, + attrs: Attributes, is_generic: bool, - is_var_args: bool, - /// TODO change the language spec to make this not optional. + /// `null` means the return type is generic, i.e. it depends on a function argument. return_type: ?type, - params: []const Param, - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. - pub const Param = struct { - is_generic: bool, - is_noalias: bool, - type: ?type, + /// A `null` element represents either an `anytype` parameter, or a parameter with a generic + /// type, i.e. where the type depends on a previous function argument. + param_types: []const ?type, + /// Guaranteed to have the same length as `param_types`. + param_attrs: []const ParamAttributes, - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. - pub const Attributes = struct { - @"noalias": bool = false, - }; + pub const ParamAttributes = struct { + @"noalias": bool = false, }; - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. pub const Attributes = struct { @"callconv": CallingConvention = .auto, varargs: bool = false, @@ -810,7 +784,7 @@ pub const Type = union(enum) { /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. pub const Opaque = struct { - decls: []const Declaration, + decl_names: []const [:0]const u8, }; /// This data structure is used by the Zig language code generation and @@ -831,12 +805,6 @@ pub const Type = union(enum) { len: comptime_int, child: type, }; - - /// This data structure is used by the Zig language code generation and - /// therefore must be kept in sync with the compiler implementation. - pub const Declaration = struct { - name: [:0]const u8, - }; }; /// This data structure is used by the Zig language code generation and diff --git a/lib/std/math.zig b/lib/std/math.zig index 54488ddeda..0df59050ce 100644 --- a/lib/std/math.zig +++ b/lib/std/math.zig @@ -1648,8 +1648,8 @@ pub const CompareOperator = enum { } test reverse { - inline for (@typeInfo(CompareOperator).@"enum".fields) |op_field| { - const op = @as(CompareOperator, @enumFromInt(op_field.value)); + inline for (@typeInfo(CompareOperator).@"enum".field_values) |op_field_value| { + const op = @as(CompareOperator, @enumFromInt(op_field_value)); try testing.expect(compare(2, op, 3) == compare(3, op.reverse(), 2)); try testing.expect(compare(3, op, 3) == compare(3, op.reverse(), 3)); try testing.expect(compare(4, op, 3) == compare(3, op.reverse(), 4)); diff --git a/lib/std/mem.zig b/lib/std/mem.zig index 2226f25ce6..ba8602e90b 100644 --- a/lib/std/mem.zig +++ b/lib/std/mem.zig @@ -297,9 +297,13 @@ pub fn zeroes(comptime T: type) T { return item; } else { var structure: T = undefined; - inline for (struct_info.fields) |field| { - if (!field.is_comptime) { - @field(structure, field.name) = zeroes(field.type); + inline for ( + struct_info.field_names, + struct_info.field_types, + struct_info.field_attrs, + ) |field_name, field_type, field_attrs| { + if (!field_attrs.@"comptime") { + @field(structure, field_name) = zeroes(field_type); } } return structure; @@ -321,7 +325,7 @@ pub fn zeroes(comptime T: type) T { return null; }, .one, .many => { - if (ptr_info.is_allowzero) return @ptrFromInt(0); + if (ptr_info.attrs.@"allowzero") return @ptrFromInt(0); @compileError("Only nullable and allowzero pointers can be set to zero."); }, } @@ -471,44 +475,49 @@ pub fn zeroInit(comptime T: type, init: anytype) T { switch (@typeInfo(Init)) { .@"struct" => |init_info| { if (init_info.is_tuple) { - if (init_info.fields.len > struct_info.fields.len) { + if (init_info.field_names.len > struct_info.field_names.len) { @compileError("Tuple initializer has more elements than there are fields in `" ++ @typeName(T) ++ "`"); } } else { - inline for (init_info.fields) |field| { - if (!@hasField(T, field.name)) { - @compileError("Encountered an initializer for `" ++ field.name ++ "`, but it is not a field of " ++ @typeName(T)); + inline for (init_info.field_names) |field_name| { + if (!@hasField(T, field_name)) { + @compileError("Encountered an initializer for `" ++ field_name ++ "`, but it is not a field of " ++ @typeName(T)); } } } var value: T = if (struct_info.layout == .@"extern") zeroes(T) else undefined; - inline for (struct_info.fields, 0..) |field, i| { - if (field.is_comptime) { + inline for ( + struct_info.field_names, + struct_info.field_types, + struct_info.field_attrs, + 0.., + ) |f_name, f_type, f_attr, i| { + if (f_attr.@"comptime") { continue; } - if (init_info.is_tuple and init_info.fields.len > i) { - @field(value, field.name) = @field(init, init_info.fields[i].name); - } else if (@hasField(@TypeOf(init), field.name)) { - switch (@typeInfo(field.type)) { + if (init_info.is_tuple and init_info.field_names.len > i) { + @field(value, f_name) = @field(init, init_info.field_names[i]); + } else if (@hasField(@TypeOf(init), f_name)) { + switch (@typeInfo(f_type)) { .@"struct" => { - @field(value, field.name) = zeroInit(field.type, @field(init, field.name)); + @field(value, f_name) = zeroInit(f_type, @field(init, f_name)); }, else => { - @field(value, field.name) = @field(init, field.name); + @field(value, f_name) = @field(init, f_name); }, } - } else if (field.defaultValue()) |val| { - @field(value, field.name) = val; + } else if (f_attr.defaultValue(f_type)) |val| { + @field(value, f_name) = val; } else { - switch (@typeInfo(field.type)) { + switch (@typeInfo(f_type)) { .@"struct" => { - @field(value, field.name) = std.mem.zeroInit(field.type, .{}); + @field(value, f_name) = std.mem.zeroInit(f_type, .{}); }, else => { - @field(value, field.name) = std.mem.zeroes(@TypeOf(@field(value, field.name))); + @field(value, f_name) = std.mem.zeroes(@TypeOf(@field(value, f_name))); }, } } @@ -867,13 +876,9 @@ fn Span(comptime T: type) type { .many => ptr_info.sentinel() orelse @compileError("invalid type given to std.mem.span: " ++ @typeName(T)), .c => 0, }; - return @Pointer(.slice, .{ - .@"const" = ptr_info.is_const, - .@"volatile" = ptr_info.is_volatile, - .@"allowzero" = ptr_info.is_allowzero and ptr_info.size != .c, - .@"align" = ptr_info.alignment, - .@"addrspace" = ptr_info.address_space, - }, ptr_info.child, new_sentinel); + var attrs = ptr_info.attrs; + attrs.@"allowzero" = attrs.@"allowzero" and ptr_info.size != .c; + return @Pointer(.slice, attrs, ptr_info.child, new_sentinel); }, else => {}, } @@ -933,13 +938,9 @@ fn SliceTo(comptime T: type, comptime end: std.meta.Elem(T)) type { .many => if (std.meta.sentinel(T)) |s| s == end else true, .c => true, }; - return @Pointer(.slice, .{ - .@"const" = ptr_info.is_const, - .@"volatile" = ptr_info.is_volatile, - .@"allowzero" = ptr_info.is_allowzero and ptr_info.size != .c, - .@"align" = ptr_info.alignment, - .@"addrspace" = ptr_info.address_space, - }, Elem, if (have_sentinel) end else null); + var attrs = ptr_info.attrs; + attrs.@"allowzero" = attrs.@"allowzero" and ptr_info.size != .c; + return @Pointer(.slice, attrs, Elem, if (have_sentinel) end else null); }, else => {}, } @@ -2210,19 +2211,19 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a .@"struct" => |struct_info| { if (struct_info.backing_integer) |Int| { ptr.* = @bitCast(@byteSwap(@as(Int, @bitCast(ptr.*)))); - } else inline for (std.meta.fields(S)) |f| { - switch (@typeInfo(f.type)) { - .@"struct" => byteSwapAllFieldsAligned(f.type, .fromByteUnits(f.alignment orelse @alignOf(f.type)), &@field(ptr, f.name)), - .@"union", .array => byteSwapAllFieldsAligned(f.type, .fromByteUnits(f.alignment orelse @alignOf(f.type)), &@field(ptr, f.name)), + } else inline for (struct_info.field_types, struct_info.field_names, struct_info.field_attrs) |f_type, f_name, f_attr| { + switch (@typeInfo(f_type)) { + .@"struct" => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)), + .@"union", .array => byteSwapAllFieldsAligned(f_type, .fromByteUnits(f_attr.@"align" orelse @alignOf(f_type)), &@field(ptr, f_name)), .@"enum" => { - @field(ptr, f.name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f.name)))); + @field(ptr, f_name) = @enumFromInt(@byteSwap(@intFromEnum(@field(ptr, f_name)))); }, .bool => {}, .float => |float_info| { - @field(ptr, f.name) = @bitCast(@byteSwap(@as(@Int(.unsigned, float_info.bits), @bitCast(@field(ptr, f.name))))); + @field(ptr, f_name) = @bitCast(@byteSwap(@as(@Int(.unsigned, float_info.bits), @bitCast(@field(ptr, f_name))))); }, else => { - @field(ptr, f.name) = @byteSwap(@field(ptr, f.name)); + @field(ptr, f_name) = @byteSwap(@field(ptr, f_name)); }, } } @@ -2232,9 +2233,9 @@ pub fn byteSwapAllFieldsAligned(comptime S: type, comptime a: Alignment, ptr: *a @compileError("byteSwapAllFields expects an untagged union"); } - const first_size = @bitSizeOf(union_info.fields[0].type); - inline for (union_info.fields) |field| { - if (@bitSizeOf(field.type) != first_size) { + const first_size = @bitSizeOf(union_info.field_types[0]); + inline for (union_info.field_types) |field_type| { + if (@bitSizeOf(field_type) != first_size) { @compileError("Unable to byte-swap unions with varying field sizes"); } } @@ -3940,15 +3941,8 @@ pub fn ReverseIterator(comptime T: type) type { .many, .c => @compileError("expected slice or pointer to array, found '" ++ @typeName(T) ++ "'"), } const Element = std.meta.Elem(T); - const attrs: std.builtin.Type.Pointer.Attributes = .{ - .@"const" = ptr.is_const, - .@"volatile" = ptr.is_volatile, - .@"allowzero" = ptr.is_allowzero, - .@"align" = ptr.alignment, - .@"addrspace" = ptr.address_space, - }; - const Pointer = @Pointer(.many, attrs, Element, std.meta.sentinel(T)); - const ElementPointer = @Pointer(.one, attrs, Element, null); + const Pointer = @Pointer(.many, ptr.attrs, Element, std.meta.sentinel(T)); + const ElementPointer = @Pointer(.one, ptr.attrs, Element, null); return struct { ptr: Pointer, index: usize, @@ -4255,7 +4249,7 @@ pub fn alignPointerOffset(ptr: anytype, align_to: usize) ?usize { @compileError("expected many item pointer, got " ++ @typeName(T)); // Do nothing if the pointer is already well-aligned. - if (align_to <= info.pointer.alignment orelse @alignOf(info.pointer.child)) + if (align_to <= info.pointer.attrs.@"align" orelse @alignOf(info.pointer.child)) return 0; // Calculate the aligned base address with an eye out for overflow. @@ -4309,17 +4303,14 @@ fn CopyPtrAttrs( comptime child: type, ) type { const ptr = @typeInfo(source).pointer; - return @Pointer(size, .{ - .@"const" = ptr.is_const, - .@"volatile" = ptr.is_volatile, - .@"allowzero" = ptr.is_allowzero, - .@"align" = ptr.alignment orelse a: { - // If the new child is aligned differently than the old one, explicitly align the type. - const want = @alignOf(ptr.child); - break :a if (@alignOf(child) == want) null else want; - }, - .@"addrspace" = ptr.address_space, - }, child, null); + var attrs = ptr.attrs; + if (attrs.@"align" == null) { + const want = @alignOf(ptr.child); + if (@alignOf(child) != want) { + attrs.@"align" = want; + } + } + return @Pointer(size, attrs, child, null); } fn AsBytesReturnType(comptime P: type) type { @@ -4383,10 +4374,13 @@ test "asBytes preserves pointer attributes" { const in = @typeInfo(@TypeOf(inPtr)).pointer; const out = @typeInfo(@TypeOf(outSlice)).pointer; - try testing.expectEqual(in.is_const, out.is_const); - try testing.expectEqual(in.is_volatile, out.is_volatile); - try testing.expectEqual(in.is_allowzero, out.is_allowzero); - try testing.expectEqual(in.alignment, out.alignment); + const in_attrs = in.attrs; + const out_attrs = out.attrs; + + try testing.expectEqual(in_attrs.@"const", out_attrs.@"const"); + try testing.expectEqual(in_attrs.@"volatile", out_attrs.@"volatile"); + try testing.expectEqual(in_attrs.@"allowzero", out_attrs.@"allowzero"); + try testing.expectEqual(in_attrs.@"align", out_attrs.@"align"); } /// Given any value, returns a copy of its bytes in an array. @@ -4463,13 +4457,13 @@ test "bytesAsValue preserves pointer attributes" { const inSlice = @as(*align(16) const volatile [4]u8, @ptrCast(&inArr))[0..]; const outPtr = bytesAsValue(u32, inSlice); - const in = @typeInfo(@TypeOf(inSlice)).pointer; - const out = @typeInfo(@TypeOf(outPtr)).pointer; + const in_attrs = @typeInfo(@TypeOf(inSlice)).pointer.attrs; + const out_attrs = @typeInfo(@TypeOf(outPtr)).pointer.attrs; - try testing.expectEqual(in.is_const, out.is_const); - try testing.expectEqual(in.is_volatile, out.is_volatile); - try testing.expectEqual(in.is_allowzero, out.is_allowzero); - try testing.expectEqual(in.alignment, out.alignment); + try testing.expectEqual(in_attrs.@"const", out_attrs.@"const"); + try testing.expectEqual(in_attrs.@"volatile", out_attrs.@"volatile"); + try testing.expectEqual(in_attrs.@"allowzero", out_attrs.@"allowzero"); + try testing.expectEqual(in_attrs.@"align", out_attrs.@"align"); } /// Given a pointer to an array of bytes, returns a value of the specified type backed by a @@ -4566,13 +4560,13 @@ test "bytesAsSlice preserves pointer attributes" { const inSlice = @as(*align(16) const volatile [4]u8, @ptrCast(&inArr))[0..]; const outSlice = bytesAsSlice(u16, inSlice); - const in = @typeInfo(@TypeOf(inSlice)).pointer; - const out = @typeInfo(@TypeOf(outSlice)).pointer; + const in_attrs = @typeInfo(@TypeOf(inSlice)).pointer.attrs; + const out_attrs = @typeInfo(@TypeOf(outSlice)).pointer.attrs; - try testing.expectEqual(in.is_const, out.is_const); - try testing.expectEqual(in.is_volatile, out.is_volatile); - try testing.expectEqual(in.is_allowzero, out.is_allowzero); - try testing.expectEqual(in.alignment, out.alignment); + try testing.expectEqual(in_attrs.@"const", out_attrs.@"const"); + try testing.expectEqual(in_attrs.@"volatile", out_attrs.@"volatile"); + try testing.expectEqual(in_attrs.@"allowzero", out_attrs.@"allowzero"); + try testing.expectEqual(in_attrs.@"align", out_attrs.@"align"); } test "bytesAsSlice with zero-bit element type" { @@ -4678,25 +4672,19 @@ test "sliceAsBytes preserves pointer attributes" { const inSlice = @as(*align(16) const volatile [2]u16, @ptrCast(&inArr))[0..]; const outSlice = sliceAsBytes(inSlice); - const in = @typeInfo(@TypeOf(inSlice)).pointer; - const out = @typeInfo(@TypeOf(outSlice)).pointer; + const in_attrs = @typeInfo(@TypeOf(inSlice)).pointer.attrs; + const out_attrs = @typeInfo(@TypeOf(outSlice)).pointer.attrs; - try testing.expectEqual(in.is_const, out.is_const); - try testing.expectEqual(in.is_volatile, out.is_volatile); - try testing.expectEqual(in.is_allowzero, out.is_allowzero); - try testing.expectEqual(in.alignment, out.alignment); + try testing.expectEqual(in_attrs.@"const", out_attrs.@"const"); + try testing.expectEqual(in_attrs.@"volatile", out_attrs.@"volatile"); + try testing.expectEqual(in_attrs.@"allowzero", out_attrs.@"allowzero"); + try testing.expectEqual(in_attrs.@"align", out_attrs.@"align"); } fn AbsorbSentinelReturnType(comptime Slice: type) type { const info = @typeInfo(Slice).pointer; assert(info.size == .slice); - return @Pointer(.slice, .{ - .@"const" = info.is_const, - .@"volatile" = info.is_volatile, - .@"allowzero" = info.is_allowzero, - .@"addrspace" = info.address_space, - .@"align" = info.alignment, - }, info.child, null); + return @Pointer(.slice, info.attrs, info.child, null); } /// If the provided slice is not sentinel terminated, do nothing and return that slice. @@ -4949,13 +4937,9 @@ test "freeing empty string with null-terminated sentinel" { /// all other pointer attributes copied from `AttributeSource`. fn AlignedSlice(comptime AttributeSource: type, comptime new_alignment: usize) type { const ptr = @typeInfo(AttributeSource).pointer; - return @Pointer(.slice, .{ - .@"const" = ptr.is_const, - .@"volatile" = ptr.is_volatile, - .@"allowzero" = ptr.is_allowzero, - .@"align" = new_alignment, - .@"addrspace" = ptr.address_space, - }, ptr.child, null); + var attrs = ptr.attrs; + attrs.@"align" = new_alignment; + return @Pointer(.slice, attrs, ptr.child, null); } /// Returns the largest slice in the given bytes that conforms to the new alignment, diff --git a/lib/std/mem/Allocator.zig b/lib/std/mem/Allocator.zig index 4ca16f2125..76e5d11cc4 100644 --- a/lib/std/mem/Allocator.zig +++ b/lib/std/mem/Allocator.zig @@ -183,7 +183,7 @@ pub fn destroy(self: Allocator, ptr: anytype) void { const non_const_ptr = @as([*]u8, @ptrCast(@constCast(ptr))); self.rawFree( non_const_ptr[0..@sizeOf(T)], - .fromByteUnits(info.alignment orelse @alignOf(T)), + .fromByteUnits(info.attrs.@"align" orelse @alignOf(T)), @returnAddress(), ); } @@ -331,7 +331,7 @@ pub fn resize(self: Allocator, allocation: anytype, new_len: usize) bool { const new_len_bytes = math.mul(usize, @sizeOf(T), new_len) catch return false; return self.rawResize( old_memory, - .fromByteUnits(slice_info.alignment orelse @alignOf(T)), + .fromByteUnits(slice_info.attrs.@"align" orelse @alignOf(T)), new_len_bytes, @returnAddress(), ); @@ -377,7 +377,7 @@ pub fn remap(self: Allocator, allocation: anytype, new_len: usize) ?@TypeOf(allo const new_len_bytes = math.mul(usize, @sizeOf(T), new_len) catch return null; const new_ptr = self.rawRemap( old_memory, - .fromByteUnits(slice_info.alignment orelse @alignOf(T)), + .fromByteUnits(slice_info.attrs.@"align" orelse @alignOf(T)), new_len_bytes, @returnAddress(), ) orelse return null; @@ -412,11 +412,11 @@ pub fn reallocAdvanced( comptime assert(slice_info.size == .slice); const T = slice_info.child; if (old_mem.len == 0) { - return self.allocAdvancedWithRetAddr(T, .fromByteUnitsOptional(slice_info.alignment), new_n, return_address); + return self.allocAdvancedWithRetAddr(T, .fromByteUnitsOptional(slice_info.attrs.@"align"), new_n, return_address); } if (new_n == 0) { self.free(old_mem); - const alignment = slice_info.alignment orelse @alignOf(T); + const alignment = slice_info.attrs.@"align" orelse @alignOf(T); const addr = comptime std.mem.alignBackward(usize, math.maxInt(usize), alignment); const ptr: *align(alignment) [0]T = @ptrFromInt(addr); return ptr; @@ -425,16 +425,16 @@ pub fn reallocAdvanced( const old_byte_slice: []u8 = @ptrCast(@constCast(mem.absorbSentinel(old_mem))); const byte_count = math.mul(usize, @sizeOf(T), new_n) catch return error.OutOfMemory; // Note: can't set shrunk memory to undefined as memory shouldn't be modified on realloc failure - if (self.rawRemap(old_byte_slice, .fromByteUnits(slice_info.alignment orelse @alignOf(T)), byte_count, return_address)) |p| { + if (self.rawRemap(old_byte_slice, .fromByteUnits(slice_info.attrs.@"align" orelse @alignOf(T)), byte_count, return_address)) |p| { return @ptrCast(@alignCast(p[0..byte_count])); } - const new_mem = self.rawAlloc(byte_count, .fromByteUnits(slice_info.alignment orelse @alignOf(T)), return_address) orelse + const new_mem = self.rawAlloc(byte_count, .fromByteUnits(slice_info.attrs.@"align" orelse @alignOf(T)), return_address) orelse return error.OutOfMemory; const copy_len = @min(byte_count, old_byte_slice.len); @memcpy(new_mem[0..copy_len], old_byte_slice[0..copy_len]); @memset(old_byte_slice, undefined); - self.rawFree(old_byte_slice, .fromByteUnits(slice_info.alignment orelse @alignOf(T)), return_address); + self.rawFree(old_byte_slice, .fromByteUnits(slice_info.attrs.@"align" orelse @alignOf(T)), return_address); return @ptrCast(@alignCast(new_mem[0..byte_count])); } @@ -448,7 +448,7 @@ pub fn free(self: Allocator, memory: anytype) void { const bytes: []u8 = @ptrCast(@constCast(mem.absorbSentinel(memory))); if (bytes.len == 0) return; @memset(bytes, undefined); - self.rawFree(bytes, .fromByteUnits(slice_info.alignment orelse @alignOf(slice_info.child)), @returnAddress()); + self.rawFree(bytes, .fromByteUnits(slice_info.attrs.@"align" orelse @alignOf(slice_info.child)), @returnAddress()); } /// Copies `m` to newly allocated memory. Caller owns the memory. diff --git a/lib/std/meta.zig b/lib/std/meta.zig index 689888e318..85f3171fa5 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -8,7 +8,7 @@ const root = @import("root"); pub const TrailerFlags = @import("meta/trailer_flags.zig").TrailerFlags; -const Type = std.builtin.Type; +const Type = std.lang.Type; test { _ = TrailerFlags; @@ -22,21 +22,21 @@ pub fn stringToEnum(comptime T: type, str: []const u8) ?T { // TODO The '100' here is arbitrary and should be increased when possible: // - https://github.com/ziglang/zig/issues/4055 // - https://github.com/ziglang/zig/issues/3863 - if (@typeInfo(T).@"enum".fields.len <= 100) { + if (@typeInfo(T).@"enum".field_names.len <= 100) { const kvs = comptime build_kvs: { const EnumKV = struct { []const u8, T }; - var kvs_array: [@typeInfo(T).@"enum".fields.len]EnumKV = undefined; - for (@typeInfo(T).@"enum".fields, 0..) |enumField, i| { - kvs_array[i] = .{ enumField.name, @field(T, enumField.name) }; + var kvs_array: [@typeInfo(T).@"enum".field_names.len]EnumKV = undefined; + for (@typeInfo(T).@"enum".field_names, 0..) |name, i| { + kvs_array[i] = .{ name, @field(T, name) }; } break :build_kvs kvs_array[0..]; }; const map = std.StaticStringMap(T).initComptime(kvs); return map.get(str); } else { - inline for (@typeInfo(T).@"enum".fields) |enumField| { - if (mem.eql(u8, str, enumField.name)) { - return @field(T, enumField.name); + inline for (@typeInfo(T).@"enum".field_names) |name| { + if (mem.eql(u8, str, name)) { + return @field(T, name); } } return null; @@ -63,7 +63,7 @@ pub fn alignment(comptime T: type) comptime_int { .pointer, .@"fn" => alignment(info.child), else => @alignOf(T), }, - .pointer => |info| info.alignment orelse @alignOf(info.child), + .pointer => |info| info.attrs.@"align" orelse @alignOf(info.child), else => @alignOf(T), }; } @@ -171,34 +171,20 @@ pub fn Sentinel(comptime T: type, comptime sentinel_val: Elem(T)) type { switch (@typeInfo(T)) { .pointer => |info| switch (info.size) { .one => switch (@typeInfo(info.child)) { - .array => |array_info| return @Pointer(.one, .{ - .@"const" = info.is_const, - .@"volatile" = info.is_volatile, - .@"allowzero" = info.is_allowzero, - .@"align" = info.alignment, - .@"addrspace" = info.address_space, - }, [array_info.len:sentinel_val]array_info.child, null), + .array => |array_info| return @Pointer( + .one, + info.attrs, + [array_info.len:sentinel_val]array_info.child, + null, + ), else => {}, }, - .many, .slice => |size| return @Pointer(size, .{ - .@"const" = info.is_const, - .@"volatile" = info.is_volatile, - .@"allowzero" = info.is_allowzero, - .@"align" = info.alignment, - .@"addrspace" = info.address_space, - }, info.child, sentinel_val), + .many, .slice => |size| return @Pointer(size, info.attrs, info.child, sentinel_val), else => {}, }, .optional => |info| switch (@typeInfo(info.child)) { .pointer => |ptr_info| switch (ptr_info.size) { - .many => return ?@Pointer(.many, .{ - .@"const" = ptr_info.is_const, - .@"volatile" = ptr_info.is_volatile, - .@"allowzero" = ptr_info.is_allowzero, - .@"align" = ptr_info.alignment, - .@"addrspace" = ptr_info.address_space, - .child = ptr_info.child, - }, ptr_info.child, sentinel_val), + .many => return ?@Pointer(.many, ptr_info.attrs, ptr_info.child, sentinel_val), else => {}, }, else => {}, @@ -238,14 +224,14 @@ test containerLayout { try testing.expect(containerLayout(U3) == .@"extern"); } -/// Instead of this function, prefer to use e.g. `@typeInfo(foo).@"struct".decls` +/// Instead of this function, prefer to use e.g. `@typeInfo(foo).@"struct".decl_names` /// directly when you know what kind of type it is. -pub fn declarations(comptime T: type) []const Type.Declaration { +pub fn declarations(comptime T: type) []const [:0]const u8 { return switch (@typeInfo(T)) { - .@"struct" => |info| info.decls, - .@"enum" => |info| info.decls, - .@"union" => |info| info.decls, - .@"opaque" => |info| info.decls, + .@"struct" => |info| info.decl_names, + .@"enum" => |info| info.decl_names, + .@"union" => |info| info.decl_names, + .@"opaque" => |info| info.decl_names, else => @compileError("Expected struct, enum, union, or opaque type, found '" ++ @typeName(T) ++ "'"), }; } @@ -268,7 +254,7 @@ test declarations { pub fn a() void {} }; - const decls = comptime [_][]const Type.Declaration{ + const decls = comptime [_][]const [:0]const u8{ declarations(E1), declarations(S1), declarations(U1), @@ -277,97 +263,41 @@ test declarations { inline for (decls) |decl| { try testing.expect(decl.len == 1); - try testing.expect(comptime mem.eql(u8, decl[0].name, "a")); + try testing.expect(comptime mem.eql(u8, decl[0], "a")); } } -pub fn declarationInfo(comptime T: type, comptime decl_name: []const u8) Type.Declaration { - inline for (comptime declarations(T)) |decl| { - if (comptime mem.eql(u8, decl.name, decl_name)) - return decl; - } - - @compileError("'" ++ @typeName(T) ++ "' has no declaration '" ++ decl_name ++ "'"); -} - -test declarationInfo { - const E1 = enum { - A, - - pub fn a() void {} - }; - const S1 = struct { - pub fn a() void {} - }; - const U1 = union { - b: u8, - - pub fn a() void {} - }; - - const infos = comptime [_]Type.Declaration{ - declarationInfo(E1, "a"), - declarationInfo(S1, "a"), - declarationInfo(U1, "a"), - }; - - inline for (infos) |info| { - try testing.expect(comptime mem.eql(u8, info.name, "a")); - } -} -pub inline fn fields(comptime T: type) switch (@typeInfo(T)) { - .@"struct" => []const Type.StructField, - .@"union" => []const Type.UnionField, - .@"enum" => []const Type.EnumField, - .error_set => []const Type.Error, - else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), -} { - return switch (@typeInfo(T)) { - .@"struct" => |info| info.fields, - .@"union" => |info| info.fields, - .@"enum" => |info| info.fields, - .error_set => |errors| errors.?, // must be non global error set - else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), - }; -} - -test fields { - const E1 = enum { - A, - }; - const E2 = error{A}; - const S1 = struct { - a: u8, - }; - const U1 = union { - a: u8, - }; - - const e1f = comptime fields(E1); - const e2f = comptime fields(E2); - const sf = comptime fields(S1); - const uf = comptime fields(U1); - - try testing.expect(e1f.len == 1); - try testing.expect(e2f.len == 1); - try testing.expect(sf.len == 1); - try testing.expect(uf.len == 1); - try testing.expect(mem.eql(u8, e1f[0].name, "A")); - try testing.expect(mem.eql(u8, e2f[0].name, "A")); - try testing.expect(mem.eql(u8, sf[0].name, "a")); - try testing.expect(mem.eql(u8, uf[0].name, "a")); - try testing.expect(comptime sf[0].type == u8); - try testing.expect(comptime uf[0].type == u8); -} +/// To be removed after Zig 0.17.0 is tagged. +pub const declarationInfo = @compileError("Deprecated; use '@hasDecl' instead"); +/// To be removed after Zig 0.17.0 is tagged. +pub const fields = @compileError("Deprecated; use 'fieldNames' and 'fieldTypes' instead"); pub fn fieldInfo(comptime T: type, comptime field: FieldEnum(T)) switch (@typeInfo(T)) { - .@"struct" => Type.StructField, - .@"union" => Type.UnionField, - .@"enum" => Type.EnumField, - .error_set => Type.Error, + .@"struct" => struct { name: [:0]const u8, type: type, attrs: Type.Struct.FieldAttributes }, + .@"union" => struct { name: [:0]const u8, type: type, attrs: Type.Union.FieldAttributes }, + .@"enum" => struct { name: [:0]const u8, value: comptime_int }, + .error_set => struct { name: [:0]const u8 }, else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), } { - return fields(T)[@intFromEnum(field)]; + const idx = @intFromEnum(field); + return switch (@typeInfo(T)) { + .@"struct" => |info| .{ + .name = info.field_names[idx], + .type = info.field_types[idx], + .attrs = info.field_attrs[idx], + }, + .@"union" => |info| .{ + .name = info.field_names[idx], + .type = info.field_types[idx], + .attrs = info.field_attrs[idx], + }, + .@"enum" => |info| .{ + .name = info.field_names[idx], + .value = info.field_values[idx], + }, + .error_set => |info| .{ .name = info.error_names.?[idx] }, + else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), + }; } test fieldInfo { @@ -395,13 +325,13 @@ test fieldInfo { try testing.expect(comptime uf.type == u8); } -pub fn fieldNames(comptime T: type) *const [fields(T).len][:0]const u8 { - return comptime blk: { - const fieldInfos = fields(T); - var names: [fieldInfos.len][:0]const u8 = undefined; - for (&names, fieldInfos) |*name, field| name.* = field.name; - const final = names; - break :blk &final; +pub fn fieldNames(comptime T: type) []const [:0]const u8 { + return switch (@typeInfo(T)) { + .@"struct" => |s| s.field_names, + .@"union" => |u| u.field_names, + .@"enum" => |e| e.field_names, + .error_set => |es| es.error_names.?, + else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), }; } @@ -433,14 +363,41 @@ test fieldNames { try testing.expectEqualSlices(u8, u1names[1], "b"); } +pub fn fieldTypes(comptime T: type) []const type { + return switch (@typeInfo(T)) { + .@"struct" => |s| s.field_types, + .@"union" => |u| u.field_types, + else => @compileError("Expected struct or union type, found '" ++ @typeName(T) ++ "'"), + }; +} + +test fieldTypes { + const S1 = struct { + a: u8, + }; + const U1 = union { + a: u8, + b: void, + }; + + const s1types = comptime fieldTypes(S1); + const u1types = comptime fieldTypes(U1); + + try testing.expect(s1types.len == 1); + try testing.expect(s1types[0] == u8); + try testing.expect(u1types.len == 2); + try testing.expect(u1types[0] == u8); + try testing.expect(u1types[1] == void); +} + /// Given an enum or error set type, returns a pointer to an array containing all tags for that /// enum or error set. -pub fn tags(comptime T: type) *const [fields(T).len]T { +pub fn tags(comptime T: type) *const [fieldNames(T).len]T { return comptime blk: { - const fieldInfos = fields(T); - var res: [fieldInfos.len]T = undefined; - for (fieldInfos, 0..) |field, i| { - res[i] = @field(T, field.name); + const field_names = fieldNames(T); + var res: [field_names.len]T = undefined; + for (field_names, 0..) |field_name, i| { + res[i] = @field(T, field_name); } const final = res; break :blk &final; @@ -491,27 +448,30 @@ fn expectEqualEnum(expected: anytype, actual: @TypeOf(expected)) !void { // because the language does not guarantee that the slice pointers for field names // and decl names will be the same. comptime { - const expected_fields = @typeInfo(expected).@"enum".fields; - const actual_fields = @typeInfo(actual).@"enum".fields; - if (expected_fields.len != actual_fields.len) return error.FailedTest; - for (expected_fields, 0..) |expected_field, i| { - const actual_field = actual_fields[i]; - try testing.expectEqual(expected_field.value, actual_field.value); - try testing.expectEqualStrings(expected_field.name, actual_field.name); + const expected_field_names = @typeInfo(expected).@"enum".field_names; + const expected_field_values = @typeInfo(expected).@"enum".field_values; + const actual_field_names = @typeInfo(actual).@"enum".field_names; + const actual_field_values = @typeInfo(actual).@"enum".field_values; + if (expected_field_names.len != actual_field_names.len) return error.FailedTest; + for (expected_field_names, expected_field_values, 0..) |expected_field_name, expected_field_value, i| { + const actual_field_name = actual_field_names[i]; + const actual_field_value = actual_field_values[i]; + try testing.expectEqual(expected_field_value, actual_field_value); + try testing.expectEqualStrings(expected_field_name, actual_field_name); } } comptime { - const expected_decls = @typeInfo(expected).@"enum".decls; - const actual_decls = @typeInfo(actual).@"enum".decls; - if (expected_decls.len != actual_decls.len) return error.FailedTest; - for (expected_decls, 0..) |expected_decl, i| { - const actual_decl = actual_decls[i]; - try testing.expectEqualStrings(expected_decl.name, actual_decl.name); + const expected_decl_names = @typeInfo(expected).@"enum".decl_names; + const actual_decl_names = @typeInfo(actual).@"enum".decl_names; + if (expected_decl_names.len != actual_decl_names.len) return error.FailedTest; + for (expected_decl_names, 0..) |expected_decl_name, i| { + const actual_decl_name = actual_decl_names[i]; + try testing.expectEqualStrings(expected_decl_name, actual_decl_name); } } try testing.expectEqual( - @typeInfo(expected).@"enum".is_exhaustive, - @typeInfo(actual).@"enum".is_exhaustive, + @typeInfo(expected).@"enum".mode, + @typeInfo(actual).@"enum".mode, ); } @@ -534,11 +494,9 @@ test FieldEnum { } pub fn DeclEnum(comptime T: type) type { - const decls = declarations(T); - var names: [decls.len][]const u8 = undefined; - for (&names, decls) |*name, decl| name.* = decl.name; - const IntTag = std.math.IntFittingRange(0, decls.len -| 1); - return @Enum(IntTag, .exhaustive, &names, &std.simd.iota(IntTag, decls.len)); + const decl_names = declarations(T); + const IntTag = std.math.IntFittingRange(0, decl_names.len -| 1); + return @Enum(IntTag, .exhaustive, decl_names, &std.simd.iota(IntTag, decl_names.len)); } test DeclEnum { @@ -622,8 +580,8 @@ pub fn eql(a: anytype, b: @TypeOf(a)) bool { .@"struct" => |info| { if (info.layout == .@"packed") return a == b; - inline for (info.fields) |field_info| { - if (!eql(@field(a, field_info.name), @field(b, field_info.name))) return false; + inline for (info.field_names) |field_name| { + if (!eql(@field(a, field_name), @field(b, field_name))) return false; } return true; }, @@ -744,8 +702,8 @@ test eql { /// Given a type and a name, return the field index according to source order. /// Returns `null` if the field is not found. pub fn fieldIndex(comptime T: type, comptime name: []const u8) ?comptime_int { - inline for (fields(T), 0..) |field, i| { - if (mem.eql(u8, field.name, name)) + inline for (fieldNames(T), 0..) |field_name, i| { + if (mem.eql(u8, field_name, name)) return i; } return null; @@ -782,12 +740,12 @@ pub fn ArgsTuple(comptime Function: type) type { @compileError("ArgsTuple expects a function type"); const function_info = info.@"fn"; - if (function_info.is_var_args) + if (function_info.attrs.varargs) @compileError("Cannot create ArgsTuple for variadic function"); - var argument_field_list: [function_info.params.len]type = undefined; - inline for (function_info.params, 0..) |arg, i| { - const T = arg.type orelse @compileError("cannot create ArgsTuple for function with an 'anytype' parameter"); + var argument_field_list: [function_info.param_types.len]type = undefined; + inline for (function_info.param_types, 0..) |arg_type, i| { + const T = arg_type orelse @compileError("cannot create ArgsTuple for function with an 'anytype' parameter"); argument_field_list[i] = T; } @@ -807,13 +765,15 @@ const TupleTester = struct { if (!info.@"struct".is_tuple) @compileError("Struct type must be a tuple type"); - const fields_list = std.meta.fields(Actual); - if (expected.len != fields_list.len) - @compileError("Argument count mismatch"); + const field_names = info.@"struct".field_names; + if (expected.len != field_names.len) { + const msg = std.fmt.comptimePrint("Argument count mismatch: expected {d}, got {d}", .{ expected.len, field_names.len }); + @compileError(msg); + } - inline for (fields_list, 0..) |fld, i| { - if (expected[i] != fld.type) { - @compileError("Field " ++ fld.name ++ " expected to be type " ++ @typeName(expected[i]) ++ ", but was type " ++ @typeName(fld.type)); + inline for (field_names, info.@"struct".field_types, 0..) |fld_name, fld_type, i| { + if (expected[i] != fld_type) { + @compileError("Field " ++ fld_name ++ " expected to be type " ++ @typeName(expected[i]) ++ ", but was type " ++ @typeName(fld_type)); } } } @@ -943,7 +903,7 @@ pub inline fn hasUniqueRepresentation(comptime T: type) bool { .pointer => |info| info.size != .slice, .optional => |info| switch (@typeInfo(info.child)) { - .pointer => |ptr| !ptr.is_allowzero and switch (ptr.size) { + .pointer => |ptr| !ptr.attrs.@"allowzero" and switch (ptr.size) { .slice, .c => false, .one, .many => true, }, @@ -957,10 +917,10 @@ pub inline fn hasUniqueRepresentation(comptime T: type) bool { var sum_size = @as(usize, 0); - inline for (info.fields) |field| { - if (field.is_comptime) continue; - if (!hasUniqueRepresentation(field.type)) return false; - sum_size += @sizeOf(field.type); + inline for (info.field_attrs, info.field_types) |field_attr, field_type| { + if (field_attr.@"comptime") continue; + if (!hasUniqueRepresentation(field_type)) return false; + sum_size += @sizeOf(field_type); } return @sizeOf(T) == sum_size; diff --git a/lib/std/meta/trailer_flags.zig b/lib/std/meta/trailer_flags.zig index d6c2609da1..c312825a2b 100644 --- a/lib/std/meta/trailer_flags.zig +++ b/lib/std/meta/trailer_flags.zig @@ -14,7 +14,7 @@ pub fn TrailerFlags(comptime Fields: type) type { bits: Int, pub const Int = @Int(.unsigned, bit_count); - pub const bit_count = @typeInfo(Fields).@"struct".fields.len; + pub const bit_count = @typeInfo(Fields).@"struct".field_names.len; pub const FieldEnum = std.meta.FieldEnum(Fields); @@ -22,11 +22,18 @@ pub fn TrailerFlags(comptime Fields: type) type { pub const FieldValues = blk: { var field_names: [bit_count][]const u8 = undefined; var field_types: [bit_count]type = undefined; - var field_attrs: [bit_count]std.builtin.Type.StructField.Attributes = undefined; - for (@typeInfo(Fields).@"struct".fields, &field_names, &field_types, &field_attrs) |field, *new_name, *NewType, *new_attrs| { - new_name.* = field.name; - NewType.* = ?field.type; - const default: ?field.type = null; + var field_attrs: [bit_count]std.builtin.Type.Struct.FieldAttributes = undefined; + const fields_info = @typeInfo(Fields).@"struct"; + for ( + fields_info.field_names, + fields_info.field_types, + &field_names, + &field_types, + &field_attrs, + ) |field_name, field_type, *new_name, *NewType, *new_attrs| { + new_name.* = field_name; + NewType.* = ?field_type; + const default: ?field_type = null; new_attrs.* = .{ .default_value_ptr = &default }; } break :blk @Struct(.auto, null, &field_names, &field_types, &field_attrs); @@ -53,8 +60,8 @@ pub fn TrailerFlags(comptime Fields: type) type { /// `fields` is a boolean struct where each active field is set to `true` pub fn init(fields: ActiveFields) Self { var self: Self = .{ .bits = 0 }; - inline for (@typeInfo(Fields).@"struct".fields, 0..) |field, i| { - if (@field(fields, field.name)) + inline for (@typeInfo(Fields).@"struct".field_names, 0..) |field_name, i| { + if (@field(fields, field_name)) self.bits |= 1 << i; } return self; @@ -62,8 +69,8 @@ pub fn TrailerFlags(comptime Fields: type) type { /// `fields` is a struct with each field set to an optional value pub fn setMany(self: Self, p: [*]align(@alignOf(Fields)) u8, fields: FieldValues) void { - inline for (@typeInfo(Fields).@"struct".fields, 0..) |field, i| { - if (@field(fields, field.name)) |value| + inline for (@typeInfo(Fields).@"struct".field_names, 0..) |field_name, i| { + if (@field(fields, field_name)) |value| self.set(p, @as(FieldEnum, @enumFromInt(i)), value); } } @@ -93,30 +100,30 @@ pub fn TrailerFlags(comptime Fields: type) type { pub fn offset(self: Self, comptime field: FieldEnum) usize { var off: usize = 0; - inline for (@typeInfo(Fields).@"struct".fields, 0..) |field_info, i| { + inline for (@typeInfo(Fields).@"struct".field_types, 0..) |field_type, i| { const active = (self.bits & (1 << i)) != 0; if (i == @intFromEnum(field)) { assert(active); - return mem.alignForward(usize, off, @alignOf(field_info.type)); + return mem.alignForward(usize, off, @alignOf(field_type)); } else if (active) { - off = mem.alignForward(usize, off, @alignOf(field_info.type)); - off += @sizeOf(field_info.type); + off = mem.alignForward(usize, off, @alignOf(field_type)); + off += @sizeOf(field_type); } } } pub fn Field(comptime field: FieldEnum) type { - return @typeInfo(Fields).@"struct".fields[@intFromEnum(field)].type; + return @typeInfo(Fields).@"struct".field_types[@intFromEnum(field)]; } pub fn sizeInBytes(self: Self) usize { var off: usize = 0; - inline for (@typeInfo(Fields).@"struct".fields, 0..) |field, i| { - if (@sizeOf(field.type) == 0) + inline for (@typeInfo(Fields).@"struct".field_types, 0..) |field_type, i| { + if (@sizeOf(field_type) == 0) continue; if ((self.bits & (1 << i)) != 0) { - off = mem.alignForward(usize, off, @alignOf(field.type)); - off += @sizeOf(field.type); + off = mem.alignForward(usize, off, @alignOf(field_type)); + off += @sizeOf(field_type); } } return off; diff --git a/lib/std/multi_array_list.zig b/lib/std/multi_array_list.zig index 934dcfeb02..7b99eeb63e 100644 --- a/lib/std/multi_array_list.zig +++ b/lib/std/multi_array_list.zig @@ -44,17 +44,7 @@ pub fn MultiArrayList(comptime T: type) type { const Elem = switch (@typeInfo(T)) { .@"struct" => T, .@"union" => |u| struct { - pub const Bare = Bare: { - var field_names: [u.fields.len][]const u8 = undefined; - var field_types: [u.fields.len]type = undefined; - var field_attrs: [u.fields.len]std.builtin.Type.UnionField.Attributes = undefined; - for (u.fields, &field_names, &field_types, &field_attrs) |field, *name, *Type, *attrs| { - name.* = field.name; - Type.* = field.type; - attrs.* = .{ .@"align" = field.alignment }; - } - break :Bare @Union(u.layout, null, &field_names, &field_types, &field_attrs); - }; + pub const Bare = @Union(u.layout, null, u.field_names, u.field_types[0..], u.field_attrs[0..]); pub const Tag = u.tag_type orelse @compileError("MultiArrayList does not support untagged unions"); tags: Tag, @@ -87,7 +77,7 @@ pub fn MultiArrayList(comptime T: type) type { pub const Slice = struct { /// This array is indexed by the field index which can be obtained /// by using @intFromEnum() on the Field enum - ptrs: [fields.len][*]u8, + ptrs: [field_names.len][*]u8, len: usize, capacity: usize, @@ -116,15 +106,15 @@ pub fn MultiArrayList(comptime T: type) type { .@"union" => Elem.fromT(elem), else => unreachable, }; - inline for (fields, 0..) |field_info, i| { - self.items(@as(Field, @enumFromInt(i)))[index] = @field(e, field_info.name); + inline for (field_names, 0..) |field_name, i| { + self.items(@as(Field, @enumFromInt(i)))[index] = @field(e, field_name); } } pub fn get(self: Slice, index: usize) T { var result: Elem = undefined; - inline for (fields, 0..) |field_info, i| { - @field(result, field_info.name) = self.items(@as(Field, @enumFromInt(i)))[index]; + inline for (field_names, 0..) |field_name, i| { + @field(result, field_name) = self.items(@as(Field, @enumFromInt(i)))[index]; } return switch (@typeInfo(T)) { .@"struct" => result, @@ -134,9 +124,9 @@ pub fn MultiArrayList(comptime T: type) type { } pub fn swap(self: Slice, a: usize, b: usize) void { - inline for (@typeInfo(Field).@"enum".fields) |field| { - const its = self.items(@field(Field, field.name)); - std.mem.swap(@FieldType(T, field.name), &its[a], &its[b]); + inline for (@typeInfo(Field).@"enum".field_names) |field_name| { + const its = self.items(@field(Field, field_name)); + std.mem.swap(@FieldType(T, field_name), &its[a], &its[b]); } } @@ -162,9 +152,9 @@ pub fn MultiArrayList(comptime T: type) type { /// Asserts that `off + len <= s.len`. pub fn subslice(s: Slice, off: usize, len: usize) Slice { assert(off + len <= s.len); - var ptrs: [fields.len][*]u8 = undefined; - inline for (s.ptrs, &ptrs, fields) |in, *out, field| { - out.* = in + (off * @sizeOf(field.type)); + var ptrs: [field_names.len][*]u8 = undefined; + inline for (s.ptrs, &ptrs, field_types) |in, *out, field_type| { + out.* = in + (off * @sizeOf(field_type)); } return .{ .ptrs = ptrs, @@ -185,7 +175,9 @@ pub fn MultiArrayList(comptime T: type) type { const Self = @This(); - const fields = meta.fields(Elem); + const field_names = @typeInfo(Elem).@"struct".field_names; + const field_types = @typeInfo(Elem).@"struct".field_types; + const field_attrs = @typeInfo(Elem).@"struct".field_attrs; /// `sizes.bytes` is an array of @sizeOf each T field. Sorted by alignment, descending. /// `sizes.fields` is an array mapping from `sizes.bytes` array index to field index. /// `sizes.big_align` is the overall alignment of the allocation, which equals the maximum field alignment. @@ -195,13 +187,13 @@ pub fn MultiArrayList(comptime T: type) type { size_index: usize, alignment: usize, }; - var data: [fields.len]Data = undefined; + var data: [field_names.len]Data = undefined; var big_align: usize = 1; - for (fields, 0..) |field_info, i| { + for (field_types, field_attrs, 0..) |f_type, f_attrs, i| { data[i] = .{ - .size = @sizeOf(field_info.type), + .size = @sizeOf(f_type), .size_index = i, - .alignment = field_info.alignment orelse @alignOf(field_info.type), + .alignment = f_attrs.@"align" orelse @alignOf(f_type), }; big_align = @max(big_align, data[i].alignment); } @@ -211,10 +203,10 @@ pub fn MultiArrayList(comptime T: type) type { return lhs.alignment > rhs.alignment; } }; - @setEvalBranchQuota(3 * fields.len * std.math.log2(fields.len)); + @setEvalBranchQuota(3 * field_names.len * std.math.log2(field_names.len)); mem.sort(Data, &data, {}, Sort.lessThan); - var sizes_bytes: [fields.len]usize = undefined; - var field_indexes: [fields.len]usize = undefined; + var sizes_bytes: [field_names.len]usize = undefined; + var field_indexes: [field_names.len]usize = undefined; for (data, 0..) |elem, i| { sizes_bytes[i] = elem.size; field_indexes[i] = elem.size_index; @@ -368,13 +360,13 @@ pub fn MultiArrayList(comptime T: type) type { else => unreachable, }; const slices = self.slice(); - inline for (fields, 0..) |field_info, field_index| { + inline for (field_names, 0..) |field_name, field_index| { const field_slice = slices.items(@as(Field, @enumFromInt(field_index))); var i: usize = self.len - 1; while (i > index) : (i -= 1) { field_slice[i] = field_slice[i - 1]; } - field_slice[index] = @field(entry, field_info.name); + field_slice[index] = @field(entry, field_name); } } @@ -394,7 +386,7 @@ pub fn MultiArrayList(comptime T: type) type { /// retain list ordering. pub fn swapRemove(self: *Self, index: usize) void { const slices = self.slice(); - inline for (fields, 0..) |_, i| { + inline for (field_names, 0..) |_, i| { const field_slice = slices.items(@as(Field, @enumFromInt(i))); field_slice[index] = field_slice[self.len - 1]; field_slice[self.len - 1] = undefined; @@ -406,7 +398,7 @@ pub fn MultiArrayList(comptime T: type) type { /// after it to preserve order. pub fn orderedRemove(self: *Self, index: usize) void { const slices = self.slice(); - inline for (fields, 0..) |_, field_index| { + inline for (field_names, 0..) |_, field_index| { const field_slice = slices.items(@as(Field, @enumFromInt(field_index))); var i = index; while (i < self.len - 1) : (i += 1) { @@ -437,7 +429,7 @@ pub fn MultiArrayList(comptime T: type) type { if (removed == end) continue; // allows duplicates in `sorted_indexes` const start = removed + 1; const len = end - start; // safety checks `sorted_indexes` are sorted - inline for (fields, 0..) |_, field_index| { + inline for (field_names, 0..) |_, field_index| { const field_slice = slices.items(@enumFromInt(field_index)); @memmove(field_slice[start - shift ..][0..len], field_slice[start..][0..len]); // safety checks initial `sorted_indexes` are in range } @@ -446,7 +438,7 @@ pub fn MultiArrayList(comptime T: type) type { const start = sorted_indexes[sorted_indexes.len - 1] + 1; const end = self.len; const len = end - start; // safety checks final `sorted_indexes` are in range - inline for (fields, 0..) |_, field_index| { + inline for (field_names, 0..) |_, field_index| { const field_slice = slices.items(@enumFromInt(field_index)); @memmove(field_slice[start - shift ..][0..len], field_slice[start..][0..len]); } @@ -471,8 +463,8 @@ pub fn MultiArrayList(comptime T: type) type { const other_bytes = gpa.alignedAlloc(u8, sizes.big_align, capacityInBytes(new_len)) catch { const self_slice = self.slice(); - inline for (fields, 0..) |field_info, i| { - if (@sizeOf(field_info.type) != 0) { + inline for (field_types, 0..) |field_type, i| { + if (@sizeOf(field_type) != 0) { const field = @as(Field, @enumFromInt(i)); const dest_slice = self_slice.items(field)[new_len..]; // We use memset here for more efficient codegen in safety-checked, @@ -492,8 +484,8 @@ pub fn MultiArrayList(comptime T: type) type { self.len = new_len; const self_slice = self.slice(); const other_slice = other.slice(); - inline for (fields, 0..) |field_info, i| { - if (@sizeOf(field_info.type) != 0) { + inline for (field_types, 0..) |field_type, i| { + if (@sizeOf(field_type) != 0) { const field = @as(Field, @enumFromInt(i)); @memcpy(other_slice.items(field), self_slice.items(field)); } @@ -529,7 +521,7 @@ pub fn MultiArrayList(comptime T: type) type { const init_capacity: comptime_int = init: { var max: comptime_int = 1; - for (fields) |field| max = @max(max, @sizeOf(field.type)); + for (field_types) |field_type| max = @max(max, @sizeOf(field_type)); break :init @max(1, std.atomic.cache_line / max); }; @@ -564,8 +556,8 @@ pub fn MultiArrayList(comptime T: type) type { }; const self_slice = self.slice(); const other_slice = other.slice(); - inline for (fields, 0..) |field_info, i| { - if (@sizeOf(field_info.type) != 0) { + inline for (field_types, 0..) |field_type, i| { + if (@sizeOf(field_type) != 0) { const field = @as(Field, @enumFromInt(i)); @memcpy(other_slice.items(field), self_slice.items(field)); } @@ -583,8 +575,8 @@ pub fn MultiArrayList(comptime T: type) type { result.len = self.len; const self_slice = self.slice(); const result_slice = result.slice(); - inline for (fields, 0..) |field_info, i| { - if (@sizeOf(field_info.type) != 0) { + inline for (field_types, 0..) |field_type, i| { + if (@sizeOf(field_type) != 0) { const field = @as(Field, @enumFromInt(i)); @memcpy(result_slice.items(field), self_slice.items(field)); } @@ -600,11 +592,11 @@ pub fn MultiArrayList(comptime T: type) type { slice: Slice, pub fn swap(sc: @This(), a_index: usize, b_index: usize) void { - inline for (fields, 0..) |field_info, i| { - if (@sizeOf(field_info.type) != 0) { + inline for (field_types, 0..) |field_type, i| { + if (@sizeOf(field_type) != 0) { const field: Field = @enumFromInt(i); const ptr = sc.slice.items(field); - mem.swap(field_info.type, &ptr[a_index], &ptr[b_index]); + mem.swap(field_type, &ptr[a_index], &ptr[b_index]); } } } @@ -676,18 +668,18 @@ pub fn MultiArrayList(comptime T: type) type { } const Entry = entry: { - var field_names: [fields.len][]const u8 = undefined; - var field_types: [fields.len]type = undefined; - var field_attrs: [fields.len]std.builtin.Type.StructField.Attributes = undefined; - for (sizes.fields, &field_names, &field_types, &field_attrs) |i, *name, *Type, *attrs| { - name.* = fields[i].name ++ "_ptr"; - Type.* = *fields[i].type; + var entry_field_names: [field_names.len][]const u8 = undefined; + var entry_field_types: [field_names.len]type = undefined; + var entry_field_attrs: [field_names.len]std.builtin.Type.Struct.FieldAttributes = undefined; + for (sizes.fields, &entry_field_names, &entry_field_types, &entry_field_attrs) |i, *name, *Type, *attrs| { + name.* = field_names[i] ++ "_ptr"; + Type.* = *field_types[i]; attrs.* = .{ - .@"comptime" = fields[i].is_comptime, - .@"align" = fields[i].alignment, + .@"comptime" = field_attrs[i].@"comptime", + .@"align" = field_attrs[i].@"align", }; } - break :entry @Struct(.@"extern", null, &field_names, &field_types, &field_attrs); + break :entry @Struct(.@"extern", null, &entry_field_names, &entry_field_types, &entry_field_attrs); }; /// This function is used in the debugger pretty formatters in tools/ to fetch the /// child field order and entry type to facilitate fancy debug printing for this type. diff --git a/lib/std/os/uefi/protocol/device_path.zig b/lib/std/os/uefi/protocol/device_path.zig index ebd2463be4..b47212ad69 100644 --- a/lib/std/os/uefi/protocol/device_path.zig +++ b/lib/std/os/uefi/protocol/device_path.zig @@ -82,16 +82,17 @@ pub const DevicePath = extern struct { } pub fn getDevicePath(self: *const DevicePath) ?uefi.DevicePath { - inline for (@typeInfo(uefi.DevicePath).@"union".fields) |ufield| { - const enum_value = std.meta.stringToEnum(uefi.DevicePath.Type, ufield.name); + const u_info = @typeInfo(uefi.DevicePath).@"union"; + inline for (u_info.field_names, u_info.field_types) |ufield_name, ufield_type| { + const enum_value = std.meta.stringToEnum(uefi.DevicePath.Type, ufield_name); // Got the associated union type for self.type, now // we need to initialize it and its subtype if (self.type == enum_value) { - const subtype = self.initSubtype(ufield.type); + const subtype = self.initSubtype(ufield_type); if (subtype) |sb| { // e.g. return .{ .hardware = .{ .pci = @ptrCast(...) } } - return @unionInit(uefi.DevicePath, ufield.name, sb); + return @unionInit(uefi.DevicePath, ufield_name, sb); } } } @@ -103,13 +104,13 @@ pub const DevicePath = extern struct { const type_info = @typeInfo(TUnion).@"union"; const TTag = type_info.tag_type.?; - inline for (type_info.fields) |subtype| { + inline for (type_info.field_names, type_info.field_types) |subtype_name, subtype_type| { // The tag names match the union names, so just grab that off the enum - const tag_val: u8 = @intFromEnum(@field(TTag, subtype.name)); + const tag_val: u8 = @intFromEnum(@field(TTag, subtype_name)); if (self.subtype == tag_val) { // e.g. expr = .{ .pci = @ptrCast(...) } - return @unionInit(TUnion, subtype.name, @as(subtype.type, @ptrCast(self))); + return @unionInit(TUnion, subtype_name, @as(subtype_type, @ptrCast(self))); } } diff --git a/lib/std/os/uefi/tables/boot_services.zig b/lib/std/os/uefi/tables/boot_services.zig index 219c3704d1..cef52f9c99 100644 --- a/lib/std/os/uefi/tables/boot_services.zig +++ b/lib/std/os/uefi/tables/boot_services.zig @@ -1271,7 +1271,7 @@ fn ProtocolInterfaces(HandleType: type, Interfaces: type) type { @compileError("expected tuple of protocol interfaces, got " ++ @typeName(Interfaces)); const interfaces_info = interfaces_type_info.@"struct"; - var tuple_types: [interfaces_info.fields.len * 2 + 2]type = undefined; + var tuple_types: [interfaces_info.field_names.len * 2 + 2]type = undefined; tuple_types[0] = HandleType; tuple_types[tuple_types.len - 1] = ?*const Guid; diff --git a/lib/std/os/windows.zig b/lib/std/os/windows.zig index a7a1852c4c..89105b6736 100644 --- a/lib/std/os/windows.zig +++ b/lib/std/os/windows.zig @@ -144,7 +144,7 @@ pub const OBJECT = struct { Session = 5, _, - pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len; + pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".field_names.len; }; pub const NAME_INFORMATION = extern struct { @@ -575,7 +575,7 @@ pub const FILE = struct { MupProvider = 83, _, - pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".fields.len; + pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".field_names.len; }; pub const BASIC_INFORMATION = extern struct { @@ -881,7 +881,7 @@ pub const DIRECTORY = struct { NotifyFull = 3, _, - pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".fields.len; + pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".field_names.len; }; }; @@ -930,14 +930,8 @@ pub const CONSOLE = struct { pub const Tag = @typeInfo(WITH).@"union".tag_type.?; pub const Payload = PAYLOAD: { - const with_fields = @typeInfo(WITH).@"union".fields; - var field_names: [with_fields.len][]const u8 = undefined; - var field_types: [with_fields.len]type = undefined; - for (with_fields, &field_names, &field_types) |field, *field_name, *field_type| { - field_name.* = field.name; - field_type.* = field.type; - } - break :PAYLOAD @Union(.@"extern", null, &field_names, &field_types, &@splat(.{})); + const with_info = @typeInfo(WITH).@"union"; + break :PAYLOAD @Union(.@"extern", null, with_info.field_names, with_info.field_types[0..], &@splat(.{})); }; }; }; @@ -2122,7 +2116,7 @@ pub const HEAP = opaque { Custom, _, - pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len; + pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".field_names.len; }; pub const VA_CALLBACKS = extern struct { @@ -3369,7 +3363,7 @@ pub const FS_INFORMATION_CLASS = enum(c_int) { Guid = 15, _, - pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".fields.len; + pub const Maximum: @typeInfo(@This()).@"enum".tag_type = 1 + @typeInfo(@This()).@"enum".field_names.len; }; pub const SECTION_INHERIT = enum(c_int) { @@ -3493,7 +3487,7 @@ pub const MEM = struct { ImageMachine, _, - pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len; + pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".field_names.len; }; }; }; @@ -4467,7 +4461,7 @@ pub const KEY = struct { Layer = 5, _, - pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".fields.len; + pub const Max: @typeInfo(@This()).@"enum".tag_type = @typeInfo(@This()).@"enum".field_names.len; }; pub const PARTIAL_INFORMATION = extern struct { diff --git a/lib/std/posix/test.zig b/lib/std/posix/test.zig index aad293278a..3423ac4e4d 100644 --- a/lib/std/posix/test.zig +++ b/lib/std/posix/test.zig @@ -332,8 +332,8 @@ test "fsync" { test "getrlimit and setrlimit" { if (posix.system.rlimit_resource == void) return error.SkipZigTest; - inline for (@typeInfo(posix.rlimit_resource).@"enum".fields) |field| { - const resource: posix.rlimit_resource = @enumFromInt(field.value); + inline for (@typeInfo(posix.rlimit_resource).@"enum".field_values) |field_value| { + const resource: posix.rlimit_resource = @enumFromInt(field_value); const limit = try posix.getrlimit(resource); // XNU kernel does not support RLIMIT_STACK if a custom stack is active, diff --git a/lib/std/start.zig b/lib/std/start.zig index e05208731e..e8478384d5 100644 --- a/lib/std/start.zig +++ b/lib/std/start.zig @@ -24,7 +24,7 @@ comptime { if (native_os == .windows and !builtin.link_libc and !@hasDecl(root, dll_main_crt_startup)) { @export(&DllMainCRTStartup, .{ .name = dll_main_crt_startup }); } else if (native_os == .windows and builtin.link_libc and @hasDecl(root, "DllMain")) { - if (!@typeInfo(@TypeOf(root.DllMain)).@"fn".calling_convention.eql(.winapi)) { + if (!@typeInfo(@TypeOf(root.DllMain)).@"fn".attrs.@"callconv".eql(.winapi)) { @export(&DllMain, .{ .name = "DllMain" }); } } @@ -32,11 +32,11 @@ comptime { if (builtin.link_libc and @hasDecl(root, "main")) { if (is_wasm) { @export(&mainWithoutEnv, .{ .name = "__main_argc_argv" }); - } else if (!@typeInfo(@TypeOf(root.main)).@"fn".calling_convention.eql(.c)) { + } else if (!@typeInfo(@TypeOf(root.main)).@"fn".attrs.@"callconv".eql(.c)) { @export(&main, .{ .name = "main" }); } } else if (native_os == .windows and builtin.link_libc and @hasDecl(root, "wWinMain")) { - if (!@typeInfo(@TypeOf(root.wWinMain)).@"fn".calling_convention.eql(.c)) { + if (!@typeInfo(@TypeOf(root.wWinMain)).@"fn".attrs.@"callconv".eql(.c)) { @export(&wWinMain, .{ .name = "wWinMain" }); } } else if (native_os == .windows) { @@ -728,8 +728,8 @@ var safe_allocator: std.heap.SafeAllocator = .init(std.heap.page_allocator, .{}) inline fn callMain(args: std.process.Args.Vector, environ: std.process.Environ.Block) u8 { const fn_info = @typeInfo(@TypeOf(root.main)).@"fn"; - if (fn_info.params.len == 0) return wrapMain(root.main()); - if (fn_info.params[0].type.? == std.process.Init.Minimal) return wrapMain(root.main(.{ + if (fn_info.param_types.len == 0) return wrapMain(root.main()); + if (fn_info.param_types[0].? == std.process.Init.Minimal) return wrapMain(root.main(.{ .args = .{ .vector = args }, .environ = .{ .block = environ }, })); @@ -809,7 +809,7 @@ inline fn wrapMain(result: anytype) u8 { fn call_wWinMain() std.os.windows.INT { const peb = std.os.windows.peb(); - const MAIN_HINSTANCE = @typeInfo(@TypeOf(root.wWinMain)).@"fn".params[0].type.?; + const MAIN_HINSTANCE = @typeInfo(@TypeOf(root.wWinMain)).@"fn".param_types[0].?; const hInstance: MAIN_HINSTANCE = @ptrCast(peb.ImageBaseAddress); const lpCmdLine: [*:0]u16 = @ptrCast(peb.ProcessParameters.CommandLine.Buffer); diff --git a/lib/std/testing.zig b/lib/std/testing.zig index e8a214fa23..9f00c270d4 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -141,16 +141,16 @@ fn expectEqualInner(comptime T: type, expected: T, actual: T) !void { }, .@"struct" => |structType| { - inline for (structType.fields) |field| { - try expectEqual(@field(expected, field.name), @field(actual, field.name)); + inline for (structType.field_names) |field_name| { + try expectEqual(@field(expected, field_name), @field(actual, field_name)); } }, .@"union" => |union_info| { if (union_info.tag_type == null) { - const first_size = @bitSizeOf(union_info.fields[0].type); - inline for (union_info.fields) |field| { - if (@bitSizeOf(field.type) != first_size) { + const first_size = @bitSizeOf(union_info.field_types[0]); + inline for (union_info.field_types) |field_type| { + if (@bitSizeOf(field_type) != first_size) { @compileError("Unable to compare untagged unions with varying field sizes for type " ++ @typeName(@TypeOf(actual))); } } @@ -840,9 +840,9 @@ fn expectEqualDeepInner(comptime T: type, expected: T, actual: T) error{TestExpe }, .@"struct" => |structType| { - inline for (structType.fields) |field| { - expectEqualDeep(@field(expected, field.name), @field(actual, field.name)) catch |e| { - print("Field {s} incorrect. expected {any}, found {any}\n", .{ field.name, @field(expected, field.name), @field(actual, field.name) }); + inline for (structType.field_names) |field_name| { + expectEqualDeep(@field(expected, field_name), @field(actual, field_name)) catch |e| { + print("Field {s} incorrect. expected {any}, found {any}\n", .{ field_name, @field(expected, field_name), @field(actual, field_name) }); return e; }; } @@ -1165,14 +1165,14 @@ fn CheckAllAllocationFailuresExtraArgs(comptime TestFn: type) type { const ArgsTuple = std.meta.ArgsTuple(TestFn); - const fields = @typeInfo(ArgsTuple).@"struct".fields; - if (fields.len == 0 or fields[0].type != std.mem.Allocator) { + const field_types = @typeInfo(ArgsTuple).@"struct".field_types; + if (field_types.len == 0 or field_types[0] != std.mem.Allocator) { @compileError("The provided function must have an " ++ @typeName(std.mem.Allocator) ++ " as its first argument"); } - var extra_args: [fields.len - 1]type = undefined; - for (&extra_args, fields[1..]) |*arg, field| { - arg.* = field.type; + var extra_args: [field_types.len - 1]type = undefined; + for (&extra_args, field_types[1..]) |*arg, field_type| { + arg.* = field_type; } return @Tuple(&extra_args); @@ -1204,8 +1204,8 @@ test "checkAllAllocationFailures provide result type to 'extra_args' argument" { /// Given a type, references all the declarations inside, so that the semantic analyzer sees them. pub fn refAllDecls(comptime T: type) void { if (!builtin.is_test) return; - inline for (comptime std.meta.declarations(T)) |decl| { - _ = &@field(T, decl.name); + inline for (comptime std.meta.declarations(T)) |decl_name| { + _ = &@field(T, decl_name); } } diff --git a/lib/std/testing/Smith.zig b/lib/std/testing/Smith.zig index e36c97c50e..4aaeee2a48 100644 --- a/lib/std/testing/Smith.zig +++ b/lib/std/testing/Smith.zig @@ -35,7 +35,12 @@ fn fromExcessK(T: type, x: Backing(T)) T { return @as(T, @bitCast(x)) +% std.math.minInt(T); } -fn enumFieldLessThan(_: void, a: std.builtin.Type.EnumField, b: std.builtin.Type.EnumField) bool { +const EnumField = struct { + name: [:0]const u8, + value: comptime_int, +}; + +fn enumFieldLessThan(_: void, a: EnumField, b: EnumField) bool { return a.value < b.value; } @@ -67,17 +72,26 @@ pub inline fn baselineWeights(T: type) []const Weight { baselineWeights(Backing(T)) else @compileError("non-packed unions cannot be weighted"), - .@"enum" => |e| if (!e.is_exhaustive) + .@"enum" => |e| if (e.mode == .nonexhaustive) baselineWeights(e.tag_type) - else if (e.fields.len == 0) + else if (e.field_names.len == 0) // Cannot be included in below branch due to `log2_int_ceil` @compileError("exhaustive zero-field enums cannot be weighted") else e: { - @setEvalBranchQuota(@intCast(4 * e.fields.len * - std.math.log2_int_ceil(usize, e.fields.len))); + @setEvalBranchQuota(@intCast(4 * e.field_names.len * + std.math.log2_int_ceil(usize, e.field_names.len))); - var sorted_fields = e.fields[0..e.fields.len].*; - std.mem.sortUnstable(std.builtin.Type.EnumField, &sorted_fields, {}, enumFieldLessThan); + var sorted_fields = blk: { + var fields: [e.field_names.len]EnumField = undefined; + for (e.field_names, e.field_values, &fields) |f_name, f_value, *field| { + field.* = .{ + .name = f_name, + .value = f_value, + }; + } + break :blk fields; + }; + std.mem.sortUnstable(EnumField, &sorted_fields, {}, enumFieldLessThan); var weights: []const Weight = &.{}; var seq_first: u64 = sorted_fields[0].value; @@ -316,10 +330,10 @@ fn weightsContain(int: u64, weights: []const Weight) bool { inline fn allBitPatternsValid(T: type) bool { return comptime switch (@typeInfo(T)) { .void, .bool, .int, .float => true, - inline .@"struct", .@"union" => |c| c.layout == .@"packed" and for (c.fields) |f| { - if (!allBitPatternsValid(f.type)) break false; + inline .@"struct", .@"union" => |c| c.layout == .@"packed" and for (c.field_types) |f_type| { + if (!allBitPatternsValid(f_type)) break false; } else true, - .@"enum" => |e| !e.is_exhaustive, + .@"enum" => |e| e.mode == .nonexhaustive, else => unreachable, }; } @@ -346,16 +360,16 @@ fn UnionTagWithoutUninitializable(T: type) type { const u = @typeInfo(T).@"union"; const Tag = u.tag_type orelse @compileError("union must have tag"); const e = @typeInfo(Tag).@"enum"; - var field_names: [e.fields.len][]const u8 = undefined; - var field_values: [e.fields.len]e.tag_type = undefined; + var field_names: [e.field_names.len][]const u8 = undefined; + var field_values: [e.field_names.len]e.tag_type = undefined; var n_fields = 0; - for (u.fields) |f| { - switch (f.type) { + for (u.field_names, u.field_types) |f_name, f_type| { + switch (f_type) { noreturn => continue, else => {}, } - field_names[n_fields] = f.name; - field_values[n_fields] = @intFromEnum(@field(Tag, f.name)); + field_names[n_fields] = f_name; + field_values[n_fields] = @intFromEnum(@field(Tag, f_name)); n_fields += 1; } return @Enum(e.tag_type, .exhaustive, field_names[0..n_fields], field_values[0..n_fields]); @@ -381,12 +395,12 @@ pub fn valueWithHash(s: *Smith, T: type, hash: u32) T { } break :full @bitCast(int); }, - .@"enum" => |e| if (e.is_exhaustive) v: { + .@"enum" => |e| if (e.mode == .exhaustive) v: { if (@bitSizeOf(e.tag_type) <= 64) { break :v s.valueWeightedWithHash(T, baselineWeights(T), hash); } break :v std.enums.fromInt(T, s.valueWithHash(e.tag_type, hash)) orelse - @enumFromInt(e.fields[0].value); + @enumFromInt(e.field_values[0]); } else @enumFromInt(s.valueWithHash(e.tag_type, hash)), .optional => |o| if (s.valueWithHash(bool, hash)) null @@ -406,11 +420,11 @@ pub fn valueWithHash(s: *Smith, T: type, hash: u32) T { .@"struct" => |st| if (!allBitPatternsValid(T)) v: { var v: T = undefined; var rhash = hash; - inline for (st.fields) |f| { + inline for (st.field_names, st.field_types) |f_name, f_type| { // rhash is incremented in the call so our rhash state is not reused (e.g. with // two nested structs. note that xor cannot work for this case as the bit would // be flipped back here) - @field(v, f.name) = s.valueWithHash(f.type, rhash +% 1); + @field(v, f_name) = s.valueWithHash(f_type, rhash +% 1); rhash = std.hash.int(rhash); } break :v v; diff --git a/lib/std/zig.zig b/lib/std/zig.zig index 18d2c1459c..6cd6deecb6 100644 --- a/lib/std/zig.zig +++ b/lib/std/zig.zig @@ -736,8 +736,8 @@ pub fn parseTargetQueryOrReportFatalError( help: { var help_text = std.array_list.Managed(u8).init(allocator); defer help_text.deinit(); - inline for (@typeInfo(std.Target.ObjectFormat).@"enum".fields) |field| { - help_text.print(" {s}\n", .{field.name}) catch break :help; + inline for (@typeInfo(std.Target.ObjectFormat).@"enum".field_names) |field_name| { + help_text.print(" {s}\n", .{field_name}) catch break :help; } std.log.info("available object formats:\n{s}", .{help_text.items}); } @@ -747,8 +747,8 @@ pub fn parseTargetQueryOrReportFatalError( help: { var help_text = std.array_list.Managed(u8).init(allocator); defer help_text.deinit(); - inline for (@typeInfo(std.Target.Cpu.Arch).@"enum".fields) |field| { - help_text.print(" {s}\n", .{field.name}) catch break :help; + inline for (@typeInfo(std.Target.Cpu.Arch).@"enum".field_names) |field_name| { + help_text.print(" {s}\n", .{field_name}) catch break :help; } std.log.info("available architectures:\n{s} native\n", .{help_text.items}); } diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig index 7fe0962ecf..372823324e 100644 --- a/lib/std/zig/Ast.zig +++ b/lib/std/zig/Ast.zig @@ -298,17 +298,17 @@ pub fn extraDataSliceWithLen(tree: Ast, start: ExtraIndex, len: u32, comptime T: } pub fn extraData(tree: Ast, index: ExtraIndex, comptime T: type) T { - const fields = std.meta.fields(T); + const info = @typeInfo(T).@"struct"; var result: T = undefined; - inline for (fields, 0..) |field, i| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + @field(result, field_name) = switch (field_type) { Node.Index, Node.OptionalIndex, OptionalTokenIndex, ExtraIndex, => @enumFromInt(tree.extra_data[@intFromEnum(index) + i]), TokenIndex => tree.extra_data[@intFromEnum(index) + i], - else => @compileError("unexpected field type: " ++ @typeName(field.type)), + else => @compileError("unexpected field type: " ++ @typeName(field_type)), }; } return result; diff --git a/lib/std/zig/AstGen.zig b/lib/std/zig/AstGen.zig index 83139bab3d..b02f4cc056 100644 --- a/lib/std/zig/AstGen.zig +++ b/lib/std/zig/AstGen.zig @@ -74,25 +74,25 @@ src_hasher: std.zig.SrcHasher, const InnerError = error{ OutOfMemory, AnalysisFail }; fn addExtra(astgen: *AstGen, extra: anytype) Allocator.Error!u32 { - const fields = std.meta.fields(@TypeOf(extra)); - try astgen.extra.ensureUnusedCapacity(astgen.gpa, fields.len); + const field_count = std.meta.fieldNames(@TypeOf(extra)).len; + try astgen.extra.ensureUnusedCapacity(astgen.gpa, field_count); return addExtraAssumeCapacity(astgen, extra); } fn addExtraAssumeCapacity(astgen: *AstGen, extra: anytype) u32 { - const fields = std.meta.fields(@TypeOf(extra)); + const field_count = std.meta.fieldNames(@TypeOf(extra)).len; const extra_index: u32 = @intCast(astgen.extra.items.len); - astgen.extra.items.len += fields.len; + astgen.extra.items.len += field_count; setExtra(astgen, extra_index, extra); return extra_index; } fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void { - const fields = std.meta.fields(@TypeOf(extra)); + const info = @typeInfo(@TypeOf(extra)).@"struct"; var i = index; - inline for (fields) |field| { - astgen.extra.items[i] = switch (field.type) { - u32 => @field(extra, field.name), + inline for (info.field_names, info.field_types) |field_name, field_type| { + astgen.extra.items[i] = switch (field_type) { + u32 => @field(extra, field_name), Zir.Inst.Ref, Zir.Inst.Index, @@ -103,13 +103,13 @@ fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void { Ast.OptionalTokenIndex, Ast.Node.Index, Ast.Node.OptionalIndex, - => @intFromEnum(@field(extra, field.name)), + => @intFromEnum(@field(extra, field_name)), Ast.TokenOffset, Ast.OptionalTokenOffset, Ast.Node.Offset, Ast.Node.OptionalOffset, - => @bitCast(@intFromEnum(@field(extra, field.name))), + => @bitCast(@intFromEnum(@field(extra, field_name))), i32, Zir.Inst.Call.Flags, @@ -118,7 +118,7 @@ fn setExtra(astgen: *AstGen, index: usize, extra: anytype) void { Zir.Inst.FuncFancy.Bits, Zir.Inst.Param.Type, Zir.Inst.Func.RetTy, - => @bitCast(@field(extra, field.name)), + => @bitCast(@field(extra, field_name)), else => @compileError("bad field type"), }; @@ -166,7 +166,7 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir { try astgen.instructions.ensureTotalCapacity(gpa, tree.nodes.len); // First few indexes of extra are reserved and set at the end. - const reserved_count = @typeInfo(Zir.ExtraIndex).@"enum".fields.len; + const reserved_count = @typeInfo(Zir.ExtraIndex).@"enum".field_names.len; try astgen.extra.ensureTotalCapacity(gpa, tree.nodes.len + reserved_count); astgen.extra.items.len += reserved_count; @@ -212,7 +212,7 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir { astgen.extra.items[err_index] = 0; } else { try astgen.extra.ensureUnusedCapacity(gpa, 1 + astgen.compile_errors.items.len * - @typeInfo(Zir.Inst.CompileErrors.Item).@"struct".fields.len); + @typeInfo(Zir.Inst.CompileErrors.Item).@"struct".field_names.len); astgen.extra.items[err_index] = astgen.addExtraAssumeCapacity(Zir.Inst.CompileErrors{ .items_len = @intCast(astgen.compile_errors.items.len), @@ -227,8 +227,8 @@ pub fn generate(gpa: Allocator, tree: Ast) Allocator.Error!Zir { if (astgen.imports.count() == 0) { astgen.extra.items[imports_index] = 0; } else { - try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Imports).@"struct".fields.len + - astgen.imports.count() * @typeInfo(Zir.Inst.Imports.Item).@"struct".fields.len); + try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Imports).@"struct".field_names.len + + astgen.imports.count() * @typeInfo(Zir.Inst.Imports.Item).@"struct".field_names.len); astgen.extra.items[imports_index] = astgen.addExtraAssumeCapacity(Zir.Inst.Imports{ .imports_len = @intCast(astgen.imports.count()), @@ -1888,7 +1888,7 @@ fn structInitExprAnon( .abs_line = astgen.source_line, .fields_len = @intCast(struct_init.ast.fields.len), }); - const field_size = @typeInfo(Zir.Inst.StructInitAnon.Item).@"struct".fields.len; + const field_size = @typeInfo(Zir.Inst.StructInitAnon.Item).@"struct".field_names.len; var extra_index: usize = try reserveExtra(astgen, struct_init.ast.fields.len * field_size); for (struct_init.ast.fields) |field_init| { @@ -1921,7 +1921,7 @@ fn structInitExprTyped( .abs_line = astgen.source_line, .fields_len = @intCast(struct_init.ast.fields.len), }); - const field_size = @typeInfo(Zir.Inst.StructInit.Item).@"struct".fields.len; + const field_size = @typeInfo(Zir.Inst.StructInit.Item).@"struct".field_names.len; var extra_index: usize = try reserveExtra(astgen, struct_init.ast.fields.len * field_size); for (struct_init.ast.fields) |field_init| { @@ -3804,7 +3804,7 @@ fn ptrType( const gpa = gz.astgen.gpa; try gz.instructions.ensureUnusedCapacity(gpa, 1); try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); - try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.PtrType).@"struct".fields.len + + try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.PtrType).@"struct".field_names.len + trailing_count); const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.PtrType{ @@ -5096,7 +5096,7 @@ fn tupleDecl( const extra_trail = astgen.scratch.items[fields_start..]; assert(extra_trail.len == fields_len * 2); - try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.TupleDecl).@"struct".fields.len + extra_trail.len); + try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.TupleDecl).@"struct".field_names.len + extra_trail.len); const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.TupleDecl{ .src_node = gz.nodeIndexToRelative(node), }); @@ -5670,7 +5670,7 @@ fn errorSetDecl(gz: *GenZir, ri: ResultInfo, node: Ast.Node.Index) InnerError!Zi const gpa = astgen.gpa; const tree = astgen.tree; - const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).@"struct".fields.len); + const payload_index = try reserveExtra(astgen, @typeInfo(Zir.Inst.ErrorSetDecl).@"struct".field_names.len); var fields_len: usize = 0; { var idents: std.AutoHashMapUnmanaged(Zir.NullTerminatedString, Ast.TokenIndex) = .empty; @@ -6332,7 +6332,7 @@ fn setCondBrPayload( const else_body_len = astgen.countBodyLenAfterFixups(else_body); try astgen.extra.ensureUnusedCapacity( astgen.gpa, - @typeInfo(Zir.Inst.CondBr).@"struct".fields.len + then_body_len + else_body_len, + @typeInfo(Zir.Inst.CondBr).@"struct".field_names.len + then_body_len + else_body_len, ); const zir_datas = astgen.instructions.items(.data); @@ -6761,7 +6761,7 @@ fn forExpr( const len: Zir.Inst.Ref = len: { const all_lens = @as([*]Zir.Inst.Ref, @ptrCast(lens))[0 .. lens.len * 2]; const lens_len: u32 = @intCast(all_lens.len); - try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.MultiOp).@"struct".fields.len + lens_len); + try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.MultiOp).@"struct".field_names.len + lens_len); const len = try parent_gz.addPlNode(.for_len, node, Zir.Inst.MultiOp{ .operands_len = lens_len, }); @@ -7791,7 +7791,7 @@ fn switchExpr( // by copying our bodies from `payloads` to `extra`, this time in the order // expected by ZIR consumers. - try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.SwitchBlock).@"struct".fields.len + + try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.SwitchBlock).@"struct".field_names.len + @intFromBool(multi_cases_len > 0) + // multi_cases_len @intFromBool(payload_capture_inst_is_placeholder) + // payload_capture_placeholder @intFromBool(tag_capture_inst_is_placeholder) + // tag_capture_placeholder @@ -8878,7 +8878,7 @@ fn typeOf( try gz.instructions.append(gpa, typeof_inst); return rvalue(gz, ri, typeof_inst.toRef(), node); } - const payload_size: u32 = std.meta.fields(Zir.Inst.TypeOfPeer).len; + const payload_size: u32 = @typeInfo(Zir.Inst.TypeOfPeer).@"struct".field_names.len; const payload_index = try reserveExtra(astgen, payload_size + args.len); const args_index = payload_index + payload_size; @@ -11348,7 +11348,7 @@ const GenZir = struct { const body_len = astgen.countBodyLenAfterFixups(body); try astgen.extra.ensureUnusedCapacity( gpa, - @typeInfo(Zir.Inst.BoolBr).@"struct".fields.len + body_len, + @typeInfo(Zir.Inst.BoolBr).@"struct".field_names.len + body_len, ); const zir_datas = astgen.instructions.items(.data); zir_datas[@intFromEnum(bool_br)].pl_node.payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.BoolBr{ @@ -11372,7 +11372,7 @@ const GenZir = struct { try astgen.extra.ensureUnusedCapacity( gpa, - @typeInfo(Zir.Inst.Block).@"struct".fields.len + body_len, + @typeInfo(Zir.Inst.Block).@"struct".field_names.len + body_len, ); const zir_datas = astgen.instructions.items(.data); zir_datas[@intFromEnum(inst)].pl_node.payload_index = astgen.addExtraAssumeCapacity( @@ -11395,7 +11395,7 @@ const GenZir = struct { try astgen.extra.ensureUnusedCapacity( gpa, - @typeInfo(Zir.Inst.BlockComptime).@"struct".fields.len + body_len, + @typeInfo(Zir.Inst.BlockComptime).@"struct".field_names.len + body_len, ); const zir_datas = astgen.instructions.items(.data); zir_datas[@intFromEnum(inst)].pl_node.payload_index = astgen.addExtraAssumeCapacity( @@ -11416,7 +11416,7 @@ const GenZir = struct { const body_len = astgen.countBodyLenAfterFixups(body); try astgen.extra.ensureUnusedCapacity( gpa, - @typeInfo(Zir.Inst.Try).@"struct".fields.len + body_len, + @typeInfo(Zir.Inst.Try).@"struct".field_names.len + body_len, ); const zir_datas = astgen.instructions.items(.data); zir_datas[@intFromEnum(inst)].pl_node.payload_index = astgen.addExtraAssumeCapacity( @@ -11529,7 +11529,7 @@ const GenZir = struct { inst_info: { try astgen.extra.ensureUnusedCapacity( gpa, - @typeInfo(Zir.Inst.FuncFancy).@"struct".fields.len + + @typeInfo(Zir.Inst.FuncFancy).@"struct".field_names.len + fancyFnExprExtraLen(astgen, &.{}, cc_body, args.cc_ref) + fancyFnExprExtraLen(astgen, args.ret_param_refs, ret_body, ret_ref) + body_len + src_locs_and_hash.len + @@ -11589,7 +11589,7 @@ const GenZir = struct { } else inst_info: { try astgen.extra.ensureUnusedCapacity( gpa, - @typeInfo(Zir.Inst.Func).@"struct".fields.len + 1 + + @typeInfo(Zir.Inst.Func).@"struct".field_names.len + 1 + fancyFnExprExtraLen(astgen, args.ret_param_refs, ret_body, ret_ref) + body_len + src_locs_and_hash.len, ); @@ -11777,7 +11777,7 @@ const GenZir = struct { const param_body = param_gz.instructionsSlice(); const body_len = gz.astgen.countBodyLenAfterFixupsExtraRefs(param_body, prev_param_insts); try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); - try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Param).@"struct".fields.len + body_len); + try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Param).@"struct".field_names.len + body_len); const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Param{ .name = name, @@ -11847,7 +11847,7 @@ const GenZir = struct { try astgen.instructions.ensureUnusedCapacity(gpa, 1); try astgen.extra.ensureUnusedCapacity( gpa, - @typeInfo(Zir.Inst.NodeMultiOp).@"struct".fields.len + operands.len, + @typeInfo(Zir.Inst.NodeMultiOp).@"struct".field_names.len + operands.len, ); const payload_index = astgen.addExtraAssumeCapacity(Zir.Inst.NodeMultiOp{ @@ -12088,7 +12088,7 @@ const GenZir = struct { ) !Zir.Inst.Index { const gpa = gz.astgen.gpa; try gz.astgen.instructions.ensureUnusedCapacity(gpa, 1); - try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Break).@"struct".fields.len); + try gz.astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Break).@"struct".field_names.len); const new_index: Zir.Inst.Index = @enumFromInt(gz.astgen.instructions.len); gz.astgen.instructions.appendAssumeCapacity(.{ @@ -12211,7 +12211,7 @@ const GenZir = struct { try astgen.instructions.ensureUnusedCapacity(gpa, 1); try astgen.extra.ensureUnusedCapacity( gpa, - @typeInfo(Zir.Inst.AllocExtended).@"struct".fields.len + + @typeInfo(Zir.Inst.AllocExtended).@"struct".field_names.len + @intFromBool(args.type_inst != .none) + @intFromBool(args.align_inst != .none), ); @@ -12263,9 +12263,9 @@ const GenZir = struct { try gz.instructions.ensureUnusedCapacity(gpa, 1); try astgen.instructions.ensureUnusedCapacity(gpa, 1); - try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Asm).@"struct".fields.len + - args.outputs.len * @typeInfo(Zir.Inst.Asm.Output).@"struct".fields.len + - args.inputs.len * @typeInfo(Zir.Inst.Asm.Input).@"struct".fields.len); + try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.Asm).@"struct".field_names.len + + args.outputs.len * @typeInfo(Zir.Inst.Asm.Output).@"struct".field_names.len + + args.inputs.len * @typeInfo(Zir.Inst.Asm.Input).@"struct".field_names.len); const payload_index = gz.astgen.addExtraAssumeCapacity(Zir.Inst.Asm{ .src_node = gz.nodeIndexToRelative(args.node), @@ -12374,7 +12374,7 @@ const GenZir = struct { const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); - try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.StructDecl).@"struct".fields.len + + try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.StructDecl).@"struct".field_names.len + 4 + // `captures_len`, `decls_len`, `fields_len`, `backing_int_type_body_len` captures_len * 2 + // `capture`, `capture_name` args.remaining.len); @@ -12441,7 +12441,7 @@ const GenZir = struct { const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); - try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.UnionDecl).@"struct".fields.len + + try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.UnionDecl).@"struct".field_names.len + 4 + // `captures_len`, `decls_len`, `fields_len`, `arg_type_body_len` captures_len * 2 + // `capture`, `capture_name` args.remaining.len); @@ -12509,7 +12509,7 @@ const GenZir = struct { const fields_hash_arr: [4]u32 = @bitCast(args.fields_hash); - try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.EnumDecl).@"struct".fields.len + + try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.EnumDecl).@"struct".field_names.len + 4 + // `captures_len`, `decls_len`, `fields_len`, `tag_type_body_len` captures_len * 2 + // `capture`, `capture_name` args.remaining.len); @@ -12565,7 +12565,7 @@ const GenZir = struct { const captures_len: u32 = @intCast(args.captures.len); assert(args.capture_names.len == captures_len); - try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).@"struct".fields.len + + try astgen.extra.ensureUnusedCapacity(gpa, @typeInfo(Zir.Inst.OpaqueDecl).@"struct".field_names.len + 2 + // `captures_len`, `decls_len` captures_len * 2 + // `capture`, `capture_name` args.decls.len); @@ -13465,7 +13465,7 @@ fn setDeclaration( const flags_arr: [2]u32 = @bitCast(flags); const need_extra: usize = - @typeInfo(Zir.Inst.Declaration).@"struct".fields.len + + @typeInfo(Zir.Inst.Declaration).@"struct".field_names.len + @as(usize, @intFromBool(id.hasName())) + @as(usize, @intFromBool(id.hasLibName())) + @as(usize, @intFromBool(id.hasTypeBody())) + diff --git a/lib/std/zig/ErrorBundle.zig b/lib/std/zig/ErrorBundle.zig index fab4789fad..4b51c9f4b9 100644 --- a/lib/std/zig/ErrorBundle.zig +++ b/lib/std/zig/ErrorBundle.zig @@ -117,7 +117,7 @@ pub fn getSourceLocation(eb: ErrorBundle, index: SourceLocationIndex) SourceLoca pub fn getNotes(eb: ErrorBundle, index: MessageIndex) []const MessageIndex { const notes_len = eb.getErrorMessage(index).notes_len; - const start = @intFromEnum(index) + @typeInfo(ErrorMessage).@"struct".fields.len; + const start = @intFromEnum(index) + @typeInfo(ErrorMessage).@"struct".field_names.len; return @as([]const MessageIndex, @ptrCast(eb.extra[start..][0..notes_len])); } @@ -128,11 +128,12 @@ pub fn getCompileLogOutput(eb: ErrorBundle) [:0]const u8 { /// Returns the requested data, as well as the new index which is at the start of the /// trailers for the object. fn extraData(eb: ErrorBundle, comptime T: type, index: usize) struct { data: T, end: usize } { - const fields = @typeInfo(T).@"struct".fields; + const field_names = @typeInfo(T).@"struct".field_names; + const field_types = @typeInfo(T).@"struct".field_types; var i: usize = index; var result: T = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (field_names, field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => eb.extra[i], MessageIndex => @as(MessageIndex, @enumFromInt(eb.extra[i])), SourceLocationIndex => @as(SourceLocationIndex, @enumFromInt(eb.extra[i])), @@ -498,7 +499,7 @@ pub const Wip = struct { pub fn reserveNotes(wip: *Wip, notes_len: u32) !u32 { try wip.extra.ensureUnusedCapacity(wip.gpa, notes_len + - notes_len * @typeInfo(ErrorBundle.ErrorMessage).@"struct".fields.len); + notes_len * @typeInfo(ErrorBundle.ErrorMessage).@"struct".field_names.len); wip.extra.items.len += notes_len; return @intCast(wip.extra.items.len - notes_len); } @@ -731,13 +732,13 @@ pub const Wip = struct { fn addExtra(wip: *Wip, extra: anytype) Allocator.Error!u32 { const gpa = wip.gpa; - const fields = @typeInfo(@TypeOf(extra)).@"struct".fields; + const fields = @typeInfo(@TypeOf(extra)).@"struct".field_names; try wip.extra.ensureUnusedCapacity(gpa, fields.len); return addExtraAssumeCapacity(wip, extra); } fn addExtraAssumeCapacity(wip: *Wip, extra: anytype) u32 { - const fields = @typeInfo(@TypeOf(extra)).@"struct".fields; + const fields = @typeInfo(@TypeOf(extra)).@"struct".field_names; const result: u32 = @intCast(wip.extra.items.len); wip.extra.items.len += fields.len; setExtra(wip, result, extra); @@ -745,13 +746,15 @@ pub const Wip = struct { } fn setExtra(wip: *Wip, index: usize, extra: anytype) void { - const fields = @typeInfo(@TypeOf(extra)).@"struct".fields; + const extra_info = @typeInfo(@TypeOf(extra)).@"struct"; + const field_names = extra_info.field_names; + const field_types = extra_info.field_types; var i = index; - inline for (fields) |field| { - wip.extra.items[i] = switch (field.type) { - u32 => @field(extra, field.name), - MessageIndex => @intFromEnum(@field(extra, field.name)), - SourceLocationIndex => @intFromEnum(@field(extra, field.name)), + inline for (field_names, field_types) |field_name, field_type| { + wip.extra.items[i] = switch (field_type) { + u32 => @field(extra, field_name), + MessageIndex => @intFromEnum(@field(extra, field_name)), + SourceLocationIndex => @intFromEnum(@field(extra, field_name)), else => @compileError("bad field type"), }; i += 1; diff --git a/lib/std/zig/LibCInstallation.zig b/lib/std/zig/LibCInstallation.zig index dd45c96407..441ed520db 100644 --- a/lib/std/zig/LibCInstallation.zig +++ b/lib/std/zig/LibCInstallation.zig @@ -43,12 +43,13 @@ pub const FindError = error{ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const std.Target) !LibCInstallation { var self: LibCInstallation = .{}; - const fields = std.meta.fields(LibCInstallation); + const field_names = comptime std.meta.fieldNames(LibCInstallation); const FoundKey = struct { found: bool, allocated: ?[:0]u8, }; - var found_keys: [fields.len]FoundKey = @splat(.{ .found = false, .allocated = null }); + + var found_keys: [field_names.len]FoundKey = @splat(.{ .found = false, .allocated = null }); errdefer { self = .{}; for (found_keys) |found_key| { @@ -65,22 +66,22 @@ pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const var line_it = std.mem.splitScalar(u8, line, '='); const name = line_it.first(); const value = line_it.rest(); - inline for (fields, 0..) |field, i| { - if (std.mem.eql(u8, name, field.name)) { + inline for (field_names, 0..) |field_name, i| { + if (std.mem.eql(u8, name, field_name)) { found_keys[i].found = true; if (value.len == 0) { - @field(self, field.name) = null; + @field(self, field_name) = null; } else { found_keys[i].allocated = try allocator.dupeSentinel(u8, value, 0); - @field(self, field.name) = found_keys[i].allocated; + @field(self, field_name) = found_keys[i].allocated; } break; } } } - inline for (fields, 0..) |field, i| { + inline for (field_names, 0..) |field_name, i| { if (!found_keys[i].found) { - log.err("missing field: {s}", .{field.name}); + log.err("missing field: {s}", .{field_name}); return error.ParseError; } } @@ -235,9 +236,8 @@ pub fn findNative(gpa: Allocator, io: Io, args: FindNativeOptions) FindError!Lib /// Must be the same allocator passed to `parse` or `findNative`. pub fn deinit(self: *LibCInstallation, allocator: Allocator) void { - const fields = std.meta.fields(LibCInstallation); - inline for (fields) |field| { - if (@field(self, field.name)) |payload| { + inline for (@typeInfo(LibCInstallation).@"struct".field_names) |field_name| { + if (@field(self, field_name)) |payload| { allocator.free(payload); } } diff --git a/lib/std/zig/Parse.zig b/lib/std/zig/Parse.zig index 4eae777732..0abbc03abf 100644 --- a/lib/std/zig/Parse.zig +++ b/lib/std/zig/Parse.zig @@ -89,18 +89,18 @@ fn unreserveNode(p: *Parse, node_index: usize) void { } fn addExtra(p: *Parse, extra: anytype) Allocator.Error!ExtraIndex { - const fields = std.meta.fields(@TypeOf(extra)); - try p.extra_data.ensureUnusedCapacity(p.gpa, fields.len); + const info = @typeInfo(@TypeOf(extra)).@"struct"; + try p.extra_data.ensureUnusedCapacity(p.gpa, info.field_names.len); const result: ExtraIndex = @enumFromInt(p.extra_data.items.len); - inline for (fields) |field| { - const data: u32 = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + const data: u32 = switch (field_type) { Node.Index, Node.OptionalIndex, OptionalTokenIndex, ExtraIndex, - => @intFromEnum(@field(extra, field.name)), + => @intFromEnum(@field(extra, field_name)), TokenIndex, - => @field(extra, field.name), + => @field(extra, field_name), else => @compileError("unexpected field type"), }; p.extra_data.appendAssumeCapacity(data); diff --git a/lib/std/zig/Zir.zig b/lib/std/zig/Zir.zig index 245b56c5fb..b649b7aff0 100644 --- a/lib/std/zig/Zir.zig +++ b/lib/std/zig/Zir.zig @@ -68,11 +68,11 @@ fn ExtraData(comptime T: type) type { /// Returns the requested data, as well as the new index which is at the start of the /// trailers for the object. pub fn extraData(code: Zir, comptime T: type, index: usize) ExtraData(T) { - const fields = @typeInfo(T).@"struct".fields; + const info = @typeInfo(T).@"struct"; var i: usize = index; var result: T = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => code.extra[i], Inst.Ref, @@ -1877,7 +1877,7 @@ pub const Inst = struct { // Uncomment to view how many tag slots are available. //comptime { - // @compileLog("ZIR tags left: ", 256 - @typeInfo(Tag).@"enum".fields.len); + // @compileLog("ZIR tags left: ", 256 - @typeInfo(Tag).@"enum".field_names.len); //} }; @@ -2325,7 +2325,7 @@ pub const Inst = struct { _, - pub const static_len = @typeInfo(@This()).@"enum".fields.len - 1; + pub const static_len = @typeInfo(@This()).@"enum".field_names.len - 1; pub fn toIndex(inst: Ref) ?Index { assert(inst != .none); @@ -3186,7 +3186,7 @@ pub const Inst = struct { pub const ReifySliceArgInfo = enum(u16) { /// Input element type is `type`. - /// Output element type is `std.lang.Type.Fn.Param.Attributes`. + /// Output element type is `std.lang.Type.Fn.ParamAttributes`. type_to_fn_param_attrs, /// Input element type is `[]const u8`. /// Output element type is `type`. @@ -3194,10 +3194,10 @@ pub const Inst = struct { /// Identical to `string_to_struct_field_type` aside from emitting slightly different error messages. string_to_union_field_type, /// Input element type is `[]const u8`. - /// Output element type is `std.lang.Type.StructField.Attributes`. + /// Output element type is `std.lang.Type.Struct.FieldAttributes`. string_to_struct_field_attrs, /// Input element type is `[]const u8`. - /// Output element type is `std.lang.Type.UnionField.Attributes`. + /// Output element type is `std.lang.Type.Union.FieldAttributes`. string_to_union_field_attrs, }; @@ -4842,7 +4842,7 @@ pub fn getAssociatedSrcHash(zir: Zir, inst: Zir.Inst.Index) ?std.zig.SrcHash { const extra_index = extra.end + extra.data.ret_ty.body_len + extra.data.body_len + - @typeInfo(Inst.Func.SrcLocs).@"struct".fields.len; + @typeInfo(Inst.Func.SrcLocs).@"struct".field_names.len; return @bitCast([4]u32{ zir.extra[extra_index + 0], zir.extra[extra_index + 1], @@ -4869,7 +4869,7 @@ pub fn getAssociatedSrcHash(zir: Zir, inst: Zir.Inst.Index) ?std.zig.SrcHash { } else extra_index += @intFromBool(bits.has_ret_ty_ref); extra_index += @intFromBool(bits.has_any_noalias); extra_index += extra.data.body_len; - extra_index += @typeInfo(Zir.Inst.Func.SrcLocs).@"struct".fields.len; + extra_index += @typeInfo(Zir.Inst.Func.SrcLocs).@"struct".field_names.len; return @bitCast([4]u32{ zir.extra[extra_index + 0], zir.extra[extra_index + 1], diff --git a/lib/std/zig/c_translation/helpers.zig b/lib/std/zig/c_translation/helpers.zig index e8916ce4be..8dd8f7f45a 100644 --- a/lib/std/zig/c_translation/helpers.zig +++ b/lib/std/zig/c_translation/helpers.zig @@ -199,8 +199,8 @@ pub fn cast(comptime DestType: type, target: anytype) DestType { } }, .@"union" => |info| { - inline for (info.fields) |field| { - if (field.type == SourceType) return @unionInit(DestType, field.name, target); + inline for (info.field_names, info.field_types) |field_name, field_type| { + if (field_type == SourceType) return @unionInit(DestType, field_name, target); } @compileError("cast to union type '" ++ @typeName(DestType) ++ "' from type '" ++ @typeName(SourceType) ++ "' which is not present in union"); diff --git a/lib/std/zig/llvm/BitcodeReader.zig b/lib/std/zig/llvm/BitcodeReader.zig index e32e8afc03..3ed1e0e928 100644 --- a/lib/std/zig/llvm/BitcodeReader.zig +++ b/lib/std/zig/llvm/BitcodeReader.zig @@ -282,7 +282,7 @@ fn startBlock(bc: *BitcodeReader, block_id: ?u32, new_abbrev_len: u6) !void { }; try state.abbrevs.abbrevs.ensureTotalCapacity( bc.allocator, - @typeInfo(Abbrev.Builtin).@"enum".fields.len + abbrevs.len, + @typeInfo(Abbrev.Builtin).@"enum".field_names.len + abbrevs.len, ); assert(state.abbrevs.abbrevs.items.len == @intFromEnum(Abbrev.Builtin.end_block)); @@ -318,7 +318,7 @@ fn startBlock(bc: *BitcodeReader, block_id: ?u32, new_abbrev_len: u6) !void { .{ .encoding = .{ .vbr = 6 } }, // ops }, }); - assert(state.abbrevs.abbrevs.items.len == @typeInfo(Abbrev.Builtin).@"enum".fields.len); + assert(state.abbrevs.abbrevs.items.len == @typeInfo(Abbrev.Builtin).@"enum".field_names.len); for (abbrevs) |abbrev| try state.abbrevs.addAbbrevAssumeCapacity(bc.allocator, abbrev); } @@ -457,7 +457,7 @@ const Abbrev = struct { define_abbrev, unabbrev_record, - const first_record_id: u32 = std.math.maxInt(u32) - @typeInfo(Builtin).@"enum".fields.len + 1; + const first_record_id: u32 = std.math.maxInt(u32) - @typeInfo(Builtin).@"enum".field_names.len + 1; fn toRecordId(builtin: Builtin) u32 { return first_record_id + @intFromEnum(builtin); } diff --git a/lib/std/zig/llvm/Builder.zig b/lib/std/zig/llvm/Builder.zig index f22f395c83..27a1532aab 100644 --- a/lib/std/zig/llvm/Builder.zig +++ b/lib/std/zig/llvm/Builder.zig @@ -1137,21 +1137,22 @@ pub const Attribute = union(Kind) { .no_sanitize_hwaddress, .sanitize_address_dyninit, => |kind| { - const field = comptime blk: { + const field_name, const field_type = comptime blk: { @setEvalBranchQuota(10_000); - for (@typeInfo(Attribute).@"union".fields) |field| { - if (std.mem.eql(u8, field.name, @tagName(kind))) break :blk field; + const info = @typeInfo(Attribute).@"union"; + for (info.field_names, info.field_types) |field_name, field_type| { + if (std.mem.eql(u8, field_name, @tagName(kind))) break :blk .{ field_name, field_type }; } unreachable; }; - comptime assert(std.mem.eql(u8, @tagName(kind), field.name)); - return @unionInit(Attribute, field.name, switch (field.type) { + comptime assert(std.mem.eql(u8, @tagName(kind), field_name)); + return @unionInit(Attribute, field_name, switch (field_type) { void => {}, u32 => storage.value, Alignment.Lazy, String, Type, UwTable => @enumFromInt(storage.value), AllocKind, AllocSize, FpClass, Memory, VScaleRange => @bitCast(storage.value), - else => @compileError("bad payload type: " ++ field.name ++ ": " ++ - @typeName(field.type)), + else => @compileError("bad payload type: " ++ field_name ++ ": " ++ + @typeName(field_type)), }); }, .string, .none => unreachable, @@ -1258,14 +1259,14 @@ pub const Attribute = union(Kind) { try w.print(" {s}(", .{@tagName(attribute)}); var any = false; var remaining: Int = @bitCast(fpclass); - inline for (@typeInfo(FpClass).@"struct".decls) |decl| { - const pattern: Int = @bitCast(@field(FpClass, decl.name)); + inline for (@typeInfo(FpClass).@"struct".decl_names) |decl_name| { + const pattern: Int = @bitCast(@field(FpClass, decl_name)); if (remaining & pattern == pattern) { if (!any) { try w.writeByte(' '); any = true; } - try w.writeAll(decl.name); + try w.writeAll(decl_name); remaining &= ~pattern; } } @@ -1283,14 +1284,14 @@ pub const Attribute = union(Kind) { .allockind => |allockind| { try w.print(" {t}(\"", .{attribute}); var any = false; - inline for (@typeInfo(AllocKind).@"struct".fields) |field| { - if (comptime std.mem.eql(u8, field.name, "_")) continue; - if (@field(allockind, field.name)) { + inline for (@typeInfo(AllocKind).@"struct".field_names) |field_name| { + if (comptime std.mem.eql(u8, field_name, "_")) continue; + if (@field(allockind, field_name)) { if (!any) { try w.writeByte(','); any = true; } - try w.writeAll(field.name); + try w.writeAll(field_name); } } try w.writeAll("\")"); @@ -1442,7 +1443,7 @@ pub const Attribute = union(Kind) { none = maxInt(u32), _, - pub const len = @typeInfo(Kind).@"enum".fields.len - 2; + pub const len = @typeInfo(Kind).@"enum".field_names.len - 2; pub fn fromString(str: String) Kind { assert(!str.isAnon()); @@ -5167,9 +5168,13 @@ pub const Function = struct { index: Instruction.ExtraIndex, ) struct { data: T, trail: ExtraDataTrail } { var result: T = undefined; - const fields = @typeInfo(T).@"struct".fields; - inline for (fields, self.extra[index..][0..fields.len]) |field, value| - @field(result, field.name) = switch (field.type) { + const info = @typeInfo(T).@"struct"; + inline for ( + info.field_names, + info.field_types, + self.extra[index..][0..info.field_names.len], + ) |field_name, field_type, value| + @field(result, field_name) = switch (field_type) { u32 => value, Alignment, AtomicOrdering, @@ -5183,11 +5188,11 @@ pub const Function = struct { Instruction.Alloca.Info, Instruction.Call.Info, => @bitCast(value), - else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ field_name ++ ": " ++ @typeName(field_type)), }; return .{ .data = result, - .trail = .{ .index = index + @as(Type.Item.ExtraIndex, @intCast(fields.len)) }, + .trail = .{ .index = index + @as(Type.Item.ExtraIndex, @intCast(info.field_names.len)) }, }; } @@ -6327,9 +6332,10 @@ pub const WipFunction = struct { fn addExtra(wip_extra: *@This(), extra: anytype) Instruction.ExtraIndex { const result = wip_extra.index; - inline for (@typeInfo(@TypeOf(extra)).@"struct".fields) |field| { - const value = @field(extra, field.name); - wip_extra.items[wip_extra.index] = switch (field.type) { + const info = @typeInfo(@TypeOf(extra)).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + const value = @field(extra, field_name); + wip_extra.items[wip_extra.index] = switch (field_type) { u32 => value, Alignment, AtomicOrdering, @@ -6343,7 +6349,7 @@ pub const WipFunction = struct { Instruction.Alloca.Info, Instruction.Call.Info, => @bitCast(value), - else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ field_name ++ ": " ++ @typeName(field_type)), }; wip_extra.index += 1; } @@ -6944,7 +6950,7 @@ pub const WipFunction = struct { ) Allocator.Error!void { try self.extra.ensureUnusedCapacity( self.builder.gpa, - count * (@typeInfo(Extra).@"struct".fields.len + trail_len), + count * (@typeInfo(Extra).@"struct".field_names.len + trail_len), ); } @@ -6983,9 +6989,10 @@ pub const WipFunction = struct { fn addExtraAssumeCapacity(self: *WipFunction, extra: anytype) Instruction.ExtraIndex { const result: Instruction.ExtraIndex = @intCast(self.extra.items.len); - inline for (@typeInfo(@TypeOf(extra)).@"struct".fields) |field| { - const value = @field(extra, field.name); - self.extra.appendAssumeCapacity(switch (field.type) { + const info = @typeInfo(@TypeOf(extra)).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + const value = @field(extra, field_name); + self.extra.appendAssumeCapacity(switch (field_type) { u32 => value, Alignment, AtomicOrdering, @@ -6999,7 +7006,7 @@ pub const WipFunction = struct { Instruction.Alloca.Info, Instruction.Call.Info, => @bitCast(value), - else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ field_name ++ ": " ++ @typeName(field_type)), }); } return result; @@ -7032,9 +7039,13 @@ pub const WipFunction = struct { index: Instruction.ExtraIndex, ) struct { data: T, trail: ExtraDataTrail } { var result: T = undefined; - const fields = @typeInfo(T).@"struct".fields; - inline for (fields, self.extra.items[index..][0..fields.len]) |field, value| - @field(result, field.name) = switch (field.type) { + const info = @typeInfo(T).@"struct"; + inline for ( + info.field_names, + info.field_types, + self.extra.items[index..][0..info.field_names.len], + ) |field_name, field_type, value| + @field(result, field_name) = switch (field_type) { u32 => value, Alignment, AtomicOrdering, @@ -7048,11 +7059,11 @@ pub const WipFunction = struct { Instruction.Alloca.Info, Instruction.Call.Info, => @bitCast(value), - else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ field_name ++ ": " ++ @typeName(field_type)), }; return .{ .data = result, - .trail = .{ .index = index + @as(Type.Item.ExtraIndex, @intCast(fields.len)) }, + .trail = .{ .index = index + @as(Type.Item.ExtraIndex, @intCast(info.field_names.len)) }, }; } @@ -8202,19 +8213,20 @@ pub const Metadata = packed struct(u32) { pub fn format(self: DIFlags, w: *Writer) Writer.Error!void { var need_pipe = false; - inline for (@typeInfo(DIFlags).@"struct".fields) |field| { - switch (@typeInfo(field.type)) { - .bool => if (@field(self, field.name)) { + const info = @typeInfo(DIFlags).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + switch (@typeInfo(field_type)) { + .bool => if (@field(self, field_name)) { if (need_pipe) try w.writeAll(" | ") else need_pipe = true; - try w.print("DIFlag{s}", .{field.name}); + try w.print("DIFlag{s}", .{field_name}); }, - .@"enum" => if (@field(self, field.name) != .Zero) { + .@"enum" => if (@field(self, field_name) != .Zero) { if (need_pipe) try w.writeAll(" | ") else need_pipe = true; - try w.print("DIFlag{s}", .{@tagName(@field(self, field.name))}); + try w.print("DIFlag{s}", .{@tagName(@field(self, field_name))}); }, - .int => assert(@field(self, field.name) == 0), - else => @compileError("bad field type: " ++ field.name ++ ": " ++ - @typeName(field.type)), + .int => assert(@field(self, field_name) == 0), + else => @compileError("bad field type: " ++ field_name ++ ": " ++ + @typeName(field_type)), } } if (!need_pipe) try w.writeByte('0'); @@ -8259,19 +8271,20 @@ pub const Metadata = packed struct(u32) { pub fn format(self: DISPFlags, w: *Writer) Writer.Error!void { var need_pipe = false; - inline for (@typeInfo(DISPFlags).@"struct".fields) |field| { - switch (@typeInfo(field.type)) { - .bool => if (@field(self, field.name)) { + const info = @typeInfo(DISPFlags).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + switch (@typeInfo(field_type)) { + .bool => if (@field(self, field_name)) { if (need_pipe) try w.writeAll(" | ") else need_pipe = true; - try w.print("DISPFlag{s}", .{field.name}); + try w.print("DISPFlag{s}", .{field_name}); }, - .@"enum" => if (@field(self, field.name) != .Zero) { + .@"enum" => if (@field(self, field_name) != .Zero) { if (need_pipe) try w.writeAll(" | ") else need_pipe = true; - try w.print("DISPFlag{s}", .{@tagName(@field(self, field.name))}); + try w.print("DISPFlag{s}", .{@tagName(@field(self, field_name))}); }, - .int => assert(@field(self, field.name) == 0), - else => @compileError("bad field type: " ++ field.name ++ ": " ++ - @typeName(field.type)), + .int => assert(@field(self, field_name) == 0), + else => @compileError("bad field type: " ++ field_name ++ ": " ++ + @typeName(field_type)), } } if (!need_pipe) try w.writeByte('0'); @@ -8567,7 +8580,7 @@ pub const Metadata = packed struct(u32) { })) |some| switch (@typeInfo(Some)) { .@"enum" => |enum_info| switch (Some) { Metadata.String => .{ .string = some }, - else => if (enum_info.is_exhaustive) + else => if (enum_info.mode == .exhaustive) .{ .raw = @tagName(some) } else @compileError("unknown type to format: " ++ @typeName(Node)), @@ -8763,14 +8776,15 @@ pub fn init(options: Options) Allocator.Error!Builder { } { - const static_len = @typeInfo(Type).@"enum".fields.len - 1; + const static_len = @typeInfo(Type).@"enum".field_names.len - 1; try self.type_map.ensureTotalCapacity(self.gpa, static_len); try self.type_items.ensureTotalCapacity(self.gpa, static_len); - inline for (@typeInfo(Type.Simple).@"enum".fields) |simple_field| { + const info = @typeInfo(Type.Simple).@"enum"; + inline for (info.field_names, info.field_values) |simple_field_name, simple_field_value| { const result = self.getOrPutTypeNoExtraAssumeCapacity( - .{ .tag = .simple, .data = simple_field.value }, + .{ .tag = .simple, .data = simple_field_value }, ); - assert(result.new and result.type == @field(Type, simple_field.name)); + assert(result.new and result.type == @field(Type, simple_field_name)); } inline for (.{ 1, 8, 16, 29, 32, 64, 80, 128 }) |bits| assert(self.intTypeAssumeCapacity(bits) == @@ -11016,7 +11030,7 @@ fn ensureUnusedTypeCapacity( try self.type_items.ensureUnusedCapacity(self.gpa, count); try self.type_extra.ensureUnusedCapacity( self.gpa, - count * (@typeInfo(Extra).@"struct".fields.len + trail_len), + count * (@typeInfo(Extra).@"struct".field_names.len + trail_len), ); } @@ -11046,12 +11060,13 @@ fn getOrPutTypeNoExtraAssumeCapacity(self: *Builder, item: Type.Item) struct { n fn addTypeExtraAssumeCapacity(self: *Builder, extra: anytype) Type.Item.ExtraIndex { const result: Type.Item.ExtraIndex = @intCast(self.type_extra.items.len); - inline for (@typeInfo(@TypeOf(extra)).@"struct".fields) |field| { - const value = @field(extra, field.name); - self.type_extra.appendAssumeCapacity(switch (field.type) { + const info = @typeInfo(@TypeOf(extra)).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + const value = @field(extra, field_name); + self.type_extra.appendAssumeCapacity(switch (field_type) { u32 => value, String, Type => @intFromEnum(value), - else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ field_name ++ ": " ++ @typeName(field_type)), }); } return result; @@ -11084,16 +11099,20 @@ fn typeExtraDataTrail( index: Type.Item.ExtraIndex, ) struct { data: T, trail: TypeExtraDataTrail } { var result: T = undefined; - const fields = @typeInfo(T).@"struct".fields; - inline for (fields, self.type_extra.items[index..][0..fields.len]) |field, value| - @field(result, field.name) = switch (field.type) { + const info = @typeInfo(T).@"struct"; + inline for ( + info.field_names, + info.field_types, + self.type_extra.items[index..][0..info.field_names.len], + ) |field_name, field_type, value| + @field(result, field_name) = switch (field_type) { u32 => value, String, Type => @enumFromInt(value), - else => @compileError("bad field type: " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ @typeName(field_type)), }; return .{ .data = result, - .trail = .{ .index = index + @as(Type.Item.ExtraIndex, @intCast(fields.len)) }, + .trail = .{ .index = index + @as(Type.Item.ExtraIndex, @intCast(info.field_names.len)) }, }; } @@ -11899,7 +11918,7 @@ fn ensureUnusedConstantCapacity( try self.constant_items.ensureUnusedCapacity(self.gpa, count); try self.constant_extra.ensureUnusedCapacity( self.gpa, - count * (@typeInfo(Extra).@"struct".fields.len + trail_len), + count * (@typeInfo(Extra).@"struct".field_names.len + trail_len), ); } @@ -11974,13 +11993,14 @@ fn getOrPutConstantAggregateAssumeCapacity( fn addConstantExtraAssumeCapacity(self: *Builder, extra: anytype) Constant.Item.ExtraIndex { const result: Constant.Item.ExtraIndex = @intCast(self.constant_extra.items.len); - inline for (@typeInfo(@TypeOf(extra)).@"struct".fields) |field| { - const value = @field(extra, field.name); - self.constant_extra.appendAssumeCapacity(switch (field.type) { + const info = @typeInfo(@TypeOf(extra)).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + const value = @field(extra, field_name); + self.constant_extra.appendAssumeCapacity(switch (field_type) { u32 => value, String, Type, Constant, Function.Index, Function.Block.Index => @intFromEnum(value), Constant.GetElementPtr.Info => @bitCast(value), - else => @compileError("bad field type: " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ @typeName(field_type)), }); } return result; @@ -12013,17 +12033,21 @@ fn constantExtraDataTrail( index: Constant.Item.ExtraIndex, ) struct { data: T, trail: ConstantExtraDataTrail } { var result: T = undefined; - const fields = @typeInfo(T).@"struct".fields; - inline for (fields, self.constant_extra.items[index..][0..fields.len]) |field, value| - @field(result, field.name) = switch (field.type) { + const info = @typeInfo(T).@"struct"; + inline for ( + info.field_names, + info.field_types, + self.constant_extra.items[index..][0..info.field_names.len], + ) |field_name, field_type, value| + @field(result, field_name) = switch (field_type) { u32 => value, String, Type, Constant, Function.Index, Function.Block.Index => @enumFromInt(value), Constant.GetElementPtr.Info => @bitCast(value), - else => @compileError("bad field type: " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ @typeName(field_type)), }; return .{ .data = result, - .trail = .{ .index = index + @as(Constant.Item.ExtraIndex, @intCast(fields.len)) }, + .trail = .{ .index = index + @as(Constant.Item.ExtraIndex, @intCast(info.field_names.len)) }, }; } @@ -12041,19 +12065,20 @@ fn ensureUnusedMetadataCapacity( try self.metadata_items.ensureUnusedCapacity(self.gpa, count); try self.metadata_extra.ensureUnusedCapacity( self.gpa, - count * (@typeInfo(Extra).@"struct".fields.len + trail_len), + count * (@typeInfo(Extra).@"struct".field_names.len + trail_len), ); } fn addMetadataExtraAssumeCapacity(self: *Builder, extra: anytype) Metadata.Item.ExtraIndex { const result: Metadata.Item.ExtraIndex = @intCast(self.metadata_extra.items.len); - inline for (@typeInfo(@TypeOf(extra)).@"struct".fields) |field| { - const value = @field(extra, field.name); - self.metadata_extra.appendAssumeCapacity(switch (field.type) { + const info = @typeInfo(@TypeOf(extra)).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + const value = @field(extra, field_name); + self.metadata_extra.appendAssumeCapacity(switch (field_type) { u32 => value, Metadata.String, Metadata.String.Optional, Variable.Index, Value => @intFromEnum(value), Metadata, Metadata.Optional, Metadata.DIFlags => @bitCast(value), - else => @compileError("bad field type: " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ @typeName(field_type)), }); } return result; @@ -12086,17 +12111,21 @@ fn metadataExtraDataTrail( index: Metadata.Item.ExtraIndex, ) struct { data: T, trail: MetadataExtraDataTrail } { var result: T = undefined; - const fields = @typeInfo(T).@"struct".fields; - inline for (fields, self.metadata_extra.items[index..][0..fields.len]) |field, value| - @field(result, field.name) = switch (field.type) { + const info = @typeInfo(T).@"struct"; + inline for ( + info.field_names, + info.field_types, + self.metadata_extra.items[index..][0..info.field_names.len], + ) |field_name, field_type, value| + @field(result, field_name) = switch (field_type) { u32 => value, Metadata.String, Metadata.String.Optional, Variable.Index, Value => @enumFromInt(value), Metadata, Metadata.Optional, Metadata.DIFlags => @bitCast(value), - else => @compileError("bad field type: " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ @typeName(field_type)), }; return .{ .data = result, - .trail = .{ .index = index + @as(Metadata.Item.ExtraIndex, @intCast(fields.len)) }, + .trail = .{ .index = index + @as(Metadata.Item.ExtraIndex, @intCast(info.field_names.len)) }, }; } @@ -12602,8 +12631,8 @@ fn metadataSimpleAssumeCapacity(self: *Builder, tag: Metadata.Tag, value: anytyp builder: *const Builder, pub fn hash(_: @This(), key: Key) u32 { var hasher = std.hash.Wyhash.init(std.hash.int(@intFromEnum(key.tag))); - inline for (std.meta.fields(@TypeOf(value))) |field| { - hasher.update(std.mem.asBytes(&@field(key.value, field.name))); + inline for (comptime std.meta.fieldNames(@TypeOf(value))) |field_name| { + hasher.update(std.mem.asBytes(&@field(key.value, field_name))); } return @truncate(hasher.final()); } @@ -14184,12 +14213,14 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco const MetadataKindBlock = ir.ModuleBlock.MetadataKindBlock; var metadata_kind_block = try module_block.enterSubBlock(MetadataKindBlock, true); - inline for (@typeInfo(ir.FixedMetadataKind).@"enum".fields) |field| { + const info = @typeInfo(ir.FixedMetadataKind).@"enum"; + + inline for (info.field_names, info.field_values) |field_name, field_value| { // don't include `dbg` in stripped functions - if (!(self.strip and std.mem.eql(u8, field.name, "dbg"))) { + if (!(self.strip and std.mem.eql(u8, field_name, "dbg"))) { try metadata_kind_block.writeAbbrev(MetadataKindBlock.Kind{ - .id = field.value, - .name = field.name, + .id = field_value, + .name = field_name, }); } } diff --git a/lib/std/zig/llvm/bitcode_writer.zig b/lib/std/zig/llvm/bitcode_writer.zig index 4fdfb630b9..b0f24065b9 100644 --- a/lib/std/zig/llvm/bitcode_writer.zig +++ b/lib/std/zig/llvm/bitcode_writer.zig @@ -246,14 +246,14 @@ pub fn BitcodeWriter(comptime types: []const type) type { try self.bitcode.writeBits(comptime abbrevId(Abbrev), abbrev_len); - const fields = std.meta.fields(Abbrev); + const field_names = comptime std.meta.fieldNames(Abbrev); // This abbreviation might only contain literals - if (fields.len == 0) return; + if (field_names.len == 0) return; comptime var field_index: usize = 0; inline for (Abbrev.ops) |ty| { - const param = @field(params, fields[field_index].name); + const param = @field(params, field_names[field_index]); switch (ty) { .literal => continue, .fixed => |len| try self.bitcode.writeBits(adapter.get(param), len), @@ -296,7 +296,7 @@ pub fn BitcodeWriter(comptime types: []const type) type { }, } field_index += 1; - if (field_index == fields.len) break; + if (field_index == field_names.len) break; } } diff --git a/lib/std/zig/system.zig b/lib/std/zig/system.zig index 9d47215a99..00baeb24e1 100644 --- a/lib/std/zig/system.zig +++ b/lib/std/zig/system.zig @@ -973,10 +973,10 @@ fn detectAbiAndDynamicLinker(io: Io, cpu: Target.Cpu, os: Target.Os, query: Targ // relying on `builtin.target`. const all_abis = comptime blk: { assert(@intFromEnum(Target.Abi.none) == 0); - const fields = std.meta.fields(Target.Abi)[1..]; - var array: [fields.len]Target.Abi = undefined; - for (fields, 0..) |field, i| { - array[i] = @field(Target.Abi, field.name); + const field_names = std.meta.fieldNames(Target.Abi)[1..]; + var array: [field_names.len]Target.Abi = undefined; + for (field_names, 0..) |field_name, i| { + array[i] = @field(Target.Abi, field_name); } break :blk array; }; diff --git a/lib/std/zig/system/windows.zig b/lib/std/zig/system/windows.zig index 70cfaed4d3..0e9b8ec1d7 100644 --- a/lib/std/zig/system/windows.zig +++ b/lib/std/zig/system/windows.zig @@ -60,14 +60,14 @@ fn getCpuInfoFromRegistry(core: usize, args: anytype) !void { @compileError("expected tuple or struct argument, found " ++ @typeName(ArgsType)); } - const fields_info = args_type_info.@"struct".fields; + const fields_info = args_type_info.@"struct"; // Originally, I wanted to issue a single call with a more complex table structure such that we // would sequentially visit each CPU#d subkey in the registry and pull the value of interest into // a buffer, however, NT seems to be expecting a single buffer per each table meaning we would // end up pulling only the last CPU core info, overwriting everything else. // If anyone can come up with a solution to this, please do! - const table_size = 1 + fields_info.len; + const table_size = 1 + fields_info.field_names.len; var table: [table_size + 1]std.os.windows.RTL_QUERY_REGISTRY_TABLE = undefined; const topkey = std.unicode.utf8ToUtf16LeStringLiteral("\\Registry\\Machine\\HARDWARE\\DESCRIPTION\\System\\CentralProcessor"); @@ -90,11 +90,11 @@ fn getCpuInfoFromRegistry(core: usize, args: anytype) !void { .DefaultLength = 0, }; - var tmp_bufs: [fields_info.len][max_value_len]u8 align(@alignOf(std.os.windows.UNICODE_STRING)) = undefined; + var tmp_bufs: [fields_info.field_names.len][max_value_len]u8 align(@alignOf(std.os.windows.UNICODE_STRING)) = undefined; - inline for (fields_info, 0..) |field, i| { + inline for (fields_info.field_names, 0..) |field_name, i| { const ctx: *anyopaque = blk: { - switch (@field(args, field.name).value_type) { + switch (@field(args, field_name).value_type) { .SZ, .EXPAND_SZ, .MULTI_SZ, @@ -119,7 +119,7 @@ fn getCpuInfoFromRegistry(core: usize, args: anytype) !void { }; var key_buf: [max_value_len / 2 + 1]u16 = undefined; - const key_len = try std.unicode.utf8ToUtf16Le(&key_buf, @field(args, field.name).key); + const key_len = try std.unicode.utf8ToUtf16Le(&key_buf, @field(args, field_name).key); key_buf[key_len] = 0; table[i + 1] = .{ @@ -153,12 +153,12 @@ fn getCpuInfoFromRegistry(core: usize, args: anytype) !void { ); switch (res) { .SUCCESS => { - inline for (fields_info, 0..) |field, i| switch (@field(args, field.name).value_type) { + inline for (fields_info.field_names, 0..) |field_name, i| switch (@field(args, field_name).value_type) { .SZ, .EXPAND_SZ, .MULTI_SZ, => { - var buf = @field(args, field.name).value_buf; + var buf = @field(args, field_name).value_buf; const entry: *const std.os.windows.UNICODE_STRING = @ptrCast(table[i + 1].EntryContext); const len = try std.unicode.utf16LeToUtf8(buf, entry.slice()); buf[len] = 0; @@ -169,12 +169,12 @@ fn getCpuInfoFromRegistry(core: usize, args: anytype) !void { .QWORD, => { const entry: [*]const u8 = @ptrCast(table[i + 1].EntryContext); - switch (@field(args, field.name).value_type) { + switch (@field(args, field_name).value_type) { .DWORD, .DWORD_BIG_ENDIAN => { - @memcpy(@field(args, field.name).value_buf[0..4], entry[0..4]); + @memcpy(@field(args, field_name).value_buf[0..4], entry[0..4]); }, .QWORD => { - @memcpy(@field(args, field.name).value_buf[0..8], entry[0..8]); + @memcpy(@field(args, field_name).value_buf[0..8], entry[0..8]); }, else => unreachable, } diff --git a/lib/std/zon/Serializer.zig b/lib/std/zon/Serializer.zig index 9839129e31..c9809e3083 100644 --- a/lib/std/zon/Serializer.zig +++ b/lib/std/zon/Serializer.zig @@ -165,7 +165,7 @@ pub fn valueArbitraryDepth(self: *Serializer, val: anytype, options: ValueOption }, .@"struct" => |@"struct"| if (@"struct".is_tuple) { var container = try self.beginTuple( - .{ .whitespace_style = .{ .fields = @"struct".fields.len } }, + .{ .whitespace_style = .{ .fields = @"struct".field_names.len } }, ); inline for (val) |field_value| { try container.fieldArbitraryDepth(field_value, options); @@ -173,15 +173,20 @@ pub fn valueArbitraryDepth(self: *Serializer, val: anytype, options: ValueOption try container.end(); } else { // Decide which fields to emit - const fields, const skipped: [@"struct".fields.len]bool = if (options.emit_default_optional_fields) b: { - break :b .{ @"struct".fields.len, @splat(false) }; + const fields, const skipped: [@"struct".field_names.len]bool = if (options.emit_default_optional_fields) b: { + break :b .{ @"struct".field_names.len, @splat(false) }; } else b: { - var fields = @"struct".fields.len; - var skipped: [@"struct".fields.len]bool = @splat(false); - inline for (@"struct".fields, &skipped) |field_info, *skip| { - if (field_info.default_value_ptr) |ptr| { - const default: *const field_info.type = @ptrCast(@alignCast(ptr)); - const field_value = @field(val, field_info.name); + var fields = @"struct".field_names.len; + var skipped: [@"struct".field_names.len]bool = @splat(false); + inline for ( + @"struct".field_names, + @"struct".field_types, + @"struct".field_attrs, + &skipped, + ) |field_name, field_type, field_attrs, *skip| { + if (field_attrs.default_value_ptr) |ptr| { + const default: *const field_type = @ptrCast(@alignCast(ptr)); + const field_value = @field(val, field_name); if (std.meta.eql(field_value, default.*)) { skip.* = true; fields -= 1; @@ -195,11 +200,11 @@ pub fn valueArbitraryDepth(self: *Serializer, val: anytype, options: ValueOption var container = try self.beginStruct( .{ .whitespace_style = .{ .fields = fields } }, ); - inline for (@"struct".fields, skipped) |field_info, skip| { + inline for (@"struct".field_names, skipped) |field_name, skip| { if (!skip) { try container.fieldArbitraryDepth( - field_info.name, - @field(val, field_info.name), + field_name, + @field(val, field_name), options, ); } @@ -713,11 +718,11 @@ fn typeIsRecursiveInner(comptime T: type, comptime prev_visited: []const type) b .optional => |optional| typeIsRecursiveInner(optional.child, visited), .array => |array| typeIsRecursiveInner(array.child, visited), .vector => |vector| typeIsRecursiveInner(vector.child, visited), - .@"struct" => |@"struct"| for (@"struct".fields) |field| { - if (typeIsRecursiveInner(field.type, visited)) break true; + .@"struct" => |@"struct"| for (@"struct".field_types) |field_type| { + if (typeIsRecursiveInner(field_type, visited)) break true; } else false, - .@"union" => |@"union"| inline for (@"union".fields) |field| { - if (typeIsRecursiveInner(field.type, visited)) break true; + .@"union" => |@"union"| inline for (@"union".field_types) |field_type| { + if (typeIsRecursiveInner(field_type, visited)) break true; } else false, else => false, }; @@ -761,8 +766,8 @@ fn checkValueDepth(val: anytype, depth: usize) error{ExceededMaxDepth}!void { .array => for (val) |item| { try checkValueDepth(item, child_depth); }, - .@"struct" => |@"struct"| inline for (@"struct".fields) |field_info| { - try checkValueDepth(@field(val, field_info.name), child_depth); + .@"struct" => |@"struct"| inline for (@"struct".field_names) |field_name| { + try checkValueDepth(@field(val, field_name), child_depth); }, .@"union" => |@"union"| if (@"union".tag_type == null) { return; @@ -851,7 +856,7 @@ fn canSerializeTypeInner( .@"opaque", => false, - .@"enum" => |@"enum"| @"enum".is_exhaustive, + .@"enum" => |@"enum"| @"enum".mode == .exhaustive, .pointer => |pointer| switch (pointer.size) { .one => canSerializeTypeInner(pointer.child, visited, parent_is_optional), @@ -870,8 +875,8 @@ fn canSerializeTypeInner( .@"struct" => |@"struct"| { for (visited) |V| if (T == V) return true; const new_visited = visited ++ .{T}; - for (@"struct".fields) |field| { - if (!canSerializeTypeInner(field.type, new_visited, false)) return false; + for (@"struct".field_types) |field_type| { + if (!canSerializeTypeInner(field_type, new_visited, false)) return false; } return true; }, @@ -879,8 +884,8 @@ fn canSerializeTypeInner( for (visited) |V| if (T == V) return true; const new_visited = visited ++ .{T}; if (@"union".tag_type == null) return false; - for (@"union".fields) |field| { - if (field.type != void and !canSerializeTypeInner(field.type, new_visited, false)) { + for (@"union".field_types) |field_type| { + if (field_type != void and !canSerializeTypeInner(field_type, new_visited, false)) { return false; } } diff --git a/lib/std/zon/parse.zig b/lib/std/zon/parse.zig index 4ae46ccb01..f804dad9d8 100644 --- a/lib/std/zon/parse.zig +++ b/lib/std/zon/parse.zig @@ -437,8 +437,8 @@ pub fn free(gpa: Allocator, value: anytype) void { const array: [vector.len]vector.child = value; freeArray(gpa, @TypeOf(array), &array); }, - .@"struct" => |@"struct"| inline for (@"struct".fields) |field| { - free(gpa, @field(value, field.name)); + .@"struct" => |@"struct"| inline for (@"struct".field_names) |field_name| { + free(gpa, @field(value, field_name)); }, .@"union" => |@"union"| if (@"union".tag_type == null) { if (comptime requiresAllocator(Value)) unreachable; @@ -464,13 +464,13 @@ fn requiresAllocator(T: type) bool { return switch (@typeInfo(T)) { .pointer => true, .array => |array| return array.len > 0 and requiresAllocator(array.child), - .@"struct" => |@"struct"| inline for (@"struct".fields) |field| { - if (requiresAllocator(field.type)) { + .@"struct" => |@"struct"| inline for (@"struct".field_types) |field_type| { + if (requiresAllocator(field_type)) { break true; } } else false, - .@"union" => |@"union"| inline for (@"union".fields) |field| { - if (requiresAllocator(field.type)) { + .@"union" => |@"union"| inline for (@"union".field_types) |field_type| { + if (requiresAllocator(field_type)) { break true; } } else false, @@ -589,9 +589,9 @@ const Parser = struct { .one => return self.failExpectedTypeInner(pointer.child, opt, node), .slice => { if (pointer.child == u8 and - pointer.is_const and + pointer.attrs.@"const" and (pointer.sentinel() == null or pointer.sentinel() == 0) and - (pointer.alignment == null or pointer.alignment == 1)) + (pointer.attrs.@"align" == null or pointer.attrs.@"align" == 1)) { if (opt) { return self.failNode(node, "expected optional string"); @@ -669,10 +669,10 @@ const Parser = struct { switch (node.get(self.zoir)) { .enum_literal => |field_name| { // Create a comptime string map for the enum fields - const enum_fields = @typeInfo(T).@"enum".fields; - comptime var kvs_list: [enum_fields.len]struct { []const u8, T } = undefined; - inline for (enum_fields, 0..) |field, i| { - kvs_list[i] = .{ field.name, @enumFromInt(field.value) }; + const enum_info = @typeInfo(T).@"enum"; + comptime var kvs_list: [enum_info.field_names.len]struct { []const u8, T } = undefined; + inline for (enum_info.field_names, enum_info.field_values, 0..) |enum_field_name, enum_field_value, i| { + kvs_list[i] = .{ enum_field_name, @enumFromInt(enum_field_value) }; } const enum_tags = std.StaticStringMap(T).initComptime(kvs_list); @@ -715,9 +715,9 @@ const Parser = struct { if (pointer.child != u8 or pointer.size != .slice or - !pointer.is_const or + !pointer.attrs.@"const" or (pointer.sentinel() != null and pointer.sentinel() != 0) or - (pointer.alignment != null and pointer.alignment != 1)) + (pointer.attrs.@"align" != null and pointer.attrs.@"align" != 1)) { return error.WrongType; } @@ -742,7 +742,7 @@ const Parser = struct { const slice = try self.gpa.allocWithOptions( pointer.child, nodes.len, - .fromByteUnitsOptional(pointer.alignment), + .fromByteUnitsOptional(pointer.attrs.@"align"), pointer.sentinel(), ); errdefer self.gpa.free(slice); @@ -808,30 +808,30 @@ const Parser = struct { else => return error.WrongType, }; - const field_infos = @typeInfo(T).@"struct".fields; + const info = @typeInfo(T).@"struct"; // Build a map from field name to index. // The special value `comptime_field` indicates that this is actually a comptime field. const comptime_field = std.math.maxInt(usize); const field_indices: std.StaticStringMap(usize) = comptime b: { - var kvs_list: [field_infos.len]struct { []const u8, usize } = undefined; - for (&kvs_list, field_infos, 0..) |*kv, field, i| { - kv.* = .{ field.name, if (field.is_comptime) comptime_field else i }; + var kvs_list: [info.field_names.len]struct { []const u8, usize } = undefined; + for (&kvs_list, info.field_names, info.field_attrs, 0..) |*kv, field_name, field_attrs, i| { + kv.* = .{ field_name, if (field_attrs.@"comptime") comptime_field else i }; } break :b .initComptime(kvs_list); }; // Parse the struct var result: T = undefined; - var field_found: [field_infos.len]bool = @splat(false); + var field_found: [info.field_names.len]bool = @splat(false); // If we fail partway through, free all already initialized fields var initialized: usize = 0; - errdefer if (self.options.free_on_error and field_infos.len > 0) { + errdefer if (self.options.free_on_error and info.field_names.len > 0) { for (fields.names[0..initialized]) |name_runtime| { switch (field_indices.get(name_runtime.get(self.zoir)) orelse continue) { - inline 0...(field_infos.len - 1) => |name_index| { - const name = field_infos[name_index].name; + inline 0...(info.field_names.len - 1) => |name_index| { + const name = info.field_names[name_index]; free(self.gpa, @field(result, name)); }, else => unreachable, // Can't be out of bounds @@ -856,11 +856,11 @@ const Parser = struct { field_found[field_index] = true; switch (field_index) { - inline 0...(field_infos.len - 1) => |j| { - if (field_infos[j].is_comptime) unreachable; + inline 0...(info.field_names.len - 1) => |j| { + if (info.field_attrs[j].@"comptime") unreachable; - @field(result, field_infos[j].name) = try self.parseExpr( - field_infos[j].type, + @field(result, info.field_names[j]) = try self.parseExpr( + info.field_types[j], fields.vals.at(@intCast(i)), ); }, @@ -873,15 +873,14 @@ const Parser = struct { // Fill in any missing default fields inline for (field_found, 0..) |found, i| { if (!found) { - const field_info = field_infos[i]; - if (field_info.default_value_ptr) |default| { - const typed: *const field_info.type = @ptrCast(@alignCast(default)); - @field(result, field_info.name) = typed.*; + const field_attrs = info.field_attrs[i]; + if (field_attrs.defaultValue(info.field_types[i])) |default| { + @field(result, info.field_names[i]) = default; } else { return self.failNodeFmt( node, "missing required field {s}", - .{field_infos[i].name}, + .{info.field_names[i]}, ); } } @@ -898,22 +897,21 @@ const Parser = struct { }; var result: T = undefined; - const field_infos = @typeInfo(T).@"struct".fields; + const info = @typeInfo(T).@"struct"; - if (nodes.len > field_infos.len) { + if (nodes.len > info.field_names.len) { return self.failNodeFmt( - nodes.at(field_infos.len), + nodes.at(info.field_names.len), "index {} outside of tuple length {}", - .{ field_infos.len, field_infos.len }, + .{ info.field_names.len, info.field_names.len }, ); } - inline for (0..field_infos.len) |i| { + inline for (0..info.field_names.len) |i| { // Check if we're out of bounds if (i >= nodes.len) { - if (field_infos[i].default_value_ptr) |default| { - const typed: *const field_infos[i].type = @ptrCast(@alignCast(default)); - @field(result, field_infos[i].name) = typed.*; + if (info.field_attrs[i].defaultValue(info.field_types[i])) |default| { + @field(result, info.field_names[i]) = default; } else { return self.failNodeFmt(node, "missing tuple field with index {}", .{i}); } @@ -926,10 +924,10 @@ const Parser = struct { } }; - if (field_infos[i].is_comptime) { + if (info.field_attrs[i].@"comptime") { return self.failComptimeField(node, i); } else { - result[i] = try self.parseExpr(field_infos[i].type, nodes.at(i)); + result[i] = try self.parseExpr(info.field_types[i], nodes.at(i)); } } } @@ -939,15 +937,14 @@ const Parser = struct { fn parseUnion(self: *@This(), T: type, node: Zoir.Node.Index) !T { const @"union" = @typeInfo(T).@"union"; - const field_infos = @"union".fields; - if (field_infos.len == 0) comptime unreachable; + if (@"union".field_names.len == 0) comptime unreachable; // Gather info on the fields const field_indices = b: { - comptime var kvs_list: [field_infos.len]struct { []const u8, usize } = undefined; - inline for (field_infos, 0..) |field, i| { - kvs_list[i] = .{ field.name, i }; + comptime var kvs_list: [@"union".field_names.len]struct { []const u8, usize } = undefined; + inline for (@"union".field_names, 0..) |field_name, i| { + kvs_list[i] = .{ field_name, i }; } break :b std.StaticStringMap(usize).initComptime(kvs_list); }; @@ -970,13 +967,13 @@ const Parser = struct { // Initialize the union from the given field. switch (field_index) { - inline 0...field_infos.len - 1 => |i| { + inline 0...@"union".field_names.len - 1 => |i| { // Fail if the field is not void - if (field_infos[i].type != void) + if (@"union".field_types[i] != void) return self.failNode(node, "expected union"); // Instantiate the union - return @unionInit(T, field_infos[i].name, {}); + return @unionInit(T, @"union".field_names[i], {}); }, else => unreachable, // Can't be out of bounds } @@ -994,12 +991,12 @@ const Parser = struct { return self.failUnexpected(T, "field", node, 0, field_name_str); switch (field_index) { - inline 0...field_infos.len - 1 => |i| { - if (field_infos[i].type == void) { + inline 0...@"union".field_names.len - 1 => |i| { + if (@"union".field_types[i] == void) { return self.failNode(field_val, "expected type 'void'"); } else { - const value = try self.parseExpr(field_infos[i].type, field_val); - return @unionInit(T, field_infos[i].name, value); + const value = try self.parseExpr(@"union".field_types[i], field_val); + return @unionInit(T, @"union".field_names[i], value); } }, else => unreachable, // Can't be out of bounds @@ -1106,7 +1103,7 @@ const Parser = struct { } else self.ast.nodeMainToken(node.getAstNode(self.zoir)); switch (@typeInfo(T)) { inline .@"struct", .@"union", .@"enum" => |info| { - const note: Error.TypeCheckFailure.Note = if (info.fields.len == 0) b: { + const note: Error.TypeCheckFailure.Note = if (info.field_names.len == 0) b: { break :b .{ .token = token, .offset = 0, @@ -1118,9 +1115,9 @@ const Parser = struct { var buf: std.ArrayList(u8) = try .initCapacity(gpa, 64); defer buf.deinit(gpa); try buf.appendSlice(gpa, msg); - inline for (info.fields, 0..) |field_info, i| { + inline for (info.field_names, 0..) |field_name, i| { if (i != 0) try buf.appendSlice(gpa, ", "); - try buf.print(gpa, "'{f}'", .{std.zig.fmtIdFlags(field_info.name, .{ + try buf.print(gpa, "'{f}'", .{std.zig.fmtIdFlags(field_name, .{ .allow_primitive = true, .allow_underscore = true, })}); @@ -1236,8 +1233,8 @@ fn canParseTypeInner( .@"struct" => |@"struct"| { for (visited) |V| if (T == V) return true; const new_visited = visited ++ .{T}; - for (@"struct".fields) |field| { - if (!field.is_comptime and !canParseTypeInner(field.type, new_visited, false)) { + for (@"struct".field_types, @"struct".field_attrs) |field_type, field_attrs| { + if (!field_attrs.@"comptime" and !canParseTypeInner(field_type, new_visited, false)) { return false; } } @@ -1246,8 +1243,8 @@ fn canParseTypeInner( .@"union" => |@"union"| { for (visited) |V| if (T == V) return true; const new_visited = visited ++ .{T}; - for (@"union".fields) |field| { - if (field.type != void and !canParseTypeInner(field.type, new_visited, false)) { + for (@"union".field_types) |field_type| { + if (field_type != void and !canParseTypeInner(field_type, new_visited, false)) { return false; } } diff --git a/src/Air.zig b/src/Air.zig index 5eb1314f6c..fd551de1a5 100644 --- a/src/Air.zig +++ b/src/Air.zig @@ -1805,15 +1805,15 @@ pub fn typeOfIndex(air: *const Air, inst: Air.Inst.Index, ip: *const InternPool) /// Returns the requested data, as well as the new index which is at the start of the /// trailers for the object. pub fn extraData(air: Air, comptime T: type, index: usize) struct { data: T, end: usize } { - const fields = std.meta.fields(T); + const info = @typeInfo(T).@"struct"; var i: usize = index; var result: T = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => air.extra.items[i], InternPool.Index, Inst.Ref => @enumFromInt(air.extra.items[i]), i32, CondBr.BranchHints, Asm.Flags => @bitCast(air.extra.items[i]), - else => @compileError("bad field type: " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ @typeName(field_type)), }; i += 1; } diff --git a/src/Air/Legalize.zig b/src/Air/Legalize.zig index 23956038f8..5b9c4031a9 100644 --- a/src/Air/Legalize.zig +++ b/src/Air/Legalize.zig @@ -2635,7 +2635,7 @@ const Block = struct { .data = .{ .legalize_compiler_rt_call = .{ .func = func, .payload = payload: { - const extra_len = @typeInfo(Air.Call).@"struct".fields.len + args.len; + const extra_len = @typeInfo(Air.Call).@"struct".field_names.len + args.len; try l.air_extra.ensureUnusedCapacity(l.pt.zcu.gpa, extra_len); const index = l.addExtra(Air.Call, .{ .args_len = @intCast(args.len) }) catch unreachable; l.air_extra.appendSliceAssumeCapacity(@ptrCast(args)); @@ -2913,12 +2913,12 @@ fn addInstAssumeCapacity(l: *Legalize, inst: Air.Inst) Air.Inst.Index { } fn addExtra(l: *Legalize, comptime Extra: type, extra: Extra) Error!u32 { - const extra_fields = @typeInfo(Extra).@"struct".fields; - try l.air_extra.ensureUnusedCapacity(l.pt.zcu.gpa, extra_fields.len); - defer inline for (extra_fields) |field| l.air_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), - Air.Inst.Ref => @intFromEnum(@field(extra, field.name)), - else => @compileError(@typeName(field.type)), + const extra_info = @typeInfo(Extra).@"struct"; + try l.air_extra.ensureUnusedCapacity(l.pt.zcu.gpa, extra_info.field_names.len); + defer inline for (extra_info.field_names, extra_info.field_types) |field_name, field_type| l.air_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), + Air.Inst.Ref => @intFromEnum(@field(extra, field_name)), + else => @compileError(@typeName(field_type)), }); return @intCast(l.air_extra.items.len); } @@ -2954,7 +2954,7 @@ fn compilerRtCall( const func_ret_ty = func.returnType(); if (func_ret_ty.toIntern() == result_ty.toIntern()) { - try l.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).@"struct".fields.len + args.len); + try l.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).@"struct".field_names.len + args.len); const payload = l.addExtra(Air.Call, .{ .args_len = @intCast(args.len) }) catch unreachable; l.air_extra.appendSliceAssumeCapacity(@ptrCast(args)); return l.replaceInst(orig_inst, .legalize_compiler_rt_call, .{ .legalize_compiler_rt_call = .{ diff --git a/src/Air/Liveness.zig b/src/Air/Liveness.zig index 0178a2244a..cc0b4803b6 100644 --- a/src/Air/Liveness.zig +++ b/src/Air/Liveness.zig @@ -351,17 +351,17 @@ const Analysis = struct { extra: std.ArrayList(u32), fn addExtra(a: *Analysis, extra: anytype) Allocator.Error!u32 { - const fields = std.meta.fields(@TypeOf(extra)); - try a.extra.ensureUnusedCapacity(a.gpa, fields.len); + const field_count = std.meta.fieldNames(@TypeOf(extra)).len; + try a.extra.ensureUnusedCapacity(a.gpa, field_count); return addExtraAssumeCapacity(a, extra); } fn addExtraAssumeCapacity(a: *Analysis, extra: anytype) u32 { - const fields = std.meta.fields(@TypeOf(extra)); + const info = @typeInfo(@TypeOf(extra)).@"struct"; const result = @as(u32, @intCast(a.extra.items.len)); - inline for (fields) |field| { - a.extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + inline for (info.field_names, info.field_types) |field_name, field_type| { + a.extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -1002,7 +1002,7 @@ fn analyzeInstBlock( const block_scope = data.block_scopes.get(inst).?; const num_deaths = data.live_set.count() - block_scope.live_set.count(); - try a.extra.ensureUnusedCapacity(gpa, num_deaths + std.meta.fields(Block).len); + try a.extra.ensureUnusedCapacity(gpa, num_deaths + std.meta.fieldNames(Block).len); const extra_index = a.addExtraAssumeCapacity(Block{ .death_count = num_deaths, }); @@ -1265,7 +1265,7 @@ fn analyzeInstCondBr( // Write the mirrored deaths to `extra` const then_death_count = @as(u32, @intCast(then_mirrored_deaths.items.len)); const else_death_count = @as(u32, @intCast(else_mirrored_deaths.items.len)); - try a.extra.ensureUnusedCapacity(gpa, std.meta.fields(CondBr).len + then_death_count + else_death_count); + try a.extra.ensureUnusedCapacity(gpa, std.meta.fieldNames(CondBr).len + then_death_count + else_death_count); const extra_index = a.addExtraAssumeCapacity(CondBr{ .then_death_count = then_death_count, .else_death_count = else_death_count, diff --git a/src/Builtin.zig b/src/Builtin.zig index 7a15f6a701..b45841d152 100644 --- a/src/Builtin.zig +++ b/src/Builtin.zig @@ -23,8 +23,8 @@ wasi_exec_model: std.lang.WasiExecModel, /// of the resulting file contents. pub fn hash(opts: @This()) [std.Build.Cache.bin_digest_len]u8 { var h: Cache.Hasher = Cache.hasher_init; - inline for (@typeInfo(@This()).@"struct".fields) |f| { - if (comptime std.mem.eql(u8, f.name, "target")) { + inline for (@typeInfo(@This()).@"struct".field_names) |f_name| { + if (comptime std.mem.eql(u8, f_name, "target")) { // This needs special handling. std.hash.autoHash(&h, opts.target.cpu); std.hash.autoHash(&h, opts.target.os.tag); @@ -33,7 +33,7 @@ pub fn hash(opts: @This()) [std.Build.Cache.bin_digest_len]u8 { std.hash.autoHash(&h, opts.target.ofmt); std.hash.autoHash(&h, opts.target.dynamic_linker); } else { - std.hash.autoHash(&h, @field(opts, f.name)); + std.hash.autoHash(&h, @field(opts, f_name)); } } return h.finalResult(); diff --git a/src/Compilation.zig b/src/Compilation.zig index 43e0ebb7fd..8f5cd5ce89 100644 --- a/src/Compilation.zig +++ b/src/Compilation.zig @@ -298,15 +298,15 @@ const QueuedJobs = struct { ubsan_rt_lib: bool = false, ubsan_rt_obj: bool = false, fuzzer_lib: bool = false, - musl_crt_file: [@typeInfo(musl.CrtFile).@"enum".fields.len]bool = @splat(false), - glibc_crt_file: [@typeInfo(glibc.CrtFile).@"enum".fields.len]bool = @splat(false), - freebsd_crt_file: [@typeInfo(freebsd.CrtFile).@"enum".fields.len]bool = @splat(false), - netbsd_crt_file: [@typeInfo(netbsd.CrtFile).@"enum".fields.len]bool = @splat(false), - openbsd_crt_file: [@typeInfo(openbsd.CrtFile).@"enum".fields.len]bool = @splat(false), + musl_crt_file: [@typeInfo(musl.CrtFile).@"enum".field_names.len]bool = @splat(false), + glibc_crt_file: [@typeInfo(glibc.CrtFile).@"enum".field_names.len]bool = @splat(false), + freebsd_crt_file: [@typeInfo(freebsd.CrtFile).@"enum".field_names.len]bool = @splat(false), + netbsd_crt_file: [@typeInfo(netbsd.CrtFile).@"enum".field_names.len]bool = @splat(false), + openbsd_crt_file: [@typeInfo(openbsd.CrtFile).@"enum".field_names.len]bool = @splat(false), /// one of WASI libc static objects - wasi_libc_crt_file: [@typeInfo(wasi_libc.CrtFile).@"enum".fields.len]bool = @splat(false), + wasi_libc_crt_file: [@typeInfo(wasi_libc.CrtFile).@"enum".field_names.len]bool = @splat(false), /// one of the mingw-w64 static objects - mingw_crt_file: [@typeInfo(mingw.CrtFile).@"enum".fields.len]bool = @splat(false), + mingw_crt_file: [@typeInfo(mingw.CrtFile).@"enum".field_names.len]bool = @splat(false), /// all of the glibc shared objects glibc_shared_objects: bool = false, freebsd_shared_objects: bool = false, @@ -2552,10 +2552,10 @@ pub fn create(gpa: Allocator, arena: Allocator, io: Io, diag: *CreateDiagnostic, error.LibCInstallationMissingCrtDir => return diag.fail(.libc_installation_missing_crt_dir), }; - const fields = @typeInfo(@TypeOf(paths)).@"struct".fields; - try comp.oneshot_prelink_tasks.ensureUnusedCapacity(gpa, fields.len + 1); - inline for (fields) |field| { - if (@field(paths, field.name)) |path| { + const field_names = @typeInfo(@TypeOf(paths)).@"struct".field_names; + try comp.oneshot_prelink_tasks.ensureUnusedCapacity(gpa, field_names.len + 1); + inline for (field_names) |field_name| { + if (@field(paths, field_name)) |path| { comp.oneshot_prelink_tasks.appendAssumeCapacity(.{ .load_object = path }); } } @@ -4667,49 +4667,49 @@ fn dispatchPrelinkWork(comp: *Compilation, main_progress_node: std.Progress.Node prelink_group.async(io, buildLibZigC, .{ comp, main_progress_node }); } - for (0..@typeInfo(musl.CrtFile).@"enum".fields.len) |i| { + for (0..@typeInfo(musl.CrtFile).@"enum".field_names.len) |i| { if (comp.queued_jobs.musl_crt_file[i]) { const tag: musl.CrtFile = @enumFromInt(i); prelink_group.async(io, buildMuslCrtFile, .{ comp, tag, main_progress_node }); } } - for (0..@typeInfo(glibc.CrtFile).@"enum".fields.len) |i| { + for (0..@typeInfo(glibc.CrtFile).@"enum".field_names.len) |i| { if (comp.queued_jobs.glibc_crt_file[i]) { const tag: glibc.CrtFile = @enumFromInt(i); prelink_group.async(io, buildGlibcCrtFile, .{ comp, tag, main_progress_node }); } } - for (0..@typeInfo(freebsd.CrtFile).@"enum".fields.len) |i| { + for (0..@typeInfo(freebsd.CrtFile).@"enum".field_names.len) |i| { if (comp.queued_jobs.freebsd_crt_file[i]) { const tag: freebsd.CrtFile = @enumFromInt(i); prelink_group.async(io, buildFreeBSDCrtFile, .{ comp, tag, main_progress_node }); } } - for (0..@typeInfo(netbsd.CrtFile).@"enum".fields.len) |i| { + for (0..@typeInfo(netbsd.CrtFile).@"enum".field_names.len) |i| { if (comp.queued_jobs.netbsd_crt_file[i]) { const tag: netbsd.CrtFile = @enumFromInt(i); prelink_group.async(io, buildNetBSDCrtFile, .{ comp, tag, main_progress_node }); } } - for (0..@typeInfo(openbsd.CrtFile).@"enum".fields.len) |i| { + for (0..@typeInfo(openbsd.CrtFile).@"enum".field_names.len) |i| { if (comp.queued_jobs.openbsd_crt_file[i]) { const tag: openbsd.CrtFile = @enumFromInt(i); prelink_group.async(io, buildOpenBSDCrtFile, .{ comp, tag, main_progress_node }); } } - for (0..@typeInfo(wasi_libc.CrtFile).@"enum".fields.len) |i| { + for (0..@typeInfo(wasi_libc.CrtFile).@"enum".field_names.len) |i| { if (comp.queued_jobs.wasi_libc_crt_file[i]) { const tag: wasi_libc.CrtFile = @enumFromInt(i); prelink_group.async(io, buildWasiLibcCrtFile, .{ comp, tag, main_progress_node }); } } - for (0..@typeInfo(mingw.CrtFile).@"enum".fields.len) |i| { + for (0..@typeInfo(mingw.CrtFile).@"enum".field_names.len) |i| { if (comp.queued_jobs.mingw_crt_file[i]) { const tag: mingw.CrtFile = @enumFromInt(i); prelink_group.async(io, buildMingwCrtFile, .{ comp, tag, main_progress_node }); diff --git a/src/InternPool.zig b/src/InternPool.zig index 98c06a0af0..b32dee237d 100644 --- a/src/InternPool.zig +++ b/src/InternPool.zig @@ -1070,17 +1070,15 @@ const Local = struct { fn PtrArrayElem(comptime len: usize) type { const elem_info = @typeInfo(Elem).@"struct"; - const elem_fields = elem_info.fields; - var new_names: [elem_fields.len][]const u8 = undefined; - var new_types: [elem_fields.len]type = undefined; - for (elem_fields, &new_names, &new_types) |elem_field, *new_name, *NewType| { - new_name.* = elem_field.name; - NewType.* = *[len]elem_field.type; + + var new_types: [elem_info.field_types.len]type = undefined; + for (&new_types, elem_info.field_types) |*NewType, elem_field_type| { + NewType.* = *[len]elem_field_type; } if (elem_info.is_tuple) { return @Tuple(&new_types); } else { - return @Struct(.auto, null, &new_names, &new_types, &@splat(.{})); + return @Struct(.auto, null, elem_info.field_names, &new_types, &@splat(.{})); } } fn PtrElem(comptime opts: struct { @@ -1088,17 +1086,14 @@ const Local = struct { is_const: bool = false, }) type { const elem_info = @typeInfo(Elem).@"struct"; - const elem_fields = elem_info.fields; - var new_names: [elem_fields.len][]const u8 = undefined; - var new_types: [elem_fields.len]type = undefined; - for (elem_fields, &new_names, &new_types) |elem_field, *new_name, *NewType| { - new_name.* = elem_field.name; - NewType.* = @Pointer(opts.size, .{ .@"const" = opts.is_const }, elem_field.type, null); + var new_types: [elem_info.field_types.len]type = undefined; + for (&new_types, elem_info.field_types) |*NewType, elem_field_type| { + NewType.* = @Pointer(opts.size, .{ .@"const" = opts.is_const }, elem_field_type, null); } if (elem_info.is_tuple) { return @Tuple(&new_types); } else { - return @Struct(.auto, null, &new_names, &new_types, &@splat(.{})); + return @Struct(.auto, null, elem_info.field_names, &new_types, &@splat(.{})); } } @@ -4295,48 +4290,51 @@ pub const Index = enum(u32) { }, }) void { _ = self; - const map_fields = @typeInfo(@typeInfo(@TypeOf(tag_to_encoding_map)).pointer.child).@"struct".fields; + const map_info = @typeInfo(@typeInfo(@TypeOf(tag_to_encoding_map)).pointer.child).@"struct"; @setEvalBranchQuota(3_000); - inline for (@typeInfo(Tag).@"enum".fields, 0..) |tag, start| { - inline for (0..map_fields.len) |offset| { - if (comptime std.mem.eql(u8, tag.name, map_fields[(start + offset) % map_fields.len].name)) break; + inline for (@typeInfo(Tag).@"enum".field_names, 0..) |tag_name, start| { + inline for (0..map_info.field_names.len) |offset| { + if (comptime std.mem.eql(u8, tag_name, map_info.field_names[(start + offset) % map_info.field_names.len])) break; } else { - @compileError(@typeName(Tag) ++ "." ++ tag.name ++ " missing dbHelper tag_to_encoding_map entry"); + @compileError(@typeName(Tag) ++ "." ++ tag_name ++ " missing dbHelper tag_to_encoding_map entry"); } } } comptime { if (!builtin.strip_debug_info) switch (builtin.zig_backend) { .stage2_llvm => _ = &dbHelper, - .stage2_x86_64 => for (@typeInfo(Tag).@"enum".fields) |tag| { - if (!@hasField(@TypeOf(Tag.encodings), tag.name)) @compileLog("missing: " ++ @typeName(Tag) ++ ".encodings." ++ tag.name); - const encoding = @field(Tag.encodings, tag.name); - if (@hasField(@TypeOf(encoding), "trailing")) for (@typeInfo(encoding.trailing).@"struct".fields) |field| { - struct { - fn checkConfig(name: []const u8) void { - if (!@hasField(@TypeOf(encoding.config), name)) @compileError("missing field: " ++ @typeName(Tag) ++ ".encodings." ++ tag.name ++ ".config.@\"" ++ name ++ "\""); - const FieldType = @TypeOf(@field(encoding.config, name)); - if (@typeInfo(FieldType) != .enum_literal) @compileError("expected enum literal: " ++ @typeName(Tag) ++ ".encodings." ++ tag.name ++ ".config.@\"" ++ name ++ "\": " ++ @typeName(FieldType)); - } - fn checkField(name: []const u8, Type: type) void { - switch (@typeInfo(Type)) { - .int => {}, - .@"enum" => {}, - .@"struct" => |info| assert(info.layout == .@"packed"), - .optional => |info| { - checkConfig(name ++ ".?"); - checkField(name ++ ".?", info.child); - }, - .pointer => |info| { - assert(info.size == .slice); - checkConfig(name ++ ".len"); - checkField(name ++ "[0]", info.child); - }, - else => @compileError("unsupported type: " ++ @typeName(Tag) ++ ".encodings." ++ tag.name ++ "." ++ name ++ ": " ++ @typeName(Type)), + .stage2_x86_64 => for (@typeInfo(Tag).@"enum".field_names) |tag_name| { + if (!@hasField(@TypeOf(Tag.encodings), tag_name)) @compileLog("missing: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name); + const encoding = @field(Tag.encodings, tag_name); + if (@hasField(@TypeOf(encoding), "trailing")) { + const trailing_info = @typeInfo(encoding.trailing).@"struct"; + for (trailing_info.field_names, trailing_info.field_types) |field_name, field_type| { + struct { + fn checkConfig(name: []const u8) void { + if (!@hasField(@TypeOf(encoding.config), name)) @compileError("missing field: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name ++ ".config.@\"" ++ name ++ "\""); + const FieldType = @TypeOf(@field(encoding.config, name)); + if (@typeInfo(FieldType) != .enum_literal) @compileError("expected enum literal: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name ++ ".config.@\"" ++ name ++ "\": " ++ @typeName(FieldType)); } - } - }.checkField("trailing." ++ field.name, field.type); - }; + fn checkField(name: []const u8, Type: type) void { + switch (@typeInfo(Type)) { + .int => {}, + .@"enum" => {}, + .@"struct" => |info| assert(info.layout == .@"packed"), + .optional => |info| { + checkConfig(name ++ ".?"); + checkField(name ++ ".?", info.child); + }, + .pointer => |info| { + assert(info.size == .slice); + checkConfig(name ++ ".len"); + checkField(name ++ "[0]", info.child); + }, + else => @compileError("unsupported type: " ++ @typeName(Tag) ++ ".encodings." ++ tag_name ++ "." ++ name ++ ": " ++ @typeName(Type)), + } + } + }.checkField("trailing." ++ field_name, field_type); + } + } }, else => {}, }; @@ -6965,7 +6963,7 @@ fn extraFuncInstance(ip: *const InternPool, tid: Zcu.PerThread.Id, extra: Local. const ty: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "ty").?]); const generic_owner: Index = @enumFromInt(extra_items[extra_index + std.meta.fieldIndex(Tag.FuncInstance, "generic_owner").?]); const func_decl = ip.funcDeclInfo(generic_owner); - const end_extra_index = extra_index + @as(u32, @typeInfo(Tag.FuncInstance).@"struct".fields.len); + const end_extra_index = extra_index + @as(u32, @typeInfo(Tag.FuncInstance).@"struct".field_names.len); return .{ .tid = tid, .ty = ty, @@ -7305,7 +7303,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: const names_map = try ip.addMap(gpa, io, tid, names.len); ip.addStringsToMap(names_map, names); const names_len = error_set_type.names.len; - try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).@"struct".fields.len + names_len); + try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).@"struct".field_names.len + names_len); items.appendAssumeCapacity(.{ .tag = .type_error_set, .data = addExtraAssumeCapacity(extra, Tag.ErrorSet{ @@ -7861,7 +7859,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: .repeated_elem => |elem| elem, }; - try extra.ensureUnusedCapacity(@typeInfo(Repeated).@"struct".fields.len); + try extra.ensureUnusedCapacity(@typeInfo(Repeated).@"struct".field_names.len); items.appendAssumeCapacity(.{ .tag = .repeated, .data = addExtraAssumeCapacity(extra, Repeated{ @@ -7876,7 +7874,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: const string_bytes = ip.getLocal(tid).getMutableStringBytes(gpa, io); const start = string_bytes.mutate.len; try string_bytes.ensureUnusedCapacity(@intCast(len_including_sentinel + 1)); - try extra.ensureUnusedCapacity(@typeInfo(Bytes).@"struct".fields.len); + try extra.ensureUnusedCapacity(@typeInfo(Bytes).@"struct".field_names.len); switch (aggregate.storage) { .bytes => |bytes| string_bytes.appendSliceAssumeCapacity(.{bytes.toSlice(len, ip)}), .elems => |elems| for (elems[0..@intCast(len)]) |elem| switch (ip.indexToKey(elem)) { @@ -7917,7 +7915,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: } try extra.ensureUnusedCapacity( - @typeInfo(Tag.Aggregate).@"struct".fields.len + @as(usize, @intCast(len_including_sentinel + 1)), + @typeInfo(Tag.Aggregate).@"struct".field_names.len + @as(usize, @intCast(len_including_sentinel + 1)), ); items.appendAssumeCapacity(.{ .tag = .aggregate, @@ -7943,7 +7941,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: .memoized_call => |memoized_call| { for (memoized_call.arg_values) |arg| assert(arg != .none); - try extra.ensureUnusedCapacity(@typeInfo(MemoizedCall).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(MemoizedCall).@"struct".field_names.len + memoized_call.arg_values.len); items.appendAssumeCapacity(.{ .tag = .memoized_call, @@ -8006,7 +8004,7 @@ pub fn getDeclaredStructType( .auto => false, .@"extern" => true, .@"packed" => { - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStructPacked).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStructPacked).@"struct".field_names.len + ini.captures.len + // capture ini.fields_len + // field_name ini.fields_len + // field_type @@ -8053,7 +8051,7 @@ pub fn getDeclaredStructType( }, }; - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStruct).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStruct).@"struct".field_names.len + 1 + // captures_len ini.captures.len + // capture ini.fields_len + // field_name @@ -8150,7 +8148,7 @@ pub fn getReifiedStructType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Pe .auto => false, .@"extern" => true, .@"packed" => { - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStructPacked).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStructPacked).@"struct".field_names.len + 2 + // type_hash ini.fields_len + // field_name ini.fields_len + // field_type @@ -8203,7 +8201,7 @@ pub fn getReifiedStructType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Pe }, }; - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStruct).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeStruct).@"struct".field_names.len + 2 + // type_hash ini.fields_len + // field_name ini.fields_len + // field_type @@ -8323,7 +8321,7 @@ pub fn getDeclaredUnionType( .auto => false, .@"extern" => true, .@"packed" => { - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnionPacked).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnionPacked).@"struct".field_names.len + ini.captures.len + // capture ini.fields_len); // field_type @@ -8364,7 +8362,7 @@ pub fn getDeclaredUnionType( }, }; - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnion).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnion).@"struct".field_names.len + 1 + // captures_len ini.captures.len + // capture ini.fields_len + // field_type @@ -8445,7 +8443,7 @@ pub fn getReifiedUnionType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Per .auto => false, .@"extern" => true, .@"packed" => { - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnionPacked).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnionPacked).@"struct".field_names.len + 2 + // type_hash ini.fields_len + // reified_field_name ini.fields_len); // field_type @@ -8490,7 +8488,7 @@ pub fn getReifiedUnionType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.Per }, }; - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnion).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeUnion).@"struct".field_names.len + 2 + // type_hash ini.fields_len + // reified_field_name ini.fields_len + // field_type @@ -8597,7 +8595,7 @@ pub fn getDeclaredEnumType( const field_value_map = if (have_values) try ip.addMap(gpa, io, tid, ini.fields_len) else undefined; errdefer local.mutate.maps.len -= @intFromBool(have_values); - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeEnum).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeEnum).@"struct".field_names.len + 1 + // zir_index ini.captures.len + // capture @intFromBool(have_values) + // field_value_map @@ -8672,7 +8670,7 @@ pub fn getReifiedEnumType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerT const field_value_map = if (have_values) try ip.addMap(gpa, io, tid, ini.fields_len) else undefined; errdefer local.mutate.maps.len -= @intFromBool(have_values); - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeEnum).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeEnum).@"struct".field_names.len + 1 + // zir_index 2 + // type_hash @intFromBool(have_values) + // field_value_map @@ -8746,7 +8744,7 @@ pub fn getGeneratedEnumTagType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu const field_value_map = if (have_values) try ip.addMap(gpa, io, tid, ini.fields_len) else undefined; errdefer local.mutate.maps.len -= @intFromBool(have_values); - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeEnum).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeEnum).@"struct".field_names.len + 1 + // owner_union @intFromBool(have_values) + // field_value_map ini.fields_len + // field_name @@ -8805,7 +8803,7 @@ pub fn getDeclaredOpaqueType(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.P const extra = local.getMutableExtra(gpa, io); try items.ensureUnusedCapacity(1); - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeOpaque).@"struct".fields.len + ini.captures.len); + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeOpaque).@"struct".field_names.len + ini.captures.len); const extra_index = addExtraAssumeCapacity(extra, Tag.TypeOpaque{ .zir_index = ini.zir_index, .captures_len = @intCast(ini.captures.len), @@ -8938,7 +8936,7 @@ pub fn getTupleType( try items.ensureUnusedCapacity(1); try extra.ensureUnusedCapacity( - @typeInfo(TypeTuple).@"struct".fields.len + (fields_len * 3), + @typeInfo(TypeTuple).@"struct".field_names.len + (fields_len * 3), ); const extra_index = addExtraAssumeCapacity(extra, TypeTuple{ @@ -8996,7 +8994,7 @@ pub fn getFuncType( const prev_extra_len = extra.mutate.len; const params_len: u32 = @intCast(key.param_types.len); - try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeFunction).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.TypeFunction).@"struct".field_names.len + @intFromBool(key.comptime_bits != 0) + @intFromBool(key.noalias_bits != 0) + params_len); @@ -9059,7 +9057,7 @@ pub fn getExtern( const items = local.getMutableItems(gpa, io); const extra = local.getMutableExtra(gpa, io); try items.ensureUnusedCapacity(1); - try extra.ensureUnusedCapacity(@typeInfo(Tag.Extern).@"struct".fields.len); + try extra.ensureUnusedCapacity(@typeInfo(Tag.Extern).@"struct".field_names.len); try local.getMutableNavs(gpa, io).ensureUnusedCapacity(1); // Predict the index the `@"extern" will live at, so we can construct the owner `Nav` before releasing the shard's mutex. @@ -9138,7 +9136,7 @@ pub fn getFuncDecl( // arrays. This is similar to what `getOrPutTrailingString` does. const prev_extra_len = extra.mutate.len; - try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncDecl).@"struct".fields.len); + try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncDecl).@"struct".field_names.len); const func_decl_extra_index = addExtraAssumeCapacity(extra, Tag.FuncDecl{ .analysis = .{ @@ -9225,10 +9223,10 @@ pub fn getFuncDeclIes( const prev_extra_len = extra.mutate.len; const params_len: u32 = @intCast(key.param_types.len); - try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncDecl).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncDecl).@"struct".field_names.len + 1 + // inferred_error_set - @typeInfo(Tag.ErrorUnionType).@"struct".fields.len + - @typeInfo(Tag.TypeFunction).@"struct".fields.len + + @typeInfo(Tag.ErrorUnionType).@"struct".field_names.len + + @typeInfo(Tag.TypeFunction).@"struct".field_names.len + @intFromBool(key.comptime_bits != 0) + @intFromBool(key.noalias_bits != 0) + params_len); @@ -9364,7 +9362,7 @@ pub fn getErrorSetType( const local = ip.getLocal(tid); const items = local.getMutableItems(gpa, io); const extra = local.getMutableExtra(gpa, io); - try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).@"struct".fields.len + names.len); + try extra.ensureUnusedCapacity(@typeInfo(Tag.ErrorSet).@"struct".field_names.len + names.len); const names_map = try ip.addMap(gpa, io, tid, names.len); errdefer local.mutate.maps.len -= 1; @@ -9440,7 +9438,7 @@ pub fn getFuncInstance( const local = ip.getLocal(tid); const items = local.getMutableItems(gpa, io); const extra = local.getMutableExtra(gpa, io); - try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncInstance).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncInstance).@"struct".field_names.len + arg.comptime_args.len); assert(arg.comptime_args.len == ip.funcTypeParamsLen(ip.typeOf(generic_owner))); @@ -9524,11 +9522,11 @@ fn getFuncInstanceIes( const prev_extra_len = extra.mutate.len; const params_len: u32 = @intCast(arg.param_types.len); - try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncInstance).@"struct".fields.len + + try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncInstance).@"struct".field_names.len + 1 + // inferred_error_set arg.comptime_args.len + - @typeInfo(Tag.ErrorUnionType).@"struct".fields.len + - @typeInfo(Tag.TypeFunction).@"struct".fields.len + + @typeInfo(Tag.ErrorUnionType).@"struct".field_names.len + + @typeInfo(Tag.TypeFunction).@"struct".field_names.len + @intFromBool(arg.noalias_bits != 0) + params_len); @@ -9774,15 +9772,16 @@ fn addInt( } fn addExtra(extra: Local.Extra.Mutable, item: anytype) Allocator.Error!u32 { - const fields = @typeInfo(@TypeOf(item)).@"struct".fields; - try extra.ensureUnusedCapacity(fields.len); + const field_count = @typeInfo(@TypeOf(item)).@"struct".field_names.len; + try extra.ensureUnusedCapacity(field_count); return addExtraAssumeCapacity(extra, item); } fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 { const result: u32 = extra.mutate.len; - inline for (@typeInfo(@TypeOf(item)).@"struct".fields) |field| { - extra.appendAssumeCapacity(.{switch (field.type) { + const info = @typeInfo(@TypeOf(item)).@"struct"; + inline for (info.field_types, info.field_names) |field_type, field_name| { + extra.appendAssumeCapacity(.{switch (field_type) { Index, Nav.Index, Nav.Index.Optional, @@ -9797,7 +9796,7 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 { TrackedInst.Index, TrackedInst.Index.Optional, ComptimeAllocIndex, - => @intFromEnum(@field(item, field.name)), + => @intFromEnum(@field(item, field_name)), u32, i32, @@ -9811,9 +9810,9 @@ fn addExtraAssumeCapacity(extra: Local.Extra.Mutable, item: anytype) u32 { Tag.TypeStructPacked.Bits, Tag.TypeUnionPacked.Bits, Tag.TypeEnum.Bits, - => @bitCast(@field(item, field.name)), + => @bitCast(@field(item, field_name)), - else => @compileError("bad field type: " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ @typeName(field_type)), }}); } return result; @@ -9826,11 +9825,12 @@ fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 { else => @compileError("unsupported host"), } const result: u32 = @intCast(ip.limbs.items.len); - inline for (@typeInfo(@TypeOf(extra)).@"struct".fields, 0..) |field, i| { - const new: u32 = switch (field.type) { - u32 => @field(extra, field.name), - Index => @intFromEnum(@field(extra, field.name)), - else => @compileError("bad field type: " ++ @typeName(field.type)), + const info = @typeInfo(@TypeOf(extra)).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + const new: u32 = switch (field_type) { + u32 => @field(extra, field_name), + Index => @intFromEnum(@field(extra, field_name)), + else => @compileError("bad field type: " ++ @typeName(field_type)), }; if (i % 2 == 0) { ip.limbs.appendAssumeCapacity(new); @@ -9844,10 +9844,11 @@ fn addLimbsExtraAssumeCapacity(ip: *InternPool, extra: anytype) u32 { fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { data: T, end: u32 } { const extra_items = extra.view().items(.@"0"); var result: T = undefined; - const fields = @typeInfo(T).@"struct".fields; - inline for (fields, index..) |field, extra_index| { + const field_names = @typeInfo(T).@"struct".field_names; + const field_types = @typeInfo(T).@"struct".field_types; + inline for (field_names, field_types, index..) |field_name, field_type, extra_index| { const extra_item = extra_items[extra_index]; - @field(result, field.name) = switch (field.type) { + @field(result, field_name) = switch (field_type) { Index, Nav.Index, Nav.Index.Optional, @@ -9878,12 +9879,12 @@ fn extraDataTrail(extra: Local.Extra, comptime T: type, index: u32) struct { dat Tag.TypeEnum.Bits, => @bitCast(extra_item), - else => @compileError("bad field type: " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ @typeName(field_type)), }; } return .{ .data = result, - .end = @intCast(index + fields.len), + .end = @intCast(index + field_names.len), }; } @@ -10311,7 +10312,7 @@ fn getCoercedFunc( const extra = local.getMutableExtra(gpa, io); const prev_extra_len = extra.mutate.len; - try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncCoerced).@"struct".fields.len); + try extra.ensureUnusedCapacity(@typeInfo(Tag.FuncCoerced).@"struct".field_names.len); const extra_index = addExtraAssumeCapacity(extra, Tag.FuncCoerced{ .ty = ty, @@ -10601,7 +10602,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo }, .type_struct => b: { - var n: usize = @typeInfo(Tag.TypeStruct).@"struct".fields.len; + var n: usize = @typeInfo(Tag.TypeStruct).@"struct".field_names.len; const extra = extraDataTrail(extra_list, Tag.TypeStruct, data); switch (extra.data.flags.any_captures) { .reified => n += 2, // type_hash: PackedU64 @@ -10629,7 +10630,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo break :b n * @sizeOf(u32); }, .type_struct_packed_auto, .type_struct_packed_explicit => b: { - var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".fields.len; + var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".field_names.len; const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data); switch (extra.data.bits.captures_len) { .reified => n += 2, // type_hash: PackedU64 @@ -10640,7 +10641,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo break :b n * @sizeOf(u32); }, .type_struct_packed_auto_defaults, .type_struct_packed_explicit_defaults => b: { - var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".fields.len; + var n: usize = @typeInfo(Tag.TypeStructPacked).@"struct".field_names.len; const extra = extraDataTrail(extra_list, Tag.TypeStructPacked, data); switch (extra.data.bits.captures_len) { .reified => n += 2, // type_hash: PackedU64 @@ -10652,7 +10653,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo break :b n * @sizeOf(u32); }, .type_union => b: { - var n: usize = @typeInfo(Tag.TypeUnion).@"struct".fields.len; + var n: usize = @typeInfo(Tag.TypeUnion).@"struct".field_names.len; const extra = extraDataTrail(extra_list, Tag.TypeUnion, data); switch (extra.data.flags.any_captures) { .reified => n += 2, // type_hash: PackedU64 @@ -10669,7 +10670,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo break :b n * @sizeOf(u32); }, .type_union_packed_auto, .type_union_packed_explicit => b: { - var n: usize = @typeInfo(Tag.TypeUnionPacked).@"struct".fields.len; + var n: usize = @typeInfo(Tag.TypeUnionPacked).@"struct".field_names.len; const extra = extraDataTrail(extra_list, Tag.TypeUnionPacked, data); switch (extra.data.bits.captures_len) { .reified => n += 2, // type_hash: PackedU64 @@ -10679,7 +10680,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo break :b n * @sizeOf(u32); }, .type_enum_auto => b: { - var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len; + var n: usize = @typeInfo(Tag.TypeEnum).@"struct".field_names.len; const extra = extraData(extra_list, Tag.TypeEnum, data); switch (extra.bits.captures_len) { .generated_union_tag => n += 1, // owner_union: Index @@ -10696,7 +10697,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo break :b n * @sizeOf(u32); }, .type_enum_explicit, .type_enum_nonexhaustive => b: { - var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len; + var n: usize = @typeInfo(Tag.TypeEnum).@"struct".field_names.len; const extra = extraData(extra_list, Tag.TypeEnum, data); switch (extra.bits.captures_len) { .generated_union_tag => n += 1, // owner_union: Index @@ -10715,7 +10716,7 @@ fn dumpStatsFallible(ip: *const InternPool, w: *Io.Writer, arena: Allocator) !vo break :b n * @sizeOf(u32); }, .type_opaque => b: { - var n: usize = @typeInfo(Tag.TypeEnum).@"struct".fields.len; + var n: usize = @typeInfo(Tag.TypeEnum).@"struct".field_names.len; const extra = extraData(extra_list, Tag.TypeOpaque, data); n += extra.captures_len; // capture: CaptureValue break :b n * @sizeOf(u32); @@ -12131,8 +12132,8 @@ fn funcIesResolvedPtr(ip: *const InternPool, func_index: Index) *Index { const func_extra = unwrapped_func.getExtra(ip); const func_item = unwrapped_func.getItem(ip); const extra_index = switch (func_item.tag) { - .func_decl => func_item.data + @typeInfo(Tag.FuncDecl).@"struct".fields.len, - .func_instance => func_item.data + @typeInfo(Tag.FuncInstance).@"struct".fields.len, + .func_decl => func_item.data + @typeInfo(Tag.FuncDecl).@"struct".field_names.len, + .func_instance => func_item.data + @typeInfo(Tag.FuncInstance).@"struct".field_names.len, .func_coerced => { const uncoerced_func_index: Index = @enumFromInt(func_extra.view().items(.@"0")[ func_item.data + std.meta.fieldIndex(Tag.FuncCoerced, "func").? @@ -12141,8 +12142,8 @@ fn funcIesResolvedPtr(ip: *const InternPool, func_index: Index) *Index { const uncoerced_func_item = unwrapped_uncoerced_func.getItem(ip); return @ptrCast(&unwrapped_uncoerced_func.getExtra(ip).view().items(.@"0")[ switch (uncoerced_func_item.tag) { - .func_decl => uncoerced_func_item.data + @typeInfo(Tag.FuncDecl).@"struct".fields.len, - .func_instance => uncoerced_func_item.data + @typeInfo(Tag.FuncInstance).@"struct".fields.len, + .func_decl => uncoerced_func_item.data + @typeInfo(Tag.FuncDecl).@"struct".field_names.len, + .func_instance => uncoerced_func_item.data + @typeInfo(Tag.FuncInstance).@"struct".field_names.len, else => unreachable, } ]); diff --git a/src/Sema.zig b/src/Sema.zig index b94a818f87..b2ba7c8643 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -2822,6 +2822,17 @@ fn interpretStdLangType( }; } +fn uninterpretStdLangType( + sema: *Sema, + val: anytype, + ty: Type, +) !Value { + return Value.uninterpret(val, ty, sema.pt) catch |err| switch (err) { + error.OutOfMemory => |e| return e, + error.TypeMismatch => @panic("std.lang is corrupt"), + }; +} + fn zirTupleDecl( sema: *Sema, block: *Block, @@ -3934,7 +3945,7 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com _ = try replacement_block.addBr(placeholder_inst, .void_value); try sema.air_extra.ensureUnusedCapacity( gpa, - @typeInfo(Air.Block).@"struct".fields.len + replacement_block.instructions.items.len, + @typeInfo(Air.Block).@"struct".field_names.len + replacement_block.instructions.items.len, ); sema.air_instructions.set(@intFromEnum(placeholder_inst), .{ .tag = .block, @@ -5175,7 +5186,7 @@ fn zirLoop(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError try child_block.instructions.append(gpa, loop_inst); - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".fields.len + loop_block_len + 1); + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".field_names.len + loop_block_len + 1); sema.air_instructions.items(.data)[@intFromEnum(loop_inst)].ty_pl.payload = sema.addExtraAssumeCapacity( Air.Block{ .body_len = @intCast(loop_block_len + 1) }, ); @@ -5274,7 +5285,7 @@ fn resolveBlockBody( // We need a runtime block for scoping reasons. _ = try child_block.addBr(merges.block_inst, .void_value); try parent_block.instructions.append(sema.gpa, merges.block_inst); - try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Block).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Block).@"struct".field_names.len + child_block.instructions.items.len); sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ .ty = .void_type, @@ -5350,7 +5361,7 @@ fn resolveAnalyzedBlock( .dbg_inline_block => { // Create a block containing all instruction from the body. try parent_block.instructions.append(gpa, merges.block_inst); - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).@"struct".field_names.len + child_block.instructions.items.len); sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ .ty = .noreturn_type, @@ -5388,7 +5399,7 @@ fn resolveAnalyzedBlock( try parent_block.instructions.append(gpa, merges.block_inst); switch (block_tag) { .block => { - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".field_names.len + child_block.instructions.items.len); sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ .ty = .void_type, @@ -5398,7 +5409,7 @@ fn resolveAnalyzedBlock( } }; }, .dbg_inline_block => { - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).@"struct".field_names.len + child_block.instructions.items.len); sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ .ty = .void_type, @@ -5453,7 +5464,7 @@ fn resolveAnalyzedBlock( const ty_inst = Air.internedToRef(resolved_ty.toIntern()); switch (block_tag) { .block => { - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".field_names.len + child_block.instructions.items.len); sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ .ty = ty_inst, @@ -5463,7 +5474,7 @@ fn resolveAnalyzedBlock( } }; }, .dbg_inline_block => { - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.DbgInlineBlock).@"struct".field_names.len + child_block.instructions.items.len); sema.air_instructions.items(.data)[@intFromEnum(merges.block_inst)] = .{ .ty_pl = .{ .ty = ty_inst, @@ -5500,7 +5511,7 @@ fn resolveAnalyzedBlock( // Convert the br instruction to a block instruction that has the coercion // and then a new br inside that returns the coerced instruction. const sub_block_len: u32 = @intCast(coerce_block.instructions.items.len + 1); - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".field_names.len + sub_block_len); try sema.air_instructions.ensureUnusedCapacity(gpa, 1); const sub_br_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len); @@ -6061,7 +6072,7 @@ fn popErrorReturnTrace( // The result might be an error. If it is, we leave the error trace alone. If it isn't, we need // to pop any error trace that may have been propagated from our arguments. - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".fields.len); + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".field_names.len); const cond_block_inst = try block.addInstAsIndex(.{ .tag = .block, .data = .{ @@ -6089,9 +6100,9 @@ fn popErrorReturnTrace( defer else_block.instructions.deinit(gpa); _ = try else_block.addBr(cond_block_inst, .void_value); - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).@"struct".field_names.len + then_block.instructions.items.len + else_block.instructions.items.len + - @typeInfo(Air.Block).@"struct".fields.len + 1); // +1 for the sole .cond_br instruction in the .block + @typeInfo(Air.Block).@"struct".field_names.len + 1); // +1 for the sole .cond_br instruction in the .block const cond_br_inst: Air.Inst.Index = @enumFromInt(sema.air_instructions.len); try sema.air_instructions.append(gpa, .{ @@ -7008,7 +7019,7 @@ fn analyzeCall( => unreachable, }; - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).@"struct".fields.len + runtime_args.len); + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Call).@"struct".field_names.len + runtime_args.len); const call_ref = try block.addInst(.{ .tag = call_tag, .data = .{ .pl_op = .{ @@ -9958,7 +9969,7 @@ fn zirSwitchBlockErrUnion(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Comp } } - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).@"struct".field_names.len + non_err_block.instructions.items.len + switch_block.instructions.items.len); const cond_br_payload = sema.addExtraAssumeCapacity(Air.CondBr{ .then_body_len = @intCast(non_err_block.instructions.items.len), @@ -10314,7 +10325,7 @@ fn analyzeSwitchBlock( _ = try sema.analyzeBodyRuntimeBreak(&case_block, body); } - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".field_names.len + case_block.instructions.items.len); const payload_index = sema.addExtraAssumeCapacity(Air.Block{ .body_len = @intCast(case_block.instructions.items.len), @@ -10405,7 +10416,7 @@ fn analyzeSwitchBlock( // Replace placeholder with a block. // No `br` is needed as the block is a switch dispatch so necessarily `noreturn`. - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".field_names.len + replacement_block.instructions.items.len); sema.air_instructions.set(@intFromEnum(placeholder_inst), .{ .tag = .block, @@ -10508,7 +10519,7 @@ fn finishSwitchBr( defer branch_hints.bags.deinit(gpa); var cases_extra: std.ArrayList(u32) = try .initCapacity(gpa, estimated_cases_len * - @typeInfo(Air.SwitchBr.Case).@"struct".fields.len); + @typeInfo(Air.SwitchBr.Case).@"struct".field_names.len); defer cases_extra.deinit(gpa); // We will reuse this block for each case. @@ -10598,7 +10609,7 @@ fn finishSwitchBr( }; branch_hints.appendAssumeCapacity(prong_hint); - try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".fields.len + + try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".field_names.len + 1 + // `item`, no ranges case_block.instructions.items.len); cases_extra.appendSliceAssumeCapacity(&payloadToExtraItems(Air.SwitchBr.Case{ @@ -10685,7 +10696,7 @@ fn finishSwitchBr( ); try branch_hints.append(gpa, prong_hint); - try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".fields.len + + try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".field_names.len + 1 + // `item`, no ranges case_block.instructions.items.len); cases_extra.appendSliceAssumeCapacity(&payloadToExtraItems(Air.SwitchBr.Case{ @@ -10741,7 +10752,7 @@ fn finishSwitchBr( }; try branch_hints.append(gpa, prong_hint); - try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".fields.len + + try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".field_names.len + item_refs.len + 2 * range_refs.len + case_block.instructions.items.len); @@ -10828,7 +10839,7 @@ fn finishSwitchBr( }; try branch_hints.append(gpa, prong_hint); - try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".fields.len + + try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".field_names.len + 1 + // `item`, no ranges case_block.instructions.items.len); cases_extra.appendSliceAssumeCapacity(&payloadToExtraItems(Air.SwitchBr.Case{ @@ -10888,11 +10899,11 @@ fn finishSwitchBr( }; try branch_hints.append(gpa, prong_hint); - try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".fields.len + + try cases_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr.Case).@"struct".field_names.len + (validated_switch.seen_enum_fields.len + 1 - zir_switch.totalItemsLen()) + // +1 because totalItemsLen includes the _ case_block.instructions.items.len); const extra_case = cases_extra.addManyAsArrayAssumeCapacity( - @typeInfo(Air.SwitchBr.Case).@"struct".fields.len, + @typeInfo(Air.SwitchBr.Case).@"struct".field_names.len, ); var items_len: u32 = 0; for (validated_switch.seen_enum_fields, 0..) |seen_field, field_i| { @@ -10985,7 +10996,7 @@ fn finishSwitchBr( assert(branch_hints.count == cases_len + 1); // +1 for catch-all hint - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.SwitchBr).@"struct".field_names.len + branch_hints.bags.items.len + cases_extra.items.len + catch_all_extra.len); @@ -12356,7 +12367,7 @@ fn analyzeSwitchPayloadCapture( const coerced = try sema.coerce(&coerce_block, capture_ty, uncoerced, case_src); _ = try coerce_block.addBr(capture_block_inst, coerced); - try cases_extra.ensureUnusedCapacity(@typeInfo(Air.SwitchBr.Case).@"struct".fields.len + + try cases_extra.ensureUnusedCapacity(@typeInfo(Air.SwitchBr.Case).@"struct".field_names.len + 1 + // `item`, no ranges coerce_block.instructions.items.len); cases_extra.appendSliceAssumeCapacity(&payloadToExtraItems(Air.SwitchBr.Case{ @@ -12384,9 +12395,9 @@ fn analyzeSwitchPayloadCapture( break :len coerce_block.instructions.items.len; }; - try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.SwitchBr).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.SwitchBr).@"struct".field_names.len + cases_extra.items.len + - @typeInfo(Air.Block).@"struct".fields.len + + @typeInfo(Air.Block).@"struct".field_names.len + 1); const switch_br_inst: u32 = @intCast(sema.air_instructions.len); @@ -15226,7 +15237,7 @@ fn zirAsm( var extra_i = extra.end; var output_type_bits = extra.data.output_type_bits; - var needed_capacity: usize = @typeInfo(Air.Asm).@"struct".fields.len + outputs_len + inputs_len; + var needed_capacity: usize = @typeInfo(Air.Asm).@"struct".field_names.len + outputs_len + inputs_len; const ConstraintName = struct { c: []const u8, n: []const u8 }; const out_args = try sema.arena.alloc(Air.Inst.Ref, outputs_len); @@ -15988,13 +15999,19 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai .@"fn" => { const fn_info_ty = try sema.getStdLangType(src, .@"Type.Fn"); - const param_info_ty = try sema.getStdLangType(src, .@"Type.Fn.Param"); + const param_attrs_ty = try sema.getStdLangType(src, .@"Type.Fn.ParamAttributes"); + const fn_attr_ty = try sema.getStdLangType(src, .@"Type.Fn.Attributes"); const func_ty_info = zcu.typeToFunc(ty).?; - const param_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); + const param_type_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); + const param_attr_vals = try sema.arena.alloc(InternPool.Index, func_ty_info.param_types.len); var func_is_generic = false; - for (param_vals, 0..) |*param_val, param_index| { + for ( + param_type_vals, + param_attr_vals, + 0.., + ) |*param_type_val, *param_attr_val, param_index| { const param_ty = func_ty_info.param_types.get(ip)[param_index]; const is_generic = param_ty == .generic_poison_type; const is_noalias, const is_comptime = flags: { @@ -16011,25 +16028,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai .val = if (is_generic) .none else param_ty, } }); - const param_fields = .{ - // is_generic: bool, - Value.makeBool(is_generic).toIntern(), - // is_noalias: bool, + const param_attrs_fields = .{ + // @"noalias": bool, Value.makeBool(is_noalias).toIntern(), - // type: ?type, - param_ty_val, }; - param_val.* = (try pt.aggregateValue(param_info_ty, ¶m_fields)).toIntern(); + + param_type_val.* = param_ty_val; + param_attr_val.* = (try pt.aggregateValue(param_attrs_ty, ¶m_attrs_fields)).toIntern(); } - const args_val = v: { + const param_types_val = v: { const new_decl_ty = try pt.arrayType(.{ - .len = param_vals.len, - .child = param_info_ty.toIntern(), + .len = param_type_vals.len, + .child = try pt.intern(.{ .opt_type = .type_type }), }); - const new_decl_val = (try pt.aggregateValue(new_decl_ty, param_vals)).toIntern(); + const new_decl_val = (try pt.aggregateValue(new_decl_ty, param_type_vals)).toIntern(); const slice_ty = (try pt.ptrType(.{ - .child = param_info_ty.toIntern(), + .child = try pt.intern(.{ .opt_type = .type_type }), .flags = .{ .size = .slice, .is_const = true, @@ -16046,7 +16061,34 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai } }, .byte_offset = 0, } }), - .len = (try pt.intValue(.usize, param_vals.len)).toIntern(), + .len = (try pt.intValue(.usize, param_type_vals.len)).toIntern(), + } }); + }; + const param_attrs_val = v: { + const new_decl_ty = try pt.arrayType(.{ + .len = param_attr_vals.len, + .child = param_attrs_ty.toIntern(), + }); + const new_decl_val = (try pt.aggregateValue(new_decl_ty, param_attr_vals)).toIntern(); + const slice_ty = (try pt.ptrType(.{ + .child = param_attrs_ty.toIntern(), + .flags = .{ + .size = .slice, + .is_const = true, + }, + })).toIntern(); + const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern(); + break :v try pt.intern(.{ .slice = .{ + .ty = slice_ty, + .ptr = try pt.intern(.{ .ptr = .{ + .ty = manyptr_ty, + .base_addr = .{ .uav = .{ + .orig_ty = manyptr_ty, + .val = new_decl_val, + } }, + .byte_offset = 0, + } }), + .len = (try pt.intValue(.usize, param_attr_vals.len)).toIntern(), } }); }; @@ -16075,17 +16117,25 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai error.OutOfMemory => |e| return e, }; - const field_values: [5]InternPool.Index = .{ - // calling_convention: CallingConvention, + const fn_attrs_values = .{ + // @"callconv": CallingConvention = .auto, callconv_val.toIntern(), + // varargs: bool = false, + Value.makeBool(func_ty_info.is_var_args).toIntern(), + }; + + const field_values = .{ + // attrs: Attributes, + (try pt.aggregateValue(fn_attr_ty, &fn_attrs_values)).toIntern(), // is_generic: bool, Value.makeBool(func_is_generic).toIntern(), - // is_var_args: bool, - Value.makeBool(func_ty_info.is_var_args).toIntern(), // return_type: ?type, ret_ty_opt, - // args: []const Fn.Param, - args_val, + + // param_types: []const ?type, + param_types_val, + // param_attrs: []const ParamAttributes, + param_attrs_val, }; return Air.internedToRef((try pt.internUnion(.{ .ty = type_info_ty.toIntern(), @@ -16139,23 +16189,34 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const addrspace_ty = try sema.getStdLangType(src, .AddressSpace); const pointer_ty = try sema.getStdLangType(src, .@"Type.Pointer"); const ptr_size_ty = try sema.getStdLangType(src, .@"Type.Pointer.Size"); + const ptr_attrs_ty = try sema.getStdLangType(src, .@"Type.Pointer.Attributes"); + + const opt_addrspace_val = try pt.intern(.{ .opt = .{ + .ty = (try pt.optionalType(addrspace_ty.toIntern())).toIntern(), + .val = (try sema.uninterpretStdLangType(info.flags.address_space, addrspace_ty)).toIntern(), + } }); + + const attributes = .{ + // @"const": bool = false, + Value.makeBool(info.flags.is_const).toIntern(), + // @"volatile": bool = false, + Value.makeBool(info.flags.is_volatile).toIntern(), + // @"allowzero": bool = false, + Value.makeBool(info.flags.is_allowzero).toIntern(), + // @"addrspace": ?AddressSpace = null, + opt_addrspace_val, + // @"align": ?usize = null, + alignment_val.toIntern(), + }; const field_values = .{ // size: Size, (try pt.enumValueFieldIndex(ptr_size_ty, @intFromEnum(info.flags.size))).toIntern(), - // is_const: bool, - Value.makeBool(info.flags.is_const).toIntern(), - // is_volatile: bool, - Value.makeBool(info.flags.is_volatile).toIntern(), - // alignment: ?usize, - alignment_val.toIntern(), - // address_space: AddressSpace - (try pt.enumValueFieldIndex(addrspace_ty, @intFromEnum(info.flags.address_space))).toIntern(), + // attrs: Attributes + (try pt.aggregateValue(ptr_attrs_ty, &attributes)).toIntern(), // child: type, info.child, - // is_allowzero: bool, - Value.makeBool(info.flags.is_allowzero).toIntern(), - // sentinel: ?*const anyopaque, + // sentinel_ptr: ?*const anyopaque, (try sema.optRefValue(switch (info.sentinel) { .none => null, else => Value.fromInterned(info.sentinel), @@ -16215,8 +16276,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai }))); }, .error_set => { - // Get the Error type - const error_field_ty = try sema.getStdLangType(src, .@"Type.Error"); + const error_set_ty = try sema.getStdLangType(src, .@"Type.ErrorSet"); // Build our list of Error values // Optional value is only null if anyerror @@ -16253,20 +16313,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai } }); }; - const error_field_fields = .{ - // name: [:0]const u8, - error_name_val, - }; - field_val.* = (try pt.aggregateValue(error_field_ty, &error_field_fields)).toIntern(); + field_val.* = error_name_val; } break :blk vals; }, }; - // Build our ?[]const Error value + // Build our ?[]const [:0]const u8 value const slice_errors_ty = try pt.ptrType(.{ - .child = error_field_ty.toIntern(), + .child = .slice_const_u8_sentinel_0_type, .flags = .{ .size = .slice, .is_const = true, @@ -16276,7 +16332,7 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const errors_payload_val: InternPool.Index = if (error_field_vals) |vals| v: { const array_errors_ty = try pt.arrayType(.{ .len = vals.len, - .child = error_field_ty.toIntern(), + .child = .slice_const_u8_sentinel_0_type, }); const new_decl_val = (try pt.aggregateValue(array_errors_ty, vals)).toIntern(); const manyptr_errors_ty = slice_errors_ty.slicePtrFieldType(zcu).toIntern(); @@ -16298,11 +16354,16 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai .val = errors_payload_val, } }); + const field_values = .{ + // error_names: ?[]const [:0]const u8 + errors_val, + }; + // Construct Type{ .error_set = errors_val } return Air.internedToRef((try pt.internUnion(.{ .ty = type_info_ty.toIntern(), .tag = (try pt.enumValueFieldIndex(type_info_tag_ty, @intFromEnum(std.lang.TypeId.error_set))).toIntern(), - .val = errors_val, + .val = (try pt.aggregateValue(error_set_ty, &field_values)).toIntern(), }))); }, .error_union => { @@ -16322,12 +16383,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai }, .@"enum" => { const enum_obj = ip.loadEnumType(ty.toIntern()); - const is_exhaustive: Value = .makeBool(!enum_obj.nonexhaustive); - const enum_field_ty = try sema.getStdLangType(src, .@"Type.EnumField"); + const enum_mode_ty = try sema.getStdLangType(src, .@"Type.Enum.Mode"); - const enum_field_vals = try sema.arena.alloc(InternPool.Index, enum_obj.field_names.len); - for (enum_field_vals, 0..) |*field_val, tag_index| { + const enum_mode_tag: std.builtin.Type.Enum.Mode = if (enum_obj.nonexhaustive) .nonexhaustive else .exhaustive; + + const enum_mode: Value = try sema.uninterpretStdLangType(enum_mode_tag, enum_mode_ty); + + const enum_field_name_vals = try sema.arena.alloc(InternPool.Index, enum_obj.field_names.len); + const enum_field_value_vals = try sema.arena.alloc(InternPool.Index, enum_obj.field_names.len); + for ( + enum_field_name_vals, + enum_field_value_vals, + 0.., + ) |*field_name_val, *field_value_val, tag_index| { const value_val = if (enum_obj.field_values.len > 0) try ip.getCoercedInts( gpa, @@ -16366,23 +16435,18 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai } }); }; - const enum_field_fields = .{ - // name: [:0]const u8, - name_val, - // value: comptime_int, - value_val, - }; - field_val.* = (try pt.aggregateValue(enum_field_ty, &enum_field_fields)).toIntern(); + field_name_val.* = name_val; + field_value_val.* = value_val; } - const fields_val = v: { - const fields_array_ty = try pt.arrayType(.{ - .len = enum_field_vals.len, - .child = enum_field_ty.toIntern(), + const fields_names_val = v: { + const fields_names_array_ty = try pt.arrayType(.{ + .len = enum_field_name_vals.len, + .child = .slice_const_u8_sentinel_0_type, }); - const new_decl_val = (try pt.aggregateValue(fields_array_ty, enum_field_vals)).toIntern(); + const new_decl_val = (try pt.aggregateValue(fields_names_array_ty, enum_field_name_vals)).toIntern(); const slice_ty = (try pt.ptrType(.{ - .child = enum_field_ty.toIntern(), + .child = .slice_const_u8_sentinel_0_type, .flags = .{ .size = .slice, .is_const = true, @@ -16399,23 +16463,55 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai } }, .byte_offset = 0, } }), - .len = (try pt.intValue(.usize, enum_field_vals.len)).toIntern(), + .len = (try pt.intValue(.usize, enum_field_name_vals.len)).toIntern(), } }); }; - const decls_val = try sema.typeInfoDecls(src, ip.loadEnumType(ty.toIntern()).namespace.toOptional()); + const fields_values_val = v: { + const fields_values_array_ty = try pt.arrayType(.{ + .len = enum_field_value_vals.len, + .child = .comptime_int_type, + }); + const new_decl_val = (try pt.aggregateValue(fields_values_array_ty, enum_field_value_vals)).toIntern(); + const slice_ty = (try pt.ptrType(.{ + .child = .comptime_int_type, + .flags = .{ + .size = .slice, + .is_const = true, + }, + })).toIntern(); + const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern(); + break :v try pt.intern(.{ .slice = .{ + .ty = slice_ty, + .ptr = try pt.intern(.{ .ptr = .{ + .ty = manyptr_ty, + .base_addr = .{ .uav = .{ + .val = new_decl_val, + .orig_ty = manyptr_ty, + } }, + .byte_offset = 0, + } }), + .len = (try pt.intValue(.usize, enum_field_value_vals.len)).toIntern(), + } }); + }; + + const decl_names_val = try sema.typeInfoDecls(ip.loadEnumType(ty.toIntern()).namespace.toOptional()); const type_enum_ty = try sema.getStdLangType(src, .@"Type.Enum"); const field_values = .{ // tag_type: type, ip.loadEnumType(ty.toIntern()).int_tag_type, - // fields: []const EnumField, - fields_val, - // decls: []const Declaration, - decls_val, - // is_exhaustive: bool, - is_exhaustive.toIntern(), + // mode: Mode + enum_mode.toIntern(), + + // field_names: []const [:0]const u8, + fields_names_val, + // field_values: []const comptime_int, + fields_values_val, + + // decl_names: []const [:0]const u8, + decl_names_val, }; return Air.internedToRef((try pt.internUnion(.{ .ty = type_info_ty.toIntern(), @@ -16425,16 +16521,26 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai }, .@"union" => { const type_union_ty = try sema.getStdLangType(src, .@"Type.Union"); - const union_field_ty = try sema.getStdLangType(src, .@"Type.UnionField"); + const union_field_attr_ty = try sema.getStdLangType(src, .@"Type.Union.FieldAttributes"); const union_obj = ip.loadUnionType(ty.toIntern()); const enum_obj = ip.loadEnumType(union_obj.enum_tag_type); const layout = union_obj.layout; - const union_field_vals = try gpa.alloc(InternPool.Index, enum_obj.field_names.len); - defer gpa.free(union_field_vals); + const union_field_names = try gpa.alloc(InternPool.Index, enum_obj.field_names.len); + defer gpa.free(union_field_names); + const union_field_attrs = try gpa.alloc(InternPool.Index, enum_obj.field_names.len); + defer gpa.free(union_field_attrs); - for (union_field_vals, 0..) |*field_val, field_index| { + for ( + union_field_names, + union_field_attrs, + 0.., + ) | + *field_name_val, + *field_attr_val, + field_index, + | { const name_val = v: { const field_name = enum_obj.field_names.get(ip)[field_index]; const field_name_len = field_name.length(ip); @@ -16461,8 +16567,6 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai } }); }; - const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]); - const alignment_ty = try pt.optionalType(.usize_type); const alignment_val: Value = val: { const a: Alignment = switch (layout) { @@ -16479,25 +16583,23 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai } })); }; - const union_field_fields = .{ - // name: [:0]const u8, - name_val, - // type: type, - field_ty.toIntern(), + field_name_val.* = name_val; + const union_field_attr = .{ // alignment: ?usize, alignment_val.toIntern(), }; - field_val.* = (try pt.aggregateValue(union_field_ty, &union_field_fields)).toIntern(); + + field_attr_val.* = (try pt.aggregateValue(union_field_attr_ty, &union_field_attr)).toIntern(); } - const fields_val = v: { - const array_fields_ty = try pt.arrayType(.{ - .len = union_field_vals.len, - .child = union_field_ty.toIntern(), + const field_names_val = v: { + const array_field_names_ty = try pt.arrayType(.{ + .len = union_field_names.len, + .child = .slice_const_u8_sentinel_0_type, }); - const new_decl_val = (try pt.aggregateValue(array_fields_ty, union_field_vals)).toIntern(); + const new_decl_val = (try pt.aggregateValue(array_field_names_ty, union_field_names)).toIntern(); const slice_ty = (try pt.ptrType(.{ - .child = union_field_ty.toIntern(), + .child = .slice_const_u8_sentinel_0_type, .flags = .{ .size = .slice, .is_const = true, @@ -16514,11 +16616,67 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai } }, .byte_offset = 0, } }), - .len = (try pt.intValue(.usize, union_field_vals.len)).toIntern(), + .len = (try pt.intValue(.usize, union_field_names.len)).toIntern(), + } }); + }; + const field_types_val = v: { + const union_field_types = union_obj.field_types.get(ip); + + const array_fields_ty = try pt.arrayType(.{ + .len = union_field_types.len, + .child = .type_type, + }); + const new_decl_val = (try pt.aggregateValue(array_fields_ty, union_field_types)).toIntern(); + const slice_ty = (try pt.ptrType(.{ + .child = .type_type, + .flags = .{ + .size = .slice, + .is_const = true, + }, + })).toIntern(); + const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern(); + break :v try pt.intern(.{ .slice = .{ + .ty = slice_ty, + .ptr = try pt.intern(.{ .ptr = .{ + .ty = manyptr_ty, + .base_addr = .{ .uav = .{ + .orig_ty = manyptr_ty, + .val = new_decl_val, + } }, + .byte_offset = 0, + } }), + .len = (try pt.intValue(.usize, union_field_types.len)).toIntern(), + } }); + }; + const field_attrs_val = v: { + const array_fields_ty = try pt.arrayType(.{ + .len = union_field_attrs.len, + .child = union_field_attr_ty.toIntern(), + }); + const new_decl_val = (try pt.aggregateValue(array_fields_ty, union_field_attrs)).toIntern(); + const slice_ty = (try pt.ptrType(.{ + .child = union_field_attr_ty.toIntern(), + .flags = .{ + .size = .slice, + .is_const = true, + }, + })).toIntern(); + const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern(); + break :v try pt.intern(.{ .slice = .{ + .ty = slice_ty, + .ptr = try pt.intern(.{ .ptr = .{ + .ty = manyptr_ty, + .base_addr = .{ .uav = .{ + .orig_ty = manyptr_ty, + .val = new_decl_val, + } }, + .byte_offset = 0, + } }), + .len = (try pt.intValue(.usize, union_field_attrs.len)).toIntern(), } }); }; - const decls_val = try sema.typeInfoDecls(src, ty.getNamespaceIndex(zcu).toOptional()); + const decl_names_val = try sema.typeInfoDecls(ty.getNamespaceIndex(zcu).toOptional()); const enum_tag_ty_val = try pt.intern(.{ .opt = .{ .ty = (try pt.optionalType(.type_type)).toIntern(), @@ -16527,16 +16685,32 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const container_layout_ty = try sema.getStdLangType(src, .@"Type.ContainerLayout"); + const backing_integer_val = try pt.intern(.{ .opt = .{ + .ty = (try pt.optionalType(.type_type)).toIntern(), + .val = if (layout == .@"packed") val: { + assert(Type.fromInterned(union_obj.packed_backing_int_type).isInt(zcu)); + break :val union_obj.packed_backing_int_type; + } else .none, + } }); + const field_values = .{ // layout: ContainerLayout, (try pt.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(), // tag_type: ?type, enum_tag_ty_val, - // fields: []const UnionField, - fields_val, - // decls: []const Declaration, - decls_val, + // backing_integer: ?type, + backing_integer_val, + + // field_names: []const [:0]const u8, + field_names_val, + // field_types: []const type, + field_types_val, + // field_attrs: []const FieldAttributes, + field_attrs_val, + + // decl_names: []const [:0]const u8, + decl_names_val, }; return Air.internedToRef((try pt.internUnion(.{ .ty = type_info_ty.toIntern(), @@ -16546,16 +16720,26 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai }, .@"struct" => { const type_struct_ty = try sema.getStdLangType(src, .@"Type.Struct"); - const struct_field_ty = try sema.getStdLangType(src, .@"Type.StructField"); + const struct_field_attr_ty = try sema.getStdLangType(src, .@"Type.Struct.FieldAttributes"); - var struct_field_vals: []InternPool.Index = &.{}; - defer gpa.free(struct_field_vals); + var struct_field_name_vals: []InternPool.Index = &.{}; + defer gpa.free(struct_field_name_vals); + var struct_field_attr_vals: []InternPool.Index = &.{}; + defer gpa.free(struct_field_attr_vals); fv: { const struct_type = switch (ip.indexToKey(ty.toIntern())) { .tuple_type => |tuple_type| { - struct_field_vals = try gpa.alloc(InternPool.Index, tuple_type.types.len); - for (struct_field_vals, 0..) |*struct_field_val, field_index| { - const field_ty = tuple_type.types.get(ip)[field_index]; + struct_field_name_vals = try gpa.alloc(InternPool.Index, tuple_type.types.len); + struct_field_attr_vals = try gpa.alloc(InternPool.Index, tuple_type.types.len); + for ( + struct_field_name_vals, + struct_field_attr_vals, + 0.., + ) | + *struct_field_name_val, + *struct_field_attr_val, + field_index, + | { const field_val = tuple_type.values.get(ip)[field_index]; const name_val = v: { const field_name = try ip.getOrPutStringFmt(gpa, io, pt.tid, "{d}", .{field_index}, .no_embedded_nulls); @@ -16587,19 +16771,17 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const opt_default_val = if (is_comptime) Value.fromInterned(field_val) else null; const default_val_ptr = try sema.optRefValue(opt_default_val); - const struct_field_fields = .{ - // name: [:0]const u8, - name_val, - // type: type, - field_ty, - // default_value: ?*const anyopaque, - default_val_ptr.toIntern(), - // is_comptime: bool, + const struct_field_attr_fields = .{ + // @"comptime": bool, Value.makeBool(is_comptime).toIntern(), - // alignment: ?usize, + // @"align": ?usize, (try pt.nullValue(try pt.optionalType(.usize_type))).toIntern(), + // default_value_ptr: ?*const anyopaque, + default_val_ptr.toIntern(), }; - struct_field_val.* = (try pt.aggregateValue(struct_field_ty, &struct_field_fields)).toIntern(); + + struct_field_name_val.* = name_val; + struct_field_attr_val.* = (try pt.aggregateValue(struct_field_attr_ty, &struct_field_attr_fields)).toIntern(); } break :fv; }, @@ -16607,12 +16789,20 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai else => unreachable, }; try sema.ensureStructDefaultsResolved(ty, src); // can't do this sooner, since it's not allowed on tuples - struct_field_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len); + struct_field_name_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len); + struct_field_attr_vals = try gpa.alloc(InternPool.Index, struct_type.field_types.len); - for (struct_field_vals, 0..) |*field_val, field_index| { + for ( + struct_field_name_vals, + struct_field_attr_vals, + 0.., + ) | + *field_name_val, + *field_attr_val, + field_index, + | { const field_name = struct_type.field_names.get(ip)[field_index]; const field_name_len = field_name.length(ip); - const field_ty: Type = .fromInterned(struct_type.field_types.get(ip)[field_index]); const field_default: InternPool.Index = if (struct_type.field_defaults.len > 0) d: { break :d struct_type.field_defaults.get(ip)[field_index]; } else .none; @@ -16660,30 +16850,27 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai } })); }; - const struct_field_fields = .{ - // name: [:0]const u8, - name_val, - // type: type, - field_ty.toIntern(), - // default_value: ?*const anyopaque, - default_val_ptr.toIntern(), - // is_comptime: bool, + const struct_field_attr_fields = .{ + // @"comptime": bool, Value.makeBool(field_is_comptime).toIntern(), - // alignment: ?usize, + // @"align": ?usize, alignment_val.toIntern(), + // default_value_ptr: ?*const anyopaque, + default_val_ptr.toIntern(), }; - field_val.* = (try pt.aggregateValue(struct_field_ty, &struct_field_fields)).toIntern(); + field_name_val.* = name_val; + field_attr_val.* = (try pt.aggregateValue(struct_field_attr_ty, &struct_field_attr_fields)).toIntern(); } } - const fields_val = v: { + const field_names_val = v: { const array_fields_ty = try pt.arrayType(.{ - .len = struct_field_vals.len, - .child = struct_field_ty.toIntern(), + .len = struct_field_name_vals.len, + .child = .slice_const_u8_sentinel_0_type, }); - const new_decl_val = (try pt.aggregateValue(array_fields_ty, struct_field_vals)).toIntern(); + const new_decl_val = (try pt.aggregateValue(array_fields_ty, struct_field_name_vals)).toIntern(); const slice_ty = (try pt.ptrType(.{ - .child = struct_field_ty.toIntern(), + .child = .slice_const_u8_sentinel_0_type, .flags = .{ .size = .slice, .is_const = true, @@ -16700,11 +16887,74 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai } }, .byte_offset = 0, } }), - .len = (try pt.intValue(.usize, struct_field_vals.len)).toIntern(), + .len = (try pt.intValue(.usize, struct_field_name_vals.len)).toIntern(), } }); }; - const decls_val = try sema.typeInfoDecls(src, ty.getNamespace(zcu)); + const field_types_val = v: { + const struct_field_type_vals = switch (ip.indexToKey(ty.toIntern())) { + .tuple_type => |tt| tt.types.get(ip), + .struct_type => blk: { + const st = ip.loadStructType(ty.toIntern()); + break :blk st.field_types.get(ip); + }, + else => unreachable, + }; + const array_fields_ty = try pt.arrayType(.{ + .len = struct_field_type_vals.len, + .child = .type_type, + }); + const new_decl_val = (try pt.aggregateValue(array_fields_ty, struct_field_type_vals)).toIntern(); + const slice_ty = (try pt.ptrType(.{ + .child = .type_type, + .flags = .{ + .size = .slice, + .is_const = true, + }, + })).toIntern(); + const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern(); + break :v try pt.intern(.{ .slice = .{ + .ty = slice_ty, + .ptr = try pt.intern(.{ .ptr = .{ + .ty = manyptr_ty, + .base_addr = .{ .uav = .{ + .orig_ty = manyptr_ty, + .val = new_decl_val, + } }, + .byte_offset = 0, + } }), + .len = (try pt.intValue(.usize, struct_field_type_vals.len)).toIntern(), + } }); + }; + const field_attrs_val = v: { + const array_fields_ty = try pt.arrayType(.{ + .len = struct_field_attr_vals.len, + .child = struct_field_attr_ty.toIntern(), + }); + const new_decl_val = (try pt.aggregateValue(array_fields_ty, struct_field_attr_vals)).toIntern(); + const slice_ty = (try pt.ptrType(.{ + .child = struct_field_attr_ty.toIntern(), + .flags = .{ + .size = .slice, + .is_const = true, + }, + })).toIntern(); + const manyptr_ty = Type.fromInterned(slice_ty).slicePtrFieldType(zcu).toIntern(); + break :v try pt.intern(.{ .slice = .{ + .ty = slice_ty, + .ptr = try pt.intern(.{ .ptr = .{ + .ty = manyptr_ty, + .base_addr = .{ .uav = .{ + .orig_ty = manyptr_ty, + .val = new_decl_val, + } }, + .byte_offset = 0, + } }), + .len = (try pt.intValue(.usize, struct_field_attr_vals.len)).toIntern(), + } }); + }; + + const decl_names_val = try sema.typeInfoDecls(ty.getNamespace(zcu)); const backing_integer_val = try pt.intern(.{ .opt = .{ .ty = (try pt.optionalType(.type_type)).toIntern(), @@ -16719,16 +16969,22 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai const layout = ty.containerLayout(zcu); const field_values = [_]InternPool.Index{ + // is_tuple: bool, + Value.makeBool(ty.isTuple(zcu)).toIntern(), // layout: ContainerLayout, (try pt.enumValueFieldIndex(container_layout_ty, @intFromEnum(layout))).toIntern(), // backing_integer: ?type, backing_integer_val, - // fields: []const StructField, - fields_val, - // decls: []const Declaration, - decls_val, - // is_tuple: bool, - Value.makeBool(ty.isTuple(zcu)).toIntern(), + + // field_names: []const [:0]const u8, + field_names_val, + // field_types: []const type, + field_types_val, + // field_attrs: []const FieldAttributes, + field_attrs_val, + + // decl_names: []const [:0]const u8, + decl_names_val, }; return Air.internedToRef((try pt.internUnion(.{ .ty = type_info_ty.toIntern(), @@ -16739,11 +16995,11 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai .@"opaque" => { const type_opaque_ty = try sema.getStdLangType(src, .@"Type.Opaque"); - const decls_val = try sema.typeInfoDecls(src, ty.getNamespace(zcu)); + const decl_names_val = try sema.typeInfoDecls(ty.getNamespace(zcu)); const field_values = .{ - // decls: []const Declaration, - decls_val, + // decl_names: []const [:0]const u8, + decl_names_val, }; return Air.internedToRef((try pt.internUnion(.{ .ty = type_info_ty.toIntern(), @@ -16758,30 +17014,27 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai fn typeInfoDecls( sema: *Sema, - src: LazySrcLoc, opt_namespace: InternPool.OptionalNamespaceIndex, ) CompileError!InternPool.Index { const pt = sema.pt; const zcu = pt.zcu; const gpa = sema.gpa; - const declaration_ty = try sema.getStdLangType(src, .@"Type.Declaration"); - var decl_vals = std.array_list.Managed(InternPool.Index).init(gpa); defer decl_vals.deinit(); var seen_namespaces = std.AutoHashMap(*Namespace, void).init(gpa); defer seen_namespaces.deinit(); - try sema.typeInfoNamespaceDecls(opt_namespace, declaration_ty, &decl_vals, &seen_namespaces); + try sema.typeInfoNamespaceDecls(opt_namespace, &decl_vals, &seen_namespaces); const array_decl_ty = try pt.arrayType(.{ .len = decl_vals.items.len, - .child = declaration_ty.toIntern(), + .child = .slice_const_u8_sentinel_0_type, }); const new_decl_val = (try pt.aggregateValue(array_decl_ty, decl_vals.items)).toIntern(); const slice_ty = (try pt.ptrType(.{ - .child = declaration_ty.toIntern(), + .child = .slice_const_u8_sentinel_0_type, .flags = .{ .size = .slice, .is_const = true, @@ -16805,7 +17058,6 @@ fn typeInfoDecls( fn typeInfoNamespaceDecls( sema: *Sema, opt_namespace_index: InternPool.OptionalNamespaceIndex, - declaration_ty: Type, decl_vals: *std.array_list.Managed(InternPool.Index), seen_namespaces: *std.AutoHashMap(*Namespace, void), ) !void { @@ -16850,11 +17102,7 @@ fn typeInfoNamespaceDecls( }, }); }; - const fields = [_]InternPool.Index{ - // name: [:0]const u8, - name_val, - }; - try decl_vals.append((try pt.aggregateValue(declaration_ty, &fields)).toIntern()); + try decl_vals.append(name_val); } } @@ -17120,9 +17368,9 @@ fn finishCondBr( ) !Air.Inst.Ref { const gpa = sema.gpa; - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).@"struct".field_names.len + then_block.instructions.items.len + else_block.instructions.items.len + - @typeInfo(Air.Block).@"struct".fields.len + child_block.instructions.items.len + 1); + @typeInfo(Air.Block).@"struct".field_names.len + child_block.instructions.items.len + 1); const cond_br_payload = sema.addExtraAssumeCapacity(Air.CondBr{ .then_body_len = @intCast(then_block.instructions.items.len), @@ -17331,7 +17579,7 @@ fn zirCondbr( break :h .unlikely; } else try sema.analyzeBodyRuntimeBreak(&sub_block, else_body); - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.CondBr).@"struct".field_names.len + true_instructions.len + sub_block.instructions.items.len); _ = try parent_block.addInst(.{ .tag = .cond_br, @@ -17403,7 +17651,7 @@ fn zirTry(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileError! // The only interesting hint here is `.cold`, which can come from e.g. `errdefer @panic`. const is_cold = sema.branch_hint == .cold; - try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Try).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.Try).@"struct".field_names.len + sub_block.instructions.items.len); const try_inst = try parent_block.addInst(.{ .tag = if (is_cold) .try_cold else .@"try", @@ -17483,7 +17731,7 @@ fn zirTryPtr(sema: *Sema, parent_block: *Block, inst: Zir.Inst.Index) CompileErr }, }); const res_ty_ref = Air.internedToRef(res_ty.toIntern()); - try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.TryPtr).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(sema.gpa, @typeInfo(Air.TryPtr).@"struct".field_names.len + sub_block.instructions.items.len); const try_inst = try parent_block.addInst(.{ .tag = if (is_cold) .try_ptr_cold else .try_ptr, @@ -17731,9 +17979,9 @@ fn maybePushErrorTrace( try sema.air_instructions.ensureUnusedCapacity(gpa, 4); try sema.air_extra.ensureUnusedCapacity( gpa, - @typeInfo(Air.Block).@"struct".fields.len + + @typeInfo(Air.Block).@"struct".field_names.len + 1 + // the main block contains only the `cond_br` - @typeInfo(Air.CondBr).@"struct".fields.len + + @typeInfo(Air.CondBr).@"struct".field_names.len + 1 + // the non-error branch contains only a `br` err_block.instructions.items.len + 1, // the error branch contains the `returnError` call and a `br` ); @@ -19470,11 +19718,11 @@ fn zirReifySliceArgTy( const comptime_reason: std.zig.SimpleComptimeReason, const in_scalar_ty: Type, const out_scalar_ty: Type = switch (info) { // zig fmt: off - .type_to_fn_param_attrs => .{ .fn_param_attrs, .type, try sema.getStdLangType(src, .@"Type.Fn.Param.Attributes") }, + .type_to_fn_param_attrs => .{ .fn_param_attrs, .type, try sema.getStdLangType(src, .@"Type.Fn.ParamAttributes") }, .string_to_struct_field_type => .{ .struct_field_types, .slice_const_u8, .type }, .string_to_union_field_type => .{ .union_field_types, .slice_const_u8, .type }, - .string_to_struct_field_attrs => .{ .struct_field_attrs, .slice_const_u8, try sema.getStdLangType(src, .@"Type.StructField.Attributes") }, - .string_to_union_field_attrs => .{ .union_field_attrs, .slice_const_u8, try sema.getStdLangType(src, .@"Type.UnionField.Attributes") }, + .string_to_struct_field_attrs => .{ .struct_field_attrs, .slice_const_u8, try sema.getStdLangType(src, .@"Type.Struct.FieldAttributes") }, + .string_to_union_field_attrs => .{ .union_field_attrs, .slice_const_u8, try sema.getStdLangType(src, .@"Type.Union.FieldAttributes") }, // zig fmt: on }; @@ -19688,7 +19936,7 @@ fn zirReifyFn( const ret_ty_src = block.builtinCallArgSrc(extra.node, 2); const fn_attrs_src = block.builtinCallArgSrc(extra.node, 3); - const single_param_attrs_ty = try sema.getStdLangType(param_attrs_src, .@"Type.Fn.Param.Attributes"); + const single_param_attrs_ty = try sema.getStdLangType(param_attrs_src, .@"Type.Fn.ParamAttributes"); const fn_attrs_ty = try sema.getStdLangType(fn_attrs_src, .@"Type.Fn.Attributes"); const param_types_uncoerced = sema.resolveInst(extra.param_types); @@ -19722,7 +19970,7 @@ fn zirReifyFn( block, param_attrs_src, try param_attrs_arr.elemValue(pt, param_idx), - std.lang.Type.Fn.Param.Attributes, + std.lang.Type.Fn.ParamAttributes, ); try sema.checkParamType( block, @@ -19827,7 +20075,7 @@ fn zirReifyStruct( }; const container_layout_ty = try sema.getStdLangType(layout_src, .@"Type.ContainerLayout"); - const single_field_attrs_ty = try sema.getStdLangType(field_attrs_src, .@"Type.StructField.Attributes"); + const single_field_attrs_ty = try sema.getStdLangType(field_attrs_src, .@"Type.Struct.FieldAttributes"); const layout_uncoerced = sema.resolveInst(extra.layout); const layout_coerced = try sema.coerce(block, container_layout_ty, layout_uncoerced, layout_src); @@ -19913,15 +20161,15 @@ fn zirReifyStruct( const field_name = try sema.sliceToIpString(block, field_names_src, field_name_val, .{ .simple = .struct_field_names }); const field_attr_comptime = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex( - std.lang.Type.StructField.Attributes, + std.lang.Type.Struct.FieldAttributes, "comptime", ).?); const field_attr_align = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex( - std.lang.Type.StructField.Attributes, + std.lang.Type.Struct.FieldAttributes, "align", ).?); const field_attr_default_value_ptr = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex( - std.lang.Type.StructField.Attributes, + std.lang.Type.Struct.FieldAttributes, "default_value_ptr", ).?); @@ -19998,15 +20246,15 @@ fn zirReifyStruct( wip.field_types.get(ip)[field_idx] = field_ty.toIntern(); const field_attr_comptime = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex( - std.lang.Type.StructField.Attributes, + std.lang.Type.Struct.FieldAttributes, "comptime", ).?); const field_attr_align = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex( - std.lang.Type.StructField.Attributes, + std.lang.Type.Struct.FieldAttributes, "align", ).?); const field_attr_default_value_ptr = try field_attrs_val.fieldValue(pt, std.meta.fieldIndex( - std.lang.Type.StructField.Attributes, + std.lang.Type.Struct.FieldAttributes, "default_value_ptr", ).?); @@ -20107,7 +20355,7 @@ fn zirReifyUnion( }; const container_layout_ty = try sema.getStdLangType(layout_src, .@"Type.ContainerLayout"); - const single_field_attrs_ty = try sema.getStdLangType(field_attrs_src, .@"Type.UnionField.Attributes"); + const single_field_attrs_ty = try sema.getStdLangType(field_attrs_src, .@"Type.Union.FieldAttributes"); const layout_uncoerced = sema.resolveInst(extra.layout); const layout_coerced = try sema.coerce(block, container_layout_ty, layout_uncoerced, layout_src); @@ -20196,7 +20444,7 @@ fn zirReifyUnion( block, field_attrs_src, try field_attrs_arr.elemValue(pt, field_idx), - std.lang.Type.UnionField.Attributes, + std.lang.Type.Union.FieldAttributes, ); if (field_attrs.@"align") |bytes| { if (layout == .@"packed") { @@ -20245,7 +20493,7 @@ fn zirReifyUnion( block, .unneeded, try field_attrs_arr.elemValue(pt, field_idx), - std.lang.Type.UnionField.Attributes, + std.lang.Type.Union.FieldAttributes, ); if (field_attrs.@"align") |bytes| { // No source location; first loop checked this is valid. @@ -25211,9 +25459,9 @@ fn addSafetyCheckExtra( try parent_block.instructions.ensureUnusedCapacity(gpa, 1); - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".field_names.len + 1 + // The main block only needs space for the cond_br. - @typeInfo(Air.CondBr).@"struct".fields.len + + @typeInfo(Air.CondBr).@"struct".field_names.len + 1 + // The ok branch of the cond_br only needs space for the br. fail_block.instructions.items.len); @@ -33021,8 +33269,8 @@ pub fn getTmpAir(sema: Sema) Air { } pub fn addExtra(sema: *Sema, extra: anytype) Allocator.Error!u32 { - const fields = std.meta.fields(@TypeOf(extra)); - try sema.air_extra.ensureUnusedCapacity(sema.gpa, fields.len); + const field_count = std.meta.fieldNames(@TypeOf(extra)).len; + try sema.air_extra.ensureUnusedCapacity(sema.gpa, field_count); return sema.addExtraAssumeCapacity(extra); } @@ -33032,15 +33280,15 @@ pub fn addExtraAssumeCapacity(sema: *Sema, extra: anytype) u32 { return result; } -fn payloadToExtraItems(data: anytype) [@typeInfo(@TypeOf(data)).@"struct".fields.len]u32 { - const fields = @typeInfo(@TypeOf(data)).@"struct".fields; - var result: [fields.len]u32 = undefined; - inline for (&result, fields) |*val, field| { - val.* = switch (field.type) { - u32 => @field(data, field.name), - i32, Air.CondBr.BranchHints, Air.Asm.Flags => @bitCast(@field(data, field.name)), - Air.Inst.Ref, InternPool.Index => @intFromEnum(@field(data, field.name)), - else => @compileError("bad field type: " ++ @typeName(field.type)), +fn payloadToExtraItems(data: anytype) [@typeInfo(@TypeOf(data)).@"struct".field_names.len]u32 { + const info = @typeInfo(@TypeOf(data)).@"struct"; + var result: [info.field_names.len]u32 = undefined; + inline for (&result, info.field_names, info.field_types) |*val, field_name, field_type| { + val.* = switch (field_type) { + u32 => @field(data, field_name), + i32, Air.CondBr.BranchHints, Air.Asm.Flags => @bitCast(@field(data, field_name)), + Air.Inst.Ref, InternPool.Index => @intFromEnum(@field(data, field_name)), + else => @compileError("bad field type: " ++ @typeName(field_type)), }; } return result; diff --git a/src/Value.zig b/src/Value.zig index e79b1f31e8..40ccd52792 100644 --- a/src/Value.zig +++ b/src/Value.zig @@ -2288,23 +2288,23 @@ pub fn interpret(val: Value, comptime T: type, pt: Zcu.PerThread) error{ OutOfMe .@"struct" => |@"struct"| switch (interpret_mode) { .direct => { - if (ty.structFieldCount(zcu) != @"struct".fields.len) return error.TypeMismatch; + if (ty.structFieldCount(zcu) != @"struct".field_names.len) return error.TypeMismatch; var result: T = undefined; - inline for (@"struct".fields, 0..) |field, field_idx| { + inline for (@"struct".field_names, @"struct".field_types, 0..) |field_name, field_type, field_idx| { const field_val = try val.fieldValue(pt, field_idx); - @field(result, field.name) = try field_val.interpret(field.type, pt); + @field(result, field_name) = try field_val.interpret(field_type, pt); } return result; }, .by_name => { const struct_obj = zcu.typeToStruct(ty) orelse return error.TypeMismatch; var result: T = undefined; - inline for (@"struct".fields) |field| { - const field_name_ip = try ip.getOrPutString(zcu.gpa, io, pt.tid, field.name, .no_embedded_nulls); - @field(result, field.name) = if (struct_obj.nameIndex(ip, field_name_ip)) |field_idx| f: { + inline for (@"struct".field_names, @"struct".field_types, @"struct".field_attrs) |field_name, field_type, field_attr| { + const field_name_ip = try ip.getOrPutString(zcu.gpa, io, pt.tid, field_name, .no_embedded_nulls); + @field(result, field_name) = if (struct_obj.nameIndex(ip, field_name_ip)) |field_idx| f: { const field_val = try val.fieldValue(pt, field_idx); - break :f try field_val.interpret(field.type, pt); - } else (field.defaultValue() orelse return error.TypeMismatch); + break :f try field_val.interpret(field_type, pt); + } else (field_attr.defaultValue(field_type) orelse return error.TypeMismatch); } return result; }, @@ -2385,11 +2385,11 @@ pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory .@"struct" => |@"struct"| switch (interpret_mode) { .direct => { - if (ty.structFieldCount(zcu) != @"struct".fields.len) return error.TypeMismatch; - var field_vals: [@"struct".fields.len]InternPool.Index = undefined; - inline for (&field_vals, @"struct".fields, 0..) |*field_val, field, field_idx| { + if (ty.structFieldCount(zcu) != @"struct".field_names.len) return error.TypeMismatch; + var field_vals: [@"struct".field_names.len]InternPool.Index = undefined; + inline for (&field_vals, @"struct".field_names, 0..) |*field_val, field_name, field_idx| { const field_ty = ty.fieldType(field_idx, zcu); - field_val.* = (try uninterpret(@field(val, field.name), field_ty, pt)).toIntern(); + field_val.* = (try uninterpret(@field(val, field_name), field_ty, pt)).toIntern(); } return pt.aggregateValue(ty, &field_vals); }, @@ -2399,11 +2399,11 @@ pub fn uninterpret(val: anytype, ty: Type, pt: Zcu.PerThread) error{ OutOfMemory const field_vals = try zcu.gpa.alloc(InternPool.Index, want_fields_len); defer zcu.gpa.free(field_vals); @memset(field_vals, .none); - inline for (@"struct".fields) |field| { - const field_name_ip = try ip.getOrPutString(zcu.gpa, io, pt.tid, field.name, .no_embedded_nulls); + inline for (@"struct".field_names) |field_name| { + const field_name_ip = try ip.getOrPutString(zcu.gpa, io, pt.tid, field_name, .no_embedded_nulls); if (struct_obj.nameIndex(ip, field_name_ip)) |field_idx| { const field_ty = ty.fieldType(field_idx, zcu); - field_vals[field_idx] = (try uninterpret(@field(val, field.name), field_ty, pt)).toIntern(); + field_vals[field_idx] = (try uninterpret(@field(val, field_name), field_ty, pt)).toIntern(); } } for (field_vals, 0..) |*field_val, field_idx| { diff --git a/src/Zcu.zig b/src/Zcu.zig index 16ee66ae70..80c3366381 100644 --- a/src/Zcu.zig +++ b/src/Zcu.zig @@ -48,12 +48,12 @@ const ZonGen = std.zig.ZonGen; comptime { @setEvalBranchQuota(4000); for ( - @typeInfo(Zir.Inst.Ref).@"enum".fields, - @typeInfo(Air.Inst.Ref).@"enum".fields, - @typeInfo(InternPool.Index).@"enum".fields, - ) |zir_field, air_field, ip_field| { - assert(mem.eql(u8, zir_field.name, ip_field.name)); - assert(mem.eql(u8, air_field.name, ip_field.name)); + @typeInfo(Zir.Inst.Ref).@"enum".field_names, + @typeInfo(Air.Inst.Ref).@"enum".field_names, + @typeInfo(InternPool.Index).@"enum".field_names, + ) |zir_field_name, air_field_name, ip_field_name| { + assert(mem.eql(u8, zir_field_name, ip_field_name)); + assert(mem.eql(u8, air_field_name, ip_field_name)); } } @@ -448,8 +448,7 @@ pub const StdLangDecl = enum { Type, @"Type.Fn", - @"Type.Fn.Param", - @"Type.Fn.Param.Attributes", + @"Type.Fn.ParamAttributes", @"Type.Fn.Attributes", @"Type.Int", @"Type.Float", @@ -459,20 +458,16 @@ pub const StdLangDecl = enum { @"Type.Array", @"Type.Vector", @"Type.Optional", - @"Type.Error", @"Type.ErrorUnion", - @"Type.EnumField", + @"Type.ErrorSet", @"Type.Enum", @"Type.Enum.Mode", @"Type.Union", - @"Type.UnionField", - @"Type.UnionField.Attributes", + @"Type.Union.FieldAttributes", @"Type.Struct", - @"Type.StructField", - @"Type.StructField.Attributes", + @"Type.Struct.FieldAttributes", @"Type.ContainerLayout", @"Type.Opaque", - @"Type.Declaration", panic, @"panic.call", @@ -533,8 +528,7 @@ pub const StdLangDecl = enum { .Type, .@"Type.Fn", - .@"Type.Fn.Param", - .@"Type.Fn.Param.Attributes", + .@"Type.Fn.ParamAttributes", .@"Type.Fn.Attributes", .@"Type.Int", .@"Type.Float", @@ -544,20 +538,16 @@ pub const StdLangDecl = enum { .@"Type.Array", .@"Type.Vector", .@"Type.Optional", - .@"Type.Error", .@"Type.ErrorUnion", - .@"Type.EnumField", + .@"Type.ErrorSet", .@"Type.Enum", .@"Type.Enum.Mode", .@"Type.Union", - .@"Type.UnionField", - .@"Type.UnionField.Attributes", + .@"Type.Union.FieldAttributes", .@"Type.Struct", - .@"Type.StructField", - .@"Type.StructField.Attributes", + .@"Type.Struct.FieldAttributes", .@"Type.ContainerLayout", .@"Type.Opaque", - .@"Type.Declaration", => .type, .panic => .type, @@ -611,7 +601,7 @@ pub const StdLangDecl = enum { .VaList => .va_list, .assembly, .@"assembly.Clobbers" => .assembly, else => { - if (@intFromEnum(decl) <= @intFromEnum(StdLangDecl.@"Type.Declaration")) { + if (@intFromEnum(decl) <= @intFromEnum(StdLangDecl.@"Type.Opaque")) { return .main; } else { return .panic; diff --git a/src/Zcu/PerThread.zig b/src/Zcu/PerThread.zig index ed10d9b70d..e4a3b9ca82 100644 --- a/src/Zcu/PerThread.zig +++ b/src/Zcu/PerThread.zig @@ -3344,7 +3344,7 @@ fn analyzeFuncBodyInner( ip.funcSetHasErrorTrace(io, func_index, fn_ty_info.cc == .auto); // First few indexes of extra are reserved and set at the end. - const reserved_count = @typeInfo(Air.ExtraIndex).@"enum".fields.len; + const reserved_count = @typeInfo(Air.ExtraIndex).@"enum".field_names.len; try sema.air_extra.ensureTotalCapacity(gpa, reserved_count); sema.air_extra.items.len += reserved_count; @@ -3477,7 +3477,7 @@ fn analyzeFuncBodyInner( } // Copy the block into place and mark that as the main block. - try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".fields.len + + try sema.air_extra.ensureUnusedCapacity(gpa, @typeInfo(Air.Block).@"struct".field_names.len + inner_block.instructions.items.len); const main_block_index = sema.addExtraAssumeCapacity(Air.Block{ .body_len = @intCast(inner_block.instructions.items.len), diff --git a/src/codegen/aarch64/Assemble.zig b/src/codegen/aarch64/Assemble.zig index 8ee9e933a4..2875f6fc96 100644 --- a/src/codegen/aarch64/Assemble.zig +++ b/src/codegen/aarch64/Assemble.zig @@ -41,7 +41,7 @@ fn zonCast(comptime Result: type, zon_value: anytype, symbols: anytype) Result { .void, .bool, .int, .float, .pointer, .comptime_float, .comptime_int, .@"enum" => return zon_value, .@"struct" => |zon_struct| switch (@typeInfo(Result)) { .pointer => |result_pointer| { - comptime assert(result_pointer.size == .slice and result_pointer.is_const); + comptime assert(result_pointer.size == .slice and result_pointer.attrs.@"const"); const elems = comptime blk: { var temp_elems: [zon_value.len]result_pointer.child = undefined; for (&temp_elems, zon_value) |*elem, zon_elem| elem.* = zonCast(result_pointer.child, zon_elem, symbols); @@ -52,16 +52,17 @@ fn zonCast(comptime Result: type, zon_value: anytype, symbols: anytype) Result { .@"struct" => |result_struct| { comptime var used_zon_fields = 0; var result: Result = undefined; - inline for (result_struct.fields) |result_field| @field(result, result_field.name) = if (@hasField(ZonValue, result_field.name)) result: { - used_zon_fields += 1; - break :result zonCast(@FieldType(Result, result_field.name), @field(zon_value, result_field.name), symbols); - } else result_field.defaultValue() orelse @compileError(std.fmt.comptimePrint("missing zon field '{s}': {} <- {any}", .{ result_field.name, Result, zon_value })); - if (used_zon_fields != zon_struct.fields.len) @compileError(std.fmt.comptimePrint("unused zon field: {} <- {any}", .{ Result, zon_value })); + inline for (result_struct.field_names, result_struct.field_types, result_struct.field_attrs) |result_field_name, result_field_type, result_field_attrs| + @field(result, result_field_name) = if (@hasField(ZonValue, result_field_name)) result: { + used_zon_fields += 1; + break :result zonCast(@FieldType(Result, result_field_name), @field(zon_value, result_field_name), symbols); + } else result_field_attrs.defaultValue(result_field_type) orelse @compileError(std.fmt.comptimePrint("missing zon field '{s}': {} <- {any}", .{ result_field_name, Result, zon_value })); + if (used_zon_fields != zon_struct.field_names.len) @compileError(std.fmt.comptimePrint("unused zon field: {} <- {any}", .{ Result, zon_value })); return result; }, .@"union" => { - if (zon_struct.fields.len != 1) @compileError(std.fmt.comptimePrint("{} <- {any}", .{ Result, zon_value })); - const field_name = zon_struct.fields[0].name; + if (zon_struct.field_names.len != 1) @compileError(std.fmt.comptimePrint("{} <- {any}", .{ Result, zon_value })); + const field_name = zon_struct.field_names[0]; return @unionInit( Result, field_name, @@ -106,12 +107,12 @@ const matchers = matchers: { var mut_matchers: [instructions.len]*const fn (as: *Assemble) error{InvalidSyntax}!?Instruction = undefined; for (instructions, &mut_matchers) |instruction, *matcher| matcher.* = struct { fn match(as: *Assemble) !?Instruction { - comptime for (@typeInfo(@TypeOf(instruction)).@"struct".fields) |field| { - if (std.mem.eql(u8, field.name, "requires")) continue; - if (std.mem.eql(u8, field.name, "pattern")) continue; - if (std.mem.eql(u8, field.name, "symbols")) continue; - if (std.mem.eql(u8, field.name, "encode")) continue; - @compileError("unexpected field '" ++ field.name ++ "'"); + comptime for (@typeInfo(@TypeOf(instruction)).@"struct".field_names) |field_name| { + if (std.mem.eql(u8, field_name, "requires")) continue; + if (std.mem.eql(u8, field_name, "pattern")) continue; + if (std.mem.eql(u8, field_name, "symbols")) continue; + if (std.mem.eql(u8, field_name, "encode")) continue; + @compileError("unexpected field '" ++ field_name ++ "'"); }; if (@hasField(@TypeOf(instruction), "requires")) _ = zonCast( []const std.Target.aarch64.Feature, @@ -119,12 +120,12 @@ const matchers = matchers: { .{}, ); var symbols: Symbols: { - const symbols = @typeInfo(@TypeOf(instruction.symbols)).@"struct".fields; - var field_names: [symbols.len][]const u8 = undefined; - var field_types: [symbols.len]type = undefined; - for (symbols, &field_names, &field_types) |symbol, *field_name, *FieldType| { - field_name.* = symbol.name; - FieldType.* = zonCast(SymbolSpec, @field(instruction.symbols, symbol.name), .{}).Storage(); + const symbol_names = @typeInfo(@TypeOf(instruction.symbols)).@"struct".field_names; + var field_names: [symbol_names.len][]const u8 = undefined; + var field_types: [symbol_names.len]type = undefined; + for (symbol_names, &field_names, &field_types) |symbol_name, *field_name, *FieldType| { + field_name.* = symbol_name; + FieldType.* = zonCast(SymbolSpec, @field(instruction.symbols, symbol_name), .{}).Storage(); } break :Symbols @Struct(.auto, null, &field_names, &field_types, &@splat(.{})); } = undefined; @@ -158,8 +159,8 @@ const matchers = matchers: { const encode = @field(Instruction, @tagName(instruction.encode[0])); const Encode = @TypeOf(encode); var args: std.meta.ArgsTuple(Encode) = undefined; - inline for (&args, @typeInfo(Encode).@"fn".params, 1..instruction.encode.len) |*arg, param, encode_index| - arg.* = zonCast(param.type.?, instruction.encode[encode_index], symbols); + inline for (&args, @typeInfo(Encode).@"fn".param_types, 1..instruction.encode.len) |*arg, param_type, encode_index| + arg.* = zonCast(param_type.?, instruction.encode[encode_index], symbols); return @call(.auto, encode, args); } else if (pattern_token[0] == '<') { const symbol_name = comptime pattern_token[1 .. std.mem.indexOfScalarPos(u8, pattern_token, 1, '|') orelse @@ -369,7 +370,7 @@ const SymbolSpec = union(enum) { var buf: [ max_len: { var max_len = 0; - for (@typeInfo(Result).@"enum".fields) |field| max_len = @max(max_len, field.name.len); + for (@typeInfo(Result).@"enum".field_names) |field_name| max_len = @max(max_len, field_name.len); break :max_len max_len; } + 1 ]u8 = undefined; @@ -466,7 +467,7 @@ const SymbolSpec = union(enum) { var buf: [ max_len: { var max_len = 0; - for (@typeInfo(Result).@"enum".fields) |field| max_len = @max(max_len, field.name.len); + for (@typeInfo(Result).@"enum".field_names) |field_name| max_len = @max(max_len, field_name.len); break :max_len max_len; } + 1 ]u8 = undefined; @@ -487,7 +488,7 @@ const SymbolSpec = union(enum) { var buf: [ max_len: { var max_len = 0; - for (@typeInfo(Result).@"enum".fields) |field| max_len = @max(max_len, field.name.len); + for (@typeInfo(Result).@"enum".field_names) |field_name| max_len = @max(max_len, field_name.len); break :max_len max_len; } + 1 ]u8 = undefined; @@ -508,7 +509,7 @@ const SymbolSpec = union(enum) { var buf: [ max_len: { var max_len = 0; - for (@typeInfo(Result).@"enum".fields) |field| max_len = @max(max_len, field.name.len); + for (@typeInfo(Result).@"enum".field_names) |field_name| max_len = @max(max_len, field_name.len); break :max_len max_len; } + 1 ]u8 = undefined; diff --git a/src/codegen/aarch64/Select.zig b/src/codegen/aarch64/Select.zig index 5a1bb5eb9b..71dca1d925 100644 --- a/src/codegen/aarch64/Select.zig +++ b/src/codegen/aarch64/Select.zig @@ -8891,14 +8891,8 @@ pub const Value = struct { pub const Tag = @typeInfo(Parent).@"union".tag_type.?; pub const Payload = Payload: { - const fields = @typeInfo(Parent).@"union".fields; - var types: [fields.len]type = undefined; - var names: [fields.len][]const u8 = undefined; - for (fields, &types, &names) |f, *ty, *name| { - ty.* = f.type; - name.* = f.name; - } - break :Payload @Union(.auto, null, &names, &types, &@splat(.{})); + const info = @typeInfo(Parent).@"union"; + break :Payload @Union(.auto, null, info.field_names, info.field_types[0..], &@splat(.{})); }; }; @@ -8916,14 +8910,8 @@ pub const Value = struct { pub const Tag = @typeInfo(Location).@"union".tag_type.?; pub const Payload = Payload: { - const fields = @typeInfo(Location).@"union".fields; - var types: [fields.len]type = undefined; - var names: [fields.len][]const u8 = undefined; - for (fields, &types, &names) |f, *ty, *name| { - ty.* = f.type; - name.* = f.name; - } - break :Payload @Union(.auto, null, &names, &types, &@splat(.{})); + const info = @typeInfo(Location).@"union"; + break :Payload @Union(.auto, null, info.field_names, info.field_types[0..], &@splat(.{})); }; }; @@ -11257,7 +11245,7 @@ fn dumpValuesInner(isel: *Select, which: WhichValues) !void { var reverse_live_registers: std.AutoHashMapUnmanaged(Value.Index, Register.Alias) = .empty; defer reverse_live_registers.deinit(gpa); { - try reverse_live_registers.ensureTotalCapacity(gpa, @typeInfo(Register.Alias).@"enum".fields.len); + try reverse_live_registers.ensureTotalCapacity(gpa, @typeInfo(Register.Alias).@"enum".field_names.len); var live_reg_it = isel.live_registers.iterator(); while (live_reg_it.next()) |live_reg_entry| switch (live_reg_entry.value.*) { _ => reverse_live_registers.putAssumeCapacityNoClobber(live_reg_entry.value.*, live_reg_entry.key), diff --git a/src/codegen/aarch64/encoding.zig b/src/codegen/aarch64/encoding.zig index 1a9c9a2dc7..c2b8d61828 100644 --- a/src/codegen/aarch64/encoding.zig +++ b/src/codegen/aarch64/encoding.zig @@ -1271,9 +1271,9 @@ pub const Register = struct { if (symbol_it.next() != null) break :encoded; return .{ .op0 = op0, .op1 = op1, .CRn = CRn, .CRm = CRm, .op2 = op2 }; } - inline for (@typeInfo(System).@"struct".decls) |decl| { - if (@TypeOf(@field(System, decl.name)) != System) continue; - if (toLowerEqlAssertLower(reg, decl.name)) return @field(System, decl.name); + inline for (@typeInfo(System).@"struct".decl_names) |decl_name| { + if (@TypeOf(@field(System, decl_name)) != System) continue; + if (toLowerEqlAssertLower(reg, decl_name)) return @field(System, decl_name); } return null; } @@ -16561,30 +16561,30 @@ pub const Instruction = packed union { if (info.layout != .@"packed" or @bitSizeOf(Type) != @bitSizeOf(Backing)) { @compileLog(name ++ " should have u32 abi"); } - for (info.fields) |field| verify(name ++ "." ++ field.name, field.type); + for (info.field_names, info.field_types) |field_name, field_type| verify(name ++ "." ++ field_name, field_type); }, .@"struct" => |info| { if (info.layout != .@"packed" or info.backing_integer != Backing) { @compileLog(name ++ " should have u32 abi"); } var bit_offset = 0; - for (info.fields) |field| { - if (std.mem.startsWith(u8, field.name, "encoded")) { - if (if (std.fmt.parseInt(u5, field.name["encoded".len..], 10)) |encoded_bit_offset| encoded_bit_offset != bit_offset else |_| true) { - @compileError(std.fmt.comptimePrint("{s}.{s} should be named encoded{d}", .{ name, field.name, bit_offset })); + for (info.field_names, info.field_types, info.field_attrs) |field_name, field_type, field_attrs| { + if (std.mem.startsWith(u8, field_name, "encoded")) { + if (if (std.fmt.parseInt(u5, field_name["encoded".len..], 10)) |encoded_bit_offset| encoded_bit_offset != bit_offset else |_| true) { + @compileError(std.fmt.comptimePrint("{s}.{s} should be named encoded{d}", .{ name, field_name, bit_offset })); } - if (field.default_value_ptr != null) { - @compileError(std.fmt.comptimePrint("{s}.{s} should be named decoded{d}", .{ name, field.name, bit_offset })); + if (field_attrs.default_value_ptr != null) { + @compileError(std.fmt.comptimePrint("{s}.{s} should be named decoded{d}", .{ name, field_name, bit_offset })); } - } else if (std.mem.startsWith(u8, field.name, "decoded")) { - if (if (std.fmt.parseInt(u5, field.name["decoded".len..], 10)) |decoded_bit_offset| decoded_bit_offset != bit_offset else |_| true) { - @compileError(std.fmt.comptimePrint("{s}.{s} should be named decoded{d}", .{ name, field.name, bit_offset })); + } else if (std.mem.startsWith(u8, field_name, "decoded")) { + if (if (std.fmt.parseInt(u5, field_name["decoded".len..], 10)) |decoded_bit_offset| decoded_bit_offset != bit_offset else |_| true) { + @compileError(std.fmt.comptimePrint("{s}.{s} should be named decoded{d}", .{ name, field_name, bit_offset })); } - if (field.default_value_ptr == null) { - @compileError(std.fmt.comptimePrint("{s}.{s} should be named encoded{d}", .{ name, field.name, bit_offset })); + if (field_attrs.default_value_ptr == null) { + @compileError(std.fmt.comptimePrint("{s}.{s} should be named encoded{d}", .{ name, field_name, bit_offset })); } } - bit_offset += @bitSizeOf(field.type); + bit_offset += @bitSizeOf(field_type); } }, else => @compileError(name ++ " has an unexpected field type"), diff --git a/src/codegen/riscv64/bits.zig b/src/codegen/riscv64/bits.zig index d883615b4a..b2fea0171d 100644 --- a/src/codegen/riscv64/bits.zig +++ b/src/codegen/riscv64/bits.zig @@ -190,7 +190,7 @@ pub const Register = enum(u8) { /// The goal of this function is to return the same ID for `zero` and `x0` but two /// seperate IDs for `x0` and `f0`. We will assume that each register set has 32 registers /// and is repeated twice, once for the named version, once for the number version. - pub fn id(reg: Register) std.math.IntFittingRange(0, @typeInfo(Register).@"enum".fields.len) { + pub fn id(reg: Register) std.math.IntFittingRange(0, @typeInfo(Register).@"enum".field_names.len) { const base = switch (@intFromEnum(reg)) { // zig fmt: off @intFromEnum(Register.zero) ... @intFromEnum(Register.x31) => @intFromEnum(Register.zero), @@ -251,7 +251,7 @@ pub const FrameIndex = enum(u32) { /// Other indices are used for local variable stack slots _, - pub const named_count = @typeInfo(FrameIndex).@"enum".fields.len; + pub const named_count = @typeInfo(FrameIndex).@"enum".field_names.len; pub fn isNamed(fi: FrameIndex) bool { return @intFromEnum(fi) < named_count; diff --git a/src/codegen/riscv64/encoding.zig b/src/codegen/riscv64/encoding.zig index 109e1d08f8..a6c4303af3 100644 --- a/src/codegen/riscv64/encoding.zig +++ b/src/codegen/riscv64/encoding.zig @@ -498,8 +498,8 @@ pub const Instruction = union(Lir.Format) { extra: u32, comptime { - for (std.meta.fields(Instruction)) |field| { - assert(@bitSizeOf(field.type) == 32); + for (std.meta.fieldTypes(Instruction)) |field_type| { + assert(@bitSizeOf(field_type) == 32); } } diff --git a/src/codegen/sparc64/Mir.zig b/src/codegen/sparc64/Mir.zig index 3e4d8ce2c2..d50f7260d0 100644 --- a/src/codegen/sparc64/Mir.zig +++ b/src/codegen/sparc64/Mir.zig @@ -410,11 +410,11 @@ pub fn emit( /// Returns the requested data, as well as the new index which is at the start of the /// trailers for the object. pub fn extraData(mir: Mir, comptime T: type, index: usize) struct { data: T, end: usize } { - const fields = std.meta.fields(T); + const info = @typeInfo(T).@"struct"; var i: usize = index; var result: T = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => mir.extra[i], i32 => @as(i32, @bitCast(mir.extra[i])), else => @compileError("bad field type"), diff --git a/src/codegen/spirv/Section.zig b/src/codegen/spirv/Section.zig index 42009a7c9d..c3194a5456 100644 --- a/src/codegen/spirv/Section.zig +++ b/src/codegen/spirv/Section.zig @@ -102,13 +102,13 @@ pub fn writeDoubleWord(section: *Section, dword: DoubleWord) void { } fn writeOperands(section: *Section, comptime Operands: type, operands: Operands) void { - const fields = switch (@typeInfo(Operands)) { - .@"struct" => |info| info.fields, + const info = switch (@typeInfo(Operands)) { + .@"struct" => |info| info, .void => return, else => unreachable, }; - inline for (fields) |field| { - section.writeOperand(field.type, @field(operands, field.name)); + inline for (info.field_names, info.field_types) |field_name, field_type| { + section.writeOperand(field_type, @field(operands, field_name)); } } @@ -171,12 +171,13 @@ fn writeContextDependentNumber(section: *Section, operand: spec.LiteralContextDe fn writeExtendedMask(section: *Section, comptime Operand: type, operand: Operand) void { var mask: Word = 0; - inline for (@typeInfo(Operand).@"struct".fields, 0..) |field, bit| { - switch (@typeInfo(field.type)) { - .optional => if (@field(operand, field.name) != null) { + const info = @typeInfo(Operand).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, bit| { + switch (@typeInfo(field_type)) { + .optional => if (@field(operand, field_name) != null) { mask |= 1 << @as(u5, @intCast(bit)); }, - .bool => if (@field(operand, field.name)) { + .bool => if (@field(operand, field_name)) { mask |= 1 << @as(u5, @intCast(bit)); }, else => unreachable, @@ -185,10 +186,10 @@ fn writeExtendedMask(section: *Section, comptime Operand: type, operand: Operand section.writeWord(mask); - inline for (@typeInfo(Operand).@"struct".fields) |field| { - switch (@typeInfo(field.type)) { - .optional => |info| if (@field(operand, field.name)) |child| { - section.writeOperands(info.child, child); + inline for (info.field_names, info.field_types) |field_name, field_type| { + switch (@typeInfo(field_type)) { + .optional => |opt_info| if (@field(operand, field_name)) |child| { + section.writeOperands(opt_info.child, child); }, .bool => {}, else => unreachable, @@ -213,15 +214,15 @@ fn instructionSize(comptime opcode: spec.Opcode, operands: opcode.Operands()) us } fn operandsSize(comptime Operands: type, operands: Operands) usize { - const fields = switch (@typeInfo(Operands)) { - .@"struct" => |info| info.fields, + const info = switch (@typeInfo(Operands)) { + .@"struct" => |info| info, .void => return 0, else => unreachable, }; var total: usize = 0; - inline for (fields) |field| { - total += operandSize(field.type, @field(operands, field.name)); + inline for (info.field_names, info.field_types) |field_name, field_type| { + total += operandSize(field_type, @field(operands, field_name)); } return total; @@ -252,9 +253,9 @@ fn operandSize(comptime Operand: type, operand: Operand) usize { if (struct_info.layout == .@"packed") return 1; var total: usize = 0; - inline for (@typeInfo(Operand).@"struct".fields) |field| { - switch (@typeInfo(field.type)) { - .optional => |info| if (@field(operand, field.name)) |child| { + inline for (struct_info.field_names, struct_info.field_types) |field_name, field_type| { + switch (@typeInfo(field_type)) { + .optional => |info| if (@field(operand, field_name)) |child| { total += operandsSize(info.child, child); }, .bool => {}, diff --git a/src/codegen/wasm/CodeGen.zig b/src/codegen/wasm/CodeGen.zig index 415dc5b369..fb13224288 100644 --- a/src/codegen/wasm/CodeGen.zig +++ b/src/codegen/wasm/CodeGen.zig @@ -563,24 +563,24 @@ fn addCallIntrinsic(cg: *CodeGen, intrinsic: Mir.Intrinsic) error{OutOfMemory}!v /// Appends entries to `mir_extra` based on the type of `extra`. /// Returns the index into `mir_extra` fn addExtra(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 { - const fields = std.meta.fields(@TypeOf(extra)); - try cg.mir_extra.ensureUnusedCapacity(cg.gpa, fields.len); + const field_count = std.meta.fieldNames(@TypeOf(extra)).len; + try cg.mir_extra.ensureUnusedCapacity(cg.gpa, field_count); return cg.addExtraAssumeCapacity(extra); } /// Appends entries to `mir_extra` based on the type of `extra`. /// Returns the index into `mir_extra` fn addExtraAssumeCapacity(cg: *CodeGen, extra: anytype) error{OutOfMemory}!u32 { - const fields = std.meta.fields(@TypeOf(extra)); + const info = @typeInfo(@TypeOf(extra)).@"struct"; const result: u32 = @intCast(cg.mir_extra.items.len); - inline for (fields) |field| { - cg.mir_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), - i32 => @bitCast(@field(extra, field.name)), + inline for (info.field_names, info.field_types) |field_name, field_type| { + cg.mir_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), + i32 => @bitCast(@field(extra, field_name)), InternPool.Index, InternPool.Nav.Index, - => @intFromEnum(@field(extra, field.name)), - else => |field_type| @compileError("Unsupported field type " ++ @typeName(field_type)), + => @intFromEnum(@field(extra, field_name)), + else => @compileError("Unsupported field type " ++ @typeName(field_type)), }); } return result; diff --git a/src/codegen/wasm/Mir.zig b/src/codegen/wasm/Mir.zig index 7a455ba6d9..662e177447 100644 --- a/src/codegen/wasm/Mir.zig +++ b/src/codegen/wasm/Mir.zig @@ -731,11 +731,11 @@ pub fn lower(mir: *const Mir, wasm: *Wasm, code: *std.ArrayList(u8)) std.mem.All } pub fn extraData(self: *const Mir, comptime T: type, index: usize) struct { data: T, end: usize } { - const fields = std.meta.fields(T); + const info = @typeInfo(T).@"struct"; var i: usize = index; var result: T = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.extra[i], i32 => @bitCast(self.extra[i]), Wasm.UavsObjIndex, @@ -743,7 +743,7 @@ pub fn extraData(self: *const Mir, comptime T: type, index: usize) struct { data InternPool.Nav.Index, InternPool.Index, => @enumFromInt(self.extra[i]), - else => |field_type| @compileError("Unsupported field type " ++ @typeName(field_type)), + else => @compileError("Unsupported field type " ++ @typeName(field_type)), }; i += 1; } diff --git a/src/codegen/x86_64/CodeGen.zig b/src/codegen/x86_64/CodeGen.zig index 05556aaed9..ee09abc3c3 100644 --- a/src/codegen/x86_64/CodeGen.zig +++ b/src/codegen/x86_64/CodeGen.zig @@ -1214,20 +1214,20 @@ fn addInst(self: *CodeGen, inst: Mir.Inst) error{OutOfMemory}!Mir.Inst.Index { } fn addExtra(self: *CodeGen, extra: anytype) Allocator.Error!u32 { - const fields = std.meta.fields(@TypeOf(extra)); - try self.mir_extra.ensureUnusedCapacity(self.gpa, fields.len); + const field_count = std.meta.fieldNames(@TypeOf(extra)).len; + try self.mir_extra.ensureUnusedCapacity(self.gpa, field_count); return self.addExtraAssumeCapacity(extra); } fn addExtraAssumeCapacity(self: *CodeGen, extra: anytype) u32 { - const fields = std.meta.fields(@TypeOf(extra)); + const info = @typeInfo(@TypeOf(extra)).@"struct"; const result: u32 = @intCast(self.mir_extra.items.len); - inline for (fields) |field| { - self.mir_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), - i32, Mir.Memory.Info => @bitCast(@field(extra, field.name)), - FrameIndex => @intFromEnum(@field(extra, field.name)), - else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.mir_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), + i32, Mir.Memory.Info => @bitCast(@field(extra, field_name)), + FrameIndex => @intFromEnum(@field(extra, field_name)), + else => @compileError("bad field type: " ++ field_name ++ ": " ++ @typeName(field_type)), }); } return result; @@ -177140,7 +177140,7 @@ fn airBr(self: *CodeGen, inst: Air.Inst.Index) !void { } fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { - @setEvalBranchQuota(1_100 + @typeInfo(Mir.Inst.Fixes).@"enum".fields.len); + @setEvalBranchQuota(1_100 + @typeInfo(Mir.Inst.Fixes).@"enum".field_names.len); const pt = self.pt; const zcu = pt.zcu; const unwrapped_asm = self.air.unwrapAsm(inst); @@ -177748,8 +177748,8 @@ fn airAsm(self: *CodeGen, inst: Air.Inst.Index) !void { std.mem.reverse(Operand, ops[0..ops_len]); if (mnem_size.size != .none and !mnem_size.used) { comptime var max_mnem_len: usize = 0; - inline for (@typeInfo(encoder.Instruction.Mnemonic).@"enum".fields) |mnem| - max_mnem_len = @max(mnem.name.len, max_mnem_len); + inline for (@typeInfo(encoder.Instruction.Mnemonic).@"enum".field_names) |mnem_name| + max_mnem_len = @max(mnem_name.len, max_mnem_len); var intel_mnem_buf: [max_mnem_len + 1]u8 = undefined; const intel_mnem_str = std.fmt.bufPrint(&intel_mnem_buf, "{s}{c}", .{ @tagName(mnem_tag), diff --git a/src/codegen/x86_64/Encoding.zig b/src/codegen/x86_64/Encoding.zig index 7aca0c3497..8115efeee5 100644 --- a/src/codegen/x86_64/Encoding.zig +++ b/src/codegen/x86_64/Encoding.zig @@ -1028,7 +1028,7 @@ const mnemonic_to_encodings_map = init: { const Entry = struct { Mnemonic, OpEn, []const Op, []const u8, ModrmExt, Mode, Feature }; const encodings: []const Entry = @import("encodings.zon"); - const mnemonic_count = @typeInfo(Mnemonic).@"enum".fields.len; + const mnemonic_count = @typeInfo(Mnemonic).@"enum".field_names.len; var mnemonic_map: [mnemonic_count][]Data = @splat(&.{}); for (encodings) |entry| mnemonic_map[@intFromEnum(entry[0])].len += 1; var data_storage: [encodings.len]Data = undefined; diff --git a/src/codegen/x86_64/Lower.zig b/src/codegen/x86_64/Lower.zig index 508ed964ee..1f42fb5638 100644 --- a/src/codegen/x86_64/Lower.zig +++ b/src/codegen/x86_64/Lower.zig @@ -425,8 +425,8 @@ fn encode(lower: *Lower, prefix: Prefix, mnemonic: Mnemonic, ops: []const Operan lower.result_insts_len += 1; } -const inst_tags_len = @typeInfo(Mir.Inst.Tag).@"enum".fields.len; -const inst_fixes_len = @typeInfo(Mir.Inst.Fixes).@"enum".fields.len; +const inst_tags_len = @typeInfo(Mir.Inst.Tag).@"enum".field_names.len; +const inst_fixes_len = @typeInfo(Mir.Inst.Fixes).@"enum".field_names.len; /// Lookup table, indexed by `@intFromEnum(inst.tag) * inst_fixes_len + @intFromEnum(fixes)`. /// The value is the resulting `Mnemonic`, or `null` if the combination is not valid. const mnemonic_table: [inst_tags_len * inst_fixes_len]?Mnemonic = table: { diff --git a/src/codegen/x86_64/Mir.zig b/src/codegen/x86_64/Mir.zig index 69f089ee4d..2e70a04b61 100644 --- a/src/codegen/x86_64/Mir.zig +++ b/src/codegen/x86_64/Mir.zig @@ -1732,9 +1732,9 @@ pub const Inst = struct { assert(@sizeOf(Data) == 8); } const Mnemonic = @import("Encoding.zig").Mnemonic; - if (@typeInfo(Mnemonic).@"enum".fields.len != 978 or - @typeInfo(Fixes).@"enum".fields.len != 231 or - @typeInfo(Tag).@"enum".fields.len != 251) + if (@typeInfo(Mnemonic).@"enum".field_names.len != 978 or + @typeInfo(Fixes).@"enum".field_names.len != 231 or + @typeInfo(Tag).@"enum".field_names.len != 251) { const cond_src = (struct { fn src() std.lang.SourceLocation { @@ -1742,32 +1742,32 @@ pub const Inst = struct { } }).src(); @setEvalBranchQuota(2_000_000); - for (@typeInfo(Mnemonic).@"enum".fields) |mnemonic| { - if (mnemonic.name[0] == '.') continue; - for (@typeInfo(Fixes).@"enum".fields) |fixes| { - const pattern = fixes.name[if (std.mem.indexOfScalar(u8, fixes.name, ' ')) |index| index + " ".len else 0..]; + for (@typeInfo(Mnemonic).@"enum".field_names) |mnemonic_name| { + if (mnemonic_name[0] == '.') continue; + for (@typeInfo(Fixes).@"enum".field_names) |fixes_name| { + const pattern = fixes_name[if (std.mem.indexOfScalar(u8, fixes_name, ' ')) |index| index + " ".len else 0..]; const wildcard_index = std.mem.indexOfScalar(u8, pattern, '_').?; const mnem_prefix = pattern[0..wildcard_index]; const mnem_suffix = pattern[wildcard_index + "_".len ..]; - if (!std.mem.startsWith(u8, mnemonic.name, mnem_prefix)) continue; - if (!std.mem.endsWith(u8, mnemonic.name, mnem_suffix)) continue; + if (!std.mem.startsWith(u8, mnemonic_name, mnem_prefix)) continue; + if (!std.mem.endsWith(u8, mnemonic_name, mnem_suffix)) continue; if (@hasField( Tag, - mnemonic.name[mnem_prefix.len .. mnemonic.name.len - mnem_suffix.len], + mnemonic_name[mnem_prefix.len .. mnemonic_name.len - mnem_suffix.len], )) break; - } else @compileError("'" ++ mnemonic.name ++ "' is not encodable in Mir"); + } else @compileError("'" ++ mnemonic_name ++ "' is not encodable in Mir"); } @compileError(std.fmt.comptimePrint( \\All mnemonics are encodable in Mir! You may now change the condition at {s}:{d} to: - \\if (@typeInfo(Mnemonic).@"enum".fields.len != {d} or - \\ @typeInfo(Fixes).@"enum".fields.len != {d} or - \\ @typeInfo(Tag).@"enum".fields.len != {d}) + \\if (@typeInfo(Mnemonic).@"enum".field_names.len != {d} or + \\ @typeInfo(Fixes).@"enum".field_names.len != {d} or + \\ @typeInfo(Tag).@"enum".field_names.len != {d}) , .{ cond_src.file, cond_src.line - 6, - @typeInfo(Mnemonic).@"enum".fields.len, - @typeInfo(Fixes).@"enum".fields.len, - @typeInfo(Tag).@"enum".fields.len, + @typeInfo(Mnemonic).@"enum".field_names.len, + @typeInfo(Fixes).@"enum".field_names.len, + @typeInfo(Tag).@"enum".field_names.len, })); } } @@ -2069,15 +2069,15 @@ pub fn emitLazy( } pub fn extraData(mir: Mir, comptime T: type, index: u32) struct { data: T, end: u32 } { - const fields = std.meta.fields(T); + const info = @typeInfo(T).@"struct"; var i: u32 = index; var result: T = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => mir.extra[i], i32, Memory.Info => @bitCast(mir.extra[i]), bits.FrameIndex => @enumFromInt(mir.extra[i]), - else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), + else => @compileError("bad field type: " ++ field_name ++ ": " ++ @typeName(field_type)), }; i += 1; } diff --git a/src/codegen/x86_64/bits.zig b/src/codegen/x86_64/bits.zig index 5e464af42b..ece1ad1cf0 100644 --- a/src/codegen/x86_64/bits.zig +++ b/src/codegen/x86_64/bits.zig @@ -722,7 +722,7 @@ pub const FrameIndex = enum(u32) { // Other indices are used for local variable stack slots _, - pub const named_count = @typeInfo(FrameIndex).@"enum".fields.len; + pub const named_count = @typeInfo(FrameIndex).@"enum".field_names.len; pub fn isNamed(fi: FrameIndex) bool { return @intFromEnum(fi) < named_count; diff --git a/src/codegen/x86_64/encoder.zig b/src/codegen/x86_64/encoder.zig index 2fd88b6426..8e83ad9004 100644 --- a/src/codegen/x86_64/encoder.zig +++ b/src/codegen/x86_64/encoder.zig @@ -2272,9 +2272,9 @@ const Assembler = struct { fn mnemonicFromString(bytes: []const u8) ?Instruction.Mnemonic { const ti = @typeInfo(Instruction.Mnemonic).@"enum"; - inline for (ti.fields) |field| { - if (std.mem.eql(u8, bytes, field.name)) { - return @field(Instruction.Mnemonic, field.name); + inline for (ti.field_names) |field_name| { + if (std.mem.eql(u8, bytes, field_name)) { + return @field(Instruction.Mnemonic, field_name); } } return null; @@ -2325,9 +2325,9 @@ const Assembler = struct { fn registerFromString(bytes: []const u8) ?Register { const ti = @typeInfo(Register).@"enum"; - inline for (ti.fields) |field| { - if (std.mem.eql(u8, bytes, field.name)) { - return @field(Register, field.name); + inline for (ti.field_names) |field_name| { + if (std.mem.eql(u8, bytes, field_name)) { + return @field(Register, field_name); } } return null; diff --git a/src/link.zig b/src/link.zig index d9b514428f..dca69bfc75 100644 --- a/src/link.zig +++ b/src/link.zig @@ -52,7 +52,7 @@ pub const Diags = struct { alloc_failure_occurred: bool = false, const Int = blk: { - const bits = @typeInfo(@This()).@"struct".fields.len; + const bits = @typeInfo(@This()).@"struct".field_names.len; break :blk @Int(.unsigned, bits); }; diff --git a/src/link/Coff.zig b/src/link/Coff.zig index 4279265ae9..c2d5f83498 100644 --- a/src/link/Coff.zig +++ b/src/link/Coff.zig @@ -248,7 +248,7 @@ pub const Node = union(enum) { pub const Tag = @typeInfo(Node).@"union".tag_type.?; - const known_count = @typeInfo(@TypeOf(known)).@"struct".fields.len; + const known_count = @typeInfo(@TypeOf(known)).@"struct".field_names.len; const known = known: { const Known = enum { file, @@ -260,8 +260,9 @@ pub const Node = union(enum) { section_table, }; var mut_known: std.enums.EnumFieldStruct(Known, MappedFile.Node.Index, null) = undefined; - for (@typeInfo(Known).@"enum".fields) |field| - @field(mut_known, field.name) = @enumFromInt(field.value); + const info = @typeInfo(Known).@"enum"; + for (info.field_names, info.field_values) |field_name, field_value| + @field(mut_known, field_name) = @enumFromInt(field_value); break :known mut_known; }; @@ -387,7 +388,7 @@ pub const Symbol = struct { text, _, - const known_count = @typeInfo(Index).@"enum".fields.len; + const known_count = @typeInfo(Index).@"enum".field_names.len; pub fn get(si: Symbol.Index, coff: *Coff) *Symbol { return &coff.symbol_table.items[@intFromEnum(si)]; diff --git a/src/link/Dwarf.zig b/src/link/Dwarf.zig index d97dc8f87e..5d8f1a02e2 100644 --- a/src/link/Dwarf.zig +++ b/src/link/Dwarf.zig @@ -5110,16 +5110,16 @@ pub fn resolveRelocs(dwarf: *Dwarf) RelocError!void { } fn DeclValEnum(comptime T: type) type { - const decls = @typeInfo(T).@"struct".decls; - @setEvalBranchQuota(10 * decls.len); - var field_names: [decls.len][]const u8 = undefined; + const decl_names = @typeInfo(T).@"struct".decl_names; + @setEvalBranchQuota(10 * decl_names.len); + var field_names: [decl_names.len][]const u8 = undefined; var fields_len = 0; var min_value: ?comptime_int = null; var max_value: ?comptime_int = null; - for (decls) |decl| { - if (std.mem.startsWith(u8, decl.name, "HP_") or std.mem.endsWith(u8, decl.name, "_user")) continue; - const value = @field(T, decl.name); - field_names[fields_len] = decl.name; + for (decl_names) |decl_name| { + if (std.mem.startsWith(u8, decl_name, "HP_") or std.mem.endsWith(u8, decl_name, "_user")) continue; + const value = @field(T, decl_name); + field_names[fields_len] = decl_name; fields_len += 1; if (min_value == null or min_value.? > value) min_value = value; if (max_value == null or max_value.? < value) max_value = value; diff --git a/src/link/Elf.zig b/src/link/Elf.zig index edf7a3a465..f59e4d8597 100644 --- a/src/link/Elf.zig +++ b/src/link/Elf.zig @@ -1194,7 +1194,7 @@ fn parseDso( // TODO: save this work for later const nsyms = parsed.symbols.len; try so.symbols.ensureTotalCapacityPrecise(gpa, nsyms); - try so.symbols_extra.ensureTotalCapacityPrecise(gpa, nsyms * @typeInfo(Symbol.Extra).@"struct".fields.len); + try so.symbols_extra.ensureTotalCapacityPrecise(gpa, nsyms * @typeInfo(Symbol.Extra).@"struct".field_names.len); try so.symbols_resolver.ensureTotalCapacityPrecise(gpa, nsyms); so.symbols_resolver.appendNTimesAssumeCapacity(0, nsyms); @@ -2354,9 +2354,9 @@ fn sortPhdrs( phdr.* = slice[entry.phndx]; } - inline for (@typeInfo(ProgramHeaderIndexes).@"struct".fields) |field| { - if (@field(special_indexes, field.name).int()) |special_index| { - @field(special_indexes, field.name) = @enumFromInt(backlinks[special_index]); + inline for (@typeInfo(ProgramHeaderIndexes).@"struct".field_names) |field_name| { + if (@field(special_indexes, field_name).int()) |special_index| { + @field(special_indexes, field_name) = @enumFromInt(backlinks[special_index]); } } @@ -2474,9 +2474,9 @@ pub fn sortShdrs( } } - inline for (@typeInfo(SectionIndexes).@"struct".fields) |field| { - if (@field(section_indexes, field.name)) |special_index| { - @field(section_indexes, field.name) = backlinks[special_index]; + inline for (@typeInfo(SectionIndexes).@"struct".field_names) |field_name| { + if (@field(section_indexes, field_name)) |special_index| { + @field(section_indexes, field_name) = backlinks[special_index]; } } diff --git a/src/link/Elf/Atom.zig b/src/link/Elf/Atom.zig index 7f34383f35..269959c9ee 100644 --- a/src/link/Elf/Atom.zig +++ b/src/link/Elf/Atom.zig @@ -878,9 +878,9 @@ pub fn resolveRelocsNonAlloc(self: Atom, elf_file: *Elf, code: []u8, undefs: any pub fn addExtra(atom: *Atom, opts: Extra.AsOptionals, elf_file: *Elf) void { const file_ptr = atom.file(elf_file).?; var extras = file_ptr.atomExtra(atom.extra_index); - inline for (@typeInfo(@TypeOf(opts)).@"struct".fields) |field| { - if (@field(opts, field.name)) |x| { - @field(extras, field.name) = x; + inline for (@typeInfo(@TypeOf(opts)).@"struct".field_names) |field_name| { + if (@field(opts, field_name)) |x| { + @field(extras, field_name) = x; } } file_ptr.setAtomExtra(atom.extra_index, extras); diff --git a/src/link/Elf/LinkerDefined.zig b/src/link/Elf/LinkerDefined.zig index 3704de0dd7..658e2aeea5 100644 --- a/src/link/Elf/LinkerDefined.zig +++ b/src/link/Elf/LinkerDefined.zig @@ -396,17 +396,17 @@ fn addSymbolAssumeCapacity(self: *LinkerDefined) Symbol.Index { } pub fn addSymbolExtra(self: *LinkerDefined, allocator: Allocator, extra: Symbol.Extra) !u32 { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len); + const field_count = @typeInfo(Symbol.Extra).@"struct".field_names.len; + try self.symbols_extra.ensureUnusedCapacity(allocator, field_count); return self.addSymbolExtraAssumeCapacity(extra); } pub fn addSymbolExtraAssumeCapacity(self: *LinkerDefined, extra: Symbol.Extra) u32 { const index = @as(u32, @intCast(self.symbols_extra.items.len)); - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields) |field| { - self.symbols_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.symbols_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -414,11 +414,11 @@ pub fn addSymbolExtraAssumeCapacity(self: *LinkerDefined, extra: Symbol.Extra) u } pub fn symbolExtra(self: *LinkerDefined, index: u32) Symbol.Extra { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; + const info = @typeInfo(Symbol.Extra).@"struct"; var i: usize = index; var result: Symbol.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.symbols_extra.items[i], else => @compileError("bad field type"), }; @@ -428,10 +428,10 @@ pub fn symbolExtra(self: *LinkerDefined, index: u32) Symbol.Extra { } pub fn setSymbolExtra(self: *LinkerDefined, index: u32, extra: Symbol.Extra) void { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.symbols_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + self.symbols_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } diff --git a/src/link/Elf/Object.zig b/src/link/Elf/Object.zig index 539104d067..9d6291f50c 100644 --- a/src/link/Elf/Object.zig +++ b/src/link/Elf/Object.zig @@ -1298,17 +1298,17 @@ fn addSymbolAssumeCapacity(self: *Object) Symbol.Index { } pub fn addSymbolExtra(self: *Object, gpa: Allocator, extra: Symbol.Extra) !u32 { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - try self.symbols_extra.ensureUnusedCapacity(gpa, fields.len); + const field_count = @typeInfo(Symbol.Extra).@"struct".field_names.len; + try self.symbols_extra.ensureUnusedCapacity(gpa, field_count); return self.addSymbolExtraAssumeCapacity(extra); } pub fn addSymbolExtraAssumeCapacity(self: *Object, extra: Symbol.Extra) u32 { const index = @as(u32, @intCast(self.symbols_extra.items.len)); - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields) |field| { - self.symbols_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.symbols_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -1316,11 +1316,11 @@ pub fn addSymbolExtraAssumeCapacity(self: *Object, extra: Symbol.Extra) u32 { } pub fn symbolExtra(self: *Object, index: u32) Symbol.Extra { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; + const info = @typeInfo(Symbol.Extra).@"struct"; var i: usize = index; var result: Symbol.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.symbols_extra.items[i], else => @compileError("bad field type"), }; @@ -1330,10 +1330,10 @@ pub fn symbolExtra(self: *Object, index: u32) Symbol.Extra { } pub fn setSymbolExtra(self: *Object, index: u32, extra: Symbol.Extra) void { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.symbols_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + self.symbols_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } @@ -1408,17 +1408,17 @@ pub fn atom(self: *Object, atom_index: Atom.Index) ?*Atom { } pub fn addAtomExtra(self: *Object, gpa: Allocator, extra: Atom.Extra) !u32 { - const fields = @typeInfo(Atom.Extra).@"struct".fields; - try self.atoms_extra.ensureUnusedCapacity(gpa, fields.len); + const field_count = @typeInfo(Atom.Extra).@"struct".field_names.len; + try self.atoms_extra.ensureUnusedCapacity(gpa, field_count); return self.addAtomExtraAssumeCapacity(extra); } pub fn addAtomExtraAssumeCapacity(self: *Object, extra: Atom.Extra) u32 { const index: u32 = @intCast(self.atoms_extra.items.len); - const fields = @typeInfo(Atom.Extra).@"struct".fields; - inline for (fields) |field| { - self.atoms_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Atom.Extra).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.atoms_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -1426,11 +1426,11 @@ pub fn addAtomExtraAssumeCapacity(self: *Object, extra: Atom.Extra) u32 { } pub fn atomExtra(self: *Object, index: u32) Atom.Extra { - const fields = @typeInfo(Atom.Extra).@"struct".fields; + const info = @typeInfo(Atom.Extra).@"struct"; var i: usize = index; var result: Atom.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.atoms_extra.items[i], else => @compileError("bad field type"), }; @@ -1440,10 +1440,10 @@ pub fn atomExtra(self: *Object, index: u32) Atom.Extra { } pub fn setAtomExtra(self: *Object, index: u32, extra: Atom.Extra) void { - const fields = @typeInfo(Atom.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.atoms_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Atom.Extra).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + self.atoms_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } @@ -1452,8 +1452,8 @@ pub fn setAtomExtra(self: *Object, index: u32, extra: Atom.Extra) void { fn setAtomFields(o: *Object, atom_ptr: *Atom, opts: Atom.Extra.AsOptionals) void { assert(o.index == atom_ptr.file_index); var extras = o.atomExtra(atom_ptr.extra_index); - inline for (@typeInfo(@TypeOf(opts)).@"struct".fields) |field| { - if (@field(opts, field.name)) |x| @field(extras, field.name) = x; + inline for (@typeInfo(@TypeOf(opts)).@"struct".field_names) |field_name| { + if (@field(opts, field_name)) |x| @field(extras, field_name) = x; } o.setAtomExtra(atom_ptr.extra_index, extras); } diff --git a/src/link/Elf/SharedObject.zig b/src/link/Elf/SharedObject.zig index 712ffe3f49..c7070ab0b4 100644 --- a/src/link/Elf/SharedObject.zig +++ b/src/link/Elf/SharedObject.zig @@ -498,10 +498,10 @@ pub fn addSymbolAssumeCapacity(self: *SharedObject) Symbol.Index { pub fn addSymbolExtraAssumeCapacity(self: *SharedObject, extra: Symbol.Extra) u32 { const index: u32 = @intCast(self.symbols_extra.items.len); - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields) |field| { - self.symbols_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.symbols_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -509,11 +509,11 @@ pub fn addSymbolExtraAssumeCapacity(self: *SharedObject, extra: Symbol.Extra) u3 } pub fn symbolExtra(self: *SharedObject, index: u32) Symbol.Extra { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; + const info = @typeInfo(Symbol.Extra).@"struct"; var i: usize = index; var result: Symbol.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.symbols_extra.items[i], else => @compileError("bad field type"), }; @@ -523,10 +523,10 @@ pub fn symbolExtra(self: *SharedObject, index: u32) Symbol.Extra { } pub fn setSymbolExtra(self: *SharedObject, index: u32, extra: Symbol.Extra) void { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.symbols_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + self.symbols_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } diff --git a/src/link/Elf/Symbol.zig b/src/link/Elf/Symbol.zig index 21288828a8..3ab8694304 100644 --- a/src/link/Elf/Symbol.zig +++ b/src/link/Elf/Symbol.zig @@ -259,9 +259,9 @@ const AddExtraOpts = struct { pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, elf_file: *Elf) void { var extras = symbol.extra(elf_file); - inline for (@typeInfo(@TypeOf(opts)).@"struct".fields) |field| { - if (@field(opts, field.name)) |x| { - @field(extras, field.name) = x; + inline for (@typeInfo(@TypeOf(opts)).@"struct".field_names) |field_name| { + if (@field(opts, field_name)) |x| { + @field(extras, field_name) = x; } } symbol.setExtra(extras, elf_file); diff --git a/src/link/Elf/ZigObject.zig b/src/link/Elf/ZigObject.zig index da3b4678f2..e31e6c0510 100644 --- a/src/link/Elf/ZigObject.zig +++ b/src/link/Elf/ZigObject.zig @@ -2214,17 +2214,17 @@ pub fn atom(self: *ZigObject, atom_index: Atom.Index) ?*Atom { } fn addAtomExtra(self: *ZigObject, allocator: Allocator, extra: Atom.Extra) !u32 { - const fields = @typeInfo(Atom.Extra).@"struct".fields; - try self.atoms_extra.ensureUnusedCapacity(allocator, fields.len); + const field_count = @typeInfo(Atom.Extra).@"struct".field_names.len; + try self.atoms_extra.ensureUnusedCapacity(allocator, field_count); return self.addAtomExtraAssumeCapacity(extra); } fn addAtomExtraAssumeCapacity(self: *ZigObject, extra: Atom.Extra) u32 { const index = @as(u32, @intCast(self.atoms_extra.items.len)); - const fields = @typeInfo(Atom.Extra).@"struct".fields; - inline for (fields) |field| { - self.atoms_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Atom.Extra).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.atoms_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -2232,11 +2232,11 @@ fn addAtomExtraAssumeCapacity(self: *ZigObject, extra: Atom.Extra) u32 { } pub fn atomExtra(self: ZigObject, index: u32) Atom.Extra { - const fields = @typeInfo(Atom.Extra).@"struct".fields; + const info = @typeInfo(Atom.Extra).@"struct"; var i: usize = index; var result: Atom.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.atoms_extra.items[i], else => @compileError("bad field type"), }; @@ -2247,10 +2247,10 @@ pub fn atomExtra(self: ZigObject, index: u32) Atom.Extra { pub fn setAtomExtra(self: *ZigObject, index: u32, extra: Atom.Extra) void { assert(index > 0); - const fields = @typeInfo(Atom.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.atoms_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Atom.Extra).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + self.atoms_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } @@ -2286,17 +2286,17 @@ fn addSymbolAssumeCapacity(self: *ZigObject) Symbol.Index { } pub fn addSymbolExtra(self: *ZigObject, allocator: Allocator, extra: Symbol.Extra) !u32 { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len); + const field_count = @typeInfo(Symbol.Extra).@"struct".field_names.len; + try self.symbols_extra.ensureUnusedCapacity(allocator, field_count); return self.addSymbolExtraAssumeCapacity(extra); } pub fn addSymbolExtraAssumeCapacity(self: *ZigObject, extra: Symbol.Extra) u32 { const index = @as(u32, @intCast(self.symbols_extra.items.len)); - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields) |field| { - self.symbols_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.symbols_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -2304,11 +2304,11 @@ pub fn addSymbolExtraAssumeCapacity(self: *ZigObject, extra: Symbol.Extra) u32 { } pub fn symbolExtra(self: *ZigObject, index: u32) Symbol.Extra { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; + const info = @typeInfo(Symbol.Extra).@"struct"; var i: usize = index; var result: Symbol.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.symbols_extra.items[i], else => @compileError("bad field type"), }; @@ -2318,10 +2318,10 @@ pub fn symbolExtra(self: *ZigObject, index: u32) Symbol.Extra { } pub fn setSymbolExtra(self: *ZigObject, index: u32, extra: Symbol.Extra) void { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.symbols_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + self.symbols_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } diff --git a/src/link/Elf2.zig b/src/link/Elf2.zig index 747252591f..0ba105205e 100644 --- a/src/link/Elf2.zig +++ b/src/link/Elf2.zig @@ -6330,10 +6330,10 @@ pub fn printNode( const pt = elf.targetLoad(&ph.type); if (std.enums.tagName(std.elf.PT, pt)) |pt_name| try w.writeAll(pt_name) - else inline for (@typeInfo(std.elf.PT).@"enum".decls) |decl| { - const decl_val = @field(std.elf.PT, decl.name); + else inline for (@typeInfo(std.elf.PT).@"enum".decl_names) |decl_name| { + const decl_val = @field(std.elf.PT, decl_name); if (@TypeOf(decl_val) != std.elf.PT) continue; - if (pt == @field(std.elf.PT, decl.name)) break try w.writeAll(decl.name); + if (pt == @field(std.elf.PT, decl_name)) break try w.writeAll(decl_name); } else try w.print("0x{x}", .{pt}); try w.writeAll(", "); const pf = elf.targetLoad(&ph.flags); diff --git a/src/link/LdScript.zig b/src/link/LdScript.zig index 43c196442f..2cfa6f9970 100644 --- a/src/link/LdScript.zig +++ b/src/link/LdScript.zig @@ -97,15 +97,15 @@ const Command = enum { as_needed, fn fromString(s: []const u8) ?Command { - inline for (@typeInfo(Command).@"enum".fields) |field| { + inline for (@typeInfo(Command).@"enum".field_names) |field_name| { const upper_name = n: { - comptime var buf: [field.name.len]u8 = undefined; - inline for (field.name, 0..) |c, i| { + comptime var buf: [field_name.len]u8 = undefined; + inline for (field_name, 0..) |c, i| { buf[i] = comptime std.ascii.toUpper(c); } break :n buf; }; - if (std.mem.eql(u8, &upper_name, s)) return @field(Command, field.name); + if (std.mem.eql(u8, &upper_name, s)) return @field(Command, field_name); } return null; } diff --git a/src/link/MachO/Atom.zig b/src/link/MachO/Atom.zig index df9dc381ab..7635a9cf6b 100644 --- a/src/link/MachO/Atom.zig +++ b/src/link/MachO/Atom.zig @@ -129,9 +129,9 @@ const AddExtraOpts = struct { pub fn addExtra(atom: *Atom, opts: AddExtraOpts, macho_file: *MachO) void { const file = atom.getFile(macho_file); var extra = file.getAtomExtra(atom.extra); - inline for (@typeInfo(@TypeOf(opts)).@"struct".fields) |field| { - if (@field(opts, field.name)) |x| { - @field(extra, field.name) = x; + inline for (@typeInfo(@TypeOf(opts)).@"struct".field_names) |field_name| { + if (@field(opts, field_name)) |x| { + @field(extra, field_name) = x; } } file.setAtomExtra(atom.extra, extra); diff --git a/src/link/MachO/Dylib.zig b/src/link/MachO/Dylib.zig index cc5bc74f24..d1f79b5ab7 100644 --- a/src/link/MachO/Dylib.zig +++ b/src/link/MachO/Dylib.zig @@ -627,17 +627,17 @@ pub fn getSymbolRef(self: Dylib, index: Symbol.Index, macho_file: *MachO) MachO. } pub fn addSymbolExtra(self: *Dylib, allocator: Allocator, extra: Symbol.Extra) !u32 { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len); + const field_count = @typeInfo(Symbol.Extra).@"struct".field_names.len; + try self.symbols_extra.ensureUnusedCapacity(allocator, field_count); return self.addSymbolExtraAssumeCapacity(extra); } fn addSymbolExtraAssumeCapacity(self: *Dylib, extra: Symbol.Extra) u32 { const index = @as(u32, @intCast(self.symbols_extra.items.len)); - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields) |field| { - self.symbols_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.symbols_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -645,11 +645,11 @@ fn addSymbolExtraAssumeCapacity(self: *Dylib, extra: Symbol.Extra) u32 { } pub fn getSymbolExtra(self: Dylib, index: u32) Symbol.Extra { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; + const info = @typeInfo(Symbol.Extra).@"struct"; var i: usize = index; var result: Symbol.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.symbols_extra.items[i], else => @compileError("bad field type"), }; @@ -659,10 +659,10 @@ pub fn getSymbolExtra(self: Dylib, index: u32) Symbol.Extra { } pub fn setSymbolExtra(self: *Dylib, index: u32, extra: Symbol.Extra) void { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.symbols_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + self.symbols_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } diff --git a/src/link/MachO/InternalObject.zig b/src/link/MachO/InternalObject.zig index 53ed5cf0e1..d05d0241ac 100644 --- a/src/link/MachO/InternalObject.zig +++ b/src/link/MachO/InternalObject.zig @@ -708,17 +708,17 @@ pub fn getAtoms(self: InternalObject) []const Atom.Index { } fn addAtomExtra(self: *InternalObject, allocator: Allocator, extra: Atom.Extra) !u32 { - const fields = @typeInfo(Atom.Extra).@"struct".fields; - try self.atoms_extra.ensureUnusedCapacity(allocator, fields.len); + const field_count = @typeInfo(Atom.Extra).@"struct".field_names.len; + try self.atoms_extra.ensureUnusedCapacity(allocator, field_count); return self.addAtomExtraAssumeCapacity(extra); } fn addAtomExtraAssumeCapacity(self: *InternalObject, extra: Atom.Extra) u32 { const index = @as(u32, @intCast(self.atoms_extra.items.len)); - const fields = @typeInfo(Atom.Extra).@"struct".fields; - inline for (fields) |field| { - self.atoms_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Atom.Extra).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.atoms_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -726,11 +726,11 @@ fn addAtomExtraAssumeCapacity(self: *InternalObject, extra: Atom.Extra) u32 { } pub fn getAtomExtra(self: InternalObject, index: u32) Atom.Extra { - const fields = @typeInfo(Atom.Extra).@"struct".fields; + const info = @typeInfo(Atom.Extra).@"struct"; var i: usize = index; var result: Atom.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.atoms_extra.items[i], else => @compileError("bad field type"), }; @@ -741,10 +741,10 @@ pub fn getAtomExtra(self: InternalObject, index: u32) Atom.Extra { pub fn setAtomExtra(self: *InternalObject, index: u32, extra: Atom.Extra) void { assert(index > 0); - const fields = @typeInfo(Atom.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.atoms_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Atom.Extra).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + self.atoms_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } @@ -789,17 +789,17 @@ pub fn getSymbolRef(self: InternalObject, index: Symbol.Index, macho_file: *Mach } pub fn addSymbolExtra(self: *InternalObject, allocator: Allocator, extra: Symbol.Extra) !u32 { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len); + const field_count = @typeInfo(Symbol.Extra).@"struct".field_names.len; + try self.symbols_extra.ensureUnusedCapacity(allocator, field_count); return self.addSymbolExtraAssumeCapacity(extra); } fn addSymbolExtraAssumeCapacity(self: *InternalObject, extra: Symbol.Extra) u32 { const index = @as(u32, @intCast(self.symbols_extra.items.len)); - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields) |field| { - self.symbols_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.symbols_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -807,11 +807,11 @@ fn addSymbolExtraAssumeCapacity(self: *InternalObject, extra: Symbol.Extra) u32 } pub fn getSymbolExtra(self: InternalObject, index: u32) Symbol.Extra { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; + const info = @typeInfo(Symbol.Extra).@"struct"; var i: usize = index; var result: Symbol.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.symbols_extra.items[i], else => @compileError("bad field type"), }; @@ -821,10 +821,10 @@ pub fn getSymbolExtra(self: InternalObject, index: u32) Symbol.Extra { } pub fn setSymbolExtra(self: *InternalObject, index: u32, extra: Symbol.Extra) void { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.symbols_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + self.symbols_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } diff --git a/src/link/MachO/Object.zig b/src/link/MachO/Object.zig index 69a72d9c64..cff42a447e 100644 --- a/src/link/MachO/Object.zig +++ b/src/link/MachO/Object.zig @@ -2478,17 +2478,17 @@ pub fn getAtoms(self: *Object) []const Atom.Index { } fn addAtomExtra(self: *Object, allocator: Allocator, extra: Atom.Extra) !u32 { - const fields = @typeInfo(Atom.Extra).@"struct".fields; - try self.atoms_extra.ensureUnusedCapacity(allocator, fields.len); + const field_count = @typeInfo(Atom.Extra).@"struct".field_names.len; + try self.atoms_extra.ensureUnusedCapacity(allocator, field_count); return self.addAtomExtraAssumeCapacity(extra); } fn addAtomExtraAssumeCapacity(self: *Object, extra: Atom.Extra) u32 { const index = @as(u32, @intCast(self.atoms_extra.items.len)); - const fields = @typeInfo(Atom.Extra).@"struct".fields; - inline for (fields) |field| { - self.atoms_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Atom.Extra).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.atoms_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -2496,11 +2496,11 @@ fn addAtomExtraAssumeCapacity(self: *Object, extra: Atom.Extra) u32 { } pub fn getAtomExtra(self: Object, index: u32) Atom.Extra { - const fields = @typeInfo(Atom.Extra).@"struct".fields; + const info = @typeInfo(Atom.Extra).@"struct"; var i: usize = index; var result: Atom.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.atoms_extra.items[i], else => @compileError("bad field type"), }; @@ -2511,10 +2511,10 @@ pub fn getAtomExtra(self: Object, index: u32) Atom.Extra { pub fn setAtomExtra(self: *Object, index: u32, extra: Atom.Extra) void { assert(index > 0); - const fields = @typeInfo(Atom.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.atoms_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Atom.Extra).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + self.atoms_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } @@ -2539,17 +2539,17 @@ pub fn getSymbolRef(self: Object, index: Symbol.Index, macho_file: *MachO) MachO } pub fn addSymbolExtra(self: *Object, allocator: Allocator, extra: Symbol.Extra) !u32 { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len); + const field_count = @typeInfo(Symbol.Extra).@"struct".field_names.len; + try self.symbols_extra.ensureUnusedCapacity(allocator, field_count); return self.addSymbolExtraAssumeCapacity(extra); } fn addSymbolExtraAssumeCapacity(self: *Object, extra: Symbol.Extra) u32 { const index = @as(u32, @intCast(self.symbols_extra.items.len)); - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields) |field| { - self.symbols_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types) |field_name, field_type| { + self.symbols_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -2557,11 +2557,11 @@ fn addSymbolExtraAssumeCapacity(self: *Object, extra: Symbol.Extra) u32 { } pub fn getSymbolExtra(self: Object, index: u32) Symbol.Extra { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; + const info = @typeInfo(Symbol.Extra).@"struct"; var i: usize = index; var result: Symbol.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (info.field_names, info.field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.symbols_extra.items[i], else => @compileError("bad field type"), }; @@ -2571,10 +2571,10 @@ pub fn getSymbolExtra(self: Object, index: u32) Symbol.Extra { } pub fn setSymbolExtra(self: *Object, index: u32, extra: Symbol.Extra) void { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.symbols_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + inline for (info.field_names, info.field_types, 0..) |field_name, field_type, i| { + self.symbols_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } diff --git a/src/link/MachO/Symbol.zig b/src/link/MachO/Symbol.zig index c75505a3be..7ac8e28881 100644 --- a/src/link/MachO/Symbol.zig +++ b/src/link/MachO/Symbol.zig @@ -211,9 +211,9 @@ const AddExtraOpts = struct { pub fn addExtra(symbol: *Symbol, opts: AddExtraOpts, macho_file: *MachO) void { var extra = symbol.getExtra(macho_file); - inline for (@typeInfo(@TypeOf(opts)).@"struct".fields) |field| { - if (@field(opts, field.name)) |x| { - @field(extra, field.name) = x; + inline for (@typeInfo(@TypeOf(opts)).@"struct".field_names) |field_name| { + if (@field(opts, field_name)) |x| { + @field(extra, field_name) = x; } } symbol.setExtra(extra, macho_file); diff --git a/src/link/MachO/ZigObject.zig b/src/link/MachO/ZigObject.zig index 8d54b65628..024a6f1735 100644 --- a/src/link/MachO/ZigObject.zig +++ b/src/link/MachO/ZigObject.zig @@ -1570,17 +1570,19 @@ pub fn getAtoms(self: *ZigObject) []const Atom.Index { } fn addAtomExtra(self: *ZigObject, allocator: Allocator, extra: Atom.Extra) !u32 { - const fields = @typeInfo(Atom.Extra).@"struct".fields; - try self.atoms_extra.ensureUnusedCapacity(allocator, fields.len); + const field = @typeInfo(Atom.Extra).@"struct".field_names; + try self.atoms_extra.ensureUnusedCapacity(allocator, field.len); return self.addAtomExtraAssumeCapacity(extra); } fn addAtomExtraAssumeCapacity(self: *ZigObject, extra: Atom.Extra) u32 { const index = @as(u32, @intCast(self.atoms_extra.items.len)); - const fields = @typeInfo(Atom.Extra).@"struct".fields; - inline for (fields) |field| { - self.atoms_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Atom.Extra).@"struct"; + const field_names = info.field_names; + const field_types = info.field_types; + inline for (field_names, field_types) |field_name, field_type| { + self.atoms_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -1588,11 +1590,13 @@ fn addAtomExtraAssumeCapacity(self: *ZigObject, extra: Atom.Extra) u32 { } pub fn getAtomExtra(self: ZigObject, index: u32) Atom.Extra { - const fields = @typeInfo(Atom.Extra).@"struct".fields; + const info = @typeInfo(Atom.Extra).@"struct"; + const field_names = info.field_names; + const field_types = info.field_types; var i: usize = index; var result: Atom.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (field_names, field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.atoms_extra.items[i], else => @compileError("bad field type"), }; @@ -1603,10 +1607,12 @@ pub fn getAtomExtra(self: ZigObject, index: u32) Atom.Extra { pub fn setAtomExtra(self: *ZigObject, index: u32, extra: Atom.Extra) void { assert(index > 0); - const fields = @typeInfo(Atom.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.atoms_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Atom.Extra).@"struct"; + const field_names = info.field_names; + const field_types = info.field_types; + inline for (field_names, field_types, 0..) |field_name, field_type, i| { + self.atoms_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } @@ -1631,17 +1637,19 @@ pub fn getSymbolRef(self: ZigObject, index: Symbol.Index, macho_file: *MachO) Ma } pub fn addSymbolExtra(self: *ZigObject, allocator: Allocator, extra: Symbol.Extra) !u32 { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; + const fields = @typeInfo(Symbol.Extra).@"struct".field_names; try self.symbols_extra.ensureUnusedCapacity(allocator, fields.len); return self.addSymbolExtraAssumeCapacity(extra); } fn addSymbolExtraAssumeCapacity(self: *ZigObject, extra: Symbol.Extra) u32 { const index = @as(u32, @intCast(self.symbols_extra.items.len)); - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields) |field| { - self.symbols_extra.appendAssumeCapacity(switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + const field_names = info.field_names; + const field_types = info.field_types; + inline for (field_names, field_types) |field_name, field_type| { + self.symbols_extra.appendAssumeCapacity(switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }); } @@ -1649,11 +1657,13 @@ fn addSymbolExtraAssumeCapacity(self: *ZigObject, extra: Symbol.Extra) u32 { } pub fn getSymbolExtra(self: ZigObject, index: u32) Symbol.Extra { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; + const info = @typeInfo(Symbol.Extra).@"struct"; + const field_names = info.field_names; + const field_types = info.field_types; var i: usize = index; var result: Symbol.Extra = undefined; - inline for (fields) |field| { - @field(result, field.name) = switch (field.type) { + inline for (field_names, field_types) |field_name, field_type| { + @field(result, field_name) = switch (field_type) { u32 => self.symbols_extra.items[i], else => @compileError("bad field type"), }; @@ -1663,10 +1673,12 @@ pub fn getSymbolExtra(self: ZigObject, index: u32) Symbol.Extra { } pub fn setSymbolExtra(self: *ZigObject, index: u32, extra: Symbol.Extra) void { - const fields = @typeInfo(Symbol.Extra).@"struct".fields; - inline for (fields, 0..) |field, i| { - self.symbols_extra.items[index + i] = switch (field.type) { - u32 => @field(extra, field.name), + const info = @typeInfo(Symbol.Extra).@"struct"; + const field_names = info.field_names; + const field_types = info.field_types; + inline for (field_names, field_types, 0..) |field_name, field_type, i| { + self.symbols_extra.items[index + i] = switch (field_type) { + u32 => @field(extra, field_name), else => @compileError("bad field type"), }; } diff --git a/src/link/Wasm.zig b/src/link/Wasm.zig index 95ee2fae1c..2a22e88efe 100644 --- a/src/link/Wasm.zig +++ b/src/link/Wasm.zig @@ -2992,8 +2992,8 @@ pub fn createEmpty( if (options.object_host_name) |name| wasm.object_host_name = (try wasm.internString(name)).toOptional(); - inline for (@typeInfo(PreloadedStrings).@"struct".fields) |field| { - @field(wasm.preloaded_strings, field.name) = try wasm.internString(field.name); + inline for (@typeInfo(PreloadedStrings).@"struct".field_names) |field_name| { + @field(wasm.preloaded_strings, field_name) = try wasm.internString(field_name); } wasm.entry_name = switch (options.entry) { diff --git a/src/link/tapi/yaml.zig b/src/link/tapi/yaml.zig index 8ea7a91c17..f2c0f81c3a 100644 --- a/src/link/tapi/yaml.zig +++ b/src/link/tapi/yaml.zig @@ -214,8 +214,8 @@ pub const Value = union(enum) { var list: std.ArrayList(Value) = try .initCapacity(arena); defer list.deinit(); - inline for (info.fields) |field| { - if (try encode(arena, @field(input, field.name))) |value| { + inline for (info.field_names) |field_name| { + if (try encode(arena, @field(input, field_name))) |value| { list.appendAssumeCapacity(value); } } @@ -224,11 +224,11 @@ pub const Value = union(enum) { } else { var map = Map.init(arena); errdefer map.deinit(); - try map.ensureTotalCapacity(info.fields.len); + try map.ensureTotalCapacity(info.field_names.len); - inline for (info.fields) |field| { - if (try encode(arena, @field(input, field.name))) |value| { - const key = try arena.dupe(u8, field.name); + inline for (info.field_names) |field_name| { + if (try encode(arena, @field(input, field_name))) |value| { + const key = try arena.dupe(u8, field_name); map.putAssumeCapacityNoClobber(key, value); } } @@ -237,9 +237,9 @@ pub const Value = union(enum) { }, .@"union" => |info| if (info.tag_type) |tag_type| { - inline for (info.fields) |field| { - if (@field(tag_type, field.name) == input) { - return try encode(arena, @field(input, field.name)); + inline for (info.field_names) |field_name| { + if (@field(tag_type, field_name) == input) { + return try encode(arena, @field(input, field_name)); } } else unreachable; } else return error.UntaggedUnion, @@ -396,9 +396,9 @@ pub const Yaml = struct { const union_info = @typeInfo(T).@"union"; if (union_info.tag_type) |_| { - inline for (union_info.fields) |field| { - if (self.parseValue(field.type, value)) |u_value| { - return @unionInit(T, field.name, u_value); + inline for (union_info.field_names, union_info.field_types) |field_name, field_type| { + if (self.parseValue(field_type, value)) |u_value| { + return @unionInit(T, field_name, u_value); } else |err| { if (@as(@TypeOf(err) || error{TypeMismatch}, err) != error.TypeMismatch) return err; } @@ -418,22 +418,22 @@ pub const Yaml = struct { const struct_info = @typeInfo(T).@"struct"; var parsed: T = undefined; - inline for (struct_info.fields) |field| { - const value: ?Value = map.get(field.name) orelse blk: { - const field_name = try mem.replaceOwned(u8, self.arena.allocator(), field.name, "_", "-"); - break :blk map.get(field_name); + inline for (struct_info.field_names, struct_info.field_types) |field_name, field_type| { + const value: ?Value = map.get(field_name) orelse blk: { + const field_name_ = try mem.replaceOwned(u8, self.arena.allocator(), field_name, "_", "-"); + break :blk map.get(field_name_); }; - if (@typeInfo(field.type) == .optional) { - @field(parsed, field.name) = try self.parseOptional(field.type, value); + if (@typeInfo(field_type) == .optional) { + @field(parsed, field_name) = try self.parseOptional(field_type, value); continue; } const unwrapped = value orelse { - log.debug("missing struct field: {s}: {s}", .{ field.name, @typeName(field.type) }); + log.debug("missing struct field: {s}: {s}", .{ field_name, @typeName(field_type) }); return error.StructFieldMissing; }; - @field(parsed, field.name) = try self.parseValue(field.type, unwrapped); + @field(parsed, field_name) = try self.parseValue(field_type, unwrapped); } return parsed; diff --git a/src/print_env.zig b/src/print_env.zig index ec7eadd709..9370006c72 100644 --- a/src/print_env.zig +++ b/src/print_env.zig @@ -59,8 +59,8 @@ pub fn cmdEnv( try root.field("version", build_options.version, .{}); try root.field("target", triple, .{}); var env = try root.beginStructField("env", .{}); - inline for (@typeInfo(EnvVar).@"enum".fields) |field| { - try env.field(field.name, @field(EnvVar, field.name).get(environ_map), .{}); + inline for (@typeInfo(EnvVar).@"enum".field_names) |field_name| { + try env.field(field_name, @field(EnvVar, field_name).get(environ_map), .{}); } try env.end(); try root.end(); diff --git a/src/print_zoir.zig b/src/print_zoir.zig index 45c3fb365c..9fdaa39651 100644 --- a/src/print_zoir.zig +++ b/src/print_zoir.zig @@ -5,8 +5,8 @@ pub fn renderToWriter(zoir: Zoir, arena: Allocator, w: *Writer) Error!void { const bytes_per_node = comptime n: { var n: usize = 0; - for (@typeInfo(Zoir.Node.Repr).@"struct".fields) |f| { - n += @sizeOf(f.type); + for (@typeInfo(Zoir.Node.Repr).@"struct".field_types) |f_type| { + n += @sizeOf(f_type); } break :n n; }; diff --git a/stage1/zig.h b/stage1/zig.h index 67158429fd..f2faed0b37 100644 --- a/stage1/zig.h +++ b/stage1/zig.h @@ -21,6 +21,8 @@ #if defined(__aarch64__) || (defined(zig_msvc) && defined(_M_ARM64)) #define zig_aarch64 +#elif defined(__alpha__) +#define zig_alpha #elif defined(__thumb__) || (defined(zig_msvc) && defined(_M_ARM)) #define zig_thumb #define zig_arm @@ -36,6 +38,10 @@ #elif defined(__loongarch64) #define zig_loongarch64 #define zig_loongarch +#elif defined(__m68k__) +#define zig_m68k +#elif defined(__m88k__) +#define zig_m88k #elif defined(__mips64) #define zig_mips64 #define zig_mips @@ -79,6 +85,8 @@ #elif defined(__I86__) #define zig_x86_16 #define zig_x86 +#elif defined(__xtensa__) +#define zig_xtensa #elif defined (__ez80) #define zig_ez80 #define zig_z80 @@ -390,7 +398,9 @@ #elif defined(zig_gnuc_asm) -#if defined(zig_thumb) +#if defined(zig_alpha) +#define zig_trap() __asm__ volatile("call_pal 0x000000") +#elif defined(zig_thumb) #define zig_trap() __asm__ volatile("udf #0xfe") #elif defined(zig_arm) || defined(zig_aarch64) #define zig_trap() __asm__ volatile("udf #0xfdee") @@ -398,6 +408,10 @@ #define zig_trap() __asm__ volatile("r27:26 = memd(#0xbadc0fee)") #elif defined(zig_kvx) || defined(zig_loongarch) || defined(zig_powerpc) #define zig_trap() __asm__ volatile(".word 0x0") +#elif defined(zig_m68k) +#define zig_trap() __asm__ volatile("illegal") +#elif defined(zig_m88k) +#define zig_trap() __asm__ volatile("tb0 0, %%r0, 511") #elif defined(zig_mips) #define zig_trap() __asm__ volatile(".word 0x3d") #elif defined(zig_or1k) @@ -412,6 +426,8 @@ #define zig_trap() __asm__ volatile("int $0x3") #elif defined(zig_x86) #define zig_trap() __asm__ volatile("ud2") +#elif defined(zig_xtensa) +#define zig_trap() __asm__ volatile("ill") #elif defined(zig_z80) #define zig_trap() __asm__ volatile("rst 00h") #else @@ -428,7 +444,9 @@ #define zig_breakpoint() __debugbreak() #elif defined(zig_gnuc_asm) -#if defined(zig_arm) +#if defined(zig_alpha) +#define zig_breakpoint() __asm__ volatile("call_pal 0x000080") +#elif defined(zig_arm) #define zig_breakpoint() __asm__ volatile("bkpt #0x0") #elif defined(zig_aarch64) #define zig_breakpoint() __asm__ volatile("brk #0xf000") @@ -436,6 +454,8 @@ #define zig_breakpoint() __asm__ volatile("brkpt") #elif defined(zig_kvx) || defined(zig_loongarch) #define zig_breakpoint() __asm__ volatile("break 0x0") +#elif defined(zig_m88k) +#define zig_breakpoint() __asm__ volatile("illop1") #elif defined(zig_mips) #define zig_breakpoint() __asm__ volatile("break") #elif defined(zig_or1k) @@ -450,6 +470,8 @@ #define zig_breakpoint() __asm__ volatile("ta 0x1") #elif defined(zig_x86) #define zig_breakpoint() __asm__ volatile("int $0x3") +#elif defined(zig_xtensa) +#define zig_breakpoint() __asm__ volatile("break 1, 1") #else #define zig_breakpoint() zig_breakpoint_unavailable #endif diff --git a/stage1/zig1.wasm b/stage1/zig1.wasm index 67ca7db75a..10afc539bc 100644 Binary files a/stage1/zig1.wasm and b/stage1/zig1.wasm differ diff --git a/test/behavior/align.zig b/test/behavior/align.zig index 3ade0f6164..55eb1c604e 100644 --- a/test/behavior/align.zig +++ b/test/behavior/align.zig @@ -7,7 +7,7 @@ const assert = std.debug.assert; var foo: u8 align(4) = 100; test "global variable alignment" { - comptime assert(@typeInfo(@TypeOf(&foo)).pointer.alignment == 4); + comptime assert(@typeInfo(@TypeOf(&foo)).pointer.attrs.@"align" == 4); comptime assert(@TypeOf(&foo) == *align(4) u8); { const slice = @as(*align(4) [1]u8, &foo)[0..]; diff --git a/test/behavior/basic.zig b/test/behavior/basic.zig index d9dcc4a73a..2c5e6ab9a9 100644 --- a/test/behavior/basic.zig +++ b/test/behavior/basic.zig @@ -1159,7 +1159,7 @@ test "pointer to struct literal with runtime field is constant" { var runtime_zero: usize = 0; _ = &runtime_zero; const ptr = &S{ .data = runtime_zero }; - try expect(@typeInfo(@TypeOf(ptr)).pointer.is_const); + try expect(@typeInfo(@TypeOf(ptr)).pointer.attrs.@"const"); } fn testSignedCmp(comptime T: type) !void { @@ -1284,8 +1284,8 @@ test "comptime variable initialized with addresses of literals" { }; _ = &st; - inline for (@typeInfo(@TypeOf(st)).@"struct".fields) |field| { - _ = field; + inline for (@typeInfo(@TypeOf(st)).@"struct".field_names) |field_name| { + _ = field_name; } } diff --git a/test/behavior/bitcast.zig b/test/behavior/bitcast.zig index eb1ebe17b5..28b45428d6 100644 --- a/test/behavior/bitcast.zig +++ b/test/behavior/bitcast.zig @@ -359,8 +359,8 @@ test "comptime @bitCast packed struct to int and back" { _ = &i; const rt_cast = @as(S, @bitCast(i)); const ct_cast = comptime @as(S, @bitCast(@as(Int, 0))); - inline for (@typeInfo(S).@"struct".fields) |field| { - try expectEqual(@field(rt_cast, field.name), @field(ct_cast, field.name)); + inline for (@typeInfo(S).@"struct".field_names) |field_name| { + try expectEqual(@field(rt_cast, field_name), @field(ct_cast, field_name)); } } diff --git a/test/behavior/call.zig b/test/behavior/call.zig index 1cad4c3164..9ff3e56d3e 100644 --- a/test/behavior/call.zig +++ b/test/behavior/call.zig @@ -375,7 +375,7 @@ test "Enum constructed by @Enum passed as generic argument" { try expect(@intFromEnum(a) == b); } }; - inline for (@typeInfo(S.E).@"enum".fields, 0..) |_, i| { + inline for (@typeInfo(S.E).@"enum".field_names, 0..) |_, i| { try S.foo(@as(S.E, @enumFromInt(i)), i); } } @@ -556,7 +556,7 @@ test "value returned from comptime function is comptime known" { else => unreachable, } { return switch (@typeInfo(T)) { - .@"struct" => |info| info.fields.len, + .@"struct" => |info| info.field_names.len, else => unreachable, }; } diff --git a/test/behavior/cast.zig b/test/behavior/cast.zig index 2988f4479e..2e5871d9dd 100644 --- a/test/behavior/cast.zig +++ b/test/behavior/cast.zig @@ -1042,9 +1042,9 @@ test "peer type resolution: error set supersets" { const ty = @TypeOf(a, b); const error_set_info = @typeInfo(ty); try expect(error_set_info == .error_set); - try expect(error_set_info.error_set.?.len == 2); - try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One")); - try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two")); + try expect(error_set_info.error_set.error_names.?.len == 2); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[0], "One")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[1], "Two")); } // B superset of A @@ -1052,9 +1052,9 @@ test "peer type resolution: error set supersets" { const ty = @TypeOf(b, a); const error_set_info = @typeInfo(ty); try expect(error_set_info == .error_set); - try expect(error_set_info.error_set.?.len == 2); - try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One")); - try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two")); + try expect(error_set_info.error_set.error_names.?.len == 2); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[0], "One")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[1], "Two")); } } @@ -1070,20 +1070,20 @@ test "peer type resolution: disjoint error sets" { const ty = @TypeOf(a, b); const error_set_info = @typeInfo(ty); try expect(error_set_info == .error_set); - try expect(error_set_info.error_set.?.len == 3); - try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One")); - try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two")); - try expect(mem.eql(u8, error_set_info.error_set.?[2].name, "Three")); + try expect(error_set_info.error_set.error_names.?.len == 3); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[0], "One")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[1], "Two")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[2], "Three")); } { const ty = @TypeOf(b, a); const error_set_info = @typeInfo(ty); try expect(error_set_info == .error_set); - try expect(error_set_info.error_set.?.len == 3); - try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One")); - try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two")); - try expect(mem.eql(u8, error_set_info.error_set.?[2].name, "Three")); + try expect(error_set_info.error_set.error_names.?.len == 3); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[0], "One")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[1], "Two")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[2], "Three")); } } @@ -1101,10 +1101,10 @@ test "peer type resolution: error union and error set" { try expect(info == .error_union); const error_set_info = @typeInfo(info.error_union.error_set); - try expect(error_set_info.error_set.?.len == 3); - try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One")); - try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two")); - try expect(mem.eql(u8, error_set_info.error_set.?[2].name, "Three")); + try expect(error_set_info.error_set.error_names.?.len == 3); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[0], "One")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[1], "Two")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[2], "Three")); } { @@ -1113,10 +1113,10 @@ test "peer type resolution: error union and error set" { try expect(info == .error_union); const error_set_info = @typeInfo(info.error_union.error_set); - try expect(error_set_info.error_set.?.len == 3); - try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One")); - try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two")); - try expect(mem.eql(u8, error_set_info.error_set.?[2].name, "Three")); + try expect(error_set_info.error_set.error_names.?.len == 3); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[0], "One")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[1], "Two")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[2], "Three")); } } @@ -1135,9 +1135,9 @@ test "peer type resolution: error union after non-error" { try expect(info.error_union.payload == u32); const error_set_info = @typeInfo(info.error_union.error_set); - try expect(error_set_info.error_set.?.len == 2); - try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One")); - try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two")); + try expect(error_set_info.error_set.error_names.?.len == 2); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[0], "One")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[1], "Two")); } { @@ -1147,9 +1147,9 @@ test "peer type resolution: error union after non-error" { try expect(info.error_union.payload == u32); const error_set_info = @typeInfo(info.error_union.error_set); - try expect(error_set_info.error_set.?.len == 2); - try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One")); - try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two")); + try expect(error_set_info.error_set.error_names.?.len == 2); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[0], "One")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[1], "Two")); } } @@ -2552,9 +2552,9 @@ test "peer type resolution: tuples with comptime fields" { inline for (.{ ti1, ti2 }) |ti| { const s = ti.@"struct"; comptime assert(s.is_tuple); - comptime assert(s.fields.len == 2); - comptime assert(s.fields[0].type == u32); - comptime assert(s.fields[1].type == i16); + comptime assert(s.field_names.len == 2); + comptime assert(s.field_types[0] == u32); + comptime assert(s.field_types[1] == i16); } var t = true; @@ -2665,11 +2665,11 @@ test "peer type resolution: pointer attributes are combined correctly" { const NonAllowZero = comptime blk: { const ptr = @typeInfo(@TypeOf(r1, r2, r3, r4)).pointer; break :blk @Pointer(ptr.size, .{ - .@"const" = ptr.is_const, - .@"volatile" = ptr.is_volatile, + .@"const" = ptr.attrs.@"const", + .@"volatile" = ptr.attrs.@"volatile", .@"allowzero" = false, - .@"align" = ptr.alignment, - .@"addrspace" = ptr.address_space, + .@"align" = ptr.attrs.@"align", + .@"addrspace" = ptr.attrs.@"addrspace", }, ptr.child, ptr.sentinel()); }; try expectEqualSlices(u8, std.mem.span(@volatileCast(@as(NonAllowZero, @ptrCast(r1)))), "foo"); diff --git a/test/behavior/comptime_memory.zig b/test/behavior/comptime_memory.zig index 2efd197475..769075aeff 100644 --- a/test/behavior/comptime_memory.zig +++ b/test/behavior/comptime_memory.zig @@ -118,8 +118,8 @@ fn shuffle(ptr: usize, comptime From: type, comptime To: type) usize { const pResult = @as(*align(1) [array_len]To, @ptrCast(&result)); var i: usize = 0; while (i < array_len) : (i += 1) { - inline for (@typeInfo(To).@"struct".fields) |f| { - @field(pResult[i], f.name) = @field(pSource[i], f.name); + inline for (@typeInfo(To).@"struct".field_names) |f_name| { + @field(pResult[i], f_name) = @field(pSource[i], f_name); } } return result; diff --git a/test/behavior/enum.zig b/test/behavior/enum.zig index fcd2b5844a..6557de08ca 100644 --- a/test/behavior/enum.zig +++ b/test/behavior/enum.zig @@ -644,12 +644,12 @@ test "non-exhaustive enum" { else => true, }); - try expect(@typeInfo(E).@"enum".fields.len == 2); + try expect(@typeInfo(E).@"enum".field_names.len == 2); e = @as(E, @enumFromInt(12)); try expect(@intFromEnum(e) == 12); e = @as(E, @enumFromInt(y)); try expect(@intFromEnum(e) == 52); - try expect(@typeInfo(E).@"enum".is_exhaustive == false); + try expect(@typeInfo(E).@"enum".mode == .nonexhaustive); } }; try S.doTheTest(52); @@ -668,8 +668,9 @@ test "empty non-exhaustive enum" { }); try expect(@intFromEnum(e) == y); - try expect(@typeInfo(E).@"enum".fields.len == 0); - try expect(@typeInfo(E).@"enum".is_exhaustive == false); + try expect(@typeInfo(E).@"enum".field_names.len == 0); + try expect(@typeInfo(E).@"enum".field_values.len == 0); + try expect(@typeInfo(E).@"enum".mode == .nonexhaustive); } }; try S.doTheTest(42); @@ -704,8 +705,9 @@ test "single field non-exhaustive enum" { }); try expect(@intFromEnum(@as(E, @enumFromInt(y))) == y); - try expect(@typeInfo(E).@"enum".fields.len == 1); - try expect(@typeInfo(E).@"enum".is_exhaustive == false); + try expect(@typeInfo(E).@"enum".field_names.len == 1); + try expect(@typeInfo(E).@"enum".field_values.len == 1); + try expect(@typeInfo(E).@"enum".mode == .nonexhaustive); } }; try S.doTheTest(23); diff --git a/test/behavior/error.zig b/test/behavior/error.zig index 0679736ac3..7a53776b36 100644 --- a/test/behavior/error.zig +++ b/test/behavior/error.zig @@ -206,7 +206,7 @@ const MyErrSet = error{ }; fn testErrorSetType() !void { - try expect(@typeInfo(MyErrSet).error_set.?.len == 2); + try expect(@typeInfo(MyErrSet).error_set.error_names.?.len == 2); const a: MyErrSet!i32 = 5678; const b: MyErrSet!i32 = MyErrSet.OutOfMemory; @@ -1125,9 +1125,9 @@ test "@errorCast into own inferred error set" { try expect(err == error.Bad); } - const errors = @typeInfo(@typeInfo(@TypeOf(static.foo(false))).error_union.error_set).error_set.?; - comptime assert(errors.len == 1); - comptime assert(std.mem.eql(u8, errors[0].name, "Bad")); + const error_names = @typeInfo(@typeInfo(@TypeOf(static.foo(false))).error_union.error_set).error_set.error_names.?; + comptime assert(error_names.len == 1); + comptime assert(std.mem.eql(u8, error_names[0], "Bad")); } test "@errorCast into other inferred error set" { diff --git a/test/behavior/eval.zig b/test/behavior/eval.zig index 52c4750d32..f644c4261e 100644 --- a/test/behavior/eval.zig +++ b/test/behavior/eval.zig @@ -889,16 +889,16 @@ test "const local with comptime init through array init" { }; const S = struct { - fn declarations(comptime T: type) []const std.builtin.Type.Declaration { - return @typeInfo(T).@"enum".decls; + fn declarations(comptime T: type) []const [:0]const u8 { + return @typeInfo(T).@"enum".decl_names; } }; - const decls = comptime [_][]const std.builtin.Type.Declaration{ + const decls = comptime [_][]const [:0]const u8{ S.declarations(E1), }; - comptime assert(decls[0][0].name[0] == 'a'); + comptime assert(decls[0][0][0] == 'a'); } test "closure capture type of runtime-known parameter" { diff --git a/test/behavior/fn.zig b/test/behavior/fn.zig index 2d0fb4b4db..5264814016 100644 --- a/test/behavior/fn.zig +++ b/test/behavior/fn.zig @@ -400,7 +400,7 @@ test "function with inferred error set but returning no error" { }; const return_ty = @typeInfo(@TypeOf(S.foo)).@"fn".return_type.?; - try expectEqual(0, @typeInfo(@typeInfo(return_ty).error_union.error_set).error_set.?.len); + try expectEqual(0, @typeInfo(@typeInfo(return_ty).error_union.error_set).error_set.error_names.?.len); } test "import passed byref to function in return type" { diff --git a/test/behavior/generics.zig b/test/behavior/generics.zig index b62199fea9..6f6c6d4707 100644 --- a/test/behavior/generics.zig +++ b/test/behavior/generics.zig @@ -175,7 +175,7 @@ test "generic fn keeps non-generic parameter types" { const S = struct { fn f(comptime T: type, s: []T) !void { - try expect(A != @typeInfo(@TypeOf(s)).pointer.alignment); + try expect(A != @typeInfo(@TypeOf(s)).pointer.attrs.@"align"); } }; @@ -255,10 +255,13 @@ test "generic function instantiation turns into comptime call" { } pub fn fieldInfo(comptime T: type, comptime field: FieldEnum(T)) switch (@typeInfo(T)) { - .@"enum" => std.builtin.Type.EnumField, + .@"enum" => struct { name: [:0]const u8, value: comptime_int }, else => void, } { - return @typeInfo(T).@"enum".fields[@intFromEnum(field)]; + return .{ + .name = @typeInfo(T).@"enum".field_names[@intFromEnum(field)], + .value = @typeInfo(T).@"enum".field_values[@intFromEnum(field)], + }; } pub fn FieldEnum(comptime T: type) type { diff --git a/test/behavior/memcpy.zig b/test/behavior/memcpy.zig index c35492e316..fd2cc8fe6a 100644 --- a/test/behavior/memcpy.zig +++ b/test/behavior/memcpy.zig @@ -157,9 +157,9 @@ test "@memcpy with sentinel" { const S = struct { fn doTheTest() void { - const field = @typeInfo(struct { a: u32 }).@"struct".fields[0]; - var buffer: [field.name.len]u8 = undefined; - @memcpy(&buffer, field.name); + const field_name = @typeInfo(struct { a: u32 }).@"struct".field_names[0]; + var buffer: [field_name.len]u8 = undefined; + @memcpy(&buffer, field_name); } }; diff --git a/test/behavior/packed-struct.zig b/test/behavior/packed-struct.zig index ad0107dcf1..1eb69ace53 100644 --- a/test/behavior/packed-struct.zig +++ b/test/behavior/packed-struct.zig @@ -1040,9 +1040,9 @@ test "packed struct field pointer aligned properly" { }; var f1: *align(16) Foo = @alignCast(@as(*align(1) Foo, @ptrCast(&Foo.buffer[0]))); - try expect(@typeInfo(@TypeOf(f1)).pointer.alignment == 16); + try expect(@typeInfo(@TypeOf(f1)).pointer.attrs.@"align" == 16); try expect(@intFromPtr(f1) == @intFromPtr(&f1.a)); - try expect(@typeInfo(@TypeOf(&f1.a)).pointer.alignment == 16); + try expect(@typeInfo(@TypeOf(&f1.a)).pointer.attrs.@"align" == 16); } test "load flag from packed struct in union" { diff --git a/test/behavior/pointers.zig b/test/behavior/pointers.zig index d0708788fa..357599bb44 100644 --- a/test/behavior/pointers.zig +++ b/test/behavior/pointers.zig @@ -291,8 +291,8 @@ test "allowzero pointer and slice" { comptime assert(@TypeOf(slice) == []allowzero i32); try expect(@intFromPtr(&slice[5]) == 20); - comptime assert(@typeInfo(@TypeOf(ptr)).pointer.is_allowzero); - comptime assert(@typeInfo(@TypeOf(slice)).pointer.is_allowzero); + comptime assert(@typeInfo(@TypeOf(ptr)).pointer.attrs.@"allowzero"); + comptime assert(@typeInfo(@TypeOf(slice)).pointer.attrs.@"allowzero"); } test "assign null directly to C pointer and test null equality" { @@ -470,15 +470,15 @@ test "pointer-integer arithmetic affects the alignment" { var x: usize = 1; _ = .{ &ptr, &x }; - try expect(@typeInfo(@TypeOf(ptr)).pointer.alignment == 8); + try expect(@typeInfo(@TypeOf(ptr)).pointer.attrs.@"align" == 8); const ptr1 = ptr + 1; // 1 * 4 = 4 -> lcd(4,8) = 4 - try expect(@typeInfo(@TypeOf(ptr1)).pointer.alignment == 4); + try expect(@typeInfo(@TypeOf(ptr1)).pointer.attrs.@"align" == 4); const ptr2 = ptr + 4; // 4 * 4 = 16 -> lcd(16,8) = 8 - try expect(@typeInfo(@TypeOf(ptr2)).pointer.alignment == 8); + try expect(@typeInfo(@TypeOf(ptr2)).pointer.attrs.@"align" == 8); const ptr3 = ptr + 0; // no-op - try expect(@typeInfo(@TypeOf(ptr3)).pointer.alignment == 8); + try expect(@typeInfo(@TypeOf(ptr3)).pointer.attrs.@"align" == 8); const ptr4 = ptr + x; // runtime-known addend - try expect(@typeInfo(@TypeOf(ptr4)).pointer.alignment == 4); + try expect(@typeInfo(@TypeOf(ptr4)).pointer.attrs.@"align" == 4); } { var ptr: [*]align(8) [3]u8 = undefined; @@ -486,13 +486,13 @@ test "pointer-integer arithmetic affects the alignment" { _ = .{ &ptr, &x }; const ptr1 = ptr + 17; // 3 * 17 = 51 - try expect(@typeInfo(@TypeOf(ptr1)).pointer.alignment == 1); + try expect(@typeInfo(@TypeOf(ptr1)).pointer.attrs.@"align" == 1); const ptr2 = ptr + x; // runtime-known addend - try expect(@typeInfo(@TypeOf(ptr2)).pointer.alignment == 1); + try expect(@typeInfo(@TypeOf(ptr2)).pointer.attrs.@"align" == 1); const ptr3 = ptr + 8; // 3 * 8 = 24 -> lcd(8,24) = 8 - try expect(@typeInfo(@TypeOf(ptr3)).pointer.alignment == 8); + try expect(@typeInfo(@TypeOf(ptr3)).pointer.attrs.@"align" == 8); const ptr4 = ptr + 4; // 3 * 4 = 12 -> lcd(8,12) = 4 - try expect(@typeInfo(@TypeOf(ptr4)).pointer.alignment == 4); + try expect(@typeInfo(@TypeOf(ptr4)).pointer.attrs.@"align" == 4); } } @@ -592,7 +592,7 @@ test "pointer to constant decl preserves alignment" { const aligned align(8) = @This(){ .a = 3, .b = 4 }; }; - const alignment = @typeInfo(@TypeOf(&S.aligned)).pointer.alignment; + const alignment = @typeInfo(@TypeOf(&S.aligned)).pointer.attrs.@"align"; try std.testing.expect(alignment == 8); } @@ -673,24 +673,24 @@ const Box2 = struct { fn mutable() !void { var box0: Box0 = .{ .items = undefined }; - try std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).pointer.is_const == false); + try std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).pointer.attrs.@"const" == false); var box1: Box1 = .{ .items = undefined }; - try std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).pointer.is_const == false); + try std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).pointer.attrs.@"const" == false); var box2: Box2 = .{ .items = undefined }; - try std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).pointer.is_const == false); + try std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).pointer.attrs.@"const" == false); } fn constant() !void { const box0: Box0 = .{ .items = undefined }; - try std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).pointer.is_const == true); + try std.testing.expect(@typeInfo(@TypeOf(box0.items[0..])).pointer.attrs.@"const" == true); const box1: Box1 = .{ .items = undefined }; - try std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).pointer.is_const == true); + try std.testing.expect(@typeInfo(@TypeOf(box1.items[0..])).pointer.attrs.@"const" == true); const box2: Box2 = .{ .items = undefined }; - try std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).pointer.is_const == true); + try std.testing.expect(@typeInfo(@TypeOf(box2.items[0..])).pointer.attrs.@"const" == true); } test "pointer-to-array constness for zero-size elements, var" { diff --git a/test/behavior/reflection.zig b/test/behavior/reflection.zig index b3f29da414..c5f5d8eff3 100644 --- a/test/behavior/reflection.zig +++ b/test/behavior/reflection.zig @@ -8,11 +8,11 @@ test "reflection: function return type, var args, and param types" { comptime { const info = @typeInfo(@TypeOf(dummy)).@"fn"; try expect(info.return_type.? == i32); - try expect(!info.is_var_args); - try expect(info.params.len == 3); - try expect(info.params[0].type.? == bool); - try expect(info.params[1].type.? == i32); - try expect(info.params[2].type.? == f32); + try expect(!info.attrs.varargs); + try expect(info.param_types.len == 3); + try expect(info.param_types[0].? == bool); + try expect(info.param_types[1].? == i32); + try expect(info.param_types[2].? == f32); } } diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 14040fc0d5..b0be08391b 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -388,9 +388,9 @@ test "empty array to slice" { const align_1: []align(1) u8 = empty; const align_4: []align(4) u8 = empty; const align_16: []align(16) u8 = empty; - try expect(1 == @typeInfo(@TypeOf(align_1)).pointer.alignment); - try expect(4 == @typeInfo(@TypeOf(align_4)).pointer.alignment); - try expect(16 == @typeInfo(@TypeOf(align_16)).pointer.alignment); + try expect(1 == @typeInfo(@TypeOf(align_1)).pointer.attrs.@"align"); + try expect(4 == @typeInfo(@TypeOf(align_4)).pointer.attrs.@"align"); + try expect(16 == @typeInfo(@TypeOf(align_16)).pointer.attrs.@"align"); } }; diff --git a/test/behavior/struct.zig b/test/behavior/struct.zig index 831f994ed0..4a49066995 100644 --- a/test/behavior/struct.zig +++ b/test/behavior/struct.zig @@ -1627,7 +1627,7 @@ test "packed struct field in anonymous struct" { try std.testing.expect(countFields(.{ .t = T{} }) == 1); } fn countFields(v: anytype) usize { - return @typeInfo(@TypeOf(v)).@"struct".fields.len; + return @typeInfo(@TypeOf(v)).@"struct".field_names.len; } test "struct init with no result pointer sets field result types" { diff --git a/test/behavior/tuple.zig b/test/behavior/tuple.zig index 42c3cbf101..d8510b664b 100644 --- a/test/behavior/tuple.zig +++ b/test/behavior/tuple.zig @@ -512,9 +512,9 @@ test "empty struct in tuple" { const T = struct { struct {} }; const info = @typeInfo(T); - try std.testing.expectEqual(@as(usize, 1), info.@"struct".fields.len); - try std.testing.expectEqualStrings("0", info.@"struct".fields[0].name); - try std.testing.expect(@typeInfo(info.@"struct".fields[0].type) == .@"struct"); + try std.testing.expectEqual(@as(usize, 1), info.@"struct".field_names.len); + try std.testing.expectEqualStrings("0", info.@"struct".field_names[0]); + try std.testing.expect(@typeInfo(info.@"struct".field_types[0]) == .@"struct"); } test "empty union in tuple" { @@ -524,9 +524,9 @@ test "empty union in tuple" { const T = struct { union {} }; const info = @typeInfo(T); - try std.testing.expectEqual(@as(usize, 1), info.@"struct".fields.len); - try std.testing.expectEqualStrings("0", info.@"struct".fields[0].name); - try std.testing.expect(@typeInfo(info.@"struct".fields[0].type) == .@"union"); + try std.testing.expectEqual(@as(usize, 1), info.@"struct".field_names.len); + try std.testing.expectEqualStrings("0", info.@"struct".field_names[0]); + try std.testing.expect(@typeInfo(info.@"struct".field_types[0]) == .@"union"); } test "field pointer of underaligned tuple" { @@ -551,11 +551,11 @@ test "field pointer of underaligned tuple" { test "OPV tuple fields aren't comptime" { const T = struct { void }; const t_info = @typeInfo(T); - try expect(!t_info.@"struct".fields[0].is_comptime); + try expect(!t_info.@"struct".field_attrs[0].@"comptime"); const T2 = @Tuple(&.{void}); const t2_info = @typeInfo(T2); - try expect(!t2_info.@"struct".fields[0].is_comptime); + try expect(!t2_info.@"struct".field_attrs[0].@"comptime"); } test "array of tuples that end with a zero-bit field followed by padding" { diff --git a/test/behavior/tuple_declarations.zig b/test/behavior/tuple_declarations.zig index f1a4fb2365..2b75e3d510 100644 --- a/test/behavior/tuple_declarations.zig +++ b/test/behavior/tuple_declarations.zig @@ -12,23 +12,23 @@ test "tuple declaration type info" { const T = struct { comptime u32 = 1, []const u8 }; const info = @typeInfo(T).@"struct"; + try expect(info.is_tuple); try expect(info.layout == .auto); try expect(info.backing_integer == null); - try expect(info.fields.len == 2); - try expect(info.decls.len == 0); - try expect(info.is_tuple); + try expect(info.field_names.len == 2); + try expect(info.decl_names.len == 0); - try expectEqualStrings(info.fields[0].name, "0"); - try expect(info.fields[0].type == u32); - try expect(info.fields[0].defaultValue() == 1); - try expect(info.fields[0].is_comptime); - try expect(info.fields[0].alignment == null); + try expectEqualStrings(info.field_names[0], "0"); + try expect(info.field_types[0] == u32); + try expect(info.field_attrs[0].defaultValue(info.field_types[0]) == 1); + try expect(info.field_attrs[0].@"comptime"); + try expect(info.field_attrs[0].@"align" == null); - try expectEqualStrings(info.fields[1].name, "1"); - try expect(info.fields[1].type == []const u8); - try expect(info.fields[1].defaultValue() == null); - try expect(!info.fields[1].is_comptime); - try expect(info.fields[1].alignment == null); + try expectEqualStrings(info.field_names[1], "1"); + try expect(info.field_types[1] == []const u8); + try expect(info.field_attrs[1].defaultValue(info.field_types[1]) == null); + try expect(!info.field_attrs[1].@"comptime"); + try expect(info.field_attrs[1].@"align" == null); } } diff --git a/test/behavior/type.zig b/test/behavior/type.zig index 88358db182..79f6769940 100644 --- a/test/behavior/type.zig +++ b/test/behavior/type.zig @@ -57,13 +57,7 @@ test "Type.Pointer" { [*c]align(8) volatile u8, [*c]align(8) const volatile u8, }) |testType| { const ptr = @typeInfo(testType).pointer; - try testing.expect(testType == @Pointer(ptr.size, .{ - .@"const" = ptr.is_const, - .@"volatile" = ptr.is_volatile, - .@"allowzero" = ptr.is_allowzero, - .@"align" = ptr.alignment, - .@"addrspace" = ptr.address_space, - }, ptr.child, ptr.sentinel())); + try testing.expect(testType == @Pointer(ptr.size, ptr.attrs, ptr.child, ptr.sentinel())); } } @@ -103,13 +97,7 @@ test "@Pointer on @typeInfo round-trips sentinels" { [:4]allowzero align(4) volatile u8, [:4]allowzero align(4) const volatile u8, }) |TestType| { const ptr = @typeInfo(TestType).pointer; - try testing.expect(TestType == @Pointer(ptr.size, .{ - .@"const" = ptr.is_const, - .@"volatile" = ptr.is_volatile, - .@"allowzero" = ptr.is_allowzero, - .@"align" = ptr.alignment, - .@"addrspace" = ptr.address_space, - }, ptr.child, ptr.sentinel())); + try testing.expect(TestType == @Pointer(ptr.size, ptr.attrs, ptr.child, ptr.sentinel())); } } @@ -122,9 +110,9 @@ test "Type.Opaque" { const Opaque = opaque {}; try testing.expect(Opaque != opaque {}); try testing.expectEqualSlices( - Type.Declaration, + [:0]const u8, &.{}, - @typeInfo(Opaque).@"opaque".decls, + @typeInfo(Opaque).@"opaque".decl_names, ); } @@ -141,13 +129,13 @@ test "Type.Struct" { const A = @Struct(.auto, null, &.{ "x", "y" }, &.{ u8, u32 }, &@splat(.{})); const infoA = @typeInfo(A).@"struct"; try testing.expectEqual(Type.ContainerLayout.auto, infoA.layout); - try testing.expectEqualSlices(u8, "x", infoA.fields[0].name); - try testing.expectEqual(u8, infoA.fields[0].type); - try testing.expectEqual(@as(?*const anyopaque, null), infoA.fields[0].default_value_ptr); - try testing.expectEqualSlices(u8, "y", infoA.fields[1].name); - try testing.expectEqual(u32, infoA.fields[1].type); - try testing.expectEqual(@as(?*const anyopaque, null), infoA.fields[1].default_value_ptr); - try testing.expectEqualSlices(Type.Declaration, &.{}, infoA.decls); + try testing.expectEqualSlices(u8, "x", infoA.field_names[0]); + try testing.expectEqual(u8, infoA.field_types[0]); + try testing.expectEqual(@as(?*const anyopaque, null), infoA.field_attrs[0].default_value_ptr); + try testing.expectEqualSlices(u8, "y", infoA.field_names[1]); + try testing.expectEqual(u32, infoA.field_types[1]); + try testing.expectEqual(@as(?*const anyopaque, null), infoA.field_attrs[1].default_value_ptr); + try testing.expectEqualSlices([:0]const u8, &.{}, infoA.decl_names); try testing.expectEqual(@as(bool, false), infoA.is_tuple); var a = A{ .x = 0, .y = 1 }; @@ -165,13 +153,13 @@ test "Type.Struct" { ); const infoB = @typeInfo(B).@"struct"; try testing.expectEqual(Type.ContainerLayout.@"extern", infoB.layout); - try testing.expectEqualSlices(u8, "x", infoB.fields[0].name); - try testing.expectEqual(u8, infoB.fields[0].type); - try testing.expectEqual(@as(?*const anyopaque, null), infoB.fields[0].default_value_ptr); - try testing.expectEqualSlices(u8, "y", infoB.fields[1].name); - try testing.expectEqual(u32, infoB.fields[1].type); - try testing.expectEqual(@as(u32, 5), infoB.fields[1].defaultValue().?); - try testing.expectEqual(@as(usize, 0), infoB.decls.len); + try testing.expectEqualSlices(u8, "x", infoB.field_names[0]); + try testing.expectEqual(u8, infoB.field_types[0]); + try testing.expectEqual(@as(?*const anyopaque, null), infoB.field_attrs[0].default_value_ptr); + try testing.expectEqualSlices(u8, "y", infoB.field_names[1]); + try testing.expectEqual(u32, infoB.field_types[1]); + try testing.expectEqual(@as(u32, 5), infoB.field_attrs[1].defaultValue(infoB.field_types[1]).?); + try testing.expectEqual(@as(usize, 0), infoB.decl_names.len); try testing.expectEqual(@as(bool, false), infoB.is_tuple); const C = @Struct( @@ -186,20 +174,20 @@ test "Type.Struct" { ); const infoC = @typeInfo(C).@"struct"; try testing.expectEqual(Type.ContainerLayout.@"packed", infoC.layout); - try testing.expectEqualSlices(u8, "x", infoC.fields[0].name); - try testing.expectEqual(u8, infoC.fields[0].type); - try testing.expectEqual(@as(u8, 3), infoC.fields[0].defaultValue().?); - try testing.expectEqualSlices(u8, "y", infoC.fields[1].name); - try testing.expectEqual(u32, infoC.fields[1].type); - try testing.expectEqual(@as(u32, 5), infoC.fields[1].defaultValue().?); - try testing.expectEqual(@as(usize, 0), infoC.decls.len); + try testing.expectEqualSlices(u8, "x", infoC.field_names[0]); + try testing.expectEqual(u8, infoC.field_types[0]); + try testing.expectEqual(@as(u8, 3), infoC.field_attrs[0].defaultValue(infoC.field_types[0]).?); + try testing.expectEqualSlices(u8, "y", infoC.field_names[1]); + try testing.expectEqual(u32, infoC.field_types[1]); + try testing.expectEqual(@as(u32, 5), infoC.field_attrs[1].defaultValue(infoC.field_types[1]).?); + try testing.expectEqual(@as(usize, 0), infoC.decl_names.len); try testing.expectEqual(@as(bool, false), infoC.is_tuple); // empty struct const F = @Struct(.auto, null, &.{}, &.{}, &.{}); const infoF = @typeInfo(F).@"struct"; try testing.expectEqual(Type.ContainerLayout.auto, infoF.layout); - try testing.expect(infoF.fields.len == 0); + try testing.expect(infoF.field_names.len == 0); try testing.expectEqual(@as(bool, false), infoF.is_tuple); } @@ -208,11 +196,11 @@ test "Type.Enum" { if (builtin.zig_backend == .stage2_spirv) return error.SkipZigTest; const Foo = @Enum(u8, .exhaustive, &.{ "a", "b" }, &.{ 1, 5 }); - try testing.expectEqual(true, @typeInfo(Foo).@"enum".is_exhaustive); + try testing.expectEqual(std.builtin.Type.Enum.Mode.exhaustive, @typeInfo(Foo).@"enum".mode); try testing.expectEqual(@as(u8, 1), @intFromEnum(Foo.a)); try testing.expectEqual(@as(u8, 5), @intFromEnum(Foo.b)); const Bar = @Enum(u32, .nonexhaustive, &.{ "a", "b" }, &.{ 1, 5 }); - try testing.expectEqual(false, @typeInfo(Bar).@"enum".is_exhaustive); + try testing.expectEqual(std.builtin.Type.Enum.Mode.nonexhaustive, @typeInfo(Bar).@"enum".mode); try testing.expectEqual(@as(u32, 1), @intFromEnum(Bar.a)); try testing.expectEqual(@as(u32, 5), @intFromEnum(Bar.b)); try testing.expectEqual(@as(u32, 6), @intFromEnum(@as(Bar, @enumFromInt(6)))); @@ -278,13 +266,13 @@ test "Type.Union from regular enum" { test "Type.Union from empty regular enum" { const E = enum {}; const U = @Union(.auto, E, &.{}, &.{}, &.{}); - try testing.expectEqual(@typeInfo(U).@"union".fields.len, 0); + try testing.expectEqual(@typeInfo(U).@"union".field_names.len, 0); } test "Type.Union from empty Type.Enum" { const E = @Enum(u0, .exhaustive, &.{}, &.{}); const U = @Union(.auto, E, &.{}, &.{}, &.{}); - try testing.expectEqual(@typeInfo(U).@"union".fields.len, 0); + try testing.expectEqual(@typeInfo(U).@"union".field_names.len, 0); } test "Type.Fn" { @@ -378,11 +366,11 @@ test "struct field names sliced at comptime from larger string" { } const T = @Struct(.auto, null, field_names, &@splat(usize), &@splat(.{})); - const gen_fields = @typeInfo(T).@"struct".fields; - try testing.expectEqual(3, gen_fields.len); - try testing.expectEqualStrings("f1", gen_fields[0].name); - try testing.expectEqualStrings("f2", gen_fields[1].name); - try testing.expectEqualStrings("f3", gen_fields[2].name); + const gen_field_names = @typeInfo(T).@"struct".field_names; + try testing.expectEqual(3, gen_field_names.len); + try testing.expectEqualStrings("f1", gen_field_names[0]); + try testing.expectEqualStrings("f2", gen_field_names[1]); + try testing.expectEqualStrings("f3", gen_field_names[2]); } } @@ -431,8 +419,8 @@ test "undefined type value" { test "reify struct with zero fields through const arrays" { const names: [0][]const u8 = .{}; const types: [0]type = .{}; - const attrs: [0]std.builtin.Type.StructField.Attributes = .{}; + const attrs: [0]std.builtin.Type.Struct.FieldAttributes = .{}; const S = @Struct(.auto, null, &names, &types, &attrs); comptime assert(@typeInfo(S) == .@"struct"); - comptime assert(@typeInfo(S).@"struct".fields.len == 0); + comptime assert(@typeInfo(S).@"struct".field_names.len == 0); } diff --git a/test/behavior/type_info.zig b/test/behavior/type_info.zig index cd1455e523..882edcf3ab 100644 --- a/test/behavior/type_info.zig +++ b/test/behavior/type_info.zig @@ -45,9 +45,9 @@ fn testCPtr() !void { const ptr_info = @typeInfo([*c]align(4) const i8); try expect(ptr_info == .pointer); try expect(ptr_info.pointer.size == .c); - try expect(ptr_info.pointer.is_const); - try expect(!ptr_info.pointer.is_volatile); - try expect(ptr_info.pointer.alignment == 4); + try expect(ptr_info.pointer.attrs.@"const"); + try expect(!ptr_info.pointer.attrs.@"volatile"); + try expect(ptr_info.pointer.attrs.@"align" == 4); try expect(ptr_info.pointer.child == i8); } @@ -80,9 +80,9 @@ fn testPointer() !void { const u32_ptr_info = @typeInfo(*u32); try expect(u32_ptr_info == .pointer); try expect(u32_ptr_info.pointer.size == .one); - try expect(u32_ptr_info.pointer.is_const == false); - try expect(u32_ptr_info.pointer.is_volatile == false); - try expect(u32_ptr_info.pointer.alignment == null); + try expect(u32_ptr_info.pointer.attrs.@"const" == false); + try expect(u32_ptr_info.pointer.attrs.@"volatile" == false); + try expect(u32_ptr_info.pointer.attrs.@"align" == null); try expect(u32_ptr_info.pointer.child == u32); try expect(u32_ptr_info.pointer.sentinel() == null); } @@ -96,11 +96,11 @@ fn testUnknownLenPtr() !void { const u32_ptr_info = @typeInfo([*]const volatile f64); try expect(u32_ptr_info == .pointer); try expect(u32_ptr_info.pointer.size == .many); - try expect(u32_ptr_info.pointer.is_const == true); - try expect(u32_ptr_info.pointer.is_volatile == true); - try expect(u32_ptr_info.pointer.sentinel() == null); - try expect(u32_ptr_info.pointer.alignment == null); + try expect(u32_ptr_info.pointer.attrs.@"const" == true); + try expect(u32_ptr_info.pointer.attrs.@"volatile" == true); + try expect(u32_ptr_info.pointer.attrs.@"align" == null); try expect(u32_ptr_info.pointer.child == f64); + try expect(u32_ptr_info.pointer.sentinel() == null); } test "type info: null terminated pointer type info" { @@ -112,8 +112,8 @@ fn testNullTerminatedPtr() !void { const ptr_info = @typeInfo([*:0]u8); try expect(ptr_info == .pointer); try expect(ptr_info.pointer.size == .many); - try expect(ptr_info.pointer.is_const == false); - try expect(ptr_info.pointer.is_volatile == false); + try expect(ptr_info.pointer.attrs.@"const" == false); + try expect(ptr_info.pointer.attrs.@"volatile" == false); try expect(ptr_info.pointer.sentinel().? == 0); try expect(@typeInfo([:0]u8).pointer.sentinel() != null); @@ -128,9 +128,9 @@ fn testSlice() !void { const u32_slice_info = @typeInfo([]u32); try expect(u32_slice_info == .pointer); try expect(u32_slice_info.pointer.size == .slice); - try expect(u32_slice_info.pointer.is_const == false); - try expect(u32_slice_info.pointer.is_volatile == false); - try expect(u32_slice_info.pointer.alignment == null); + try expect(u32_slice_info.pointer.attrs.@"const" == false); + try expect(u32_slice_info.pointer.attrs.@"volatile" == false); + try expect(u32_slice_info.pointer.attrs.@"align" == null); try expect(u32_slice_info.pointer.child == u32); } @@ -175,8 +175,8 @@ fn testErrorSet() !void { const error_set_info = @typeInfo(TestErrorSet); try expect(error_set_info == .error_set); - try expect(error_set_info.error_set.?.len == 3); - try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "First")); + try expect(error_set_info.error_set.error_names.?.len == 3); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[0], "First")); const error_union_info = @typeInfo(TestErrorSet!usize); try expect(error_union_info == .error_union); @@ -185,7 +185,7 @@ fn testErrorSet() !void { const global_info = @typeInfo(anyerror); try expect(global_info == .error_set); - try expect(global_info.error_set == null); + try expect(global_info.error_set.error_names == null); } test "type info: error set single value" { @@ -197,8 +197,8 @@ test "type info: error set single value" { const error_set_info = @typeInfo(@TypeOf(TestSet)); try expect(error_set_info == .error_set); - try expect(error_set_info.error_set.?.len == 1); - try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One")); + try expect(error_set_info.error_set.error_names.?.len == 1); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[0], "One")); } test "type info: error set merged" { @@ -210,10 +210,10 @@ test "type info: error set merged" { const error_set_info = @typeInfo(TestSet); try expect(error_set_info == .error_set); - try expect(error_set_info.error_set.?.len == 3); - try expect(mem.eql(u8, error_set_info.error_set.?[0].name, "One")); - try expect(mem.eql(u8, error_set_info.error_set.?[1].name, "Two")); - try expect(mem.eql(u8, error_set_info.error_set.?[2].name, "Three")); + try expect(error_set_info.error_set.error_names.?.len == 3); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[0], "One")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[1], "Two")); + try expect(mem.eql(u8, error_set_info.error_set.error_names.?[2], "Three")); } test "type info: enum info" { @@ -235,11 +235,12 @@ fn testEnum() !void { const os_info = @typeInfo(Os); try expect(os_info == .@"enum"); - try expect(os_info.@"enum".fields.len == 4); - try expect(mem.eql(u8, os_info.@"enum".fields[1].name, "Macos")); - try expect(os_info.@"enum".fields[3].value == 3); + try expect(os_info.@"enum".field_names.len == 4); + try expect(os_info.@"enum".field_values.len == os_info.@"enum".field_names.len); + try expect(mem.eql(u8, os_info.@"enum".field_names[1], "Macos")); + try expect(os_info.@"enum".field_values[3] == 3); try expect(os_info.@"enum".tag_type == u2); - try expect(os_info.@"enum".decls.len == 0); + try expect(os_info.@"enum".decl_names.len == 0); } test "type info: union info" { @@ -252,9 +253,11 @@ fn testUnion() !void { try expect(typeinfo_info == .@"union"); try expect(typeinfo_info.@"union".layout == .auto); try expect(typeinfo_info.@"union".tag_type.? == TypeId); - try expect(typeinfo_info.@"union".fields.len == 24); - try expect(typeinfo_info.@"union".fields[4].type == @TypeOf(@typeInfo(u8).int)); - try expect(typeinfo_info.@"union".decls.len == 21); + try expect(typeinfo_info.@"union".field_names.len == 24); + try expect(typeinfo_info.@"union".field_names.len == typeinfo_info.@"union".field_types.len); + try expect(typeinfo_info.@"union".field_names.len == typeinfo_info.@"union".field_attrs.len); + try expect(typeinfo_info.@"union".field_types[4] == @TypeOf(@typeInfo(u8).int)); + try expect(typeinfo_info.@"union".decl_names.len == 16); const TestNoTagUnion = union { Foo: void, @@ -265,10 +268,12 @@ fn testUnion() !void { try expect(notag_union_info == .@"union"); try expect(notag_union_info.@"union".tag_type == null); try expect(notag_union_info.@"union".layout == .auto); - try expect(notag_union_info.@"union".fields.len == 2); - try expect(notag_union_info.@"union".fields[0].alignment == null); - try expect(notag_union_info.@"union".fields[1].type == u32); - try expect(notag_union_info.@"union".fields[1].alignment == null); + try expect(notag_union_info.@"union".field_names.len == 2); + try expect(notag_union_info.@"union".field_names.len == notag_union_info.@"union".field_types.len); + try expect(notag_union_info.@"union".field_names.len == notag_union_info.@"union".field_attrs.len); + try expect(notag_union_info.@"union".field_attrs[0].@"align" == null); + try expect(notag_union_info.@"union".field_types[1] == u32); + try expect(notag_union_info.@"union".field_attrs[1].@"align" == null); const TestExternUnion = extern union { foo: *anyopaque, @@ -277,7 +282,7 @@ fn testUnion() !void { const extern_union_info = @typeInfo(TestExternUnion); try expect(extern_union_info.@"union".layout == .@"extern"); try expect(extern_union_info.@"union".tag_type == null); - try expect(extern_union_info.@"union".fields[0].type == *anyopaque); + try expect(extern_union_info.@"union".field_types[0] == *anyopaque); } test "type info: struct info" { @@ -292,9 +297,11 @@ fn testStruct() !void { const unpacked_struct_info = @typeInfo(TestStruct); try expect(unpacked_struct_info.@"struct".is_tuple == false); try expect(unpacked_struct_info.@"struct".backing_integer == null); - try expect(unpacked_struct_info.@"struct".fields[0].alignment == null); - try expect(unpacked_struct_info.@"struct".fields[0].defaultValue().? == 4); - try expect(mem.eql(u8, "foobar", unpacked_struct_info.@"struct".fields[1].defaultValue().?)); + try expect(unpacked_struct_info.@"struct".field_attrs[0].@"align" == null); + const field_0_type = unpacked_struct_info.@"struct".field_types[0]; + try expect(unpacked_struct_info.@"struct".field_attrs[0].defaultValue(field_0_type).? == 4); + const field_1_type = unpacked_struct_info.@"struct".field_types[1]; + try expect(mem.eql(u8, "foobar", unpacked_struct_info.@"struct".field_attrs[1].defaultValue(field_1_type).?)); } const TestStruct = struct { @@ -313,13 +320,17 @@ fn testPackedStruct() !void { try expect(struct_info.@"struct".is_tuple == false); try expect(struct_info.@"struct".layout == .@"packed"); try expect(struct_info.@"struct".backing_integer == u128); - try expect(struct_info.@"struct".fields.len == 4); - try expect(struct_info.@"struct".fields[0].alignment == null); - try expect(struct_info.@"struct".fields[2].type == f32); - try expect(struct_info.@"struct".fields[2].defaultValue() == null); - try expect(struct_info.@"struct".fields[3].defaultValue().? == 4); - try expect(struct_info.@"struct".fields[3].alignment == null); - try expect(struct_info.@"struct".decls.len == 1); + try expect(struct_info.@"struct".field_names.len == 4); + try expect(struct_info.@"struct".field_names.len == struct_info.@"struct".field_types.len); + try expect(struct_info.@"struct".field_names.len == struct_info.@"struct".field_attrs.len); + try expect(struct_info.@"struct".field_attrs[0].@"align" == null); + try expect(struct_info.@"struct".field_types[2] == f32); + const field_2_type = struct_info.@"struct".field_types[2]; + try expect(struct_info.@"struct".field_attrs[2].defaultValue(field_2_type) == null); + const field_3_type = struct_info.@"struct".field_types[3]; + try expect(struct_info.@"struct".field_attrs[3].defaultValue(field_3_type).? == 4); + try expect(struct_info.@"struct".field_attrs[3].@"align" == null); + try expect(struct_info.@"struct".decl_names.len == 1); } const TestPackedStruct = packed struct { @@ -346,7 +357,7 @@ fn testOpaque() !void { }; const foo_info = @typeInfo(Foo); - try expect(foo_info.@"opaque".decls.len == 2); + try expect(foo_info.@"opaque".decl_names.len == 2); } test "type info: function type info" { @@ -371,18 +382,18 @@ fn testFunction() !void { _ = S; const foo_fn_type = @TypeOf(typeInfoFoo); const foo_fn_info = @typeInfo(foo_fn_type); - try expect(foo_fn_info.@"fn".calling_convention.eql(.c)); + try expect(foo_fn_info.@"fn".attrs.@"callconv".eql(.c)); try expect(!foo_fn_info.@"fn".is_generic); - try expect(foo_fn_info.@"fn".params.len == 2); - try expect(foo_fn_info.@"fn".is_var_args); + try expect(foo_fn_info.@"fn".param_types.len == 2); + try expect(foo_fn_info.@"fn".attrs.varargs); try expect(foo_fn_info.@"fn".return_type.? == usize); const foo_ptr_fn_info = @typeInfo(@TypeOf(&typeInfoFoo)); try expect(foo_ptr_fn_info.pointer.size == .one); - try expect(foo_ptr_fn_info.pointer.is_const); - try expect(!foo_ptr_fn_info.pointer.is_volatile); - try expect(foo_ptr_fn_info.pointer.address_space == .generic); + try expect(foo_ptr_fn_info.pointer.attrs.@"const"); + try expect(!foo_ptr_fn_info.pointer.attrs.@"volatile"); + try expect(foo_ptr_fn_info.pointer.attrs.@"addrspace" == .generic); try expect(foo_ptr_fn_info.pointer.child == foo_fn_type); - try expect(!foo_ptr_fn_info.pointer.is_allowzero); + try expect(!foo_ptr_fn_info.pointer.attrs.@"allowzero"); try expect(foo_ptr_fn_info.pointer.sentinel() == null); // Avoid looking at `typeInfoFooAligned` on targets which don't support function alignment. @@ -397,19 +408,20 @@ fn testFunction() !void { const aligned_foo_fn_type = @TypeOf(typeInfoFooAligned); const aligned_foo_fn_info = @typeInfo(aligned_foo_fn_type); - try expect(aligned_foo_fn_info.@"fn".calling_convention.eql(.c)); + try expect(aligned_foo_fn_info.@"fn".attrs.@"callconv".eql(.c)); try expect(!aligned_foo_fn_info.@"fn".is_generic); - try expect(aligned_foo_fn_info.@"fn".params.len == 2); - try expect(aligned_foo_fn_info.@"fn".is_var_args); + try expect(aligned_foo_fn_info.@"fn".param_types.len == 2); + try expect(aligned_foo_fn_info.@"fn".param_types.len == aligned_foo_fn_info.@"fn".param_attrs.len); + try expect(aligned_foo_fn_info.@"fn".attrs.varargs); try expect(aligned_foo_fn_info.@"fn".return_type.? == usize); const aligned_foo_ptr_fn_info = @typeInfo(@TypeOf(&typeInfoFooAligned)); try expect(aligned_foo_ptr_fn_info.pointer.size == .one); - try expect(aligned_foo_ptr_fn_info.pointer.is_const); - try expect(!aligned_foo_ptr_fn_info.pointer.is_volatile); - try expect(aligned_foo_ptr_fn_info.pointer.alignment == 4); - try expect(aligned_foo_ptr_fn_info.pointer.address_space == .generic); + try expect(aligned_foo_ptr_fn_info.pointer.attrs.@"const"); + try expect(!aligned_foo_ptr_fn_info.pointer.attrs.@"volatile"); + try expect(aligned_foo_ptr_fn_info.pointer.attrs.@"align" == 4); + try expect(aligned_foo_ptr_fn_info.pointer.attrs.@"addrspace" == .generic); try expect(aligned_foo_ptr_fn_info.pointer.child == aligned_foo_fn_type); - try expect(!aligned_foo_ptr_fn_info.pointer.is_allowzero); + try expect(!aligned_foo_ptr_fn_info.pointer.attrs.@"allowzero"); try expect(aligned_foo_ptr_fn_info.pointer.sentinel() == null); } @@ -418,31 +430,29 @@ extern fn typeInfoFooAligned(a: usize, b: bool, ...) align(4) callconv(.c) usize test "type info: generic function types" { const G1 = @typeInfo(@TypeOf(generic1)); - try expect(G1.@"fn".params.len == 1); - try expect(G1.@"fn".params[0].is_generic == true); - try expect(G1.@"fn".params[0].type == null); + try expect(G1.@"fn".param_types.len == 1); + try expect(G1.@"fn".param_types.len == G1.@"fn".param_attrs.len); + try expect(G1.@"fn".param_types[0] == null); try expect(G1.@"fn".return_type == void); const G2 = @typeInfo(@TypeOf(generic2)); - try expect(G2.@"fn".params.len == 3); - try expect(G2.@"fn".params[0].is_generic == false); - try expect(G2.@"fn".params[0].type == type); - try expect(G2.@"fn".params[1].is_generic == true); - try expect(G2.@"fn".params[1].type == null); - try expect(G2.@"fn".params[2].is_generic == false); - try expect(G2.@"fn".params[2].type == u8); + try expect(G2.@"fn".param_types.len == 3); + try expect(G2.@"fn".param_types.len == G2.@"fn".param_attrs.len); + try expect(G2.@"fn".param_types[0] == type); + try expect(G2.@"fn".param_types[1] == null); + try expect(G2.@"fn".param_types[2] == u8); try expect(G2.@"fn".return_type == void); const G3 = @typeInfo(@TypeOf(generic3)); - try expect(G3.@"fn".params.len == 1); - try expect(G3.@"fn".params[0].is_generic == true); - try expect(G3.@"fn".params[0].type == null); + try expect(G3.@"fn".param_types.len == 1); + try expect(G3.@"fn".param_types.len == G3.@"fn".param_attrs.len); + try expect(G3.@"fn".param_types[0] == null); try expect(G3.@"fn".return_type == null); const G4 = @typeInfo(@TypeOf(generic4)); - try expect(G4.@"fn".params.len == 1); - try expect(G4.@"fn".params[0].is_generic == true); - try expect(G4.@"fn".params[0].type == null); + try expect(G4.@"fn".param_types.len == 1); + try expect(G4.@"fn".param_types.len == G4.@"fn".param_attrs.len); + try expect(G4.@"fn".param_types[0] == null); try expect(G4.@"fn".return_type == null); } @@ -530,7 +540,7 @@ test "@typeInfo does not force declarations into existence" { @compileError("test failed"); } }; - comptime assert(@typeInfo(S).@"struct".fields.len == 1); + comptime assert(@typeInfo(S).@"struct".field_names.len == 1); } fn add(a: i32, b: i32) i32 { @@ -548,12 +558,12 @@ test "Declarations are returned in declaration order" { pub const d = 4; pub const e = 5; }; - const d = @typeInfo(S).@"struct".decls; - try expect(std.mem.eql(u8, d[0].name, "a")); - try expect(std.mem.eql(u8, d[1].name, "b")); - try expect(std.mem.eql(u8, d[2].name, "c")); - try expect(std.mem.eql(u8, d[3].name, "d")); - try expect(std.mem.eql(u8, d[4].name, "e")); + const d = @typeInfo(S).@"struct".decl_names; + try expect(std.mem.eql(u8, d[0], "a")); + try expect(std.mem.eql(u8, d[1], "b")); + try expect(std.mem.eql(u8, d[2], "c")); + try expect(std.mem.eql(u8, d[3], "d")); + try expect(std.mem.eql(u8, d[4], "e")); } test "Struct.is_tuple for anon list literal" { @@ -567,25 +577,27 @@ test "Struct.is_tuple for anon struct literal" { const info = @typeInfo(@TypeOf(.{ .a = 0 })); try expect(!info.@"struct".is_tuple); - try expect(std.mem.eql(u8, info.@"struct".fields[0].name, "a")); + try expect(std.mem.eql(u8, info.@"struct".field_names[0], "a")); } test "StructField.is_comptime" { const info = @typeInfo(struct { x: u8 = 3, comptime y: u32 = 5 }).@"struct"; - try expect(!info.fields[0].is_comptime); - try expect(info.fields[1].is_comptime); + try expect(!info.field_attrs[0].@"comptime"); + try expect(info.field_attrs[1].@"comptime"); } test "value from struct @typeInfo default_value_ptr can be loaded at comptime" { comptime { - const a = @typeInfo(@TypeOf(.{ .foo = @as(u8, 1) })).@"struct".fields[0].default_value_ptr; + const a = @typeInfo(@TypeOf(.{ .foo = @as(u8, 1) })).@"struct".field_attrs[0].default_value_ptr; try expect(@as(*const u8, @ptrCast(a)).* == 1); } } test "type info of tuple of string literal default value" { - const struct_field = @typeInfo(@TypeOf(.{"hi"})).@"struct".fields[0]; - const value = struct_field.defaultValue().?; + const struct_info = @typeInfo(@TypeOf(.{"hi"})).@"struct"; + const struct_field_attrs = struct_info.field_attrs[0]; + const struct_field_type = struct_info.field_types[0]; + const value = struct_field_attrs.defaultValue(struct_field_type).?; comptime std.debug.assert(value[0] == 'h'); } diff --git a/test/behavior/union.zig b/test/behavior/union.zig index e1c655f7ad..e9dbc49aaa 100644 --- a/test/behavior/union.zig +++ b/test/behavior/union.zig @@ -445,7 +445,7 @@ test "global union with single field is correctly initialized" { if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO glbl = Foo1{ - .f = @typeInfo(Foo1).@"union".fields[0].type{ .x = 123 }, + .f = @typeInfo(Foo1).@"union".field_types[0]{ .x = 123 }, }; try expect(glbl.f.x == 123); } @@ -563,8 +563,8 @@ test "tagged union type" { const baz = Baz.B; try expect(baz == Baz.B); - try expect(@typeInfo(TaggedFoo).@"union".fields.len == 3); - try expect(@typeInfo(Baz).@"enum".fields.len == 4); + try expect(@typeInfo(TaggedFoo).@"union".field_names.len == 3); + try expect(@typeInfo(Baz).@"enum".field_names.len == 4); try expect(@sizeOf(TaggedFoo) == @sizeOf(FooNoVoid)); try expect(@sizeOf(Baz) == 1); } diff --git a/test/behavior/x86_64/math.zig b/test/behavior/x86_64/math.zig index 5662a09c77..afb1ebbd55 100644 --- a/test/behavior/x86_64/math.zig +++ b/test/behavior/x86_64/math.zig @@ -130,8 +130,8 @@ pub noinline fn checkExpected(expected: anytype, actual: @TypeOf(expected), comp }; }, }, - .@"struct" => |@"struct"| inline for (@"struct".fields) |field| { - try checkExpected(@field(expected, field.name), @field(actual, field.name), compare); + .@"struct" => |@"struct"| inline for (@"struct".field_names) |field_name| { + try checkExpected(@field(expected, field_name), @field(actual, field_name), compare); } else return, }; if (switch (@typeInfo(Expected)) { diff --git a/test/behavior/zon.zig b/test/behavior/zon.zig index 6de22701d5..d91da187b7 100644 --- a/test/behavior/zon.zig +++ b/test/behavior/zon.zig @@ -541,31 +541,31 @@ test "anon" { try expectEqual(expected[1], actual[1]); const expected_struct = expected[0]; const actual_struct = actual[0]; - const expected_fields = @typeInfo(@TypeOf(expected_struct)).@"struct".fields; - const actual_fields = @typeInfo(@TypeOf(actual_struct)).@"struct".fields; + const expected_fields = @typeInfo(@TypeOf(expected_struct)).@"struct".field_names; + const actual_fields = @typeInfo(@TypeOf(actual_struct)).@"struct".field_names; try expectEqual(expected_fields.len, actual_fields.len); - inline for (expected_fields) |field| { - try expectEqual(@field(expected_struct, field.name), @field(actual_struct, field.name)); + inline for (expected_fields) |field_name| { + try expectEqual(@field(expected_struct, field_name), @field(actual_struct, field_name)); } } test "build.zig.zon" { const build = @import("zon/build.zig.zon"); - try expectEqual(4, @typeInfo(@TypeOf(build)).@"struct".fields.len); + try expectEqual(4, @typeInfo(@TypeOf(build)).@"struct".field_names.len); try expectEqualStrings("temp", build.name); try expectEqualStrings("0.0.0", build.version); const dependencies = build.dependencies; - try expectEqual(2, @typeInfo(@TypeOf(dependencies)).@"struct".fields.len); + try expectEqual(2, @typeInfo(@TypeOf(dependencies)).@"struct".field_names.len); const example_0 = dependencies.example_0; - try expectEqual(2, @typeInfo(@TypeOf(dependencies)).@"struct".fields.len); + try expectEqual(2, @typeInfo(@TypeOf(dependencies)).@"struct".field_names.len); try expectEqualStrings("https://example.com/foo.tar.gz", example_0.url); try expectEqualStrings("...", example_0.hash); const example_1 = dependencies.example_1; - try expectEqual(2, @typeInfo(@TypeOf(dependencies)).@"struct".fields.len); + try expectEqual(2, @typeInfo(@TypeOf(dependencies)).@"struct".field_names.len); try expectEqualStrings("../foo", example_1.path); try expectEqual(false, example_1.lazy); diff --git a/test/cases/compile_errors/access_invalid_typeInfo_decl.zig b/test/cases/compile_errors/access_invalid_typeInfo_decl.zig index 05386c22e1..58853ef8c4 100644 --- a/test/cases/compile_errors/access_invalid_typeInfo_decl.zig +++ b/test/cases/compile_errors/access_invalid_typeInfo_decl.zig @@ -1,6 +1,6 @@ pub const A = B; export fn foo() void { - _ = @typeInfo(@This()).@"struct".decls[0]; + _ = @typeInfo(@This()).@"struct".decl_names[0]; } // error diff --git a/test/cases/compile_errors/comptime_store_in_comptime_switch_in_runtime_if.zig b/test/cases/compile_errors/comptime_store_in_comptime_switch_in_runtime_if.zig index 749d1db94c..8665462397 100644 --- a/test/cases/compile_errors/comptime_store_in_comptime_switch_in_runtime_if.zig +++ b/test/cases/compile_errors/comptime_store_in_comptime_switch_in_runtime_if.zig @@ -7,9 +7,9 @@ pub export fn entry() void { comptime var a = 1; const info = @typeInfo(Widget).@"union"; - inline for (info.fields) |field| { + inline for (info.field_types) |field_type| { if (foo()) { - switch (field.type) { + switch (field_type) { u0 => a = 2, else => unreachable, } diff --git a/test/cases/compile_errors/issue_15572_break_on_inline_while.zig b/test/cases/compile_errors/issue_15572_break_on_inline_while.zig index d1dc507232..dcb5c8e829 100644 --- a/test/cases/compile_errors/issue_15572_break_on_inline_while.zig +++ b/test/cases/compile_errors/issue_15572_break_on_inline_while.zig @@ -6,8 +6,8 @@ pub const DwarfSection = enum { }; pub fn main() void { - const section = inline for (@typeInfo(DwarfSection).@"enum".fields) |section| { - if (std.mem.eql(u8, section.name, "eh_frame")) break section; + const section = inline for (@typeInfo(DwarfSection).@"enum".field_names) |section_name| { + if (std.mem.eql(u8, section_name, "eh_frame")) break section_name; }; _ = section; @@ -16,4 +16,4 @@ pub fn main() void { // error // target=x86_64-linux // -// :9:28: error: incompatible types: 'lang.Type.EnumField' and 'void' +// :9:28: error: incompatible types: '[:0]const u8' and 'void' diff --git a/test/cases/compile_errors/issue_5221_invalid_struct_init_type_referenced_by_typeInfo_and_passed_into_function.zig b/test/cases/compile_errors/issue_5221_invalid_struct_init_type_referenced_by_typeInfo_and_passed_into_function.zig index becfe35011..f1723d43f0 100644 --- a/test/cases/compile_errors/issue_5221_invalid_struct_init_type_referenced_by_typeInfo_and_passed_into_function.zig +++ b/test/cases/compile_errors/issue_5221_invalid_struct_init_type_referenced_by_typeInfo_and_passed_into_function.zig @@ -7,7 +7,7 @@ export fn foo() void { wrong_type: []u8 = "foo", }; - comptime ignore(@typeInfo(MyStruct).@"struct".fields[0]); + comptime ignore(@typeInfo(MyStruct).@"struct".field_names[0]); } // error diff --git a/test/cases/compile_errors/runtime_index_into_comptime_type_slice.zig b/test/cases/compile_errors/runtime_index_into_comptime_type_slice.zig index b212eebbdb..a2ad985863 100644 --- a/test/cases/compile_errors/runtime_index_into_comptime_type_slice.zig +++ b/test/cases/compile_errors/runtime_index_into_comptime_type_slice.zig @@ -6,12 +6,11 @@ fn getIndex() usize { } export fn entry() void { const index = getIndex(); - const field = @typeInfo(Struct).@"struct".fields[index]; + const field = @typeInfo(Struct).@"struct".field_types[index]; _ = field; } // error // -// :9:54: error: values of type 'lang.Type.StructField' must be comptime-known, but index value is runtime-known -// : note: struct requires comptime because of this field +// :9:59: error: values of type 'type' must be comptime-known, but index value is runtime-known // : note: types are not available at runtime diff --git a/test/cases/fn_typeinfo_passed_to_comptime_fn.zig b/test/cases/fn_typeinfo_passed_to_comptime_fn.zig index c158f00b43..e215659d1b 100644 --- a/test/cases/fn_typeinfo_passed_to_comptime_fn.zig +++ b/test/cases/fn_typeinfo_passed_to_comptime_fn.zig @@ -9,7 +9,7 @@ fn someFn(arg: ?*c_int) f64 { return 8; } fn foo(comptime info: std.builtin.Type) !void { - try std.testing.expect(info.@"fn".params[0].type.? == ?*c_int); + try std.testing.expect(info.@"fn".param_types[0].? == ?*c_int); } // run diff --git a/test/incremental/add_remove_struct_fields b/test/incremental/add_remove_struct_fields index 44d17e618e..f5e62fad78 100644 --- a/test/incremental/add_remove_struct_fields +++ b/test/incremental/add_remove_struct_fields @@ -11,7 +11,7 @@ pub fn main(init: std.process.Init) !void { }; } fn printFieldCount(w: *Writer) Writer.Error!void { - try w.print("{d} ", .{@typeInfo(S).@"struct".fields.len}); + try w.print("{d} ", .{@typeInfo(S).@"struct".field_names.len}); } fn printOneField(w: *Writer) Writer.Error!void { const val: S = .{ .x = 100 }; @@ -34,7 +34,7 @@ pub fn main(init: std.process.Init) !void { }; } fn printFieldCount(w: *Writer) Writer.Error!void { - try w.print("{d} ", .{@typeInfo(S).@"struct".fields.len}); + try w.print("{d} ", .{@typeInfo(S).@"struct".field_names.len}); } fn printOneField(w: *Writer) Writer.Error!void { const val: S = .{ .x = 100 }; @@ -57,7 +57,7 @@ pub fn main(init: std.process.Init) !void { }; } fn printFieldCount(w: *Writer) Writer.Error!void { - try w.print("{d} ", .{@typeInfo(S).@"struct".fields.len}); + try w.print("{d} ", .{@typeInfo(S).@"struct".field_names.len}); } fn printOneField(w: *Writer) Writer.Error!void { const val: S = .{ .x = 100 }; @@ -81,7 +81,7 @@ pub fn main(init: std.process.Init) !void { }; } fn printFieldCount(w: *Writer) Writer.Error!void { - try w.print("{d} ", .{@typeInfo(S).@"struct".fields.len}); + try w.print("{d} ", .{@typeInfo(S).@"struct".field_names.len}); } fn printOneField(w: *Writer) Writer.Error!void { //const val: S = .{ .x = 100 }; diff --git a/test/incremental/add_remove_toplevel_fields b/test/incremental/add_remove_toplevel_fields index 4c36acb74a..e7ba9a2e89 100644 --- a/test/incremental/add_remove_toplevel_fields +++ b/test/incremental/add_remove_toplevel_fields @@ -12,7 +12,7 @@ pub fn main(init: std.process.Init) !void { }; } fn printFieldCount(w: *Writer) Writer.Error!void { - try w.print("{d} ", .{@typeInfo(S).@"struct".fields.len}); + try w.print("{d} ", .{@typeInfo(S).@"struct".field_names.len}); } fn printOneField(w: *Writer) Writer.Error!void { const val: S = .{ .x = 100 }; @@ -37,7 +37,7 @@ pub fn main(init: std.process.Init) !void { }; } fn printFieldCount(w: *Writer) Writer.Error!void { - try w.print("{d} ", .{@typeInfo(S).@"struct".fields.len}); + try w.print("{d} ", .{@typeInfo(S).@"struct".field_names.len}); } fn printOneField(w: *Writer) Writer.Error!void { const val: S = .{ .x = 100 }; @@ -60,7 +60,7 @@ pub fn main(init: std.process.Init) !void { }; } fn printFieldCount(w: *Writer) Writer.Error!void { - try w.print("{d} ", .{@typeInfo(S).@"struct".fields.len}); + try w.print("{d} ", .{@typeInfo(S).@"struct".field_names.len}); } fn printOneField(w: *Writer) Writer.Error!void { const val: S = .{ .x = 100 }; @@ -84,7 +84,7 @@ pub fn main(init: std.process.Init) !void { }; } fn printFieldCount(w: *Writer) Writer.Error!void { - try w.print("{d} ", .{@typeInfo(S).@"struct".fields.len}); + try w.print("{d} ", .{@typeInfo(S).@"struct".field_names.len}); } fn printOneField(w: *Writer) Writer.Error!void { //const val: S = .{ .x = 100 }; diff --git a/test/incremental/change_union_tag_type b/test/incremental/change_union_tag_type index 2e6fbf3154..5f754de42a 100644 --- a/test/incremental/change_union_tag_type +++ b/test/incremental/change_union_tag_type @@ -4,7 +4,7 @@ const A = enum(u8) { a }; const B = enum(u8) { b }; const Foo = union(A) { a: u8 }; pub fn main(init: std.process.Init) !void { - const field_name = @typeInfo(Foo).@"union".fields[0].name; + const field_name = @typeInfo(Foo).@"union".field_names[0]; var stdout_writer = std.Io.File.stdout().writerStreaming(init.io, &.{}); try stdout_writer.interface.print("{s}\n", .{field_name}); } @@ -17,7 +17,7 @@ const A = enum(u8) { a }; const B = enum(u8) { b }; const Foo = union(B) { a: u8 }; pub fn main(init: std.process.Init) !void { - const field_name = @typeInfo(Foo).@"union".fields[0].name; + const field_name = @typeInfo(Foo).@"union".field_names[0]; var stdout_writer = std.Io.File.stdout().writerStreaming(init.io, &.{}); try stdout_writer.interface.print("{s}\n", .{field_name}); } @@ -31,7 +31,7 @@ const A = enum(u8) { a }; const B = enum(u8) { b }; const Foo = union(B) { b: u8 }; pub fn main(init: std.process.Init) !void { - const field_name = @typeInfo(Foo).@"union".fields[0].name; + const field_name = @typeInfo(Foo).@"union".field_names[0]; var stdout_writer = std.Io.File.stdout().writerStreaming(init.io, &.{}); try stdout_writer.interface.print("{s}\n", .{field_name}); } diff --git a/test/incremental/do_nothing b/test/incremental/do_nothing index 6908984019..bc50b4bc03 100644 --- a/test/incremental/do_nothing +++ b/test/incremental/do_nothing @@ -7,7 +7,7 @@ pub fn main() void { } const S = struct { foo: u32, nested: struct { x: u16 } }; const U = union(enum) { a, b, c: S }; -const E = enum(u8) { a = @typeInfo(U).@"union".fields.len, b = 0, c }; +const E = enum(u8) { a = @typeInfo(U).@"union".field_names.len, b = 0, c }; const O = opaque { comptime { _ = @as(S, undefined); @@ -27,7 +27,7 @@ pub fn main() void { } const S = struct { foo: u32, nested: struct { x: u16 } }; const U = union(enum) { a, b, c: S }; -const E = enum(u8) { a = @typeInfo(U).@"union".fields.len, b = 0, c }; +const E = enum(u8) { a = @typeInfo(U).@"union".field_names.len, b = 0, c }; const O = opaque { comptime { _ = @as(S, undefined); diff --git a/test/standalone/build.zig b/test/standalone/build.zig index 9529e6907e..e36e802979 100644 --- a/test/standalone/build.zig +++ b/test/standalone/build.zig @@ -85,8 +85,7 @@ pub fn build(b: *std.Build) void { if (std.mem.eql(u8, dep_name, "simple")) continue; const all_pkgs = @import("root").dependencies.packages; - inline for (@typeInfo(all_pkgs).@"struct".decls) |decl| { - const pkg_hash = decl.name; + inline for (@typeInfo(all_pkgs).@"struct".decl_names) |pkg_hash| { if (std.mem.eql(u8, dep_hash, pkg_hash)) { const pkg = @field(all_pkgs, pkg_hash); if (!@hasDecl(pkg, "build_zig")) { diff --git a/tools/gen_stubs.zig b/tools/gen_stubs.zig index 90f039488c..f6ba7a5af0 100644 --- a/tools/gen_stubs.zig +++ b/tools/gen_stubs.zig @@ -141,10 +141,10 @@ const Family = enum { x86, }; -const arches: [@typeInfo(Arch).@"enum".fields.len]Arch = blk: { - var result: [@typeInfo(Arch).@"enum".fields.len]Arch = undefined; - for (@typeInfo(Arch).@"enum".fields) |field| { - const arch: Arch = @enumFromInt(field.value); +const arches: [@typeInfo(Arch).@"enum".field_names.len]Arch = blk: { + var result: [@typeInfo(Arch).@"enum".field_names.len]Arch = undefined; + for (@typeInfo(Arch).@"enum".field_values) |field_value| { + const arch: Arch = @enumFromInt(field_value); result[archIndex(arch)] = arch; } break :blk result; @@ -160,8 +160,8 @@ const MultiSym = struct { fn isSingleArch(ms: MultiSym) ?Arch { var result: ?Arch = null; - inline for (@typeInfo(Arch).@"enum".fields) |field| { - const arch: Arch = @enumFromInt(field.value); + inline for (@typeInfo(Arch).@"enum".field_values) |field_value| { + const arch: Arch = @enumFromInt(field_value); if (ms.present[archIndex(arch)]) { if (result != null) return null; result = arch; @@ -172,8 +172,8 @@ const MultiSym = struct { fn isFamily(ms: MultiSym) ?Family { var result: ?Family = null; - inline for (@typeInfo(Arch).@"enum".fields) |field| { - const arch: Arch = @enumFromInt(field.value); + inline for (@typeInfo(Arch).@"enum".field_values) |field_value| { + const arch: Arch = @enumFromInt(field_value); if (ms.present[archIndex(arch)]) { const family = arch.family(); if (result) |r| if (family != r) return null; @@ -193,8 +193,8 @@ const MultiSym = struct { } fn isTime32Only(ms: MultiSym) bool { - inline for (@typeInfo(Arch).@"enum".fields) |field| { - const arch: Arch = @enumFromInt(field.value); + inline for (@typeInfo(Arch).@"enum".field_values) |field_value| { + const arch: Arch = @enumFromInt(field_value); if (ms.present[archIndex(arch)] != arch.isTime32()) { return false; } @@ -233,8 +233,8 @@ const MultiSym = struct { } fn isPtrSize(ms: MultiSym, mult: u16) bool { - inline for (@typeInfo(Arch).@"enum".fields) |field| { - const arch: Arch = @enumFromInt(field.value); + inline for (@typeInfo(Arch).@"enum".field_values) |field_value| { + const arch: Arch = @enumFromInt(field_value); const arch_index = archIndex(arch); if (ms.present[arch_index] and ms.size[arch_index] != arch.ptrSize() * mult) { return false; @@ -244,8 +244,8 @@ const MultiSym = struct { } fn isWeak64(ms: MultiSym) bool { - inline for (@typeInfo(Arch).@"enum".fields) |field| { - const arch: Arch = @enumFromInt(field.value); + inline for (@typeInfo(Arch).@"enum".field_values) |field_value| { + const arch: Arch = @enumFromInt(field_value); const arch_index = archIndex(arch); const binding: u4 = switch (arch.ptrSize()) { 4 => std.elf.STB_GLOBAL, @@ -260,8 +260,8 @@ const MultiSym = struct { } fn isWeakTime64(ms: MultiSym) bool { - inline for (@typeInfo(Arch).@"enum".fields) |field| { - const arch: Arch = @enumFromInt(field.value); + inline for (@typeInfo(Arch).@"enum".field_values) |field_value| { + const arch: Arch = @enumFromInt(field_value); const arch_index = archIndex(arch); const binding: u4 = if (arch.isTime32()) std.elf.STB_GLOBAL else std.elf.STB_WEAK; if (ms.present[arch_index] and ms.binding[arch_index] != binding) { diff --git a/tools/generate_c_size_and_align_checks.zig b/tools/generate_c_size_and_align_checks.zig index 7f562dcac4..42fa4d5937 100644 --- a/tools/generate_c_size_and_align_checks.zig +++ b/tools/generate_c_size_and_align_checks.zig @@ -43,8 +43,8 @@ pub fn main(init: std.process.Init) !void { var buffer: [2000]u8 = undefined; var stdout_writer = Io.File.stdout().writerStreaming(io, &buffer); const w = &stdout_writer.interface; - inline for (@typeInfo(std.Target.CType).@"enum".fields) |field| { - const c_type: std.Target.CType = @enumFromInt(field.value); + inline for (@typeInfo(std.Target.CType).@"enum".field_values) |field_value| { + const c_type: std.Target.CType = @enumFromInt(field_value); try w.print("_Static_assert(sizeof({0s}) == {1d}, \"sizeof({0s}) == {1d}\");\n", .{ cName(c_type), target.cTypeByteSize(c_type), diff --git a/tools/update_clang_options.zig b/tools/update_clang_options.zig index af42e362a7..00a88da979 100644 --- a/tools/update_clang_options.zig +++ b/tools/update_clang_options.zig @@ -660,9 +660,9 @@ pub fn main(init: std.process.Init) !void { var llvm_to_zig_cpu_features = std.StringHashMap([]const u8).init(arena); - inline for (@typeInfo(cpu_targets).@"struct".decls) |decl| { - const Feature = @field(cpu_targets, decl.name).Feature; - const all_features = @field(cpu_targets, decl.name).all_features; + inline for (@typeInfo(cpu_targets).@"struct".decl_names) |decl_name| { + const Feature = @field(cpu_targets, decl_name).Feature; + const all_features = @field(cpu_targets, decl_name).all_features; for (all_features, 0..) |feat, i| { const llvm_name = feat.llvm_name orelse continue; diff --git a/tools/update_cpu_features.zig b/tools/update_cpu_features.zig index 2b450853e1..ea6a659507 100644 --- a/tools/update_cpu_features.zig +++ b/tools/update_cpu_features.zig @@ -2436,7 +2436,7 @@ fn processOneTargetInner(io: Io, job: Job) !void { try w.print(" @setEvalBranchQuota({d});\n", .{branch_quota}); } try w.writeAll( - \\ const len = @typeInfo(Feature).@"enum".fields.len; + \\ const len = @typeInfo(Feature).@"enum".field_names.len; \\ std.debug.assert(len <= CpuFeature.Set.needed_bit_count); \\ var result: [len]CpuFeature = undefined; \\ @@ -2505,7 +2505,7 @@ fn processOneTargetInner(io: Io, job: Job) !void { \\ const ti = @typeInfo(Feature); \\ for (&result, 0..) |*elem, i| { \\ elem.index = i; - \\ elem.name = ti.@"enum".fields[i].name; + \\ elem.name = ti.@"enum".field_names[i]; \\ } \\ break :blk result; \\};