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
master
Andrew Kelley 2018-09-03 11:32:39 -04:00
parent 95636c7e5f
commit 2a9329c998
No known key found for this signature in database
GPG Key ID: 4E7CD66038A4D47C
3 changed files with 41 additions and 13 deletions

View File

@ -1918,6 +1918,32 @@ test "linked list" {
assert(list2.first.?.data == 1234);
}
{#code_end#}
{#header_open|struct naming#}
<p>Since all structs are anonymous, Zig infers the type name based on a few rules.</p>
<ul>
<li>If the struct is in the initialization expression of a variable, it gets named after
that variable.</li>
<li>If the struct is in the <code>return</code> expression, it gets named after
the function it is returning from, with the parameter values serialized.</li>
<li>Otherwise, the struct gets a same such as <code>(anonymous struct at file.zig:7:38)</code>.</li>
</ul>
{#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#}

View File

@ -43,6 +43,7 @@ struct IrAnalyze;
struct IrExecutable {
ZigList<IrBasicBlock *> basic_block_list;
Buf *name;
FnTableEntry *name_fn;
size_t mem_slot_count;
size_t next_debug_id;
size_t *backward_branch_count;

View File

@ -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);
}
}