authorgravatar for michael.dusan@gmail.comMichael Dusan <michael.dusan@gmail.com> 2021-07-19 02:35:17-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-07-28 18:17:11-04:00
loged174b7386cb5a6f2008cb6a25c3ff684645d847
tree01a43c90ddcd3a5103278a35a993e8539983d542
parent15bec20b0013d8afb90a0a2a08c25ce9fb1f2693

stage1: fix anon struct naming in certain cases

- generic "struct:L:C" naming if rloc is NodeTypeStructValueField - generic "struct:L:C" naming if rloc is NodeTypeFnCallExpr - move some tests from test/behavior/misc to test/behavior/typename closes #4330 closes #9339

5 files changed, 182 insertions(+), 67 deletions(-)

src/stage1/astgen.cpp+63-32
...@@ -3454,7 +3454,7 @@ static Stage1ZirInst *astgen_merge_err_sets(Stage1AstGen *ag, Scope *scope, AstN...@@ -3454,7 +3454,7 @@ static Stage1ZirInst *astgen_merge_err_sets(Stage1AstGen *ag, Scope *scope, AstN
34543454
3455 // TODO only pass type_name when the || operator is the top level AST node in the var decl expr3455 // TODO only pass type_name when the || operator is the top level AST node in the var decl expr
3456 Buf bare_name = BUF_INIT;3456 Buf bare_name = BUF_INIT;
3457 Buf *type_name = get_anon_type_name(ag->codegen, ag->exec, "error", scope, node, &bare_name);3457 Buf *type_name = get_anon_type_name(ag->codegen, ag->exec, "error", scope, node, &bare_name, nullptr);
34583458
3459 return ir_build_merge_err_sets(ag, scope, node, op1, op2, type_name);3459 return ir_build_merge_err_sets(ag, scope, node, op1, op2, type_name);
3460}3460}
...@@ -7588,42 +7588,73 @@ static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *o...@@ -7588,42 +7588,73 @@ static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *o
7588}7588}
75897589
7590Buf *get_anon_type_name(CodeGen *codegen, Stage1Zir *exec, const char *kind_name,7590Buf *get_anon_type_name(CodeGen *codegen, Stage1Zir *exec, const char *kind_name,
7591 Scope *scope, AstNode *source_node, Buf *out_bare_name)7591 Scope *scope, AstNode *source_node, Buf *out_bare_name, ResultLoc *result_loc)
7592{7592{
7593 if (exec != nullptr && exec->name) {7593 // See https://ziglang.org/documentation/master/#Struct-Naming .
7594 ZigType *import = get_scope_import(scope);7594 bool force_generic = false;
7595 Buf *namespace_name = buf_alloc();7595 if (result_loc != nullptr
7596 append_namespace_qualification(codegen, namespace_name, import);7596 && result_loc->source_instruction != nullptr
7597 buf_append_buf(namespace_name, exec->name);7597 && result_loc->source_instruction->source_node != nullptr
7598 buf_init_from_buf(out_bare_name, exec->name);7598 ) {
7599 return namespace_name;7599 switch (result_loc->source_instruction->source_node->type) {
7600 } else if (exec != nullptr && exec->name_fn != nullptr) {7600 case NodeTypeVariableDeclaration: {
7601 Buf *name = buf_alloc();7601 ZigType *import = get_scope_import(scope);
7602 buf_append_buf(name, &exec->name_fn->symbol_name);7602 Buf *name = buf_alloc();
7603 buf_appendf(name, "(");7603 append_namespace_qualification(codegen, name, import);
7604 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope);7604 const auto &basename = result_loc->source_instruction->source_node->data.variable_declaration.symbol;
7605 buf_appendf(name, ")");7605 buf_append_buf(name, basename);
7606 buf_init_from_buf(out_bare_name, name);7606 buf_init_from_buf(out_bare_name, basename);
7607 return name;7607 return name;
7608 } else {7608 }
7609 ZigType *import = get_scope_import(scope);7609 case NodeTypeFnCallExpr:
7610 Buf *namespace_name = buf_alloc();7610 case NodeTypeStructValueField:
7611 append_namespace_qualification(codegen, namespace_name, import);7611 force_generic = true;
7612 RootStruct *root_struct = source_node->owner->data.structure.root_struct;7612 break;
7613 TokenLoc tok_loc = root_struct->token_locs[source_node->main_token];7613 default:
7614 buf_appendf(namespace_name, "%s:%u:%u", kind_name,7614 break;
7615 tok_loc.line + 1, tok_loc.column + 1);7615 }
7616 buf_init_from_buf(out_bare_name, namespace_name);
7617 return namespace_name;
7618 }7616 }
7617
7618 if (!force_generic) {
7619 if (exec != nullptr && exec->name != nullptr) {
7620 ZigType *import = get_scope_import(scope);
7621 Buf *namespace_name = buf_alloc();
7622 append_namespace_qualification(codegen, namespace_name, import);
7623 buf_append_buf(namespace_name, exec->name);
7624 buf_init_from_buf(out_bare_name, exec->name);
7625 return namespace_name;
7626 }
7627 if (exec != nullptr && exec->name_fn != nullptr) {
7628 Buf *name = buf_alloc();
7629 buf_append_buf(name, &exec->name_fn->symbol_name);
7630 buf_appendf(name, "(");
7631 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope);
7632 buf_appendf(name, ")");
7633 buf_init_from_buf(out_bare_name, name);
7634 return name;
7635 }
7636 }
7637
7638 ZigType *import = get_scope_import(scope);
7639 Buf *namespace_name = buf_alloc();
7640 append_namespace_qualification(codegen, namespace_name, import);
7641 RootStruct *root_struct = source_node->owner->data.structure.root_struct;
7642 TokenLoc tok_loc = root_struct->token_locs[source_node->main_token];
7643 buf_appendf(namespace_name, "%s:%u:%u", kind_name,
7644 tok_loc.line + 1, tok_loc.column + 1);
7645 buf_init_from_buf(out_bare_name, namespace_name);
7646 return namespace_name;
7619}7647}
76207648
7621static Stage1ZirInst *astgen_container_decl(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) {7649static Stage1ZirInst *astgen_container_decl(Stage1AstGen *ag, Scope *parent_scope,
7650 AstNode *node, ResultLoc *result_loc)
7651{
7622 assert(node->type == NodeTypeContainerDecl);7652 assert(node->type == NodeTypeContainerDecl);
76237653
7624 ContainerKind kind = node->data.container_decl.kind;7654 ContainerKind kind = node->data.container_decl.kind;
7625 Buf *bare_name = buf_alloc();7655 Buf *bare_name = buf_alloc();
7626 Buf *name = get_anon_type_name(ag->codegen, ag->exec, container_string(kind), parent_scope, node, bare_name);7656 Buf *name = get_anon_type_name(ag->codegen,
7657 ag->exec, container_string(kind), parent_scope, node, bare_name, result_loc);
76277658
7628 ContainerLayout layout = node->data.container_decl.layout;7659 ContainerLayout layout = node->data.container_decl.layout;
7629 ZigType *container_type = get_partial_container_type(ag->codegen, parent_scope,7660 ZigType *container_type = get_partial_container_type(ag->codegen, parent_scope,
...@@ -7653,7 +7684,7 @@ static Stage1ZirInst *astgen_err_set_decl(Stage1AstGen *ag, Scope *parent_scope,...@@ -7653,7 +7684,7 @@ static Stage1ZirInst *astgen_err_set_decl(Stage1AstGen *ag, Scope *parent_scope,
7653 uint32_t err_count = node->data.err_set_decl.decls.length;7684 uint32_t err_count = node->data.err_set_decl.decls.length;
76547685
7655 Buf bare_name = BUF_INIT;7686 Buf bare_name = BUF_INIT;
7656 Buf *type_name = get_anon_type_name(ag->codegen, ag->exec, "error", parent_scope, node, &bare_name);7687 Buf *type_name = get_anon_type_name(ag->codegen, ag->exec, "error", parent_scope, node, &bare_name, nullptr);
7657 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);7688 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
7658 buf_init_from_buf(&err_set_type->name, type_name);7689 buf_init_from_buf(&err_set_type->name, type_name);
7659 err_set_type->data.error_set.err_count = err_count;7690 err_set_type->data.error_set.err_count = err_count;
...@@ -7963,7 +7994,7 @@ static Stage1ZirInst *astgen_node_raw(Stage1AstGen *ag, AstNode *node, Scope *sc...@@ -7963,7 +7994,7 @@ static Stage1ZirInst *astgen_node_raw(Stage1AstGen *ag, AstNode *node, Scope *sc
7963 case NodeTypeCatchExpr:7994 case NodeTypeCatchExpr:
7964 return astgen_catch(ag, scope, node, lval, result_loc);7995 return astgen_catch(ag, scope, node, lval, result_loc);
7965 case NodeTypeContainerDecl:7996 case NodeTypeContainerDecl:
7966 return ir_lval_wrap(ag, scope, astgen_container_decl(ag, scope, node), lval, result_loc);7997 return ir_lval_wrap(ag, scope, astgen_container_decl(ag, scope, node, result_loc), lval, result_loc);
7967 case NodeTypeFnProto:7998 case NodeTypeFnProto:
7968 return ir_lval_wrap(ag, scope, astgen_fn_proto(ag, scope, node), lval, result_loc);7999 return ir_lval_wrap(ag, scope, astgen_fn_proto(ag, scope, node), lval, result_loc);
7969 case NodeTypeErrorSetDecl:8000 case NodeTypeErrorSetDecl:
src/stage1/astgen.hpp+1-1
...@@ -32,6 +32,6 @@ void destroy_instruction_src(Stage1ZirInst *inst);...@@ -32,6 +32,6 @@ void destroy_instruction_src(Stage1ZirInst *inst);
3232
33bool ir_should_inline(Stage1Zir *exec, Scope *scope);33bool ir_should_inline(Stage1Zir *exec, Scope *scope);
34Buf *get_anon_type_name(CodeGen *codegen, Stage1Zir *exec, const char *kind_name,34Buf *get_anon_type_name(CodeGen *codegen, Stage1Zir *exec, const char *kind_name,
35 Scope *scope, AstNode *source_node, Buf *out_bare_name);35 Scope *scope, AstNode *source_node, Buf *out_bare_name, ResultLoc *result_loc);
3636
37#endif37#endif
src/stage1/ir.cpp+9-8
...@@ -10423,7 +10423,7 @@ static Stage1AirInst *ir_analyze_tuple_cat(IrAnalyze *ira, Scope *scope, AstNode...@@ -10423,7 +10423,7 @@ static Stage1AirInst *ir_analyze_tuple_cat(IrAnalyze *ira, Scope *scope, AstNode
1042310423
10424 Buf *bare_name = buf_alloc();10424 Buf *bare_name = buf_alloc();
10425 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),10425 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),
10426 scope, source_node, bare_name);10426 scope, source_node, bare_name, nullptr);
10427 ZigType *new_type = get_partial_container_type(ira->codegen, scope,10427 ZigType *new_type = get_partial_container_type(ira->codegen, scope,
10428 ContainerKindStruct, source_node, buf_ptr(name), bare_name, ContainerLayoutAuto);10428 ContainerKindStruct, source_node, buf_ptr(name), bare_name, ContainerLayoutAuto);
10429 new_type->data.structure.special = StructSpecialInferredTuple;10429 new_type->data.structure.special = StructSpecialInferredTuple;
...@@ -10755,7 +10755,7 @@ static Stage1AirInst *ir_analyze_tuple_mult(IrAnalyze *ira, Scope *scope, AstNod...@@ -10755,7 +10755,7 @@ static Stage1AirInst *ir_analyze_tuple_mult(IrAnalyze *ira, Scope *scope, AstNod
1075510755
10756 Buf *bare_name = buf_alloc();10756 Buf *bare_name = buf_alloc();
10757 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),10757 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),
10758 scope, source_node, bare_name);10758 scope, source_node, bare_name, nullptr);
10759 ZigType *new_type = get_partial_container_type(ira->codegen, scope,10759 ZigType *new_type = get_partial_container_type(ira->codegen, scope,
10760 ContainerKindStruct, source_node, buf_ptr(name), bare_name, ContainerLayoutAuto);10760 ContainerKindStruct, source_node, buf_ptr(name), bare_name, ContainerLayoutAuto);
10761 new_type->data.structure.special = StructSpecialInferredTuple;10761 new_type->data.structure.special = StructSpecialInferredTuple;
...@@ -12277,7 +12277,7 @@ static Stage1AirInst *ir_analyze_instruction_resolve_result(IrAnalyze *ira, Stag...@@ -12277,7 +12277,7 @@ static Stage1AirInst *ir_analyze_instruction_resolve_result(IrAnalyze *ira, Stag
12277 if (implicit_elem_type == ira->codegen->builtin_types.entry_anytype) {12277 if (implicit_elem_type == ira->codegen->builtin_types.entry_anytype) {
12278 Buf *bare_name = buf_alloc();12278 Buf *bare_name = buf_alloc();
12279 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),12279 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),
12280 instruction->base.scope, instruction->base.source_node, bare_name);12280 instruction->base.scope, instruction->base.source_node, bare_name, nullptr);
1228112281
12282 StructSpecial struct_special = StructSpecialInferredStruct;12282 StructSpecial struct_special = StructSpecialInferredStruct;
12283 if (instruction->base.source_node->type == NodeTypeContainerInitExpr &&12283 if (instruction->base.source_node->type == NodeTypeContainerInitExpr &&
...@@ -18898,7 +18898,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_...@@ -18898,7 +18898,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
1889818898
18899 Buf *bare_name = buf_alloc();18899 Buf *bare_name = buf_alloc();
18900 Buf *full_name = get_anon_type_name(ira->codegen,18900 Buf *full_name = get_anon_type_name(ira->codegen,
18901 ira->zir, "opaque", scope, source_node, bare_name);18901 ira->zir, "opaque", scope, source_node, bare_name, nullptr);
18902 return get_opaque_type(ira->codegen,18902 return get_opaque_type(ira->codegen,
18903 scope, source_node, buf_ptr(full_name), bare_name);18903 scope, source_node, buf_ptr(full_name), bare_name);
18904 }18904 }
...@@ -18945,7 +18945,8 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_...@@ -18945,7 +18945,8 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
18945 assert(is_slice(slice->type));18945 assert(is_slice(slice->type));
18946 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);18946 ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet);
18947 Buf bare_name = BUF_INIT;18947 Buf bare_name = BUF_INIT;
18948 buf_init_from_buf(&err_set_type->name, get_anon_type_name(ira->codegen, ira->zir, "error", scope, source_node, &bare_name));18948 buf_init_from_buf(&err_set_type->name,
18949 get_anon_type_name(ira->codegen, ira->zir, "error", scope, source_node, &bare_name, nullptr));
18949 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits;18950 err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits;
18950 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align;18951 err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align;
18951 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size;18952 err_set_type->abi_size = ira->codegen->builtin_types.entry_global_error_set->abi_size;
...@@ -19024,7 +19025,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_...@@ -19024,7 +19025,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
1902419025
19025 ZigType *entry = new_type_table_entry(ZigTypeIdStruct);19026 ZigType *entry = new_type_table_entry(ZigTypeIdStruct);
19026 buf_init_from_buf(&entry->name,19027 buf_init_from_buf(&entry->name,
19027 get_anon_type_name(ira->codegen, ira->zir, "struct", scope, source_node, &entry->name));19028 get_anon_type_name(ira->codegen, ira->zir, "struct", scope, source_node, &entry->name, nullptr));
19028 entry->data.structure.decl_node = source_node;19029 entry->data.structure.decl_node = source_node;
19029 entry->data.structure.fields = alloc_type_struct_fields(fields_len);19030 entry->data.structure.fields = alloc_type_struct_fields(fields_len);
19030 entry->data.structure.fields_by_name.init(fields_len);19031 entry->data.structure.fields_by_name.init(fields_len);
...@@ -19134,7 +19135,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_...@@ -19134,7 +19135,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
1913419135
19135 ZigType *entry = new_type_table_entry(ZigTypeIdEnum);19136 ZigType *entry = new_type_table_entry(ZigTypeIdEnum);
19136 buf_init_from_buf(&entry->name,19137 buf_init_from_buf(&entry->name,
19137 get_anon_type_name(ira->codegen, ira->zir, "enum", scope, source_node, &entry->name));19138 get_anon_type_name(ira->codegen, ira->zir, "enum", scope, source_node, &entry->name, nullptr));
19138 entry->data.enumeration.decl_node = source_node;19139 entry->data.enumeration.decl_node = source_node;
19139 entry->data.enumeration.tag_int_type = tag_type;19140 entry->data.enumeration.tag_int_type = tag_type;
19140 entry->data.enumeration.decls_scope = create_decls_scope(19141 entry->data.enumeration.decls_scope = create_decls_scope(
...@@ -19216,7 +19217,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_...@@ -19216,7 +19217,7 @@ static ZigType *type_info_to_type(IrAnalyze *ira, Scope *scope, AstNode *source_
1921619217
19217 ZigType *entry = new_type_table_entry(ZigTypeIdUnion);19218 ZigType *entry = new_type_table_entry(ZigTypeIdUnion);
19218 buf_init_from_buf(&entry->name,19219 buf_init_from_buf(&entry->name,
19219 get_anon_type_name(ira->codegen, ira->zir, "union", scope, source_node, &entry->name));19220 get_anon_type_name(ira->codegen, ira->zir, "union", scope, source_node, &entry->name, nullptr));
19220 entry->data.unionation.decl_node = source_node;19221 entry->data.unionation.decl_node = source_node;
19221 entry->data.unionation.fields = heap::c_allocator.allocate<TypeUnionField>(fields_len);19222 entry->data.unionation.fields = heap::c_allocator.allocate<TypeUnionField>(fields_len);
19222 entry->data.unionation.fields_by_name.init(fields_len);19223 entry->data.unionation.fields_by_name.init(fields_len);
test/behavior/misc.zig-24
...@@ -436,30 +436,6 @@ const AUnion = union {...@@ -436,30 +436,6 @@ const AUnion = union {
436 Two: void,436 Two: void,
437};437};
438438
439test "@typeName" {
440 const Struct = struct {};
441 const Union = union {
442 unused: u8,
443 };
444 const Enum = enum {
445 Unused,
446 };
447 comptime {
448 try expect(mem.eql(u8, @typeName(i64), "i64"));
449 try expect(mem.eql(u8, @typeName(*usize), "*usize"));
450 // https://github.com/ziglang/zig/issues/675
451 try expect(mem.eql(u8, "behavior.misc.TypeFromFn(u8)", @typeName(TypeFromFn(u8))));
452 try expect(mem.eql(u8, @typeName(Struct), "Struct"));
453 try expect(mem.eql(u8, @typeName(Union), "Union"));
454 try expect(mem.eql(u8, @typeName(Enum), "Enum"));
455 }
456}
457
458fn TypeFromFn(comptime T: type) type {
459 _ = T;
460 return struct {};
461}
462
463test "double implicit cast in same expression" {439test "double implicit cast in same expression" {
464 var x = @as(i32, @as(u16, nine()));440 var x = @as(i32, @as(u16, nine()));
465 try expect(x == 9);441 try expect(x == 9);
test/behavior/typename.zig+109-2
...@@ -2,6 +2,113 @@ const std = @import("std");...@@ -2,6 +2,113 @@ const std = @import("std");
2const expect = std.testing.expect;2const expect = std.testing.expect;
3const expectEqualSlices = std.testing.expectEqualSlices;3const expectEqualSlices = std.testing.expectEqualSlices;
44
5test "slice" {5// Most tests here can be comptime but use runtime so that a stacktrace
6 try expectEqualSlices(u8, "[]u8", @typeName([]u8));6// can show failure location.
7//
8// Note certain results of `@typeName()` expect `behavior.zig` to be the
9// root file. Running a test against this file as root will result in
10// failures.
11
12// CAUTION: this test is source-location sensitive.
13test "anon fn param - source-location sensitive" {
14 // https://github.com/ziglang/zig/issues/9339
15 try expectEqualSlices(u8, @typeName(TypeFromFn(struct {})), "behavior.typename.TypeFromFn(behavior.typename.struct:15:52)");
16 try expectEqualSlices(u8, @typeName(TypeFromFn(union { unused: u8 })), "behavior.typename.TypeFromFn(behavior.typename.union:16:52)");
17 try expectEqualSlices(u8, @typeName(TypeFromFn(enum { unused })), "behavior.typename.TypeFromFn(behavior.typename.enum:17:52)");
18
19 try expectEqualSlices(
20 u8,
21 @typeName(TypeFromFn3(struct {}, union { unused: u8 }, enum { unused })),
22 "behavior.typename.TypeFromFn3(behavior.typename.struct:21:31,behavior.typename.union:21:42,behavior.typename.enum:21:64)",
23 );
24}
25
26// CAUTION: this test is source-location sensitive.
27test "anon field init" {
28 const Foo = .{
29 .T1 = struct {},
30 .T2 = union { unused: u8 },
31 .T3 = enum { unused },
32 };
33
34 try expectEqualSlices(u8, @typeName(Foo.T1), "behavior.typename.struct:29:15");
35 try expectEqualSlices(u8, @typeName(Foo.T2), "behavior.typename.union:30:15");
36 try expectEqualSlices(u8, @typeName(Foo.T3), "behavior.typename.enum:31:15");
37}
38
39test "basic" {
40 try expectEqualSlices(u8, @typeName(i64), "i64");
41 try expectEqualSlices(u8, @typeName(*usize), "*usize");
42 try expectEqualSlices(u8, @typeName([]u8), "[]u8");
43}
44
45test "top level decl" {
46 try expectEqualSlices(u8, @typeName(A_Struct), "A_Struct");
47 try expectEqualSlices(u8, @typeName(A_Union), "A_Union");
48 try expectEqualSlices(u8, @typeName(A_Enum), "A_Enum");
49
50 // regular fn, without error
51 try expectEqualSlices(u8, @typeName(@TypeOf(regular)), "fn() void");
52 // regular fn inside struct, with error
53 try expectEqualSlices(u8, @typeName(@TypeOf(B.doTest)), "fn() @typeInfo(@typeInfo(@TypeOf(behavior.typename.B.doTest)).Fn.return_type.?).ErrorUnion.error_set!void");
54 // generic fn
55 try expectEqualSlices(u8, @typeName(@TypeOf(TypeFromFn)), "fn(type) anytype");
56}
57
58const A_Struct = struct {};
59const A_Union = union {
60 unused: u8,
61};
62const A_Enum = enum {
63 unused,
64};
65
66fn regular() void {}
67
68test "fn body decl" {
69 try B.doTest();
70}
71
72const B = struct {
73 fn doTest() !void {
74 const B_Struct = struct {};
75 const B_Union = union {
76 unused: u8,
77 };
78 const B_Enum = enum {
79 unused,
80 };
81
82 try expectEqualSlices(u8, @typeName(B_Struct), "B_Struct");
83 try expectEqualSlices(u8, @typeName(B_Union), "B_Union");
84 try expectEqualSlices(u8, @typeName(B_Enum), "B_Enum");
85 }
86};
87
88test "fn param" {
89 // https://github.com/ziglang/zig/issues/675
90 try expectEqualSlices(u8, @typeName(TypeFromFn(u8)), "behavior.typename.TypeFromFn(u8)");
91 try expectEqualSlices(u8, @typeName(TypeFromFn(A_Struct)), "behavior.typename.TypeFromFn(behavior.typename.A_Struct)");
92 try expectEqualSlices(u8, @typeName(TypeFromFn(A_Union)), "behavior.typename.TypeFromFn(behavior.typename.A_Union)");
93 try expectEqualSlices(u8, @typeName(TypeFromFn(A_Enum)), "behavior.typename.TypeFromFn(behavior.typename.A_Enum)");
94
95 try expectEqualSlices(u8, @typeName(TypeFromFn2(u8, bool)), "behavior.typename.TypeFromFn2(u8,bool)");
96}
97
98fn TypeFromFn(comptime T: type) type {
99 _ = T;
100 return struct {};
101}
102
103fn TypeFromFn2(comptime T1: type, comptime T2: type) type {
104 _ = T1;
105 _ = T2;
106 return struct {};
107}
108
109fn TypeFromFn3(comptime T1: type, comptime T2: type, comptime T3: type) type {
110 _ = T1;
111 _ = T2;
112 _ = T3;
113 return struct {};
7}114}