| author | |
| committer | |
| log | 3dafc5b9a322124c325447a37fa117b093795448 |
| tree | eff0492d8e0ce89af1e9908dc4febd68dc4ccf0e |
| parent | c5ec096b2ffd42aff6385debe2a412a6db67868f |
| parent | bbab5e19b45436f9828ae988832c1e31b5861683 |
closes #74207 files changed, 56 insertions(+), 40 deletions(-)
lib/std/meta.zig+43-11| ... | @@ -487,19 +487,14 @@ test "std.meta.fields" { | ... | @@ -487,19 +487,14 @@ test "std.meta.fields" { |
| 487 | testing.expect(comptime uf[0].field_type == u8); | 487 | testing.expect(comptime uf[0].field_type == u8); |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | pub fn fieldInfo(comptime T: type, comptime field_name: []const u8) switch (@typeInfo(T)) { | 490 | pub fn fieldInfo(comptime T: type, comptime field: FieldEnum(T)) switch (@typeInfo(T)) { |
| 491 | .Struct => TypeInfo.StructField, | 491 | .Struct => TypeInfo.StructField, |
| 492 | .Union => TypeInfo.UnionField, | 492 | .Union => TypeInfo.UnionField, |
| 493 | .ErrorSet => TypeInfo.Error, | 493 | .ErrorSet => TypeInfo.Error, |
| 494 | .Enum => TypeInfo.EnumField, | 494 | .Enum => TypeInfo.EnumField, |
| 495 | else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), | 495 | else => @compileError("Expected struct, union, error set or enum type, found '" ++ @typeName(T) ++ "'"), |
| 496 | } { | 496 | } { |
| 497 | inline for (comptime fields(T)) |field| { | 497 | return fields(T)[@enumToInt(field)]; |
| 498 | if (comptime mem.eql(u8, field.name, field_name)) | ||
| 499 | return field; | ||
| 500 | } | ||
| 501 | |||
| 502 | @compileError("'" ++ @typeName(T) ++ "' has no field '" ++ field_name ++ "'"); | ||
| 503 | } | 498 | } |
| 504 | 499 | ||
| 505 | test "std.meta.fieldInfo" { | 500 | test "std.meta.fieldInfo" { |
| ... | @@ -514,10 +509,10 @@ test "std.meta.fieldInfo" { | ... | @@ -514,10 +509,10 @@ test "std.meta.fieldInfo" { |
| 514 | a: u8, | 509 | a: u8, |
| 515 | }; | 510 | }; |
| 516 | 511 | ||
| 517 | const e1f = comptime fieldInfo(E1, "A"); | 512 | const e1f = fieldInfo(E1, .A); |
| 518 | const e2f = comptime fieldInfo(E2, "A"); | 513 | const e2f = fieldInfo(E2, .A); |
| 519 | const sf = comptime fieldInfo(S1, "a"); | 514 | const sf = fieldInfo(S1, .a); |
| 520 | const uf = comptime fieldInfo(U1, "a"); | 515 | const uf = fieldInfo(U1, .a); |
| 521 | 516 | ||
| 522 | testing.expect(mem.eql(u8, e1f.name, "A")); | 517 | testing.expect(mem.eql(u8, e1f.name, "A")); |
| 523 | testing.expect(mem.eql(u8, e2f.name, "A")); | 518 | testing.expect(mem.eql(u8, e2f.name, "A")); |
| ... | @@ -568,6 +563,43 @@ test "std.meta.fieldNames" { | ... | @@ -568,6 +563,43 @@ test "std.meta.fieldNames" { |
| 568 | testing.expectEqualSlices(u8, u1names[1], "b"); | 563 | testing.expectEqualSlices(u8, u1names[1], "b"); |
| 569 | } | 564 | } |
| 570 | 565 | ||
| 566 | pub fn FieldEnum(comptime T: type) type { | ||
| 567 | const fieldInfos = fields(T); | ||
| 568 | var enumFields: [fieldInfos.len]std.builtin.TypeInfo.EnumField = undefined; | ||
| 569 | var decls = [_]std.builtin.TypeInfo.Declaration{}; | ||
| 570 | inline for (fieldInfos) |field, i| { | ||
| 571 | enumFields[i] = .{ | ||
| 572 | .name = field.name, | ||
| 573 | .value = i, | ||
| 574 | }; | ||
| 575 | } | ||
| 576 | return @Type(.{ | ||
| 577 | .Enum = .{ | ||
| 578 | .layout = .Auto, | ||
| 579 | .tag_type = std.math.IntFittingRange(0, fieldInfos.len - 1), | ||
| 580 | .fields = &enumFields, | ||
| 581 | .decls = &decls, | ||
| 582 | .is_exhaustive = true, | ||
| 583 | }, | ||
| 584 | }); | ||
| 585 | } | ||
| 586 | |||
| 587 | fn expectEqualEnum(expected: anytype, actual: @TypeOf(expected)) void { | ||
| 588 | // TODO: https://github.com/ziglang/zig/issues/7419 | ||
| 589 | // testing.expectEqual(@typeInfo(expected).Enum, @typeInfo(actual).Enum); | ||
| 590 | testing.expectEqual(@typeInfo(expected).Enum.layout, @typeInfo(actual).Enum.layout); | ||
| 591 | testing.expectEqual(@typeInfo(expected).Enum.tag_type, @typeInfo(actual).Enum.tag_type); | ||
| 592 | comptime testing.expectEqualSlices(std.builtin.TypeInfo.EnumField, @typeInfo(expected).Enum.fields, @typeInfo(actual).Enum.fields); | ||
| 593 | comptime testing.expectEqualSlices(std.builtin.TypeInfo.Declaration, @typeInfo(expected).Enum.decls, @typeInfo(actual).Enum.decls); | ||
| 594 | testing.expectEqual(@typeInfo(expected).Enum.is_exhaustive, @typeInfo(actual).Enum.is_exhaustive); | ||
| 595 | } | ||
| 596 | |||
| 597 | test "std.meta.FieldEnum" { | ||
| 598 | expectEqualEnum(enum { a }, FieldEnum(struct { a: u8 })); | ||
| 599 | expectEqualEnum(enum { a, b, c }, FieldEnum(struct { a: u8, b: void, c: f32 })); | ||
| 600 | expectEqualEnum(enum { a, b, c }, FieldEnum(union { a: u8, b: void, c: f32 })); | ||
| 601 | } | ||
| 602 | |||
| 571 | pub fn TagType(comptime T: type) type { | 603 | pub fn TagType(comptime T: type) type { |
| 572 | return switch (@typeInfo(T)) { | 604 | return switch (@typeInfo(T)) { |
| 573 | .Enum => |info| info.tag_type, | 605 | .Enum => |info| info.tag_type, |
lib/std/meta/trailer_flags.zig+2-18| ... | @@ -21,20 +21,7 @@ pub fn TrailerFlags(comptime Fields: type) type { | ... | @@ -21,20 +21,7 @@ pub fn TrailerFlags(comptime Fields: type) type { |
| 21 | pub const Int = meta.Int(.unsigned, bit_count); | 21 | pub const Int = meta.Int(.unsigned, bit_count); |
| 22 | pub const bit_count = @typeInfo(Fields).Struct.fields.len; | 22 | pub const bit_count = @typeInfo(Fields).Struct.fields.len; |
| 23 | 23 | ||
| 24 | pub const FieldEnum = blk: { | 24 | pub const FieldEnum = std.meta.FieldEnum(Fields); |
| 25 | comptime var fields: [bit_count]TypeInfo.EnumField = undefined; | ||
| 26 | inline for (@typeInfo(Fields).Struct.fields) |struct_field, i| | ||
| 27 | fields[i] = .{ .name = struct_field.name, .value = i }; | ||
| 28 | break :blk @Type(.{ | ||
| 29 | .Enum = .{ | ||
| 30 | .layout = .Auto, | ||
| 31 | .tag_type = std.math.IntFittingRange(0, bit_count - 1), | ||
| 32 | .fields = &fields, | ||
| 33 | .decls = &[_]TypeInfo.Declaration{}, | ||
| 34 | .is_exhaustive = true, | ||
| 35 | }, | ||
| 36 | }); | ||
| 37 | }; | ||
| 38 | 25 | ||
| 39 | pub const InitStruct = blk: { | 26 | pub const InitStruct = blk: { |
| 40 | comptime var fields: [bit_count]TypeInfo.StructField = undefined; | 27 | comptime var fields: [bit_count]TypeInfo.StructField = undefined; |
| ... | @@ -135,10 +122,7 @@ pub fn TrailerFlags(comptime Fields: type) type { | ... | @@ -135,10 +122,7 @@ pub fn TrailerFlags(comptime Fields: type) type { |
| 135 | } | 122 | } |
| 136 | 123 | ||
| 137 | pub fn Field(comptime field: FieldEnum) type { | 124 | pub fn Field(comptime field: FieldEnum) type { |
| 138 | inline for (@typeInfo(Fields).Struct.fields) |field_info, i| { | 125 | return @typeInfo(Fields).Struct.fields[@enumToInt(field)].field_type; |
| 139 | if (i == @enumToInt(field)) | ||
| 140 | return field_info.field_type; | ||
| 141 | } | ||
| 142 | } | 126 | } |
| 143 | 127 | ||
| 144 | pub fn sizeInBytes(self: Self) usize { | 128 | pub fn sizeInBytes(self: Self) usize { |
lib/std/zig/ast.zig+1-1| ... | @@ -688,7 +688,7 @@ pub const Node = struct { | ... | @@ -688,7 +688,7 @@ pub const Node = struct { |
| 688 | 688 | ||
| 689 | /// Prefer `castTag` to this. | 689 | /// Prefer `castTag` to this. |
| 690 | pub fn cast(base: *Node, comptime T: type) ?*T { | 690 | pub fn cast(base: *Node, comptime T: type) ?*T { |
| 691 | if (std.meta.fieldInfo(T, "base").default_value) |default_base| { | 691 | if (std.meta.fieldInfo(T, .base).default_value) |default_base| { |
| 692 | return base.castTag(default_base.tag); | 692 | return base.castTag(default_base.tag); |
| 693 | } | 693 | } |
| 694 | inline for (@typeInfo(Tag).Enum.fields) |field| { | 694 | inline for (@typeInfo(Tag).Enum.fields) |field| { |
src/astgen.zig+7-7| ... | @@ -758,7 +758,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, | ... | @@ -758,7 +758,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, |
| 758 | }, child_type); | 758 | }, child_type); |
| 759 | } | 759 | } |
| 760 | 760 | ||
| 761 | var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, "kw_args").field_type = .{}; | 761 | var kw_args: std.meta.fieldInfo(zir.Inst.PtrType, .kw_args).field_type = .{}; |
| 762 | kw_args.size = size; | 762 | kw_args.size = size; |
| 763 | kw_args.@"allowzero" = ptr_info.allowzero_token != null; | 763 | kw_args.@"allowzero" = ptr_info.allowzero_token != null; |
| 764 | if (ptr_info.align_info) |some| { | 764 | if (ptr_info.align_info) |some| { |
| ... | @@ -2756,8 +2756,8 @@ pub fn addZIRInstSpecial( | ... | @@ -2756,8 +2756,8 @@ pub fn addZIRInstSpecial( |
| 2756 | scope: *Scope, | 2756 | scope: *Scope, |
| 2757 | src: usize, | 2757 | src: usize, |
| 2758 | comptime T: type, | 2758 | comptime T: type, |
| 2759 | positionals: std.meta.fieldInfo(T, "positionals").field_type, | 2759 | positionals: std.meta.fieldInfo(T, .positionals).field_type, |
| 2760 | kw_args: std.meta.fieldInfo(T, "kw_args").field_type, | 2760 | kw_args: std.meta.fieldInfo(T, .kw_args).field_type, |
| 2761 | ) !*T { | 2761 | ) !*T { |
| 2762 | const gen_zir = scope.getGenZIR(); | 2762 | const gen_zir = scope.getGenZIR(); |
| 2763 | try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1); | 2763 | try gen_zir.instructions.ensureCapacity(mod.gpa, gen_zir.instructions.items.len + 1); |
| ... | @@ -2874,8 +2874,8 @@ pub fn addZIRInst( | ... | @@ -2874,8 +2874,8 @@ pub fn addZIRInst( |
| 2874 | scope: *Scope, | 2874 | scope: *Scope, |
| 2875 | src: usize, | 2875 | src: usize, |
| 2876 | comptime T: type, | 2876 | comptime T: type, |
| 2877 | positionals: std.meta.fieldInfo(T, "positionals").field_type, | 2877 | positionals: std.meta.fieldInfo(T, .positionals).field_type, |
| 2878 | kw_args: std.meta.fieldInfo(T, "kw_args").field_type, | 2878 | kw_args: std.meta.fieldInfo(T, .kw_args).field_type, |
| 2879 | ) !*zir.Inst { | 2879 | ) !*zir.Inst { |
| 2880 | const inst_special = try addZIRInstSpecial(mod, scope, src, T, positionals, kw_args); | 2880 | const inst_special = try addZIRInstSpecial(mod, scope, src, T, positionals, kw_args); |
| 2881 | return &inst_special.base; | 2881 | return &inst_special.base; |
| ... | @@ -2883,12 +2883,12 @@ pub fn addZIRInst( | ... | @@ -2883,12 +2883,12 @@ pub fn addZIRInst( |
| 2883 | 2883 | ||
| 2884 | /// TODO The existence of this function is a workaround for a bug in stage1. | 2884 | /// TODO The existence of this function is a workaround for a bug in stage1. |
| 2885 | pub fn addZIRInstConst(mod: *Module, scope: *Scope, src: usize, typed_value: TypedValue) !*zir.Inst { | 2885 | pub fn addZIRInstConst(mod: *Module, scope: *Scope, src: usize, typed_value: TypedValue) !*zir.Inst { |
| 2886 | const P = std.meta.fieldInfo(zir.Inst.Const, "positionals").field_type; | 2886 | const P = std.meta.fieldInfo(zir.Inst.Const, .positionals).field_type; |
| 2887 | return addZIRInst(mod, scope, src, zir.Inst.Const, P{ .typed_value = typed_value }, .{}); | 2887 | return addZIRInst(mod, scope, src, zir.Inst.Const, P{ .typed_value = typed_value }, .{}); |
| 2888 | } | 2888 | } |
| 2889 | 2889 | ||
| 2890 | /// TODO The existence of this function is a workaround for a bug in stage1. | 2890 | /// TODO The existence of this function is a workaround for a bug in stage1. |
| 2891 | pub fn addZIRInstLoop(mod: *Module, scope: *Scope, src: usize, body: zir.Module.Body) !*zir.Inst.Loop { | 2891 | pub fn addZIRInstLoop(mod: *Module, scope: *Scope, src: usize, body: zir.Module.Body) !*zir.Inst.Loop { |
| 2892 | const P = std.meta.fieldInfo(zir.Inst.Loop, "positionals").field_type; | 2892 | const P = std.meta.fieldInfo(zir.Inst.Loop, .positionals).field_type; |
| 2893 | return addZIRInstSpecial(mod, scope, src, zir.Inst.Loop, P{ .body = body }, .{}); | 2893 | return addZIRInstSpecial(mod, scope, src, zir.Inst.Loop, P{ .body = body }, .{}); |
| 2894 | } | 2894 | } |
src/ir.zig+1-1| ... | @@ -189,7 +189,7 @@ pub const Inst = struct { | ... | @@ -189,7 +189,7 @@ pub const Inst = struct { |
| 189 | } | 189 | } |
| 190 | 190 | ||
| 191 | pub fn Args(comptime T: type) type { | 191 | pub fn Args(comptime T: type) type { |
| 192 | return std.meta.fieldInfo(T, "args").field_type; | 192 | return std.meta.fieldInfo(T, .args).field_type; |
| 193 | } | 193 | } |
| 194 | 194 | ||
| 195 | /// Returns `null` if runtime-known. | 195 | /// Returns `null` if runtime-known. |
src/type.zig+1-1| ... | @@ -3232,7 +3232,7 @@ pub const Type = extern union { | ... | @@ -3232,7 +3232,7 @@ pub const Type = extern union { |
| 3232 | } | 3232 | } |
| 3233 | 3233 | ||
| 3234 | pub fn Data(comptime t: Tag) type { | 3234 | pub fn Data(comptime t: Tag) type { |
| 3235 | return std.meta.fieldInfo(t.Type(), "data").field_type; | 3235 | return std.meta.fieldInfo(t.Type(), .data).field_type; |
| 3236 | } | 3236 | } |
| 3237 | }; | 3237 | }; |
| 3238 | 3238 |
src/value.zig+1-1| ... | @@ -207,7 +207,7 @@ pub const Value = extern union { | ... | @@ -207,7 +207,7 @@ pub const Value = extern union { |
| 207 | } | 207 | } |
| 208 | 208 | ||
| 209 | pub fn Data(comptime t: Tag) type { | 209 | pub fn Data(comptime t: Tag) type { |
| 210 | return std.meta.fieldInfo(t.Type(), "data").field_type; | 210 | return std.meta.fieldInfo(t.Type(), .data).field_type; |
| 211 | } | 211 | } |
| 212 | }; | 212 | }; |
| 213 | 213 |