authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-03 11:32:39-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-03 11:32:39-04:00
log2a9329c9988430cfa11a8bb4b02da0dce8749028
tree3d28b4c95037be90a5dbe735728b2b07184dbd96
parent95636c7e5ff6ad0eeb768a2a0a1d7533b5872e20
signaturelock-open Commit is signed but in an unrecognized format.

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

3 files changed, 41 insertions(+), 13 deletions(-)

doc/langref.html.in+26
...@@ -1918,6 +1918,32 @@ test "linked list" {...@@ -1918,6 +1918,32 @@ test "linked list" {
1918 assert(list2.first.?.data == 1234);1918 assert(list2.first.?.data == 1234);
1919}1919}
1920 {#code_end#}1920 {#code_end#}
1921 {#header_open|struct naming#}
1922 <p>Since all structs are anonymous, Zig infers the type name based on a few rules.</p>
1923 <ul>
1924 <li>If the struct is in the initialization expression of a variable, it gets named after
1925 that variable.</li>
1926 <li>If the struct is in the <code>return</code> expression, it gets named after
1927 the function it is returning from, with the parameter values serialized.</li>
1928 <li>Otherwise, the struct gets a same such as <code>(anonymous struct at file.zig:7:38)</code>.</li>
1929 </ul>
1930 {#code_begin|exe|struct_name#}
1931const std = @import("std");
1932
1933pub fn main() void {
1934 const Foo = struct {};
1935 std.debug.warn("variable: {}\n", @typeName(Foo));
1936 std.debug.warn("anonymous: {}\n", @typeName(struct {}));
1937 std.debug.warn("function: {}\n", @typeName(List(i32)));
1938}
1939
1940fn List(comptime T: type) type {
1941 return struct {
1942 x: T,
1943 };
1944}
1945 {#code_end#}
1946 {#header_close#}
1921 {#see_also|comptime|@fieldParentPtr#}1947 {#see_also|comptime|@fieldParentPtr#}
1922 {#header_close#}1948 {#header_close#}
1923 {#header_open|enum#}1949 {#header_open|enum#}
src/all_types.hpp+1
...@@ -43,6 +43,7 @@ struct IrAnalyze;...@@ -43,6 +43,7 @@ struct IrAnalyze;
43struct IrExecutable {43struct IrExecutable {
44 ZigList<IrBasicBlock *> basic_block_list;44 ZigList<IrBasicBlock *> basic_block_list;
45 Buf *name;45 Buf *name;
46 FnTableEntry *name_fn;
46 size_t mem_slot_count;47 size_t mem_slot_count;
47 size_t next_debug_id;48 size_t next_debug_id;
48 size_t *backward_branch_count;49 size_t *backward_branch_count;
src/ir.cpp+14-13
...@@ -3186,7 +3186,11 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,...@@ -3186,7 +3186,11 @@ static IrInstruction *ir_gen_return(IrBuilder *irb, Scope *scope, AstNode *node,
3186 {3186 {
3187 IrInstruction *return_value;3187 IrInstruction *return_value;
3188 if (expr_node) {3188 if (expr_node) {
3189 // Temporarily set this so that if we return a type it gets the name of the function
3190 FnTableEntry *prev_name_fn = irb->exec->name_fn;
3191 irb->exec->name_fn = exec_fn_entry(irb->exec);
3189 return_value = ir_gen_node(irb, expr_node, scope);3192 return_value = ir_gen_node(irb, expr_node, scope);
3193 irb->exec->name_fn = prev_name_fn;
3190 if (return_value == irb->codegen->invalid_instruction)3194 if (return_value == irb->codegen->invalid_instruction)
3191 return irb->codegen->invalid_instruction;3195 return irb->codegen->invalid_instruction;
3192 } else {3196 } else {
...@@ -6481,20 +6485,17 @@ static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *o...@@ -6481,20 +6485,17 @@ static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *o
6481static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, AstNode *source_node) {6485static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name, AstNode *source_node) {
6482 if (exec->name) {6486 if (exec->name) {
6483 return exec->name;6487 return exec->name;
6488 } else if (exec->name_fn != nullptr) {
6489 Buf *name = buf_alloc();
6490 buf_append_buf(name, &exec->name_fn->symbol_name);
6491 buf_appendf(name, "(");
6492 render_instance_name_recursive(codegen, name, &exec->name_fn->fndef_scope->base, exec->begin_scope);
6493 buf_appendf(name, ")");
6494 return name;
6484 } else {6495 } else {
6485 FnTableEntry *fn_entry = exec_fn_entry(exec);6496 //Note: C-imports do not have valid location information
6486 if (fn_entry) {6497 return buf_sprintf("(anonymous %s at %s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ")", kind_name,
6487 Buf *name = buf_alloc();6498 (source_node->owner->path != nullptr) ? buf_ptr(source_node->owner->path) : "(null)", source_node->line + 1, source_node->column + 1);
6488 buf_append_buf(name, &fn_entry->symbol_name);
6489 buf_appendf(name, "(");
6490 render_instance_name_recursive(codegen, name, &fn_entry->fndef_scope->base, exec->begin_scope);
6491 buf_appendf(name, ")");
6492 return name;
6493 } else {
6494 //Note: C-imports do not have valid location information
6495 return buf_sprintf("(anonymous %s at %s:%" ZIG_PRI_usize ":%" ZIG_PRI_usize ")", kind_name,
6496 (source_node->owner->path != nullptr) ? buf_ptr(source_node->owner->path) : "(null)", source_node->line + 1, source_node->column + 1);
6497 }
6498 }6499 }
6499}6500}
65006501