| author | |
| committer | |
| log | ed174b7386cb5a6f2008cb6a25c3ff684645d847 |
| tree | 01a43c90ddcd3a5103278a35a993e8539983d542 |
| parent | 15bec20b0013d8afb90a0a2a08c25ce9fb1f2693 |
- 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 #93395 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 | 3454 | |
| 3455 | 3455 | // TODO only pass type_name when the || operator is the top level AST node in the var decl expr |
| 3456 | 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); | |
| 3458 | 3458 | |
| 3459 | 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 | 7588 | } |
| 7589 | 7589 | |
| 7590 | 7590 | Buf *get_anon_type_name(CodeGen *codegen, Stage1Zir *exec, const char *kind_name, |
| 7591 | Scope *scope, AstNode *source_node, Buf *out_bare_name) | |
| 7592 | { | |
| 7593 | if (exec != nullptr && exec->name) { | |
| 7594 | ZigType *import = get_scope_import(scope); | |
| 7595 | Buf *namespace_name = buf_alloc(); | |
| 7596 | append_namespace_qualification(codegen, namespace_name, import); | |
| 7597 | buf_append_buf(namespace_name, exec->name); | |
| 7598 | buf_init_from_buf(out_bare_name, exec->name); | |
| 7599 | return namespace_name; | |
| 7600 | } else if (exec != nullptr && exec->name_fn != nullptr) { | |
| 7601 | Buf *name = buf_alloc(); | |
| 7602 | buf_append_buf(name, &exec->name_fn->symbol_name); | |
| 7603 | buf_appendf(name, "("); | |
| 7604 | render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope); | |
| 7605 | buf_appendf(name, ")"); | |
| 7606 | buf_init_from_buf(out_bare_name, name); | |
| 7607 | return name; | |
| 7608 | } else { | |
| 7609 | ZigType *import = get_scope_import(scope); | |
| 7610 | Buf *namespace_name = buf_alloc(); | |
| 7611 | append_namespace_qualification(codegen, namespace_name, import); | |
| 7612 | RootStruct *root_struct = source_node->owner->data.structure.root_struct; | |
| 7613 | TokenLoc tok_loc = root_struct->token_locs[source_node->main_token]; | |
| 7614 | buf_appendf(namespace_name, "%s:%u:%u", kind_name, | |
| 7615 | tok_loc.line + 1, tok_loc.column + 1); | |
| 7616 | buf_init_from_buf(out_bare_name, namespace_name); | |
| 7617 | return namespace_name; | |
| 7591 | Scope *scope, AstNode *source_node, Buf *out_bare_name, ResultLoc *result_loc) | |
| 7592 | { | |
| 7593 | // See https://ziglang.org/documentation/master/#Struct-Naming . | |
| 7594 | bool force_generic = false; | |
| 7595 | if (result_loc != nullptr | |
| 7596 | && result_loc->source_instruction != nullptr | |
| 7597 | && result_loc->source_instruction->source_node != nullptr | |
| 7598 | ) { | |
| 7599 | switch (result_loc->source_instruction->source_node->type) { | |
| 7600 | case NodeTypeVariableDeclaration: { | |
| 7601 | ZigType *import = get_scope_import(scope); | |
| 7602 | Buf *name = buf_alloc(); | |
| 7603 | append_namespace_qualification(codegen, name, import); | |
| 7604 | const auto &basename = result_loc->source_instruction->source_node->data.variable_declaration.symbol; | |
| 7605 | buf_append_buf(name, basename); | |
| 7606 | buf_init_from_buf(out_bare_name, basename); | |
| 7607 | return name; | |
| 7608 | } | |
| 7609 | case NodeTypeFnCallExpr: | |
| 7610 | case NodeTypeStructValueField: | |
| 7611 | force_generic = true; | |
| 7612 | break; | |
| 7613 | default: | |
| 7614 | break; | |
| 7615 | } | |
| 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 | } |
| 7620 | 7648 | |
| 7621 | static Stage1ZirInst *astgen_container_decl(Stage1AstGen *ag, Scope *parent_scope, AstNode *node) { | |
| 7649 | static Stage1ZirInst *astgen_container_decl(Stage1AstGen *ag, Scope *parent_scope, | |
| 7650 | AstNode *node, ResultLoc *result_loc) | |
| 7651 | { | |
| 7622 | 7652 | assert(node->type == NodeTypeContainerDecl); |
| 7623 | 7653 | |
| 7624 | 7654 | ContainerKind kind = node->data.container_decl.kind; |
| 7625 | 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); | |
| 7627 | 7658 | |
| 7628 | 7659 | ContainerLayout layout = node->data.container_decl.layout; |
| 7629 | 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 | 7684 | uint32_t err_count = node->data.err_set_decl.decls.length; |
| 7654 | 7685 | |
| 7655 | 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 | 7688 | ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); |
| 7658 | 7689 | buf_init_from_buf(&err_set_type->name, type_name); |
| 7659 | 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 | 7994 | case NodeTypeCatchExpr: |
| 7964 | 7995 | return astgen_catch(ag, scope, node, lval, result_loc); |
| 7965 | 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 | 7998 | case NodeTypeFnProto: |
| 7968 | 7999 | return ir_lval_wrap(ag, scope, astgen_fn_proto(ag, scope, node), lval, result_loc); |
| 7969 | 8000 | case NodeTypeErrorSetDecl: |
src/stage1/astgen.hpp+1-1| ... | ... | @@ -32,6 +32,6 @@ void destroy_instruction_src(Stage1ZirInst *inst); |
| 32 | 32 | |
| 33 | 33 | bool ir_should_inline(Stage1Zir *exec, Scope *scope); |
| 34 | 34 | Buf *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); | |
| 36 | 36 | |
| 37 | 37 | #endif |
src/stage1/ir.cpp+9-8| ... | ... | @@ -10423,7 +10423,7 @@ static Stage1AirInst *ir_analyze_tuple_cat(IrAnalyze *ira, Scope *scope, AstNode |
| 10423 | 10423 | |
| 10424 | 10424 | Buf *bare_name = buf_alloc(); |
| 10425 | 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 | 10427 | ZigType *new_type = get_partial_container_type(ira->codegen, scope, |
| 10428 | 10428 | ContainerKindStruct, source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); |
| 10429 | 10429 | new_type->data.structure.special = StructSpecialInferredTuple; |
| ... | ... | @@ -10755,7 +10755,7 @@ static Stage1AirInst *ir_analyze_tuple_mult(IrAnalyze *ira, Scope *scope, AstNod |
| 10755 | 10755 | |
| 10756 | 10756 | Buf *bare_name = buf_alloc(); |
| 10757 | 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 | 10759 | ZigType *new_type = get_partial_container_type(ira->codegen, scope, |
| 10760 | 10760 | ContainerKindStruct, source_node, buf_ptr(name), bare_name, ContainerLayoutAuto); |
| 10761 | 10761 | new_type->data.structure.special = StructSpecialInferredTuple; |
| ... | ... | @@ -12277,7 +12277,7 @@ static Stage1AirInst *ir_analyze_instruction_resolve_result(IrAnalyze *ira, Stag |
| 12277 | 12277 | if (implicit_elem_type == ira->codegen->builtin_types.entry_anytype) { |
| 12278 | 12278 | Buf *bare_name = buf_alloc(); |
| 12279 | 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); | |
| 12281 | 12281 | |
| 12282 | 12282 | StructSpecial struct_special = StructSpecialInferredStruct; |
| 12283 | 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 | 18898 | |
| 18899 | 18899 | Buf *bare_name = buf_alloc(); |
| 18900 | 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 | 18902 | return get_opaque_type(ira->codegen, |
| 18903 | 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 | 18945 | assert(is_slice(slice->type)); |
| 18946 | 18946 | ZigType *err_set_type = new_type_table_entry(ZigTypeIdErrorSet); |
| 18947 | 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 | 18950 | err_set_type->size_in_bits = ira->codegen->builtin_types.entry_global_error_set->size_in_bits; |
| 18950 | 18951 | err_set_type->abi_align = ira->codegen->builtin_types.entry_global_error_set->abi_align; |
| 18951 | 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 | 19025 | |
| 19025 | 19026 | ZigType *entry = new_type_table_entry(ZigTypeIdStruct); |
| 19026 | 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 | 19029 | entry->data.structure.decl_node = source_node; |
| 19029 | 19030 | entry->data.structure.fields = alloc_type_struct_fields(fields_len); |
| 19030 | 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 | 19135 | |
| 19135 | 19136 | ZigType *entry = new_type_table_entry(ZigTypeIdEnum); |
| 19136 | 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 | 19139 | entry->data.enumeration.decl_node = source_node; |
| 19139 | 19140 | entry->data.enumeration.tag_int_type = tag_type; |
| 19140 | 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 | 19217 | |
| 19217 | 19218 | ZigType *entry = new_type_table_entry(ZigTypeIdUnion); |
| 19218 | 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 | 19221 | entry->data.unionation.decl_node = source_node; |
| 19221 | 19222 | entry->data.unionation.fields = heap::c_allocator.allocate<TypeUnionField>(fields_len); |
| 19222 | 19223 | entry->data.unionation.fields_by_name.init(fields_len); |
test/behavior/misc.zig-24| ... | ... | @@ -436,30 +436,6 @@ const AUnion = union { |
| 436 | 436 | Two: void, |
| 437 | 437 | }; |
| 438 | 438 | |
| 439 | test "@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 | ||
| 458 | fn TypeFromFn(comptime T: type) type { | |
| 459 | _ = T; | |
| 460 | return struct {}; | |
| 461 | } | |
| 462 | ||
| 463 | 439 | test "double implicit cast in same expression" { |
| 464 | 440 | var x = @as(i32, @as(u16, nine())); |
| 465 | 441 | try expect(x == 9); |
test/behavior/typename.zig+109-2| ... | ... | @@ -2,6 +2,113 @@ const std = @import("std"); |
| 2 | 2 | const expect = std.testing.expect; |
| 3 | 3 | const expectEqualSlices = std.testing.expectEqualSlices; |
| 4 | 4 | |
| 5 | test "slice" { | |
| 6 | try expectEqualSlices(u8, "[]u8", @typeName([]u8)); | |
| 5 | // Most tests here can be comptime but use runtime so that a stacktrace | |
| 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. | |
| 13 | test "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. | |
| 27 | test "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 | ||
| 39 | test "basic" { | |
| 40 | try expectEqualSlices(u8, @typeName(i64), "i64"); | |
| 41 | try expectEqualSlices(u8, @typeName(*usize), "*usize"); | |
| 42 | try expectEqualSlices(u8, @typeName([]u8), "[]u8"); | |
| 43 | } | |
| 44 | ||
| 45 | test "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 | ||
| 58 | const A_Struct = struct {}; | |
| 59 | const A_Union = union { | |
| 60 | unused: u8, | |
| 61 | }; | |
| 62 | const A_Enum = enum { | |
| 63 | unused, | |
| 64 | }; | |
| 65 | ||
| 66 | fn regular() void {} | |
| 67 | ||
| 68 | test "fn body decl" { | |
| 69 | try B.doTest(); | |
| 70 | } | |
| 71 | ||
| 72 | const 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 | ||
| 88 | test "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 | ||
| 98 | fn TypeFromFn(comptime T: type) type { | |
| 99 | _ = T; | |
| 100 | return struct {}; | |
| 101 | } | |
| 102 | ||
| 103 | fn TypeFromFn2(comptime T1: type, comptime T2: type) type { | |
| 104 | _ = T1; | |
| 105 | _ = T2; | |
| 106 | return struct {}; | |
| 107 | } | |
| 108 | ||
| 109 | fn TypeFromFn3(comptime T1: type, comptime T2: type, comptime T3: type) type { | |
| 110 | _ = T1; | |
| 111 | _ = T2; | |
| 112 | _ = T3; | |
| 113 | return struct {}; | |
| 7 | 114 | } |