From 24cfa3534f31f503b3c0310b935e4fc654e02cda Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 13 Jun 2019 16:51:26 -0400 Subject: [PATCH] allow comptime array literals casted to slices --- src/all_types.hpp | 2 +- src/ir.cpp | 21 +++++++++++---------- test/stage1/behavior/array.zig | 20 ++++++++++---------- 3 files changed, 22 insertions(+), 21 deletions(-) diff --git a/src/all_types.hpp b/src/all_types.hpp index 4d87b7e4b0..d81fec19e9 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -2555,8 +2555,8 @@ struct IrInstructionElemPtr { IrInstruction *array_ptr; IrInstruction *elem_index; PtrLen ptr_len; - bool safety_check_on; bool initializing; + bool safety_check_on; }; struct IrInstructionVarPtr { diff --git a/src/ir.cpp b/src/ir.cpp index d4158e1ce7..7eafedf230 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -16833,7 +16833,7 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct if (ptr_field->data.x_ptr.special == ConstPtrSpecialHardCodedAddr) { IrInstruction *result = ir_build_elem_ptr(&ira->new_irb, elem_ptr_instruction->base.scope, elem_ptr_instruction->base.source_node, array_ptr, casted_elem_index, false, - elem_ptr_instruction->ptr_len, true); + elem_ptr_instruction->ptr_len, false); result->value.type = return_type; return result; } @@ -16898,15 +16898,6 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct } } } - - if (is_slice(array_type) && elem_ptr_instruction->initializing) { - // we need a pointer to an element inside a slice. but we're initializing an array. - // this means that the slice isn't actually pointing at anything. - ir_add_error(ira, &elem_ptr_instruction->base, - buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", - buf_ptr(&array_type->name))); - return ira->codegen->invalid_instruction; - } } else { // runtime known element index switch (type_requires_comptime(ira->codegen, return_type)) { @@ -19053,6 +19044,16 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, IrInstruction *result_loc = instruction->result_loc->child; if (type_is_invalid(result_loc->value.type)) return result_loc; + ir_assert(result_loc->value.type->id == ZigTypeIdPointer, &instruction->base); + ZigType *result_elem_type = result_loc->value.type->data.pointer.child_type; + if (is_slice(result_elem_type)) { + ErrorMsg *msg = ir_add_error(ira, &instruction->base, + buf_sprintf("runtime-initialized array cannot be casted to slice type '%s'", + buf_ptr(&result_elem_type->name))); + add_error_note(ira->codegen, msg, first_non_const_instruction->source_node, + buf_sprintf("this value is not comptime-known")); + return ira->codegen->invalid_instruction; + } return ir_get_deref(ira, &instruction->base, result_loc, nullptr); } else if (container_type->id == ZigTypeIdVoid) { if (elem_count != 0) { diff --git a/test/stage1/behavior/array.zig b/test/stage1/behavior/array.zig index 8a64730c64..49f9885702 100644 --- a/test/stage1/behavior/array.zig +++ b/test/stage1/behavior/array.zig @@ -222,17 +222,17 @@ test "double nested array to const slice cast in array literal" { const S = struct { fn entry(two: i32) void { const cases = [_][]const []const i32{ - &[_][]const i32{&[_]i32{1}}, - &[_][]const i32{&[_]i32{ 2, 3 }}, - &[_][]const i32{ - &[_]i32{4}, - &[_]i32{ 5, 6, 7 }, + [_][]const i32{[_]i32{1}}, + [_][]const i32{[_]i32{ 2, 3 }}, + [_][]const i32{ + [_]i32{4}, + [_]i32{ 5, 6, 7 }, }, }; check(cases); const cases2 = [_][]const i32{ - &[_]i32{1}, + [_]i32{1}, &[_]i32{ two, 3 }, }; expect(cases2.len == 2); @@ -243,11 +243,11 @@ test "double nested array to const slice cast in array literal" { expect(cases2[1][1] == 3); const cases3 = [_][]const []const i32{ - &[_][]const i32{&[_]i32{1}}, + [_][]const i32{[_]i32{1}}, &[_][]const i32{&[_]i32{ two, 3 }}, - &[_][]const i32{ - &[_]i32{4}, - &[_]i32{ 5, 6, 7 }, + [_][]const i32{ + [_]i32{4}, + [_]i32{ 5, 6, 7 }, }, }; check(cases3);