authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-11 19:00:39-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-11 19:00:39-05:00
logb9482fc32d13886626692484e5a778355fa7934c
tree6e8f2a55bfb47910e50b39db4e41b3039a78767d
parenta33b9aec724dfce68889f6255a2c78572b47c92f
signaturelock-open Commit is signed but in an unrecognized format.

implement fully anonymous list literals


4 files changed, 73 insertions(+), 42 deletions(-)

src/analyze.cpp+3-9
...@@ -5857,15 +5857,9 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_...@@ -5857,15 +5857,9 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
58575857
58585858
5859ConstExprValue *create_const_vals(size_t count) {5859ConstExprValue *create_const_vals(size_t count) {
5860 return realloc_const_vals(nullptr, 0, count);5860 ConstGlobalRefs *global_refs = allocate<ConstGlobalRefs>(count, "ConstGlobalRefs");
5861}5861 ConstExprValue *vals = allocate<ConstExprValue>(count, "ConstExprValue");
58625862 for (size_t i = 0; i < count; i += 1) {
5863ConstExprValue *realloc_const_vals(ConstExprValue *base, size_t old_count, size_t new_count) {
5864 ConstGlobalRefs *old_global_refs = (base == nullptr) ? nullptr : base->global_refs;
5865 ConstGlobalRefs *global_refs = reallocate<ConstGlobalRefs>(old_global_refs, old_count,
5866 new_count, "ConstGlobalRefs");
5867 ConstExprValue *vals = reallocate<ConstExprValue>(base, old_count, new_count, "ConstExprValue");
5868 for (size_t i = old_count; i < new_count; i += 1) {
5869 vals[i].global_refs = &global_refs[i];5863 vals[i].global_refs = &global_refs[i];
5870 }5864 }
5871 return vals;5865 return vals;
src/analyze.hpp-1
...@@ -175,7 +175,6 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde...@@ -175,7 +175,6 @@ void init_const_arg_tuple(CodeGen *g, ConstExprValue *const_val, size_t arg_inde
175ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);175ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_t arg_index_end);
176176
177ConstExprValue *create_const_vals(size_t count);177ConstExprValue *create_const_vals(size_t count);
178ConstExprValue *realloc_const_vals(ConstExprValue *base, size_t old_count, size_t new_count);
179178
180ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);179ZigType *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
181void expand_undef_array(CodeGen *g, ConstExprValue *const_val);180void expand_undef_array(CodeGen *g, ConstExprValue *const_val);
src/ir.cpp+53-32
...@@ -204,6 +204,8 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de...@@ -204,6 +204,8 @@ static ResultLocCast *ir_build_cast_result_loc(IrBuilder *irb, IrInstruction *de
204 ResultLoc *parent_result_loc);204 ResultLoc *parent_result_loc);
205static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr,205static IrInstruction *ir_analyze_struct_field_ptr(IrAnalyze *ira, IrInstruction *source_instr,
206 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing);206 TypeStructField *field, IrInstruction *struct_ptr, ZigType *struct_type, bool initializing);
207static IrInstruction *ir_analyze_inferred_field_ptr(IrAnalyze *ira, Buf *field_name,
208 IrInstruction *source_instr, IrInstruction *container_ptr, ZigType *container_type);
207209
208static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {210static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
209 assert(get_src_ptr_type(const_val->type) != nullptr);211 assert(get_src_ptr_type(const_val->type) != nullptr);
...@@ -16329,16 +16331,14 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -16329,16 +16331,14 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
16329 uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count;16331 uint32_t old_field_count = isf->inferred_struct_type->data.structure.src_field_count;
16330 uint32_t new_field_count = old_field_count + 1;16332 uint32_t new_field_count = old_field_count + 1;
16331 isf->inferred_struct_type->data.structure.src_field_count = new_field_count;16333 isf->inferred_struct_type->data.structure.src_field_count = new_field_count;
16332 // This thing with max(x, 16) is a hack to allow this functionality to work without16334 if (new_field_count > 16) {
16333 // modifying the ConstExprValue layout of structs. That reworking needs to be16335 // This thing with 16 is a hack to allow this functionality to work without
16334 // done, but this hack lets us do it separately, in the future.16336 // modifying the ConstExprValue layout of structs. That reworking needs to be
16335 TypeStructField *prev_ptr = isf->inferred_struct_type->data.structure.fields;16337 // done, but this hack lets us do it separately, in the future.
16336 isf->inferred_struct_type->data.structure.fields = reallocate(16338 zig_panic("TODO need to rework the layout of ZigTypeStruct. This realloc would have caused invalid pointer references");
16337 isf->inferred_struct_type->data.structure.fields,16339 }
16338 (old_field_count == 0) ? 0 : max(old_field_count, 16u),16340 if (isf->inferred_struct_type->data.structure.fields == nullptr) {
16339 max(new_field_count, 16u));16341 isf->inferred_struct_type->data.structure.fields = allocate<TypeStructField>(16);
16340 if (prev_ptr != nullptr && prev_ptr != isf->inferred_struct_type->data.structure.fields) {
16341 zig_panic("TODO need to rework the layout of ZigTypeStruct. this realloc would have caused invalid pointer references");
16342 }16342 }
1634316343
16344 // This reference can't live long, don't keep it around outside this block.16344 // This reference can't live long, don't keep it around outside this block.
...@@ -16368,15 +16368,14 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -16368,15 +16368,14 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
16368 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val,16368 ConstExprValue *struct_val = const_ptr_pointee(ira, ira->codegen, ptr_val,
16369 source_instr->source_node);16369 source_instr->source_node);
16370 struct_val->special = ConstValSpecialStatic;16370 struct_val->special = ConstValSpecialStatic;
16371 ConstExprValue *prev_ptr = struct_val->data.x_struct.fields;16371 if (new_field_count > 16) {
16372 // This thing with max(x, 16) is a hack to allow this functionality to work without16372 // This thing with 16 is a hack to allow this functionality to work without
16373 // modifying the ConstExprValue layout of structs. That reworking needs to be16373 // modifying the ConstExprValue layout of structs. That reworking needs to be
16374 // done, but this hack lets us do it separately, in the future.16374 // done, but this hack lets us do it separately, in the future.
16375 struct_val->data.x_struct.fields = realloc_const_vals(struct_val->data.x_struct.fields,16375 zig_panic("TODO need to rework the layout of ConstExprValue for structs. This realloc would have caused invalid pointer references");
16376 (old_field_count == 0) ? 0 : max(old_field_count, 16u),16376 }
16377 max(new_field_count, 16u));16377 if (struct_val->data.x_struct.fields == nullptr) {
16378 if (prev_ptr != nullptr && prev_ptr != struct_val->data.x_struct.fields) {16378 struct_val->data.x_struct.fields = create_const_vals(16);
16379 zig_panic("TODO need to rework the layout of ConstExprValue for structs. this realloc would have caused invalid pointer references");
16380 }16379 }
1638116380
16382 ConstExprValue *field_val = &struct_val->data.x_struct.fields[old_field_count];16381 ConstExprValue *field_val = &struct_val->data.x_struct.fields[old_field_count];
...@@ -17893,6 +17892,19 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct...@@ -17893,6 +17892,19 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct
17893 } else if (array_type->id == ZigTypeIdVector) {17892 } else if (array_type->id == ZigTypeIdVector) {
17894 // This depends on whether the element index is comptime, so it is computed later.17893 // This depends on whether the element index is comptime, so it is computed later.
17895 return_type = nullptr;17894 return_type = nullptr;
17895 } else if (elem_ptr_instruction->init_array_type_source_node != nullptr &&
17896 array_type->id == ZigTypeIdStruct &&
17897 array_type->data.structure.resolve_status == ResolveStatusBeingInferred)
17898 {
17899 ZigType *usize = ira->codegen->builtin_types.entry_usize;
17900 IrInstruction *casted_elem_index = ir_implicit_cast(ira, elem_index, usize);
17901 if (casted_elem_index == ira->codegen->invalid_instruction)
17902 return ira->codegen->invalid_instruction;
17903 ir_assert(instr_is_comptime(casted_elem_index), &elem_ptr_instruction->base);
17904 Buf *field_name = buf_alloc();
17905 bigint_append_buf(field_name, &casted_elem_index->value.data.x_bigint, 10);
17906 return ir_analyze_inferred_field_ptr(ira, field_name, &elem_ptr_instruction->base,
17907 array_ptr, array_type);
17896 } else {17908 } else {
17897 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,17909 ir_add_error_node(ira, elem_ptr_instruction->base.source_node,
17898 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name)));17910 buf_sprintf("array access of non-array type '%s'", buf_ptr(&array_type->name)));
...@@ -20246,8 +20258,12 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc...@@ -20246,8 +20258,12 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc
20246 TypeStructField *field = &container_type->data.structure.fields[i];20258 TypeStructField *field = &container_type->data.structure.fields[i];
20247 if (field->init_val == nullptr) {20259 if (field->init_val == nullptr) {
20248 // it's not memoized. time to go analyze it20260 // it's not memoized. time to go analyze it
20249 assert(field->decl_node->type == NodeTypeStructField);20261 AstNode *init_node;
20250 AstNode *init_node = field->decl_node->data.struct_field.value;20262 if (field->decl_node->type == NodeTypeStructField) {
20263 init_node = field->decl_node->data.struct_field.value;
20264 } else {
20265 init_node = nullptr;
20266 }
20251 if (init_node == nullptr) {20267 if (init_node == nullptr) {
20252 ir_add_error_node(ira, instruction->source_node,20268 ir_add_error_node(ira, instruction->source_node,
20253 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));20269 buf_sprintf("missing field: '%s'", buf_ptr(container_type->data.structure.fields[i].name)));
...@@ -20337,23 +20353,28 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,...@@ -20337,23 +20353,28 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira,
20337 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc);20353 return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr, result_loc);
20338 }20354 }
2033920355
20340 if (container_type->id != ZigTypeIdArray) {20356 if (container_type->id == ZigTypeIdArray) {
20357 ZigType *child_type = container_type->data.array.child_type;
20358 if (container_type->data.array.len != elem_count) {
20359 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
20360
20361 ir_add_error(ira, &instruction->base,
20362 buf_sprintf("expected %s literal, found %s literal",
20363 buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
20364 return ira->codegen->invalid_instruction;
20365 }
20366 } else if (container_type->id == ZigTypeIdStruct &&
20367 container_type->data.structure.resolve_status == ResolveStatusBeingInferred)
20368 {
20369 // We're now done inferring the type.
20370 container_type->data.structure.resolve_status = ResolveStatusUnstarted;
20371 } else {
20341 ir_add_error_node(ira, instruction->base.source_node,20372 ir_add_error_node(ira, instruction->base.source_node,
20342 buf_sprintf("type '%s' does not support array initialization",20373 buf_sprintf("type '%s' does not support array initialization",
20343 buf_ptr(&container_type->name)));20374 buf_ptr(&container_type->name)));
20344 return ira->codegen->invalid_instruction;20375 return ira->codegen->invalid_instruction;
20345 }20376 }
2034620377
20347 ZigType *child_type = container_type->data.array.child_type;
20348 if (container_type->data.array.len != elem_count) {
20349 ZigType *literal_type = get_array_type(ira->codegen, child_type, elem_count);
20350
20351 ir_add_error(ira, &instruction->base,
20352 buf_sprintf("expected %s literal, found %s literal",
20353 buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
20354 return ira->codegen->invalid_instruction;
20355 }
20356
20357 switch (type_has_one_possible_value(ira->codegen, container_type)) {20378 switch (type_has_one_possible_value(ira->codegen, container_type)) {
20358 case OnePossibleValueInvalid:20379 case OnePossibleValueInvalid:
20359 return ira->codegen->invalid_instruction;20380 return ira->codegen->invalid_instruction;
test/stage1/behavior/struct.zig+17
...@@ -751,3 +751,20 @@ test "fully anonymous struct" {...@@ -751,3 +751,20 @@ test "fully anonymous struct" {
751 S.doTheTest();751 S.doTheTest();
752 comptime S.doTheTest();752 comptime S.doTheTest();
753}753}
754
755test "fully anonymous list literal" {
756 const S = struct {
757 fn doTheTest() void {
758 dump(.{ @as(u32, 1234), @as(f64, 12.34), true, "hi"});
759 }
760 fn dump(args: var) void {
761 expect(args.@"0" == 1234);
762 expect(args.@"1" == 12.34);
763 expect(args.@"2");
764 expect(args.@"3"[0] == 'h');
765 expect(args.@"3"[1] == 'i');
766 }
767 };
768 S.doTheTest();
769 comptime S.doTheTest();
770}