authorgravatar for daniele.cocca@gmail.comDaniele Cocca <daniele.cocca@gmail.com> 2021-04-27 23:57:28+01:00
committergravatar for dcocca@google.comDaniele Cocca <dcocca@google.com> 2021-06-16 22:02:42+01:00
log00e1c0082c7c3cee377cc4e31b205c26f8943419
tree3447c82d08969b65f1419c69a544cb895b6ae008
parent1184b1d560c6a86b79bbda072478320431e09189

tagName: return a null-terminated slice


4 files changed, 28 insertions(+), 13 deletions(-)

doc/langref.html.in+4-4
......@@ -2986,7 +2986,7 @@ test "@typeInfo" {
29862986 try expect(mem.eql(u8, @typeInfo(Small).Enum.fields[1].name, "two"));
29872987}
29882988
2989// @tagName gives a []const u8 representation of an enum value:
2989// @tagName gives a [:0]const u8 representation of an enum value:
29902990test "@tagName" {
29912991 try expect(mem.eql(u8, @tagName(Small.three), "three"));
29922992}
......@@ -3233,7 +3233,7 @@ test "union method" {
32333233 {#code_end#}
32343234 <p>
32353235 {#link|@tagName#} can be used to return a {#link|comptime#}
3236 {#syntax#}[]const u8{#endsyntax#} value representing the field name:
3236 {#syntax#}[:0]const u8{#endsyntax#} value representing the field name:
32373237 </p>
32383238 {#code_begin|test#}
32393239const std = @import("std");
......@@ -8494,9 +8494,9 @@ fn doTheTest() !void {
84948494 {#header_close#}
84958495
84968496 {#header_open|@tagName#}
8497 <pre>{#syntax#}@tagName(value: anytype) []const u8{#endsyntax#}</pre>
8497 <pre>{#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}</pre>
84988498 <p>
8499 Converts an enum value or union value to a slice of bytes representing the name.</p><p>If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked {#link|Undefined Behavior#}.
8499 Converts an enum value or union value to a string literal representing the name.</p><p>If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked {#link|Undefined Behavior#}.
85008500 </p>
85018501 {#header_close#}
85028502
src/stage1/ir.cpp+12-9
......@@ -16898,8 +16898,9 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
1689816898 if (target_type->id == ZigTypeIdEnumLiteral) {
1689916899 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
1690016900 Buf *field_name = target->value->data.x_enum_literal;
16901 ZigValue *array_val = create_const_str_lit(ira->codegen, field_name)->data.x_ptr.data.ref.pointee;
16902 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field_name), true);
16901 result->value = create_sentineled_str_lit(
16902 ira->codegen, field_name,
16903 ira->codegen->intern.for_zero_byte());
1690316904 return result;
1690416905 }
1690516906
......@@ -16918,9 +16919,10 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
1691816919
1691916920 if (can_fold_enum_type(target_type)) {
1692016921 TypeEnumField *only_field = &target_type->data.enumeration.fields[0];
16921 ZigValue *array_val = create_const_str_lit(ira->codegen, only_field->name)->data.x_ptr.data.ref.pointee;
1692216922 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
16923 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(only_field->name), true);
16923 result->value = create_sentineled_str_lit(
16924 ira->codegen, only_field->name,
16925 ira->codegen->intern.for_zero_byte());
1692416926 return result;
1692516927 }
1692616928
......@@ -16936,16 +16938,17 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
1693616938 buf_sprintf("no tag by value %s", buf_ptr(int_buf)));
1693716939 return ira->codegen->invalid_inst_gen;
1693816940 }
16939 ZigValue *array_val = create_const_str_lit(ira->codegen, field->name)->data.x_ptr.data.ref.pointee;
1694016941 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
16941 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field->name), true);
16942 result->value = create_sentineled_str_lit(
16943 ira->codegen, field->name,
16944 ira->codegen->intern.for_zero_byte());
1694216945 return result;
1694316946 }
1694416947
16945 ZigType *u8_ptr_type = get_pointer_to_type_extra(
16948 ZigType *u8_ptr_type = get_pointer_to_type_extra2(
1694616949 ira->codegen, ira->codegen->builtin_types.entry_u8,
16947 true, false, PtrLenUnknown,
16948 0, 0, 0, false);
16950 true, false, PtrLenUnknown, 0, 0, 0, false,
16951 VECTOR_INDEX_NONE, nullptr, ira->codegen->intern.for_zero_byte());
1694916952 ZigType *result_type = get_slice_type(ira->codegen, u8_ptr_type);
1695016953 return ir_build_tag_name_gen(ira, &instruction->base.base, target, result_type);
1695116954}
test/behavior.zig+1
......@@ -51,6 +51,7 @@ comptime {
5151 _ = @import("behavior/bugs/3384.zig");
5252 _ = @import("behavior/bugs/3586.zig");
5353 _ = @import("behavior/bugs/3742.zig");
54 _ = @import("behavior/bugs/3779.zig");
5455 _ = @import("behavior/bugs/4328.zig");
5556 _ = @import("behavior/bugs/4560.zig");
5657 _ = @import("behavior/bugs/4769_a.zig");
test/behavior/bugs/3779.zig created+11
......@@ -0,0 +1,11 @@
1const std = @import("std");
2
3const TestEnum = enum { TestEnumValue };
4const tag_name = @tagName(TestEnum.TestEnumValue);
5const ptr_tag_name: [*:0]const u8 = tag_name;
6
7test "@tagName() returns a string literal" {
8 try std.testing.expectEqual([:0]const u8, @TypeOf(tag_name));
9 try std.testing.expectEqualStrings("TestEnumValue", tag_name);
10 try std.testing.expectEqualStrings("TestEnumValue", ptr_tag_name[0..tag_name.len]);
11}