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" {...@@ -2986,7 +2986,7 @@ test "@typeInfo" {
2986 try expect(mem.eql(u8, @typeInfo(Small).Enum.fields[1].name, "two"));2986 try expect(mem.eql(u8, @typeInfo(Small).Enum.fields[1].name, "two"));
2987}2987}
29882988
2989// @tagName gives a []const u8 representation of an enum value:2989// @tagName gives a [:0]const u8 representation of an enum value:
2990test "@tagName" {2990test "@tagName" {
2991 try expect(mem.eql(u8, @tagName(Small.three), "three"));2991 try expect(mem.eql(u8, @tagName(Small.three), "three"));
2992}2992}
...@@ -3233,7 +3233,7 @@ test "union method" {...@@ -3233,7 +3233,7 @@ test "union method" {
3233 {#code_end#}3233 {#code_end#}
3234 <p>3234 <p>
3235 {#link|@tagName#} can be used to return a {#link|comptime#}3235 {#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:
3237 </p>3237 </p>
3238 {#code_begin|test#}3238 {#code_begin|test#}
3239const std = @import("std");3239const std = @import("std");
...@@ -8494,9 +8494,9 @@ fn doTheTest() !void {...@@ -8494,9 +8494,9 @@ fn doTheTest() !void {
8494 {#header_close#}8494 {#header_close#}
84958495
8496 {#header_open|@tagName#}8496 {#header_open|@tagName#}
8497 <pre>{#syntax#}@tagName(value: anytype) []const u8{#endsyntax#}</pre>8497 <pre>{#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}</pre>
8498 <p>8498 <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#}.
8500 </p>8500 </p>
8501 {#header_close#}8501 {#header_close#}
85028502
src/stage1/ir.cpp+12-9
...@@ -16898,8 +16898,9 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc...@@ -16898,8 +16898,9 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
16898 if (target_type->id == ZigTypeIdEnumLiteral) {16898 if (target_type->id == ZigTypeIdEnumLiteral) {
16899 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);16899 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
16900 Buf *field_name = target->value->data.x_enum_literal;16900 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;16901 result->value = create_sentineled_str_lit(
16902 init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field_name), true);16902 ira->codegen, field_name,
16903 ira->codegen->intern.for_zero_byte());
16903 return result;16904 return result;
16904 }16905 }
1690516906
...@@ -16918,9 +16919,10 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc...@@ -16918,9 +16919,10 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
1691816919
16919 if (can_fold_enum_type(target_type)) {16920 if (can_fold_enum_type(target_type)) {
16920 TypeEnumField *only_field = &target_type->data.enumeration.fields[0];16921 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;
16922 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);16922 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());
16924 return result;16926 return result;
16925 }16927 }
1692616928
...@@ -16936,16 +16938,17 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc...@@ -16936,16 +16938,17 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
16936 buf_sprintf("no tag by value %s", buf_ptr(int_buf)));16938 buf_sprintf("no tag by value %s", buf_ptr(int_buf)));
16937 return ira->codegen->invalid_inst_gen;16939 return ira->codegen->invalid_inst_gen;
16938 }16940 }
16939 ZigValue *array_val = create_const_str_lit(ira->codegen, field->name)->data.x_ptr.data.ref.pointee;
16940 IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);16941 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());
16942 return result;16945 return result;
16943 }16946 }
1694416947
16945 ZigType *u8_ptr_type = get_pointer_to_type_extra(16948 ZigType *u8_ptr_type = get_pointer_to_type_extra2(
16946 ira->codegen, ira->codegen->builtin_types.entry_u8,16949 ira->codegen, ira->codegen->builtin_types.entry_u8,
16947 true, false, PtrLenUnknown,16950 true, false, PtrLenUnknown, 0, 0, 0, false,
16948 0, 0, 0, false);16951 VECTOR_INDEX_NONE, nullptr, ira->codegen->intern.for_zero_byte());
16949 ZigType *result_type = get_slice_type(ira->codegen, u8_ptr_type);16952 ZigType *result_type = get_slice_type(ira->codegen, u8_ptr_type);
16950 return ir_build_tag_name_gen(ira, &instruction->base.base, target, result_type);16953 return ir_build_tag_name_gen(ira, &instruction->base.base, target, result_type);
16951}16954}
test/behavior.zig+1
...@@ -51,6 +51,7 @@ comptime {...@@ -51,6 +51,7 @@ comptime {
51 _ = @import("behavior/bugs/3384.zig");51 _ = @import("behavior/bugs/3384.zig");
52 _ = @import("behavior/bugs/3586.zig");52 _ = @import("behavior/bugs/3586.zig");
53 _ = @import("behavior/bugs/3742.zig");53 _ = @import("behavior/bugs/3742.zig");
54 _ = @import("behavior/bugs/3779.zig");
54 _ = @import("behavior/bugs/4328.zig");55 _ = @import("behavior/bugs/4328.zig");
55 _ = @import("behavior/bugs/4560.zig");56 _ = @import("behavior/bugs/4560.zig");
56 _ = @import("behavior/bugs/4769_a.zig");57 _ = @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}