mirror of
https://codeberg.org/ziglang/zig.git
synced 2026-05-29 20:36:01 +03:00
Merge pull request 'Use struct-of-arrays style for std.lang.Type' (#35234) from Der_Teufel/zig:soa-builtin-type into master
Reviewed-on: https://codeberg.org/ziglang/zig/pulls/35234
This commit is contained in:
+3
-3
@@ -5752,7 +5752,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val
|
||||
{#header_open|@Fn#}
|
||||
<pre>{#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#}</pre>
|
||||
@@ -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#}</pre>
|
||||
<p>Returns a {#link|struct#} type with the properties specified by the arguments.</p>
|
||||
{#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#}</pre>
|
||||
<p>Returns a {#link|union#} type with the properties specified by the arguments.</p>
|
||||
{#header_close#}
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 .{
|
||||
|
||||
Vendored
+52
-51
@@ -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 {
|
||||
|
||||
Vendored
+5
-5
@@ -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;
|
||||
}
|
||||
|
||||
Vendored
+7
-7
@@ -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))) {
|
||||
|
||||
Vendored
+2
-2
@@ -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),
|
||||
|
||||
Vendored
+11
-11
@@ -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)}),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+4
-4
@@ -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;
|
||||
}
|
||||
|
||||
+2
-2
@@ -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..]),
|
||||
|
||||
+14
-13
@@ -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),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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 },
|
||||
|
||||
Vendored
+3
-2
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+14
-12
@@ -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;
|
||||
|
||||
Vendored
+11
-10
@@ -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}));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Vendored
+18
-22
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
Vendored
+7
-7
@@ -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;
|
||||
});
|
||||
}
|
||||
|
||||
Vendored
+1
-1
@@ -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);
|
||||
|
||||
|
||||
Vendored
+6
-6
@@ -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);
|
||||
|
||||
@@ -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"),
|
||||
};
|
||||
|
||||
@@ -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"),
|
||||
};
|
||||
|
||||
+52
-53
@@ -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;
|
||||
|
||||
@@ -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 = .{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+7
-6
@@ -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(.{}));
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
|
||||
+10
-10
@@ -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);
|
||||
|
||||
+18
-18
@@ -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(" }");
|
||||
},
|
||||
|
||||
@@ -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;
|
||||
|
||||
+4
-4
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
|
||||
@@ -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) {
|
||||
|
||||
+1
-1
@@ -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 {
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)),
|
||||
|
||||
@@ -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 {};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)).*;
|
||||
|
||||
@@ -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;
|
||||
|
||||
+7
-7
@@ -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) {
|
||||
|
||||
+65
-66
@@ -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;
|
||||
|
||||
+1
-1
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
+14
-14
@@ -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) {
|
||||
|
||||
+47
-31
@@ -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;
|
||||
}
|
||||
|
||||
+68
-100
@@ -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
|
||||
|
||||
+2
-2
@@ -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));
|
||||
|
||||
+86
-102
@@ -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,
|
||||
|
||||
@@ -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.
|
||||
|
||||
+133
-173
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
+9
-15
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user