From 67b6dd28ec70937a29176719b56457ee17b1c136 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 31 Aug 2017 16:30:46 -0400 Subject: [PATCH] allow array literals to have size and fix comptime bug --- src/all_types.hpp | 1 + src/ir.cpp | 31 ++++++++++++++++++++++--------- test/cases/array.zig | 6 ++++++ test/compile_errors.zig | 7 +++++++ 4 files changed, 36 insertions(+), 9 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index 39e6033988..9f1dc15a39 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -50,6 +50,7 @@ struct IrExecutable { size_t next_debug_id; size_t *backward_branch_count; size_t backward_branch_quota; + bool reported_quota_exceeded; bool invalid; ZigList all_labels; ZigList goto_list; diff --git a/src/ir.cpp b/src/ir.cpp index f37194a557..f8b6c4cdf7 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7604,12 +7604,13 @@ static bool ir_emit_backward_branch(IrAnalyze *ira, IrInstruction *source_instru size_t *bbc = ira->new_irb.exec->backward_branch_count; size_t quota = ira->new_irb.exec->backward_branch_quota; - // If we're already over quota, we've already given an error message for this. - if (*bbc > quota) + if (ira->new_irb.exec->reported_quota_exceeded) { return false; + } *bbc += 1; if (*bbc > quota) { + ira->new_irb.exec->reported_quota_exceeded = true; ir_add_error(ira, source_instruction, buf_sprintf("evaluation exceeded %" ZIG_PRI_usize " backwards branches", quota)); return false; } @@ -12815,10 +12816,25 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira if (container_type->id == TypeTableEntryIdStruct && !is_slice(container_type) && elem_count == 0) { return ir_analyze_container_init_fields(ira, &instruction->base, container_type, 0, nullptr); - } else if (is_slice(container_type)) { - TypeTableEntry *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry; - assert(pointer_type->id == TypeTableEntryIdPointer); - TypeTableEntry *child_type = pointer_type->data.pointer.child_type; + } else if (is_slice(container_type) || container_type->id == TypeTableEntryIdArray) { + // array is same as slice init but we make a compile error if the length is wrong + TypeTableEntry *child_type; + if (container_type->id == TypeTableEntryIdArray) { + child_type = container_type->data.array.child_type; + if (container_type->data.array.len != elem_count) { + TypeTableEntry *literal_type = get_array_type(ira->codegen, child_type, elem_count); + + ir_add_error(ira, &instruction->base, + buf_sprintf("expected %s literal, found %s literal", + buf_ptr(&container_type->name), buf_ptr(&literal_type->name))); + return ira->codegen->builtin_types.entry_invalid; + } + } else { + TypeTableEntry *pointer_type = container_type->data.structure.fields[slice_ptr_index].type_entry; + assert(pointer_type->id == TypeTableEntryIdPointer); + child_type = pointer_type->data.pointer.child_type; + } + TypeTableEntry *fixed_size_array_type = get_array_type(ira->codegen, child_type, elem_count); ConstExprValue const_val = {}; @@ -12882,9 +12898,6 @@ static TypeTableEntry *ir_analyze_instruction_container_init_list(IrAnalyze *ira container_type_value, elem_count, new_items); ir_add_alloca(ira, new_instruction, fixed_size_array_type); return fixed_size_array_type; - } else if (container_type->id == TypeTableEntryIdArray) { - // same as slice init but we make a compile error if the length is wrong - zig_panic("TODO array container init"); } else if (container_type->id == TypeTableEntryIdVoid) { if (elem_count != 0) { ir_add_error_node(ira, instruction->base.source_node, diff --git a/test/cases/array.zig b/test/cases/array.zig index 7785afecc6..07448ecd22 100644 --- a/test/cases/array.zig +++ b/test/cases/array.zig @@ -80,3 +80,9 @@ test "set global var array via slice embedded in struct" { assert(s_array[1].b == 2); assert(s_array[2].b == 3); } + +test "array literal with specified size" { + var array = [2]u8{1, 2}; + assert(array[0] == 1); + assert(array[1] == 2); +} diff --git a/test/compile_errors.zig b/test/compile_errors.zig index cd6b0be8cd..81d1361aec 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2061,4 +2061,11 @@ pub fn addCases(cases: &tests.CompileErrorContext) { , ".tmp_source.zig:4:23: error: expected pointer alignment of at least 4, found 1"); + cases.add("wrong size to an array literal", + \\comptime { + \\ const array = [2]u8{1, 2, 3}; + \\} + , + ".tmp_source.zig:2:24: error: expected [2]u8 literal, found [3]u8 literal"); + }