From 2a9329c9988430cfa11a8bb4b02da0dce8749028 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 3 Sep 2018 11:32:39 -0400 Subject: [PATCH] better anonymous struct naming this makes anonymous structs inherit the name of the function they are in only when they are the return expression. also document the behavior and provide examples. closes #1243 --- doc/langref.html.in | 26 ++++++++++++++++++++++++++ src/all_types.hpp | 1 + src/ir.cpp | 27 ++++++++++++++------------- 3 files changed, 41 insertions(+), 13 deletions(-) diff --git a/doc/langref.html.in b/doc/langref.html.in index 31d923e84ba1de290574891fac74b158693726a7..97263347c752758113f6b3acbac22de25653a4c2 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -1918,6 +1918,32 @@ test "linked list" { assert(list2.first.?.data == 1234); } {#code_end#} + {#header_open|struct naming#} +

Since all structs are anonymous, Zig infers the type name based on a few rules.

+ + {#code_begin|exe|struct_name#} +const std = @import("std"); + +pub fn main() void { + const Foo = struct {}; + std.debug.warn("variable: {}\n", @typeName(Foo)); + std.debug.warn("anonymous: {}\n", @typeName(struct {})); + std.debug.warn("function: {}\n", @typeName(List(i32))); +} + +fn List(comptime T: type) type { + return struct { + x: T, + }; +} + {#code_end#} + {#header_close#} {#see_also|comptime|@fieldParentPtr#} {#header_close#} {#header_open|enum#} diff --git a/src/all_types.hpp b/src/all_types.hpp index 6f0dd9baacb35931f3f6a6b6ed6f6c3d20abf369..d580191afe9b787b5eedc1d4f9f222c3cec73d12 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -43,6 +43,7 @@ struct IrAnalyze; struct IrExecutable { ZigList basic_block_list; Buf *name; + FnTableEntry *name_fn; size_t mem_slot_count; size_t next_debug_id; size_t *backward_branch_count; diff --git a/src/ir.cpp b/src/ir.cpp index 2c3fadfc2dda65e6ec44c99e6f3bd131bcb46ae7..5d1bbe3c08323f96ebb35c0ae18f7f748dfd868d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3186,7 +3186,11 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node, { IrInstruction *return_value; if (expr_node) { + // Temporarily set this so that if we return a type it gets the name of the function + FnTableEntry *prev_name_fn = irb->exec->name_fn; + irb->exec->name_fn = exec_fn_entry(irb->exec); return_value = ir_gen_node(irb, expr_node, scope); + irb->exec->name_fn = prev_name_fn; if (return_value == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; } else { @@ -6481,20 +6485,17 @@ static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *o static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, AstNode *source_node) { if (exec->name) { return exec->name; + } else if (exec->name_fn != nullptr) { + Buf *name = buf_alloc(); + buf_append_buf(name, &exec->name_fn->symbol_name); + buf_appendf(name, "("); + render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope); + buf_appendf(name, ")"); + return name; } else { - FnTableEntry *fn_entry = exec_fn_entry(exec); - if (fn_entry) { - Buf *name = buf_alloc(); - buf_append_buf(name, &fn_entry->symbol_name); - buf_appendf(name, "("); - render_instance_name_recursive(codegen, name, &fn_entry->fndef_scope->base, exec->begin_scope); - buf_appendf(name, ")"); - return name; - } else { - //Note: C-imports do not have valid location information - return buf_sprintf("(anonymous %s at %s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ")", kind_name, - (source_node->owner->path != nullptr) ? buf_ptr(source_node->owner->path) : "(null)", source_node->line + 1, source_node->column + 1); - } + //Note: C-imports do not have valid location information + return buf_sprintf("(anonymous %s at %s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ")", kind_name, + (source_node->owner->path != nullptr) ? buf_ptr(source_node->owner->path) : "(null)", source_node->line + 1, source_node->column + 1); } } -- 2.54.0