diff --git a/doc/langref.html.in b/doc/langref.html.in index 4962183a77..fcf07eb6c1 100644 --- a/doc/langref.html.in +++ b/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#}
{#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:
{#code_begin|test#} const std = @import("std"); @@ -8494,9 +8494,9 @@ fn doTheTest() !void { {#header_close#} {#header_open|@tagName#} -{#syntax#}@tagName(value: anytype) []const u8{#endsyntax#}
+ {#syntax#}@tagName(value: anytype) [:0]const u8{#endsyntax#}
- Converts an enum value or union value to a slice of bytes representing the name.
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.
If the enum is non-exhaustive and the tag value does not map to a name, it invokes safety-checked {#link|Undefined Behavior#}.
{#header_close#} diff --git a/src/stage1/ir.cpp b/src/stage1/ir.cpp index 36c80a9fbb..10dfb798cb 100644 --- a/src/stage1/ir.cpp +++ b/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); } diff --git a/test/behavior.zig b/test/behavior.zig index 479fe9b422..56c1b8ec05 100644 --- a/test/behavior.zig +++ b/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"); diff --git a/test/behavior/bugs/3779.zig b/test/behavior/bugs/3779.zig new file mode 100644 index 0000000000..8866b39de3 --- /dev/null +++ b/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]); +}