Commit 24cfa3534f

Andrew Kelley <andrew@ziglang.org>
2019-06-13 22:51:26
allow comptime array literals casted to slices
1 parent 3cbe827
Changed files (3)
src
test
stage1
behavior
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 {
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) {
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);