diff --git a/doc/langref.html.in b/doc/langref.html.in index 85917680d3..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: @@ -3092,8 +3092,7 @@ test "simple union" { {#header_open|Tagged union#}
Unions can be declared with an enum tag type. This turns the union into a tagged union, which makes it eligible - to use with {#link|switch#} expressions. One can use {#link|@TagType#} to - obtain the enum type from the union type. + to use with {#link|switch#} expressions. Tagged unions coerce to their tag type: {#link|Type Coercion: unions and enums#}.
{#code_begin|test#} @@ -3119,8 +3118,8 @@ test "switch on tagged union" { } } -test "@TagType" { - expect(@TagType(ComplexType) == ComplexTypeTag); +test "get tag type" { + expect(std.meta.Tag(ComplexType) == ComplexTypeTag); } test "coerce to enum" { @@ -7740,7 +7739,7 @@ test "@hasDecl" { {#header_close#} {#header_open|@intToEnum#} -{#syntax#}@intToEnum(comptime DestType: type, int_value: @TagType(DestType)) DestType{#endsyntax#}
+ {#syntax#}@intToEnum(comptime DestType: type, int_value: std.meta.Tag(DestType)) DestType{#endsyntax#}
Converts an integer into an {#link|enum#} value.
@@ -8435,16 +8434,6 @@ fn doTheTest() void { {#header_close#} - {#header_open|@TagType#} -{#syntax#}@TagType(T: type) type{#endsyntax#}
- - For an enum, returns the integer type that is used to store the enumeration value. -
-- For a union, returns the enum type that is used to store the tag value. -
- {#header_close#} - {#header_open|@This#}{#syntax#}@This() type{#endsyntax#}
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 077b910a2c..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));
}
};
@@ -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);
}
@@ -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);
@@ -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 b6107e6fa5..30f69ae9a5 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| info.tag_type orelse @compileError(@typeName(T) ++ " has no tag type"),
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,14 +621,14 @@ 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
-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" {
@@ -646,13 +649,15 @@ 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: 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)))
@@ -662,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));
}
@@ -694,13 +699,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 +827,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;
}
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/astgen.zig b/src/astgen.zig
index 8b4f1cc93c..a74b83de44 100644
--- a/src/astgen.zig
+++ b/src/astgen.zig
@@ -3077,7 +3077,6 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool {
.{ "@round", false },
.{ "@subWithOverflow", false },
.{ "@tagName", false },
- .{ "@TagType", false },
.{ "@This", false },
.{ "@truncate", false },
.{ "@Type", false },
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/all_types.hpp b/src/stage1/all_types.hpp
index 196010ebca..d2741320d7 100644
--- a/src/stage1/all_types.hpp
+++ b/src/stage1/all_types.hpp
@@ -1811,7 +1811,6 @@ enum BuiltinFnId {
BuiltinFnIdIntToPtr,
BuiltinFnIdPtrToInt,
BuiltinFnIdTagName,
- BuiltinFnIdTagType,
BuiltinFnIdFieldParentPtr,
BuiltinFnIdByteOffsetOf,
BuiltinFnIdBitOffsetOf,
@@ -2623,7 +2622,6 @@ enum IrInstSrcId {
IrInstSrcIdDeclRef,
IrInstSrcIdPanic,
IrInstSrcIdTagName,
- IrInstSrcIdTagType,
IrInstSrcIdFieldParentPtr,
IrInstSrcIdByteOffsetOf,
IrInstSrcIdBitOffsetOf,
@@ -4074,12 +4072,6 @@ struct IrInstGenTagName {
IrInstGen *target;
};
-struct IrInstSrcTagType {
- IrInstSrc base;
-
- IrInstSrc *target;
-};
-
struct IrInstSrcFieldParentPtr {
IrInstSrc base;
diff --git a/src/stage1/analyze.cpp b/src/stage1/analyze.cpp
index faf66f59f3..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, "@TagType(%s)", 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/stage1/codegen.cpp b/src/stage1/codegen.cpp
index d850b3ee31..6aa134c3b0 100644
--- a/src/stage1/codegen.cpp
+++ b/src/stage1/codegen.cpp
@@ -8842,7 +8842,6 @@ static void define_builtin_fns(CodeGen *g) {
create_builtin_fn(g, BuiltinFnIdIntToPtr, "intToPtr", 2);
create_builtin_fn(g, BuiltinFnIdPtrToInt, "ptrToInt", 1);
create_builtin_fn(g, BuiltinFnIdTagName, "tagName", 1);
- create_builtin_fn(g, BuiltinFnIdTagType, "TagType", 1);
create_builtin_fn(g, BuiltinFnIdFieldParentPtr, "fieldParentPtr", 3);
create_builtin_fn(g, BuiltinFnIdByteOffsetOf, "byteOffsetOf", 2);
create_builtin_fn(g, BuiltinFnIdBitOffsetOf, "bitOffsetOf", 2);
diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp
index 9fd6f15873..e876873022 100644
--- a/src/stage1/ir.cpp
+++ b/src/stage1/ir.cpp
@@ -516,8 +516,6 @@ static void destroy_instruction_src(IrInstSrc *inst) {
return heap::c_allocator.destroy(reinterpret_cast