authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-10 21:58:05-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-11 13:11:58-05:00
log5b279434986b18d07ceec217c5c402a589ccc0b4
treeeac7bb2993f594bb5471633a92671d9b63833b27
parentde30438ed2efb909538f3177cced441b57eb1a5d
signaturelock-open Commit is signed but in an unrecognized format.

implement anon struct literal syntax

This implements stage1 parser support for anonymous struct literal syntax (see #685), as well as semantic analysis support for anonymous struct literals and anonymous list literals (see #208). The semantic analysis works when there is a type coercion in the result location; inferring the struct type based on the values in the literal is not implemented yet. Also remaining to do is zig fmt support for this new syntax and documentation updates.

9 files changed, 174 insertions(+), 120 deletions(-)

lib/std/builtin.zig+2-31
......@@ -90,40 +90,11 @@ pub const Mode = enum {
9090 ReleaseSmall,
9191};
9292
93/// This data structure is used by the Zig language code generation and
94/// therefore must be kept in sync with the compiler implementation.
95pub const TypeId = enum {
96 Type,
97 Void,
98 Bool,
99 NoReturn,
100 Int,
101 Float,
102 Pointer,
103 Array,
104 Struct,
105 ComptimeFloat,
106 ComptimeInt,
107 Undefined,
108 Null,
109 Optional,
110 ErrorUnion,
111 ErrorSet,
112 Enum,
113 Union,
114 Fn,
115 BoundFn,
116 ArgTuple,
117 Opaque,
118 Frame,
119 AnyFrame,
120 Vector,
121 EnumLiteral,
122};
93pub const TypeId = @TagType(TypeInfo);
12394
12495/// This data structure is used by the Zig language code generation and
12596/// therefore must be kept in sync with the compiler implementation.
126pub const TypeInfo = union(TypeId) {
97pub const TypeInfo = union(enum) {
12798 Type: void,
12899 Void: void,
129100 Bool: void,
src/all_types.hpp+4-3
......@@ -1237,6 +1237,7 @@ struct TypeStructField {
12371237enum ResolveStatus {
12381238 ResolveStatusUnstarted,
12391239 ResolveStatusInvalid,
1240 ResolveStatusBeingInferred,
12401241 ResolveStatusZeroBitsKnown,
12411242 ResolveStatusAlignmentKnown,
12421243 ResolveStatusSizeKnown,
......@@ -1285,6 +1286,7 @@ struct ZigTypeStruct {
12851286 bool requires_comptime;
12861287 bool resolve_loop_flag_zero_bits;
12871288 bool resolve_loop_flag_other;
1289 bool is_inferred;
12881290};
12891291
12901292struct ZigTypeOptional {
......@@ -2812,7 +2814,7 @@ struct IrInstructionElemPtr {
28122814
28132815 IrInstruction *array_ptr;
28142816 IrInstruction *elem_index;
2815 IrInstruction *init_array_type;
2817 AstNode *init_array_type_source_node;
28162818 PtrLen ptr_len;
28172819 bool safety_check_on;
28182820};
......@@ -2909,11 +2911,11 @@ struct IrInstructionResizeSlice {
29092911struct IrInstructionContainerInitList {
29102912 IrInstruction base;
29112913
2912 IrInstruction *container_type;
29132914 IrInstruction *elem_type;
29142915 size_t item_count;
29152916 IrInstruction **elem_result_loc_list;
29162917 IrInstruction *result_loc;
2918 AstNode *init_array_type_source_node;
29172919};
29182920
29192921struct IrInstructionContainerInitFieldsField {
......@@ -2926,7 +2928,6 @@ struct IrInstructionContainerInitFieldsField {
29262928struct IrInstructionContainerInitFields {
29272929 IrInstruction base;
29282930
2929 IrInstruction *container_type;
29302931 size_t field_count;
29312932 IrInstructionContainerInitFieldsField *fields;
29322933 IrInstruction *result_loc;
src/analyze.cpp+8-2
......@@ -140,7 +140,6 @@ void init_scope(CodeGen *g, Scope *dest, ScopeId id, AstNode *source_node, Scope
140140static ScopeDecls *create_decls_scope(CodeGen *g, AstNode *node, Scope *parent, ZigType *container_type,
141141 ZigType *import, Buf *bare_name)
142142{
143 assert(node == nullptr || node->type == NodeTypeContainerDecl || node->type == NodeTypeFnCallExpr);
144143 ScopeDecls *scope = allocate<ScopeDecls>(1);
145144 init_scope(g, &scope->base, ScopeIdDecls, node, parent);
146145 scope->decl_table.init(4);
......@@ -346,6 +345,8 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
346345 switch (status) {
347346 case ResolveStatusInvalid:
348347 zig_unreachable();
348 case ResolveStatusBeingInferred:
349 zig_unreachable();
349350 case ResolveStatusUnstarted:
350351 case ResolveStatusZeroBitsKnown:
351352 return true;
......@@ -362,6 +363,8 @@ bool type_is_resolved(ZigType *type_entry, ResolveStatus status) {
362363 switch (status) {
363364 case ResolveStatusInvalid:
364365 zig_unreachable();
366 case ResolveStatusBeingInferred:
367 zig_unreachable();
365368 case ResolveStatusUnstarted:
366369 return true;
367370 case ResolveStatusZeroBitsKnown:
......@@ -6132,6 +6135,8 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
61326135 continue;
61336136 if (instruction->ref_count == 0)
61346137 continue;
6138 if ((err = type_resolve(g, instruction->value.type, ResolveStatusZeroBitsKnown)))
6139 return ErrorSemanticAnalyzeFail;
61356140 if (!type_has_bits(instruction->value.type))
61366141 continue;
61376142 if (scope_needs_spill(instruction->scope)) {
......@@ -6271,6 +6276,8 @@ Error type_resolve(CodeGen *g, ZigType *ty, ResolveStatus status) {
62716276 switch (status) {
62726277 case ResolveStatusUnstarted:
62736278 return ErrorNone;
6279 case ResolveStatusBeingInferred:
6280 zig_unreachable();
62746281 case ResolveStatusInvalid:
62756282 zig_unreachable();
62766283 case ResolveStatusZeroBitsKnown:
......@@ -9038,4 +9045,3 @@ Error analyze_import(CodeGen *g, ZigType *source_import, Buf *import_target_str,
90389045 *out_import = add_source_file(g, target_package, resolved_path, import_code, source_kind);
90399046 return ErrorNone;
90409047}
9041
src/ast_render.cpp+3-1
......@@ -821,7 +821,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
821821 break;
822822 }
823823 case NodeTypeContainerInitExpr:
824 render_node_ungrouped(ar, node->data.container_init_expr.type);
824 if (node->data.container_init_expr.type != nullptr) {
825 render_node_ungrouped(ar, node->data.container_init_expr.type);
826 }
825827 if (node->data.container_init_expr.kind == ContainerInitKindStruct) {
826828 fprintf(ar->f, "{\n");
827829 ar->indent += ar->indent_size;
src/ir.cpp+129-75
......@@ -1350,18 +1350,17 @@ static IrInstruction *ir_build_return_ptr(IrAnalyze *ira, IrInstruction *source_
13501350
13511351static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node,
13521352 IrInstruction *array_ptr, IrInstruction *elem_index, bool safety_check_on, PtrLen ptr_len,
1353 IrInstruction *init_array_type)
1353 AstNode *init_array_type_source_node)
13541354{
13551355 IrInstructionElemPtr *instruction = ir_build_instruction<IrInstructionElemPtr>(irb, scope, source_node);
13561356 instruction->array_ptr = array_ptr;
13571357 instruction->elem_index = elem_index;
13581358 instruction->safety_check_on = safety_check_on;
13591359 instruction->ptr_len = ptr_len;
1360 instruction->init_array_type = init_array_type;
1360 instruction->init_array_type_source_node = init_array_type_source_node;
13611361
13621362 ir_ref_instruction(array_ptr, irb->current_basic_block);
13631363 ir_ref_instruction(elem_index, irb->current_basic_block);
1364 if (init_array_type != nullptr) ir_ref_instruction(init_array_type, irb->current_basic_block);
13651364
13661365 return &instruction->base;
13671366}
......@@ -1575,17 +1574,16 @@ static IrInstruction *ir_build_un_op(IrBuilder *irb, Scope *scope, AstNode *sour
15751574}
15761575
15771576static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope, AstNode *source_node,
1578 IrInstruction *container_type, size_t item_count, IrInstruction **elem_result_loc_list,
1579 IrInstruction *result_loc)
1577 size_t item_count, IrInstruction **elem_result_loc_list, IrInstruction *result_loc,
1578 AstNode *init_array_type_source_node)
15801579{
15811580 IrInstructionContainerInitList *container_init_list_instruction =
15821581 ir_build_instruction<IrInstructionContainerInitList>(irb, scope, source_node);
1583 container_init_list_instruction->container_type = container_type;
15841582 container_init_list_instruction->item_count = item_count;
15851583 container_init_list_instruction->elem_result_loc_list = elem_result_loc_list;
15861584 container_init_list_instruction->result_loc = result_loc;
1585 container_init_list_instruction->init_array_type_source_node = init_array_type_source_node;
15871586
1588 ir_ref_instruction(container_type, irb->current_basic_block);
15891587 for (size_t i = 0; i < item_count; i += 1) {
15901588 ir_ref_instruction(elem_result_loc_list[i], irb->current_basic_block);
15911589 }
......@@ -1595,17 +1593,14 @@ static IrInstruction *ir_build_container_init_list(IrBuilder *irb, Scope *scope,
15951593}
15961594
15971595static IrInstruction *ir_build_container_init_fields(IrBuilder *irb, Scope *scope, AstNode *source_node,
1598 IrInstruction *container_type, size_t field_count, IrInstructionContainerInitFieldsField *fields,
1599 IrInstruction *result_loc)
1596 size_t field_count, IrInstructionContainerInitFieldsField *fields, IrInstruction *result_loc)
16001597{
16011598 IrInstructionContainerInitFields *container_init_fields_instruction =
16021599 ir_build_instruction<IrInstructionContainerInitFields>(irb, scope, source_node);
1603 container_init_fields_instruction->container_type = container_type;
16041600 container_init_fields_instruction->field_count = field_count;
16051601 container_init_fields_instruction->fields = fields;
16061602 container_init_fields_instruction->result_loc = result_loc;
16071603
1608 ir_ref_instruction(container_type, irb->current_basic_block);
16091604 for (size_t i = 0; i < field_count; i += 1) {
16101605 ir_ref_instruction(fields[i].result_loc, irb->current_basic_block);
16111606 }
......@@ -3084,7 +3079,7 @@ static IrInstruction *ir_build_resolve_result(IrBuilder *irb, Scope *scope, AstN
30843079 instruction->result_loc = result_loc;
30853080 instruction->ty = ty;
30863081
3087 ir_ref_instruction(ty, irb->current_basic_block);
3082 if (ty != nullptr) ir_ref_instruction(ty, irb->current_basic_block);
30883083
30893084 return &instruction->base;
30903085}
......@@ -6127,28 +6122,42 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
61276122 AstNodeContainerInitExpr *container_init_expr = &node->data.container_init_expr;
61286123 ContainerInitKind kind = container_init_expr->kind;
61296124
6130 IrInstruction *container_type = nullptr;
6131 IrInstruction *elem_type = nullptr;
6132 if (container_init_expr->type->type == NodeTypeInferredArrayType) {
6133 elem_type = ir_gen_node(irb, container_init_expr->type->data.inferred_array_type.child_type, scope);
6134 if (elem_type == irb->codegen->invalid_instruction)
6135 return elem_type;
6136 } else {
6137 container_type = ir_gen_node(irb, container_init_expr->type, scope);
6138 if (container_type == irb->codegen->invalid_instruction)
6139 return container_type;
6140 }
6141
6142 switch (kind) {
6143 case ContainerInitKindStruct: {
6144 if (elem_type != nullptr) {
6125 ResultLocCast *result_loc_cast = nullptr;
6126 ResultLoc *child_result_loc;
6127 AstNode *init_array_type_source_node;
6128 if (container_init_expr->type != nullptr) {
6129 IrInstruction *container_type;
6130 if (container_init_expr->type->type == NodeTypeInferredArrayType) {
6131 if (kind == ContainerInitKindStruct) {
61456132 add_node_error(irb->codegen, container_init_expr->type,
61466133 buf_sprintf("initializing array with struct syntax"));
61476134 return irb->codegen->invalid_instruction;
61486135 }
6136 IrInstruction *elem_type = ir_gen_node(irb,
6137 container_init_expr->type->data.inferred_array_type.child_type, scope);
6138 if (elem_type == irb->codegen->invalid_instruction)
6139 return elem_type;
6140 size_t item_count = container_init_expr->entries.length;
6141 IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count);
6142 container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type);
6143 } else {
6144 container_type = ir_gen_node(irb, container_init_expr->type, scope);
6145 if (container_type == irb->codegen->invalid_instruction)
6146 return container_type;
6147 }
6148
6149 result_loc_cast = ir_build_cast_result_loc(irb, container_type, parent_result_loc);
6150 child_result_loc = &result_loc_cast->base;
6151 init_array_type_source_node = container_type->source_node;
6152 } else {
6153 child_result_loc = parent_result_loc;
6154 init_array_type_source_node = parent_result_loc->source_instruction->source_node;
6155 }
61496156
6150 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc,
6151 container_type);
6157 switch (kind) {
6158 case ContainerInitKindStruct: {
6159 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc,
6160 nullptr);
61526161
61536162 size_t field_count = container_init_expr->entries.length;
61546163 IrInstructionContainerInitFieldsField *fields = allocate<IrInstructionContainerInitFieldsField>(field_count);
......@@ -6176,29 +6185,27 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
61766185 fields[i].source_node = entry_node;
61776186 fields[i].result_loc = field_ptr;
61786187 }
6179 IrInstruction *init_fields = ir_build_container_init_fields(irb, scope, node, container_type,
6180 field_count, fields, container_ptr);
6188 IrInstruction *result = ir_build_container_init_fields(irb, scope, node, field_count,
6189 fields, container_ptr);
61816190
6182 return ir_lval_wrap(irb, scope, init_fields, lval, parent_result_loc);
6191 if (result_loc_cast != nullptr) {
6192 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast);
6193 }
6194 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc);
61836195 }
61846196 case ContainerInitKindArray: {
61856197 size_t item_count = container_init_expr->entries.length;
61866198
6187 if (container_type == nullptr) {
6188 IrInstruction *item_count_inst = ir_build_const_usize(irb, scope, node, item_count);
6189 container_type = ir_build_array_type(irb, scope, node, item_count_inst, elem_type);
6190 }
6191
6192 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, parent_result_loc,
6193 container_type);
6199 IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, node, child_result_loc,
6200 nullptr);
61946201
61956202 IrInstruction **result_locs = allocate<IrInstruction *>(item_count);
61966203 for (size_t i = 0; i < item_count; i += 1) {
61976204 AstNode *expr_node = container_init_expr->entries.at(i);
61986205
61996206 IrInstruction *elem_index = ir_build_const_usize(irb, scope, expr_node, i);
6200 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr, elem_index,
6201 false, PtrLenSingle, container_type);
6207 IrInstruction *elem_ptr = ir_build_elem_ptr(irb, scope, expr_node, container_ptr,
6208 elem_index, false, PtrLenSingle, init_array_type_source_node);
62026209 ResultLocInstruction *result_loc_inst = allocate<ResultLocInstruction>(1);
62036210 result_loc_inst->base.id = ResultLocIdInstruction;
62046211 result_loc_inst->base.source_instruction = elem_ptr;
......@@ -6213,9 +6220,12 @@ static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, A
62136220
62146221 result_locs[i] = elem_ptr;
62156222 }
6216 IrInstruction *init_list = ir_build_container_init_list(irb, scope, node, container_type,
6217 item_count, result_locs, container_ptr);
6218 return ir_lval_wrap(irb, scope, init_list, lval, parent_result_loc);
6223 IrInstruction *result = ir_build_container_init_list(irb, scope, node, item_count,
6224 result_locs, container_ptr, init_array_type_source_node);
6225 if (result_loc_cast != nullptr) {
6226 result = ir_build_implicit_cast(irb, scope, node, result, result_loc_cast);
6227 }
6228 return ir_lval_wrap(irb, scope, result, lval, parent_result_loc);
62196229 }
62206230 }
62216231 zig_unreachable();
......@@ -7935,14 +7945,14 @@ static bool render_instance_name_recursive(CodeGen *codegen, Buf *name, Scope *o
79357945static Buf *get_anon_type_name(CodeGen *codegen, IrExecutable *exec, const char *kind_name,
79367946 Scope *scope, AstNode *source_node, Buf *out_bare_name)
79377947{
7938 if (exec->name) {
7948 if (exec != nullptr && exec->name) {
79397949 ZigType *import = get_scope_import(scope);
79407950 Buf *namespace_name = buf_alloc();
79417951 append_namespace_qualification(codegen, namespace_name, import);
79427952 buf_append_buf(namespace_name, exec->name);
79437953 buf_init_from_buf(out_bare_name, exec->name);
79447954 return namespace_name;
7945 } else if (exec->name_fn != nullptr) {
7955 } else if (exec != nullptr && exec->name_fn != nullptr) {
79467956 Buf *name = buf_alloc();
79477957 buf_append_buf(name, &exec->name_fn->symbol_name);
79487958 buf_appendf(name, "(");
......@@ -15541,11 +15551,7 @@ static bool ir_result_has_type(ResultLoc *result_loc) {
1554115551static IrInstruction *ir_resolve_no_result_loc(IrAnalyze *ira, IrInstruction *suspend_source_instr,
1554215552 ResultLoc *result_loc, ZigType *value_type, bool force_runtime, bool non_null_comptime)
1554315553{
15544 Error err;
15545
1554615554 IrInstructionAllocaGen *alloca_gen = ir_build_alloca_gen(ira, suspend_source_instr, 0, "");
15547 if ((err = type_resolve(ira->codegen, value_type, ResolveStatusZeroBitsKnown)))
15548 return ira->codegen->invalid_instruction;
1554915555 alloca_gen->base.value.type = get_pointer_to_type_extra(ira->codegen, value_type, false, false,
1555015556 PtrLenSingle, 0, 0, 0, false);
1555115557 set_up_result_loc_for_inferred_comptime(&alloca_gen->base);
......@@ -15750,6 +15756,7 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
1575015756 return casted_value;
1575115757 }
1575215758
15759 bool old_parent_result_loc_written = result_cast->parent->written;
1575315760 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, result_cast->parent,
1575415761 dest_type, casted_value, force_runtime, non_null_comptime, true);
1575515762 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
......@@ -15775,6 +15782,22 @@ static IrInstruction *ir_resolve_result_raw(IrAnalyze *ira, IrInstruction *suspe
1577515782 parent_ptr_type->data.pointer.is_const, parent_ptr_type->data.pointer.is_volatile, PtrLenSingle,
1577615783 parent_ptr_align, 0, 0, parent_ptr_type->data.pointer.allow_zero);
1577715784
15785 {
15786 // we also need to check that this cast is OK.
15787 ConstCastOnly const_cast_result = types_match_const_cast_only(ira,
15788 parent_result_loc->value.type, ptr_type,
15789 result_cast->base.source_instruction->source_node, false);
15790 if (const_cast_result.id == ConstCastResultIdInvalid)
15791 return ira->codegen->invalid_instruction;
15792 if (const_cast_result.id != ConstCastResultIdOk) {
15793 // We will not be able to provide a result location for this value. Create
15794 // a new result location.
15795 result_cast->parent->written = old_parent_result_loc_written;
15796 return ir_resolve_no_result_loc(ira, suspend_source_instr, result_loc, value_type,
15797 force_runtime, non_null_comptime);
15798 }
15799 }
15800
1577815801 result_loc->written = true;
1577915802 result_loc->resolved_loc = ir_analyze_ptr_cast(ira, suspend_source_instr, parent_result_loc,
1578015803 ptr_type, result_cast->base.source_instruction, false);
......@@ -15902,10 +15925,33 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_s
1590215925 return result_loc;
1590315926}
1590415927
15905static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira, IrInstructionResolveResult *instruction) {
15906 ZigType *implicit_elem_type = ir_resolve_type(ira, instruction->ty->child);
15907 if (type_is_invalid(implicit_elem_type))
15908 return ira->codegen->invalid_instruction;
15928static IrInstruction *ir_analyze_instruction_resolve_result(IrAnalyze *ira,
15929 IrInstructionResolveResult *instruction)
15930{
15931 ZigType *implicit_elem_type;
15932 if (instruction->ty == nullptr) {
15933 if (instruction->result_loc->id == ResultLocIdCast) {
15934 implicit_elem_type = ir_resolve_type(ira,
15935 instruction->result_loc->source_instruction->child);
15936 if (type_is_invalid(implicit_elem_type))
15937 return ira->codegen->invalid_instruction;
15938 } else {
15939 Buf *bare_name = buf_alloc();
15940 Buf *name = get_anon_type_name(ira->codegen, nullptr, container_string(ContainerKindStruct),
15941 instruction->base.scope, instruction->base.source_node, bare_name);
15942
15943 ZigType *inferred_struct_type = get_partial_container_type(ira->codegen,
15944 instruction->base.scope, ContainerKindStruct, instruction->base.source_node,
15945 buf_ptr(name), bare_name, ContainerLayoutAuto);
15946 inferred_struct_type->data.structure.is_inferred = true;
15947 inferred_struct_type->data.structure.resolve_status = ResolveStatusBeingInferred;
15948 implicit_elem_type = inferred_struct_type;
15949 }
15950 } else {
15951 implicit_elem_type = ir_resolve_type(ira, instruction->ty->child);
15952 if (type_is_invalid(implicit_elem_type))
15953 return ira->codegen->invalid_instruction;
15954 }
1590915955 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
1591015956 implicit_elem_type, nullptr, false, true, true);
1591115957 if (result_loc != nullptr)
......@@ -17837,7 +17883,9 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1783717883 if (array_ptr_val == nullptr)
1783817884 return ira->codegen->invalid_instruction;
1783917885
17840 if (array_ptr_val->special == ConstValSpecialUndef && elem_ptr_instruction->init_array_type != nullptr) {
17886 if (array_ptr_val->special == ConstValSpecialUndef &&
17887 elem_ptr_instruction->init_array_type_source_node != nullptr)
17888 {
1784117889 if (array_type->id == ZigTypeIdArray || array_type->id == ZigTypeIdVector) {
1784217890 array_ptr_val->data.x_array.special = ConstArraySpecialNone;
1784317891 array_ptr_val->data.x_array.data.s_none.elements = create_const_vals(array_type->data.array.len);
......@@ -17851,11 +17899,13 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1785117899 elem_val->parent.data.p_array.elem_index = i;
1785217900 }
1785317901 } else if (is_slice(array_type)) {
17854 ZigType *actual_array_type = ir_resolve_type(ira, elem_ptr_instruction->init_array_type->child);
17902 ir_assert(array_ptr->value.type->id == ZigTypeIdPointer, &elem_ptr_instruction->base);
17903 ZigType *actual_array_type = array_ptr->value.type->data.pointer.child_type;
17904
1785517905 if (type_is_invalid(actual_array_type))
1785617906 return ira->codegen->invalid_instruction;
1785717907 if (actual_array_type->id != ZigTypeIdArray) {
17858 ir_add_error(ira, elem_ptr_instruction->init_array_type,
17908 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,
1785917909 buf_sprintf("expected array type or [_], found slice"));
1786017910 return ira->codegen->invalid_instruction;
1786117911 }
......@@ -17879,7 +17929,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1787917929 false);
1788017930 array_ptr_val->data.x_struct.fields[slice_ptr_index].data.x_ptr.mut = ConstPtrMutInfer;
1788117931 } else {
17882 ir_add_error(ira, elem_ptr_instruction->init_array_type,
17932 ir_add_error_node(ira, elem_ptr_instruction->init_array_type_source_node,
1788317933 buf_sprintf("expected array type or [_], found '%s'",
1788417934 buf_ptr(&array_type->name)));
1788517935 return ira->codegen->invalid_instruction;
......@@ -18012,7 +18062,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1801218062 if (orig_array_ptr_val->data.x_ptr.mut == ConstPtrMutInfer) {
1801318063 result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
1801418064 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index,
18015 false, elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type);
18065 false, elem_ptr_instruction->ptr_len, nullptr);
1801618066 result->value.type = return_type;
1801718067 result->value.special = ConstValSpecialStatic;
1801818068 } else {
......@@ -18073,7 +18123,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
1807318123
1807418124 IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope,
1807518125 elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, safety_check_on,
18076 elem_ptr_instruction->ptr_len, elem_ptr_instruction->init_array_type);
18126 elem_ptr_instruction->ptr_len, nullptr);
1807718127 result->value.type = return_type;
1807818128 return result;
1807918129}
......@@ -18223,6 +18273,7 @@ static IrInstruction *ir_analyze_container_field_ptr(IrAnalyze *ira, Buf *field_
1822318273 Error err;
1822418274
1822518275 ZigType *bare_type = container_ref_type(container_type);
18276
1822618277 if ((err = type_resolve(ira->codegen, bare_type, ResolveStatusZeroBitsKnown)))
1822718278 return ira->codegen->invalid_instruction;
1822818279
......@@ -20124,14 +20175,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
2012420175static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
2012520176 IrInstructionContainerInitList *instruction)
2012620177{
20127 ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child);
20128 if (type_is_invalid(container_type))
20129 return ira->codegen->invalid_instruction;
20178 ir_assert(instruction->result_loc != nullptr, &instruction->base);
20179 IrInstruction *result_loc = instruction->result_loc->child;
20180 if (type_is_invalid(result_loc->value.type))
20181 return result_loc;
20182 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
20183
20184 ZigType *container_type = result_loc->value.type->data.pointer.child_type;
2013020185
2013120186 size_t elem_count = instruction->item_count;
2013220187
2013320188 if (is_slice(container_type)) {
20134 ir_add_error(ira, instruction->container_type,
20189 ir_add_error_node(ira, instruction->init_array_type_source_node,
2013520190 buf_sprintf("expected array type or [_], found slice"));
2013620191 return ira->codegen->invalid_instruction;
2013720192 }
......@@ -20160,12 +20215,6 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
2016020215 return ira->codegen->invalid_instruction;
2016120216 }
2016220217
20163 ir_assert(instruction->result_loc != nullptr, &instruction->base);
20164 IrInstruction *result_loc = instruction->result_loc->child;
20165 if (type_is_invalid(result_loc->value.type))
20166 return result_loc;
20167 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
20168
2016920218 ZigType *child_type = container_type->data.array.child_type;
2017020219 if (container_type->data.array.len != elem_count) {
2017120220 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
......@@ -20262,16 +20311,14 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
2026220311static IrInstruction *ir_analyze_instruction_container_init_fields(IrAnalyze *ira,
2026320312 IrInstructionContainerInitFields *instruction)
2026420313{
20265 IrInstruction *container_type_value = instruction->container_type->child;
20266 ZigType *container_type = ir_resolve_type(ira, container_type_value);
20267 if (type_is_invalid(container_type))
20268 return ira->codegen->invalid_instruction;
20269
2027020314 ir_assert(instruction->result_loc != nullptr, &instruction->base);
2027120315 IrInstruction *result_loc = instruction->result_loc->child;
2027220316 if (type_is_invalid(result_loc->value.type))
2027320317 return result_loc;
2027420318
20319 ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base);
20320 ZigType *container_type = result_loc->value.type->data.pointer.child_type;
20321
2027520322 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,
2027620323 instruction->field_count, instruction->fields, result_loc);
2027720324}
......@@ -24607,6 +24654,10 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
2460724654 ZigType *src_type = ptr->value.type;
2460824655 assert(!type_is_invalid(src_type));
2460924656
24657 if (src_type == dest_type) {
24658 return ptr;
24659 }
24660
2461024661 // We have a check for zero bits later so we use get_src_ptr_type to
2461124662 // validate src_type and dest_type.
2461224663
......@@ -24656,6 +24707,9 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
2465624707 IrInstruction *result;
2465724708 if (ptr->value.data.x_ptr.mut == ConstPtrMutInfer) {
2465824709 result = ir_build_ptr_cast_gen(ira, source_instr, dest_type, ptr, safety_check_on);
24710
24711 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusZeroBitsKnown)))
24712 return ira->codegen->invalid_instruction;
2465924713 } else {
2466024714 result = ir_const(ira, source_instr, dest_type);
2466124715 }
src/ir_print.cpp+4-4
......@@ -731,7 +731,6 @@ static void ir_print_phi(IrPrint *irp, IrInstructionPhi *phi_instruction) {
731731}
732732
733733static void ir_print_container_init_list(IrPrint *irp, IrInstructionContainerInitList *instruction) {
734 ir_print_other_instruction(irp, instruction->container_type);
735734 fprintf(irp->f, "{");
736735 if (instruction->item_count > 50) {
737736 fprintf(irp->f, "...(%" ZIG_PRI_usize " items)...", instruction->item_count);
......@@ -743,11 +742,11 @@ static void ir_print_container_init_list(IrPrint *irp, IrInstructionContainerIni
743742 ir_print_other_instruction(irp, result_loc);
744743 }
745744 }
746 fprintf(irp->f, "}");
745 fprintf(irp->f, "}result=");
746 ir_print_other_instruction(irp, instruction->result_loc);
747747}
748748
749749static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerInitFields *instruction) {
750 ir_print_other_instruction(irp, instruction->container_type);
751750 fprintf(irp->f, "{");
752751 for (size_t i = 0; i < instruction->field_count; i += 1) {
753752 IrInstructionContainerInitFieldsField *field = &instruction->fields[i];
......@@ -755,7 +754,8 @@ static void ir_print_container_init_fields(IrPrint *irp, IrInstructionContainerI
755754 fprintf(irp->f, "%s.%s = ", comma, buf_ptr(field->name));
756755 ir_print_other_instruction(irp, field->result_loc);
757756 }
758 fprintf(irp->f, "} // container init");
757 fprintf(irp->f, "}result=");
758 ir_print_other_instruction(irp, instruction->result_loc);
759759}
760760
761761static void ir_print_unreachable(IrPrint *irp, IrInstructionUnreachable *instruction) {
test/compile_errors.zig+2-2
......@@ -216,9 +216,9 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
216216 \\ const obj = AstObject{ .lhsExpr = lhsExpr };
217217 \\}
218218 ,
219 "tmp.zig:4:19: error: union 'AstObject' depends on itself",
220 "tmp.zig:2:5: note: while checking this field",
219 "tmp.zig:1:17: error: struct 'LhsExpr' depends on itself",
221220 "tmp.zig:5:5: note: while checking this field",
221 "tmp.zig:2:5: note: while checking this field",
222222 );
223223
224224 cases.add(
test/stage1/behavior/async_fn.zig+2-2
......@@ -1214,7 +1214,7 @@ test "spill target expr in a for loop" {
12141214 }
12151215
12161216 const Foo = struct {
1217 slice: []i32,
1217 slice: []const i32,
12181218 };
12191219
12201220 fn atest(foo: *Foo) i32 {
......@@ -1245,7 +1245,7 @@ test "spill target expr in a for loop, with a var decl in the loop body" {
12451245 }
12461246
12471247 const Foo = struct {
1248 slice: []i32,
1248 slice: []const i32,
12491249 };
12501250
12511251 fn atest(foo: *Foo) i32 {
test/stage1/behavior/struct.zig+20
......@@ -709,3 +709,23 @@ test "packed struct field passed to generic function" {
709709 var loaded = S.genericReadPackedField(&p.b);
710710 expect(loaded == 29);
711711}
712
713test "anonymous struct literal syntax" {
714 const S = struct {
715 const Point = struct {
716 x: i32,
717 y: i32,
718 };
719
720 fn doTheTest() void {
721 var p: Point = .{
722 .x = 1,
723 .y = 2,
724 };
725 expect(p.x == 1);
726 expect(p.y == 2);
727 }
728 };
729 S.doTheTest();
730 comptime S.doTheTest();
731}