authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-31 16:30:46-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2017-08-31 16:30:46-04:00
log67b6dd28ec70937a29176719b56457ee17b1c136
treecf6e7e1585d8cb1b56ba77ec53562f7502c5e65d
parenteb0979189be33d6d957dad5104650cb5c532055b

allow array literals to have size and fix comptime bug


4 files changed, 36 insertions(+), 9 deletions(-)

src/all_types.hpp+1
......@@ -50,6 +50,7 @@ struct IrExecutable {
5050 size_t next_debug_id;
5151 size_t *backward_branch_count;
5252 size_t backward_branch_quota;
53 bool reported_quota_exceeded;
5354 bool invalid;
5455 ZigList<LabelTableEntry *> all_labels;
5556 ZigList<IrGotoItem> goto_list;
src/ir.cpp+22-9
......@@ -7604,12 +7604,13 @@ static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instru
76047604 size_t *bbc = ira->new_irb.exec->backward_branch_count;
76057605 size_t quota = ira->new_irb.exec->backward_branch_quota;
76067606
7607 // If we're already over quota, we've already given an error message for this.
7608 if (*bbc > quota)
7607 if (ira->new_irb.exec->reported_quota_exceeded) {
76097608 return false;
7609 }
76107610
76117611 *bbc += 1;
76127612 if (*bbc > quota) {
7613 ira->new_irb.exec->reported_quota_exceeded = true;
76137614 ir_add_error(ira, source_instruction, buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", quota));
76147615 return false;
76157616 }
......@@ -12815,10 +12816,25 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
1281512816 if (container_type->id == TypeTableEntryIdStruct && !is_slice(container_type) && elem_count == 0) {
1281612817 return ir_analyze_container_init_fields(ira, &instruction->base, container_type,
1281712818 0, nullptr);
12818 } else if (is_slice(container_type)) {
12819 TypeTableEntry *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry;
12820 assert(pointer_type->id == TypeTableEntryIdPointer);
12821 TypeTableEntry *child_type = pointer_type->data.pointer.child_type;
12819 } else if (is_slice(container_type) || container_type->id == TypeTableEntryIdArray) {
12820 // array is same as slice init but we make a compile error if the length is wrong
12821 TypeTableEntry *child_type;
12822 if (container_type->id == TypeTableEntryIdArray) {
12823 child_type = container_type->data.array.child_type;
12824 if (container_type->data.array.len != elem_count) {
12825 TypeTableEntry *literal_type = get_array_type(ira->codegen, child_type, elem_count);
12826
12827 ir_add_error(ira, &instruction->base,
12828 buf_sprintf("expected %s literal, found %s literal",
12829 buf_ptr(&container_type->name), buf_ptr(&literal_type->name)));
12830 return ira->codegen->builtin_types.entry_invalid;
12831 }
12832 } else {
12833 TypeTableEntry *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry;
12834 assert(pointer_type->id == TypeTableEntryIdPointer);
12835 child_type = pointer_type->data.pointer.child_type;
12836 }
12837
1282212838 TypeTableEntry *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count);
1282312839
1282412840 ConstExprValue const_val = {};
......@@ -12882,9 +12898,6 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira
1288212898 container_type_value, elem_count, new_items);
1288312899 ir_add_alloca(ira, new_instruction, fixed_size_array_type);
1288412900 return fixed_size_array_type;
12885 } else if (container_type->id == TypeTableEntryIdArray) {
12886 // same as slice init but we make a compile error if the length is wrong
12887 zig_panic("TODO array container init");
1288812901 } else if (container_type->id == TypeTableEntryIdVoid) {
1288912902 if (elem_count != 0) {
1289012903 ir_add_error_node(ira, instruction->base.source_node,
test/cases/array.zig+6
......@@ -80,3 +80,9 @@ test "set global var array via slice embedded in struct" {
8080 assert(s_array[1].b == 2);
8181 assert(s_array[2].b == 3);
8282}
83
84test "array literal with specified size" {
85 var array = [2]u8{1, 2};
86 assert(array[0] == 1);
87 assert(array[1] == 2);
88}
test/compile_errors.zig+7
......@@ -2061,4 +2061,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) {
20612061 ,
20622062 ".tmp_source.zig:4:23: error: expected pointer alignment of at least 4, found 1");
20632063
2064 cases.add("wrong size to an array literal",
2065 \\comptime {
2066 \\ const array = [2]u8{1, 2, 3};
2067 \\}
2068 ,
2069 ".tmp_source.zig:2:24: error: expected [2]u8 literal, found [3]u8 literal");
2070
20642071}