From 3d4eeafb47f97e5057d36fe2c3ed061cf0c70a63 Mon Sep 17 00:00:00 2001 From: Martin Wickham Date: Mon, 25 Jan 2021 17:18:37 -0600 Subject: Fill out more cases for std.meta.sizeof --- lib/std/meta.zig | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 87 insertions(+), 4 deletions(-) (limited to 'lib/std/meta.zig') diff --git a/lib/std/meta.zig b/lib/std/meta.zig index 2c94569bf1..b6107e6fa5 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -979,9 +979,59 @@ test "std.meta.cast" { /// Given a value returns its size as C's sizeof operator would. /// This is for translate-c and is not intended for general use. pub fn sizeof(target: anytype) usize { - switch (@typeInfo(@TypeOf(target))) { - .Type => return @sizeOf(target), - .Float, .Int, .Struct, .Union, .Enum => return @sizeOf(@TypeOf(target)), + const T: type = if (@TypeOf(target) == type) target else @TypeOf(target); + switch (@typeInfo(T)) { + .Float, .Int, .Struct, .Union, .Enum, .Array, .Bool, .Vector => return @sizeOf(T), + .Fn => { + // sizeof(main) returns 1, sizeof(&main) returns pointer size. + // We cannot distinguish those types in Zig, so use pointer size. + return @sizeOf(T); + }, + .Null => return @sizeOf(*c_void), + .Void => { + // Note: sizeof(void) is 1 on clang/gcc and 0 on MSVC. + return 1; + }, + .Opaque => { + if (T == c_void) { + // Note: sizeof(void) is 1 on clang/gcc and 0 on MSVC. + return 1; + } else { + @compileError("Cannot use C sizeof on opaque type "++@typeName(T)); + } + }, + .Optional => |opt| { + if (@typeInfo(opt.child) == .Pointer) { + return sizeof(opt.child); + } else { + @compileError("Cannot use C sizeof on non-pointer optional "++@typeName(T)); + } + }, + .Pointer => |ptr| { + if (ptr.size == .Slice) { + @compileError("Cannot use C sizeof on slice type "++@typeName(T)); + } + // for strings, sizeof("a") returns 2. + // normal pointer decay scenarios from C are handled + // in the .Array case above, but strings remain literals + // and are therefore always pointers, so they need to be + // specially handled here. + if (ptr.size == .One and ptr.is_const and @typeInfo(ptr.child) == .Array) { + const array_info = @typeInfo(ptr.child).Array; + if ((array_info.child == u8 or array_info.child == u16) and + array_info.sentinel != null and + array_info.sentinel.? == 0) { + // length of the string plus one for the null terminator. + return (array_info.len + 1) * @sizeOf(array_info.child); + } + } + // When zero sized pointers are removed, this case will no + // longer be reachable and can be deleted. + if (@sizeOf(T) == 0) { + return @sizeOf(*c_void); + } + return @sizeOf(T); + }, .ComptimeFloat => return @sizeOf(f64), // TODO c_double #3999 .ComptimeInt => { // TODO to get the correct result we have to translate @@ -991,7 +1041,7 @@ pub fn sizeof(target: anytype) usize { // TODO test if target fits in int, long or long long return @sizeOf(c_int); }, - else => @compileError("TODO implement std.meta.sizeof for type " ++ @typeName(@TypeOf(target))), + else => @compileError("std.meta.sizeof does not support type " ++ @typeName(T)), } } @@ -999,12 +1049,45 @@ test "sizeof" { const E = extern enum(c_int) { One, _ }; const S = extern struct { a: u32 }; + const ptr_size = @sizeOf(*c_void); + testing.expect(sizeof(u32) == 4); testing.expect(sizeof(@as(u32, 2)) == 4); testing.expect(sizeof(2) == @sizeOf(c_int)); + + testing.expect(sizeof(2.0) == @sizeOf(f64)); + testing.expect(sizeof(E) == @sizeOf(c_int)); testing.expect(sizeof(E.One) == @sizeOf(c_int)); + testing.expect(sizeof(S) == 4); + + testing.expect(sizeof([_]u32{4, 5, 6}) == 12); + testing.expect(sizeof([3]u32) == 12); + testing.expect(sizeof([3:0]u32) == 16); + testing.expect(sizeof(&[_]u32{4, 5, 6}) == ptr_size); + + testing.expect(sizeof(*u32) == ptr_size); + testing.expect(sizeof([*]u32) == ptr_size); + testing.expect(sizeof([*c]u32) == ptr_size); + testing.expect(sizeof(?*u32) == ptr_size); + testing.expect(sizeof(?[*]u32) == ptr_size); + testing.expect(sizeof(*c_void) == ptr_size); + testing.expect(sizeof(*void) == ptr_size); + testing.expect(sizeof(null) == ptr_size); + + testing.expect(sizeof("foobar") == 7); + testing.expect(sizeof(&[_:0]u16{'f','o','o','b','a','r'}) == 14); + testing.expect(sizeof(*const [4:0]u8) == 5); + testing.expect(sizeof(*[4:0]u8) == ptr_size); + testing.expect(sizeof([*]const [4:0]u8) == ptr_size); + testing.expect(sizeof(*const *const [4:0]u8) == ptr_size); + testing.expect(sizeof(*const [4]u8) == ptr_size); + + testing.expect(sizeof(sizeof) == @sizeOf(@TypeOf(sizeof))); + + testing.expect(sizeof(void) == 1); + testing.expect(sizeof(c_void) == 1); } /// For a given function type, returns a tuple type which fields will -- cgit v1.2.3 From 68ec54f386d387c5dd3f9dc4f0b5e14be6ae10a6 Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Mon, 11 Jan 2021 10:56:18 -0700 Subject: std.meta: rename TagType to Tag --- lib/std/json.zig | 2 +- lib/std/meta.zig | 23 +++++++++++++---------- 2 files changed, 14 insertions(+), 11 deletions(-) (limited to 'lib/std/meta.zig') diff --git a/lib/std/json.zig b/lib/std/json.zig index 077b910a2c..2ac7cdf8d5 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -1138,7 +1138,7 @@ pub const TokenStream = struct { } }; -fn checkNext(p: *TokenStream, id: std.meta.TagType(Token)) void { +fn checkNext(p: *TokenStream, id: std.meta.Tag(Token)) void { const token = (p.next() catch unreachable).?; debug.assert(std.meta.activeTag(token) == id); } diff --git a/lib/std/meta.zig b/lib/std/meta.zig index b6107e6fa5..027b9508e2 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -600,15 +600,18 @@ test "std.meta.FieldEnum" { expectEqualEnum(enum { a, b, c }, FieldEnum(union { a: u8, b: void, c: f32 })); } -pub fn TagType(comptime T: type) type { +// Deprecated: use Tag +pub const TagType = Tag; + +pub fn Tag(comptime T: type) type { return switch (@typeInfo(T)) { .Enum => |info| info.tag_type, - .Union => |info| if (info.tag_type) |Tag| Tag else null, + .Union => |info| if (info.tag_type) |TheTag| TheTag else null, else => @compileError("expected enum or union type, found '" ++ @typeName(T) ++ "'"), }; } -test "std.meta.TagType" { +test "std.meta.Tag" { const E = enum(u8) { C = 33, D, @@ -618,8 +621,8 @@ test "std.meta.TagType" { D: u16, }; - testing.expect(TagType(E) == u8); - testing.expect(TagType(U) == E); + testing.expect(Tag(E) == u8); + testing.expect(Tag(U) == E); } ///Returns the active tag of a tagged union @@ -694,13 +697,13 @@ pub fn eql(a: anytype, b: @TypeOf(a)) bool { } }, .Union => |info| { - if (info.tag_type) |Tag| { + if (info.tag_type) |UnionTag| { const tag_a = activeTag(a); const tag_b = activeTag(b); if (tag_a != tag_b) return false; inline for (info.fields) |field_info| { - if (@field(Tag, field_info.name) == tag_a) { + if (@field(UnionTag, field_info.name) == tag_a) { return eql(@field(a, field_info.name), @field(b, field_info.name)); } } @@ -822,9 +825,9 @@ test "intToEnum with error return" { pub const IntToEnumError = error{InvalidEnumTag}; -pub fn intToEnum(comptime Tag: type, tag_int: anytype) IntToEnumError!Tag { - inline for (@typeInfo(Tag).Enum.fields) |f| { - const this_tag_value = @field(Tag, f.name); +pub fn intToEnum(comptime EnumTag: type, tag_int: anytype) IntToEnumError!EnumTag { + inline for (@typeInfo(EnumTag).Enum.fields) |f| { + const this_tag_value = @field(EnumTag, f.name); if (tag_int == @enumToInt(this_tag_value)) { return this_tag_value; } -- cgit v1.2.3 From b7767eb834084adc9db94b9ed961aaa2756fc018 Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Mon, 11 Jan 2021 10:58:33 -0700 Subject: std.meta: rename TagPayloadType to TagPayload --- lib/std/json.zig | 4 ++-- lib/std/meta.zig | 8 +++++--- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'lib/std/meta.zig') diff --git a/lib/std/json.zig b/lib/std/json.zig index 2ac7cdf8d5..a97044a4d8 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -2077,7 +2077,7 @@ pub const Parser = struct { } } - fn parseString(p: *Parser, allocator: *Allocator, s: std.meta.TagPayloadType(Token, Token.String), input: []const u8, i: usize) !Value { + fn parseString(p: *Parser, allocator: *Allocator, s: std.meta.TagPayload(Token, Token.String), input: []const u8, i: usize) !Value { const slice = s.slice(input, i); switch (s.escapes) { .None => return Value{ .String = if (p.copy_strings) try allocator.dupe(u8, slice) else slice }, @@ -2090,7 +2090,7 @@ pub const Parser = struct { } } - fn parseNumber(p: *Parser, n: std.meta.TagPayloadType(Token, Token.Number), input: []const u8, i: usize) !Value { + fn parseNumber(p: *Parser, n: std.meta.TagPayload(Token, Token.Number), input: []const u8, i: usize) !Value { return if (n.is_integer) Value{ .Integer = try std.fmt.parseInt(i64, n.slice(input, i), 10) } else diff --git a/lib/std/meta.zig b/lib/std/meta.zig index 027b9508e2..9a1215e79b 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -649,9 +649,11 @@ test "std.meta.activeTag" { testing.expect(activeTag(u) == UE.Float); } +const TagPayloadType = TagPayload; + ///Given a tagged union type, and an enum, return the type of the union /// field corresponding to the enum tag. -pub fn TagPayloadType(comptime U: type, tag: @TagType(U)) type { +pub fn TagPayload(comptime U: type, tag: @TagType(U)) type { testing.expect(trait.is(.Union)(U)); const info = @typeInfo(U).Union; @@ -665,14 +667,14 @@ pub fn TagPayloadType(comptime U: type, tag: @TagType(U)) type { unreachable; } -test "std.meta.TagPayloadType" { +test "std.meta.TagPayload" { const Event = union(enum) { Moved: struct { from: i32, to: i32, }, }; - const MovedEvent = TagPayloadType(Event, Event.Moved); + const MovedEvent = TagPayload(Event, Event.Moved); var e: Event = undefined; testing.expect(MovedEvent == @TypeOf(e.Moved)); } -- cgit v1.2.3 From 0b5f3c2ef96df02341cdf54f6eefb3cdb88781d8 Mon Sep 17 00:00:00 2001 From: Tadeo Kondrak Date: Mon, 11 Jan 2021 11:19:24 -0700 Subject: Replace @TagType uses, mostly with std.meta.Tag --- doc/langref.html.in | 6 ++--- lib/std/builtin.zig | 2 +- lib/std/c/ast.zig | 2 +- lib/std/c/parse.zig | 6 ++--- lib/std/c/tokenizer.zig | 4 ++-- lib/std/hash/auto_hash.zig | 2 +- lib/std/json.zig | 4 ++-- lib/std/meta.zig | 10 ++++----- lib/std/meta/trailer_flags.zig | 2 +- lib/std/testing.zig | 6 ++--- lib/std/zig/parser_test.zig | 2 +- src/DepTokenizer.zig | 4 ++-- src/link/MachO/commands.zig | 2 +- src/stage1/analyze.cpp | 2 +- src/test.zig | 4 ++-- src/translate_c.zig | 2 +- src/type.zig | 2 +- src/value.zig | 2 +- test/compile_errors.zig | 20 ++++------------- test/runtime_safety.zig | 2 +- test/stage1/behavior/bugs/1322.zig | 4 ++-- test/stage1/behavior/enum.zig | 15 +++++++------ test/stage1/behavior/type_info.zig | 2 +- test/stage1/behavior/union.zig | 45 +++++++++++++++++++------------------- test/tests.zig | 2 +- tools/process_headers.zig | 2 +- 26 files changed, 73 insertions(+), 83 deletions(-) (limited to 'lib/std/meta.zig') diff --git a/doc/langref.html.in b/doc/langref.html.in index 3af4d7d2b1..f75fc351d9 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -2909,15 +2909,15 @@ test "enum variant switch" { expect(mem.eql(u8, what_is_it, "this is a number")); } -// @TagType can be used to access the integer tag type of an enum. +// @typeInfo can be used to access the integer tag type of an enum. const Small = enum { one, two, three, four, }; -test "@TagType" { - expect(@TagType(Small) == u2); +test "std.meta.Tag" { + expect(@typeInfo(Small).Enum.tag_type == u2); } // @typeInfo tells us the field count and the fields names: diff --git a/lib/std/builtin.zig b/lib/std/builtin.zig index c883e03ba9..7163cc5357 100644 --- a/lib/std/builtin.zig +++ b/lib/std/builtin.zig @@ -175,7 +175,7 @@ pub const SourceLocation = struct { column: u32, }; -pub const TypeId = @TagType(TypeInfo); +pub const TypeId = std.meta.Tag(TypeInfo); /// This data structure is used by the Zig language code generation and /// therefore must be kept in sync with the compiler implementation. diff --git a/lib/std/c/ast.zig b/lib/std/c/ast.zig index 207fe8eac8..71455c0ea3 100644 --- a/lib/std/c/ast.zig +++ b/lib/std/c/ast.zig @@ -110,7 +110,7 @@ pub const Error = union(enum) { pub const ExpectedToken = struct { token: TokenIndex, - expected_id: @TagType(Token.Id), + expected_id: std.meta.Tag(Token.Id), pub fn render(self: *const ExpectedToken, tree: *Tree, stream: anytype) !void { const found_token = tree.tokens.at(self.token); diff --git a/lib/std/c/parse.zig b/lib/std/c/parse.zig index 17c07611ab..3d17938d7a 100644 --- a/lib/std/c/parse.zig +++ b/lib/std/c/parse.zig @@ -26,7 +26,7 @@ pub const Options = struct { None, /// Some warnings are errors - Some: []@TagType(ast.Error), + Some: []std.meta.Tag(ast.Error), /// All warnings are errors All, @@ -1363,7 +1363,7 @@ const Parser = struct { return &node.base; } - fn eatToken(parser: *Parser, id: @TagType(Token.Id)) ?TokenIndex { + fn eatToken(parser: *Parser, id: std.meta.Tag(Token.Id)) ?TokenIndex { while (true) { switch ((parser.it.next() orelse return null).id) { .LineComment, .MultiLineComment, .Nl => continue, @@ -1377,7 +1377,7 @@ const Parser = struct { } } - fn expectToken(parser: *Parser, id: @TagType(Token.Id)) Error!TokenIndex { + fn expectToken(parser: *Parser, id: std.meta.Tag(Token.Id)) Error!TokenIndex { while (true) { switch ((parser.it.next() orelse return error.ParseError).id) { .LineComment, .MultiLineComment, .Nl => continue, diff --git a/lib/std/c/tokenizer.zig b/lib/std/c/tokenizer.zig index ea5774fe4c..2e1969e269 100644 --- a/lib/std/c/tokenizer.zig +++ b/lib/std/c/tokenizer.zig @@ -131,7 +131,7 @@ pub const Token = struct { Keyword_error, Keyword_pragma, - pub fn symbol(id: @TagType(Id)) []const u8 { + pub fn symbol(id: std.meta.TagType(Id)) []const u8 { return switch (id) { .Invalid => "Invalid", .Eof => "Eof", @@ -347,7 +347,7 @@ pub const Token = struct { pub const Tokenizer = struct { buffer: []const u8, index: usize = 0, - prev_tok_id: @TagType(Token.Id) = .Invalid, + prev_tok_id: std.meta.TagType(Token.Id) = .Invalid, pp_directive: bool = false, pub fn next(self: *Tokenizer) Token { diff --git a/lib/std/hash/auto_hash.zig b/lib/std/hash/auto_hash.zig index 8b5852c4af..4afc2b425b 100644 --- a/lib/std/hash/auto_hash.zig +++ b/lib/std/hash/auto_hash.zig @@ -239,7 +239,7 @@ fn testHashDeepRecursive(key: anytype) u64 { test "typeContainsSlice" { comptime { - testing.expect(!typeContainsSlice(@TagType(std.builtin.TypeInfo))); + testing.expect(!typeContainsSlice(meta.Tag(std.builtin.TypeInfo))); testing.expect(typeContainsSlice([]const u8)); testing.expect(!typeContainsSlice(u8)); diff --git a/lib/std/json.zig b/lib/std/json.zig index a97044a4d8..dc23155a5e 100644 --- a/lib/std/json.zig +++ b/lib/std/json.zig @@ -246,7 +246,7 @@ pub const StreamingParser = struct { // Only call this function to generate array/object final state. pub fn fromInt(x: anytype) State { debug.assert(x == 0 or x == 1); - const T = @TagType(State); + const T = std.meta.Tag(State); return @intToEnum(State, @intCast(T, x)); } }; @@ -1782,7 +1782,7 @@ test "parseFree descends into tagged union" { }; // use a string with unicode escape so we know result can't be a reference to global constant const r = try parse(T, &TokenStream.init("\"with\\u0105unicode\""), options); - testing.expectEqual(@TagType(T).string, @as(@TagType(T), r)); + testing.expectEqual(std.meta.Tag(T).string, @as(std.meta.Tag(T), r)); testing.expectEqualSlices(u8, "withÄ…unicode", r.string); testing.expectEqual(@as(usize, 0), fail_alloc.deallocations); parseFree(T, r, options); diff --git a/lib/std/meta.zig b/lib/std/meta.zig index 9a1215e79b..30f69ae9a5 100644 --- a/lib/std/meta.zig +++ b/lib/std/meta.zig @@ -606,7 +606,7 @@ pub const TagType = Tag; pub fn Tag(comptime T: type) type { return switch (@typeInfo(T)) { .Enum => |info| info.tag_type, - .Union => |info| if (info.tag_type) |TheTag| TheTag else null, + .Union => |info| info.tag_type orelse @compileError(@typeName(T) ++ " has no tag type"), else => @compileError("expected enum or union type, found '" ++ @typeName(T) ++ "'"), }; } @@ -626,9 +626,9 @@ test "std.meta.Tag" { } ///Returns the active tag of a tagged union -pub fn activeTag(u: anytype) @TagType(@TypeOf(u)) { +pub fn activeTag(u: anytype) Tag(@TypeOf(u)) { const T = @TypeOf(u); - return @as(@TagType(T), u); + return @as(Tag(T), u); } test "std.meta.activeTag" { @@ -653,11 +653,11 @@ const TagPayloadType = TagPayload; ///Given a tagged union type, and an enum, return the type of the union /// field corresponding to the enum tag. -pub fn TagPayload(comptime U: type, tag: @TagType(U)) type { +pub fn TagPayload(comptime U: type, tag: Tag(U)) type { testing.expect(trait.is(.Union)(U)); const info = @typeInfo(U).Union; - const tag_info = @typeInfo(@TagType(U)).Enum; + const tag_info = @typeInfo(Tag(U)).Enum; inline for (info.fields) |field_info| { if (comptime mem.eql(u8, field_info.name, @tagName(tag))) diff --git a/lib/std/meta/trailer_flags.zig b/lib/std/meta/trailer_flags.zig index a5882d9e1b..1697e9fe43 100644 --- a/lib/std/meta/trailer_flags.zig +++ b/lib/std/meta/trailer_flags.zig @@ -146,7 +146,7 @@ test "TrailerFlags" { b: bool, c: u64, }); - testing.expectEqual(u2, @TagType(Flags.FieldEnum)); + testing.expectEqual(u2, meta.Tag(Flags.FieldEnum)); var flags = Flags.init(.{ .b = true, diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 26938367e9..8df05ba7fe 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -119,10 +119,10 @@ pub fn expectEqual(expected: anytype, actual: @TypeOf(expected)) void { @compileError("Unable to compare untagged union values"); } - const TagType = @TagType(@TypeOf(expected)); + const Tag = std.meta.Tag(@TypeOf(expected)); - const expectedTag = @as(TagType, expected); - const actualTag = @as(TagType, actual); + const expectedTag = @as(Tag, expected); + const actualTag = @as(Tag, actual); expectEqual(expectedTag, actualTag); diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index d7cc1208a2..2f0b7ff082 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -3822,7 +3822,7 @@ fn testCanonical(source: []const u8) !void { return testTransform(source, source); } -const Error = @TagType(std.zig.ast.Error); +const Error = std.meta.Tag(std.zig.ast.Error); fn testError(source: []const u8, expected_errors: []const Error) !void { const tree = try std.zig.parse(std.testing.allocator, source); diff --git a/src/DepTokenizer.zig b/src/DepTokenizer.zig index b246a22bd0..0bd2999719 100644 --- a/src/DepTokenizer.zig +++ b/src/DepTokenizer.zig @@ -266,11 +266,11 @@ pub fn next(self: *Tokenizer) ?Token { unreachable; } -fn errorPosition(comptime id: @TagType(Token), index: usize, bytes: []const u8) Token { +fn errorPosition(comptime id: std.meta.Tag(Token), index: usize, bytes: []const u8) Token { return @unionInit(Token, @tagName(id), .{ .index = index, .bytes = bytes }); } -fn errorIllegalChar(comptime id: @TagType(Token), index: usize, char: u8) Token { +fn errorIllegalChar(comptime id: std.meta.Tag(Token), index: usize, char: u8) Token { return @unionInit(Token, @tagName(id), .{ .index = index, .char = char }); } diff --git a/src/link/MachO/commands.zig b/src/link/MachO/commands.zig index baea36b4e6..67b808d856 100644 --- a/src/link/MachO/commands.zig +++ b/src/link/MachO/commands.zig @@ -140,7 +140,7 @@ pub const LoadCommand = union(enum) { } fn eql(self: LoadCommand, other: LoadCommand) bool { - if (@as(@TagType(LoadCommand), self) != @as(@TagType(LoadCommand), other)) return false; + if (@as(meta.Tag(LoadCommand), self) != @as(meta.Tag(LoadCommand), other)) return false; return switch (self) { .DyldInfoOnly => |x| meta.eql(x, other.DyldInfoOnly), .Symtab => |x| meta.eql(x, other.Symtab), diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp index 6bc97d323a..c701abce8a 100644 --- a/src/stage1/analyze.cpp +++ b/src/stage1/analyze.cpp @@ -3267,7 +3267,7 @@ static Error resolve_union_zero_bits(CodeGen *g, ZigType *union_type) { tag_type = new_type_table_entry(ZigTypeIdEnum); buf_resize(&tag_type->name, 0); - buf_appendf(&tag_type->name, "@typeInfo(%s).Enum.tag_type", buf_ptr(&union_type->name)); + buf_appendf(&tag_type->name, "@typeInfo(%s).Union.tag_type.?", buf_ptr(&union_type->name)); tag_type->llvm_type = tag_int_type->llvm_type; tag_type->llvm_di_type = tag_int_type->llvm_di_type; tag_type->abi_size = tag_int_type->abi_size; diff --git a/src/test.zig b/src/test.zig index 150b6496c1..07eb001e14 100644 --- a/src/test.zig +++ b/src/test.zig @@ -750,7 +750,7 @@ pub const TestContext = struct { for (actual_errors.list) |actual_error| { for (case_error_list) |case_msg, i| { - const ex_tag: @TagType(@TypeOf(case_msg)) = case_msg; + const ex_tag: std.meta.Tag(@TypeOf(case_msg)) = case_msg; switch (actual_error) { .src => |actual_msg| { for (actual_msg.notes) |*note| { @@ -789,7 +789,7 @@ pub const TestContext = struct { } while (notes_to_check.popOrNull()) |note| { for (case_error_list) |case_msg, i| { - const ex_tag: @TagType(@TypeOf(case_msg)) = case_msg; + const ex_tag: std.meta.Tag(@TypeOf(case_msg)) = case_msg; switch (note.*) { .src => |actual_msg| { for (actual_msg.notes) |*sub_note| { diff --git a/src/translate_c.zig b/src/translate_c.zig index 8efac4922f..11dbacefa2 100644 --- a/src/translate_c.zig +++ b/src/translate_c.zig @@ -3288,7 +3288,7 @@ const ClangFunctionType = union(enum) { NoProto: *const clang.FunctionType, fn getReturnType(self: @This()) clang.QualType { - switch (@as(@TagType(@This()), self)) { + switch (@as(std.meta.Tag(@This()), self)) { .Proto => return self.Proto.getReturnType(), .NoProto => return self.NoProto.getReturnType(), } diff --git a/src/type.zig b/src/type.zig index be61f57c1d..1636407a87 100644 --- a/src/type.zig +++ b/src/type.zig @@ -110,7 +110,7 @@ pub const Type = extern union { pub fn tag(self: Type) Tag { if (self.tag_if_small_enough < Tag.no_payload_count) { - return @intToEnum(Tag, @intCast(@TagType(Tag), self.tag_if_small_enough)); + return @intToEnum(Tag, @intCast(std.meta.Tag(Tag), self.tag_if_small_enough)); } else { return self.ptr_otherwise.tag; } diff --git a/src/value.zig b/src/value.zig index 5b0563ca98..50298da682 100644 --- a/src/value.zig +++ b/src/value.zig @@ -223,7 +223,7 @@ pub const Value = extern union { pub fn tag(self: Value) Tag { if (self.tag_if_small_enough < Tag.no_payload_count) { - return @intToEnum(Tag, @intCast(@TagType(Tag), self.tag_if_small_enough)); + return @intToEnum(Tag, @intCast(std.meta.Tag(Tag), self.tag_if_small_enough)); } else { return self.ptr_otherwise.tag; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index ef87acf538..3b4eb61195 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -323,7 +323,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ e: E, \\}; \\export fn entry() void { - \\ if (@TagType(E) != u8) @compileError("did not infer u8 tag type"); + \\ if (@typeInfo(E).Enum.tag_type != u8) @compileError("did not infer u8 tag type"); \\ const s: S = undefined; \\} , &[_][]const u8{ @@ -2728,7 +2728,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\const InvalidToken = struct {}; \\const ExpectedVarDeclOrFn = struct {}; , &[_][]const u8{ - "tmp.zig:4:9: error: expected type '@TagType(Error)', found 'type'", + "tmp.zig:4:9: error: expected type '@typeInfo(Error).Union.tag_type.?', found 'type'", }); cases.addTest("binary OR operator on error sets", @@ -7462,24 +7462,12 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:4:5: note: declared here", }); - cases.add("@TagType when union has no attached enum", - \\const Foo = union { - \\ A: i32, - \\}; - \\export fn entry() void { - \\ const x = @TagType(Foo); - \\} - , &[_][]const u8{ - "tmp.zig:5:24: error: union 'Foo' has no tag", - "tmp.zig:1:13: note: consider 'union(enum)' here", - }); - cases.add("non-integer tag type to automatic union enum", \\const Foo = union(enum(f32)) { \\ A: i32, \\}; \\export fn entry() void { - \\ const x = @TagType(Foo); + \\ const x = @typeInfo(Foo).Union.tag_type.?; \\} , &[_][]const u8{ "tmp.zig:1:24: error: expected integer tag type, found 'f32'", @@ -7490,7 +7478,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { \\ A: i32, \\}; \\export fn entry() void { - \\ const x = @TagType(Foo); + \\ const x = @typeInfo(Foo).Union.tag_type.?; \\} , &[_][]const u8{ "tmp.zig:1:19: error: expected enum tag type, found 'u32'", diff --git a/test/runtime_safety.zig b/test/runtime_safety.zig index 2ab728b580..eb49b2dbc1 100644 --- a/test/runtime_safety.zig +++ b/test/runtime_safety.zig @@ -74,7 +74,7 @@ pub fn addCases(cases: *tests.CompareOutputContext) void { \\pub fn main() void { \\ var u: U = undefined; \\ @memset(@ptrCast([*]u8, &u), 0x55, @sizeOf(U)); - \\ var t: @TagType(U) = u; + \\ var t: @typeInfo(U).Union.tag_type.? = u; \\ var n = @tagName(t); \\} ); diff --git a/test/stage1/behavior/bugs/1322.zig b/test/stage1/behavior/bugs/1322.zig index 3231a985e7..02ead6afff 100644 --- a/test/stage1/behavior/bugs/1322.zig +++ b/test/stage1/behavior/bugs/1322.zig @@ -13,7 +13,7 @@ const C = struct {}; test "tagged union with all void fields but a meaningful tag" { var a: A = A{ .b = B{ .c = C{} } }; - std.testing.expect(@as(@TagType(B), a.b) == @TagType(B).c); + std.testing.expect(@as(std.meta.Tag(B), a.b) == std.meta.Tag(B).c); a = A{ .b = B.None }; - std.testing.expect(@as(@TagType(B), a.b) == @TagType(B).None); + std.testing.expect(@as(std.meta.Tag(B), a.b) == std.meta.Tag(B).None); } diff --git a/test/stage1/behavior/enum.zig b/test/stage1/behavior/enum.zig index 1d424d6e39..ecb95be8f5 100644 --- a/test/stage1/behavior/enum.zig +++ b/test/stage1/behavior/enum.zig @@ -1,5 +1,6 @@ const expect = @import("std").testing.expect; const mem = @import("std").mem; +const Tag = @import("std").meta.Tag; test "extern enum" { const S = struct { @@ -827,12 +828,12 @@ test "set enum tag type" { { var x = Small.One; x = Small.Two; - comptime expect(@TagType(Small) == u2); + comptime expect(Tag(Small) == u2); } { var x = Small2.One; x = Small2.Two; - comptime expect(@TagType(Small2) == u2); + comptime expect(Tag(Small2) == u2); } } @@ -905,11 +906,11 @@ fn getC(data: *const BitFieldOfEnums) C { } test "casting enum to its tag type" { - testCastEnumToTagType(Small2.Two); - comptime testCastEnumToTagType(Small2.Two); + testCastEnumTag(Small2.Two); + comptime testCastEnumTag(Small2.Two); } -fn testCastEnumToTagType(value: Small2) void { +fn testCastEnumTag(value: Small2) void { expect(@enumToInt(value) == 1); } @@ -1163,14 +1164,14 @@ test "enum with comptime_int tag type" { Two = 2, Three = 1, }; - comptime expect(@TagType(Enum) == comptime_int); + comptime expect(Tag(Enum) == comptime_int); } test "enum with one member default to u0 tag type" { const E0 = enum { X, }; - comptime expect(@TagType(E0) == u0); + comptime expect(Tag(E0) == u0); } test "tagName on enum literals" { diff --git a/test/stage1/behavior/type_info.zig b/test/stage1/behavior/type_info.zig index aa5ac89c94..6dec7ca4d2 100644 --- a/test/stage1/behavior/type_info.zig +++ b/test/stage1/behavior/type_info.zig @@ -14,7 +14,7 @@ test "type info: tag type, void info" { } fn testBasic() void { - expect(@TagType(TypeInfo) == TypeId); + expect(@typeInfo(TypeInfo).Union.tag_type == TypeId); const void_info = @typeInfo(void); expect(void_info == TypeId.Void); expect(void_info.Void == {}); diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index 63f36e755a..e46b6bb6b9 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -1,6 +1,7 @@ const std = @import("std"); const expect = std.testing.expect; const expectEqual = std.testing.expectEqual; +const Tag = std.meta.Tag; const Value = union(enum) { Int: u64, @@ -128,7 +129,7 @@ const MultipleChoice = union(enum(u32)) { test "simple union(enum(u32))" { var x = MultipleChoice.C; expect(x == MultipleChoice.C); - expect(@enumToInt(@as(@TagType(MultipleChoice), x)) == 60); + expect(@enumToInt(@as(Tag(MultipleChoice), x)) == 60); } const MultipleChoice2 = union(enum(u32)) { @@ -144,13 +145,13 @@ const MultipleChoice2 = union(enum(u32)) { }; test "union(enum(u32)) with specified and unspecified tag values" { - comptime expect(@TagType(@TagType(MultipleChoice2)) == u32); + comptime expect(Tag(Tag(MultipleChoice2)) == u32); testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 }); comptime testEnumWithSpecifiedAndUnspecifiedTagValues(MultipleChoice2{ .C = 123 }); } fn testEnumWithSpecifiedAndUnspecifiedTagValues(x: MultipleChoice2) void { - expect(@enumToInt(@as(@TagType(MultipleChoice2), x)) == 60); + expect(@enumToInt(@as(Tag(MultipleChoice2), x)) == 60); expect(1123 == switch (x) { MultipleChoice2.A => 1, MultipleChoice2.B => 2, @@ -204,11 +205,11 @@ test "union field access gives the enum values" { } test "cast union to tag type of union" { - testCastUnionToTagType(TheUnion{ .B = 1234 }); - comptime testCastUnionToTagType(TheUnion{ .B = 1234 }); + testCastUnionToTag(TheUnion{ .B = 1234 }); + comptime testCastUnionToTag(TheUnion{ .B = 1234 }); } -fn testCastUnionToTagType(x: TheUnion) void { +fn testCastUnionToTag(x: TheUnion) void { expect(@as(TheTag, x) == TheTag.B); } @@ -298,7 +299,7 @@ const TaggedUnionWithAVoid = union(enum) { fn testTaggedUnionInit(x: anytype) bool { const y = TaggedUnionWithAVoid{ .A = x }; - return @as(@TagType(TaggedUnionWithAVoid), y) == TaggedUnionWithAVoid.A; + return @as(Tag(TaggedUnionWithAVoid), y) == TaggedUnionWithAVoid.A; } pub const UnionEnumNoPayloads = union(enum) { @@ -309,8 +310,8 @@ pub const UnionEnumNoPayloads = union(enum) { test "tagged union with no payloads" { const a = UnionEnumNoPayloads{ .B = {} }; switch (a) { - @TagType(UnionEnumNoPayloads).A => @panic("wrong"), - @TagType(UnionEnumNoPayloads).B => {}, + Tag(UnionEnumNoPayloads).A => @panic("wrong"), + Tag(UnionEnumNoPayloads).B => {}, } } @@ -325,9 +326,9 @@ test "union with only 1 field casted to its enum type" { }; var e = Expr{ .Literal = Literal{ .Bool = true } }; - const Tag = @TagType(Expr); - comptime expect(@TagType(Tag) == u0); - var t = @as(Tag, e); + const ExprTag = Tag(Expr); + comptime expect(Tag(ExprTag) == u0); + var t = @as(ExprTag, e); expect(t == Expr.Literal); } @@ -337,17 +338,17 @@ test "union with only 1 field casted to its enum type which has enum value speci Bool: bool, }; - const Tag = enum(comptime_int) { + const ExprTag = enum(comptime_int) { Literal = 33, }; - const Expr = union(Tag) { + const Expr = union(ExprTag) { Literal: Literal, }; var e = Expr{ .Literal = Literal{ .Bool = true } }; - comptime expect(@TagType(Tag) == comptime_int); - var t = @as(Tag, e); + comptime expect(Tag(ExprTag) == comptime_int); + var t = @as(ExprTag, e); expect(t == Expr.Literal); expect(@enumToInt(t) == 33); comptime expect(@enumToInt(t) == 33); @@ -501,7 +502,7 @@ test "union with one member defaults to u0 tag type" { const U0 = union(enum) { X: u32, }; - comptime expect(@TagType(@TagType(U0)) == u0); + comptime expect(Tag(Tag(U0)) == u0); } test "union with comptime_int tag" { @@ -510,7 +511,7 @@ test "union with comptime_int tag" { Y: u16, Z: u8, }; - comptime expect(@TagType(@TagType(Union)) == comptime_int); + comptime expect(Tag(Tag(Union)) == comptime_int); } test "extern union doesn't trigger field check at comptime" { @@ -591,7 +592,7 @@ test "function call result coerces from tagged union to the tag" { Two: usize, }; - const ArchTag = @TagType(Arch); + const ArchTag = Tag(Arch); fn doTheTest() void { var x: ArchTag = getArch1(); @@ -696,8 +697,8 @@ test "cast from pointer to anonymous struct to pointer to union" { test "method call on an empty union" { const S = struct { - const MyUnion = union(Tag) { - pub const Tag = enum { X1, X2 }; + const MyUnion = union(MyUnionTag) { + pub const MyUnionTag = enum { X1, X2 }; X1: [0]u8, X2: [0]u8, @@ -797,7 +798,7 @@ test "union enum type gets a separate scope" { }; fn doTheTest() void { - expect(!@hasDecl(@TagType(U), "foo")); + expect(!@hasDecl(Tag(U), "foo")); } }; diff --git a/test/tests.zig b/test/tests.zig index ec6d9e1df8..a0a50d29a5 100644 --- a/test/tests.zig +++ b/test/tests.zig @@ -499,7 +499,7 @@ pub fn addPkgTests( if (skip_single_threaded and test_target.single_threaded) continue; - const ArchTag = @TagType(builtin.Arch); + const ArchTag = std.meta.Tag(builtin.Arch); if (test_target.disable_native and test_target.target.getOsTag() == std.Target.current.os.tag and test_target.target.getCpuArch() == std.Target.current.cpu.arch) diff --git a/tools/process_headers.zig b/tools/process_headers.zig index 999b62e715..c5279ba74f 100644 --- a/tools/process_headers.zig +++ b/tools/process_headers.zig @@ -47,7 +47,7 @@ const MultiAbi = union(enum) { fn eql(a: MultiAbi, b: MultiAbi) bool { if (@enumToInt(a) != @enumToInt(b)) return false; - if (@TagType(MultiAbi)(a) != .specific) + if (std.meta.Tag(MultiAbi)(a) != .specific) return true; return a.specific == b.specific; } -- cgit v1.2.3