Commit 00e1c0082c

Daniele Cocca <daniele.cocca@gmail.com>
2021-04-28 00:57:28
tagName: return a null-terminated slice
1 parent 1184b1d
Changed files (4)
doc
src
stage1
test
behavior
doc/langref.html.in
@@ -2986,7 +2986,7 @@ test "@typeInfo" {
     try expect(mem.eql(u8, @typeInfo(Small).Enum.fields[1].name, "two"));
 }
 
-// @tagName gives a []const u8 representation of an enum value:
+// @tagName gives a [:0]const u8 representation of an enum value:
 test "@tagName" {
     try expect(mem.eql(u8, @tagName(Small.three), "three"));
 }
@@ -3233,7 +3233,7 @@ test "union method" {
       {#code_end#}
       <p>
       {#link|@tagName#} can be used to return a {#link|comptime#}
-      {#syntax#}[]const u8{#endsyntax#} value representing the field name:
+      {#syntax#}[:0]const u8{#endsyntax#} value representing the field name:
       </p>
       {#code_begin|test#}
 const std = @import("std");
@@ -8494,9 +8494,9 @@ fn doTheTest() !void {
       {#header_close#}
 
       {#header_open|@tagName#}
-      <pre>{#syntax#}@tagName(value: anytype) []const u8{#endsyntax#}</pre>
+      <pre>{#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}</pre>
       <p>
-      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#}.
+      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#}.
       </p>
       {#header_close#}
 
src/stage1/ir.cpp
@@ -16898,8 +16898,9 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
     if (target_type->id == ZigTypeIdEnumLiteral) {
         IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
         Buf *field_name = target->value->data.x_enum_literal;
-        ZigValue *array_val = create_const_str_lit(ira->codegen, field_name)->data.x_ptr.data.ref.pointee;
-        init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field_name), true);
+        result->value = create_sentineled_str_lit(
+            ira->codegen, field_name,
+            ira->codegen->intern.for_zero_byte());
         return result;
     }
 
@@ -16918,9 +16919,10 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
 
     if (can_fold_enum_type(target_type)) {
         TypeEnumField *only_field = &target_type->data.enumeration.fields[0];
-        ZigValue *array_val = create_const_str_lit(ira->codegen, only_field->name)->data.x_ptr.data.ref.pointee;
         IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
-        init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(only_field->name), true);
+        result->value = create_sentineled_str_lit(
+            ira->codegen, only_field->name,
+            ira->codegen->intern.for_zero_byte());
         return result;
     }
 
@@ -16936,16 +16938,17 @@ static IrInstGen *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrInstSrc
                 buf_sprintf("no tag by value %s", buf_ptr(int_buf)));
             return ira->codegen->invalid_inst_gen;
         }
-        ZigValue *array_val = create_const_str_lit(ira->codegen, field->name)->data.x_ptr.data.ref.pointee;
         IrInstGen *result = ir_const(ira, &instruction->base.base, nullptr);
-        init_const_slice(ira->codegen, result->value, array_val, 0, buf_len(field->name), true);
+        result->value = create_sentineled_str_lit(
+            ira->codegen, field->name,
+            ira->codegen->intern.for_zero_byte());
         return result;
     }
 
-    ZigType *u8_ptr_type = get_pointer_to_type_extra(
+    ZigType *u8_ptr_type = get_pointer_to_type_extra2(
             ira->codegen, ira->codegen->builtin_types.entry_u8,
-            true, false, PtrLenUnknown,
-            0, 0, 0, false);
+            true, false, PtrLenUnknown, 0, 0, 0, false,
+            VECTOR_INDEX_NONE, nullptr, ira->codegen->intern.for_zero_byte());
     ZigType *result_type = get_slice_type(ira->codegen, u8_ptr_type);
     return ir_build_tag_name_gen(ira, &instruction->base.base, target, result_type);
 }
test/behavior/bugs/3779.zig
@@ -0,0 +1,11 @@
+const std = @import("std");
+
+const TestEnum = enum { TestEnumValue };
+const tag_name = @tagName(TestEnum.TestEnumValue);
+const ptr_tag_name: [*:0]const u8 = tag_name;
+
+test "@tagName() returns a string literal" {
+    try std.testing.expectEqual([:0]const u8, @TypeOf(tag_name));
+    try std.testing.expectEqualStrings("TestEnumValue", tag_name);
+    try std.testing.expectEqualStrings("TestEnumValue", ptr_tag_name[0..tag_name.len]);
+}
test/behavior.zig
@@ -51,6 +51,7 @@ comptime {
         _ = @import("behavior/bugs/3384.zig");
         _ = @import("behavior/bugs/3586.zig");
         _ = @import("behavior/bugs/3742.zig");
+        _ = @import("behavior/bugs/3779.zig");
         _ = @import("behavior/bugs/4328.zig");
         _ = @import("behavior/bugs/4560.zig");
         _ = @import("behavior/bugs/4769_a.zig");