Commit f824658e13

Andrew Kelley <andrew@ziglang.org>
2020-03-19 15:54:20
slicing sentinel-terminated slice without end
now results in a sentinel-terminated slice.
1 parent 61266d2
Changed files (2)
src
test
stage1
behavior
src/ir.cpp
@@ -26249,6 +26249,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
         end = nullptr;
     }
 
+    ZigValue *slice_sentinel_val = nullptr;
     ZigType *non_sentinel_slice_ptr_type;
     ZigType *elem_type;
 
@@ -26299,6 +26300,7 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
         }
     } else if (is_slice(array_type)) {
         ZigType *maybe_sentineled_slice_ptr_type = array_type->data.structure.fields[slice_ptr_index]->type_entry;
+        slice_sentinel_val = maybe_sentineled_slice_ptr_type->data.pointer.sentinel;
         non_sentinel_slice_ptr_type = adjust_ptr_sentinel(ira->codegen, maybe_sentineled_slice_ptr_type, nullptr);
         elem_type = non_sentinel_slice_ptr_type->data.pointer.child_type;
     } else {
@@ -26376,6 +26378,8 @@ static IrInstGen *ir_analyze_instruction_slice(IrAnalyze *ira, IrInstSrcSlice *i
                     PtrLenSingle, ptr_byte_alignment, 0, 0, false);
             goto done_with_return_type;
         }
+    } else if (array_sentinel == nullptr && end == nullptr) {
+        array_sentinel = slice_sentinel_val;
     }
     if (array_sentinel != nullptr) {
         // TODO deal with non-abi-alignment here
test/stage1/behavior/slice.zig
@@ -130,3 +130,82 @@ test "empty array to slice" {
     S.doTheTest();
     comptime S.doTheTest();
 }
+
+test "@ptrCast slice to pointer" {
+    const S = struct {
+        fn doTheTest() void {
+            var array align(@alignOf(u16)) = [5]u8{ 0xff, 0xff, 0xff, 0xff, 0xff };
+            var slice: []u8 = &array;
+            var ptr = @ptrCast(*u16, slice);
+            expect(ptr.* == 65535);
+        }
+    };
+
+    S.doTheTest();
+    comptime S.doTheTest();
+}
+
+test "slicing producing an array" {
+    const S = struct {
+        fn doTheTest() void {
+            testArray();
+            testArrayZ();
+            testPointer();
+            testPointerZ();
+            testSlice();
+            testSliceZ();
+        }
+
+        fn testArray() void {
+            var array = [5]u8{ 1, 2, 3, 4, 5 };
+            var slice = array[1..3];
+            comptime expect(@TypeOf(slice) == *[2]u8);
+            expect(slice[0] == 2);
+            expect(slice[1] == 3);
+        }
+
+        fn testArrayZ() void {
+            var array = [5:0]u8{ 1, 2, 3, 4, 5 };
+            comptime expect(@TypeOf(array[1..3]) == *[2]u8);
+            comptime expect(@TypeOf(array[1..5]) == *[4:0]u8);
+            comptime expect(@TypeOf(array[1..]) == *[4:0]u8);
+            comptime expect(@TypeOf(array[1..3 :4]) == *[2:4]u8);
+        }
+
+        fn testPointer() void {
+            var array = [5]u8{ 1, 2, 3, 4, 5 };
+            var pointer: [*]u8 = &array;
+            var slice = pointer[1..3];
+            comptime expect(@TypeOf(slice) == *[2]u8);
+            expect(slice[0] == 2);
+            expect(slice[1] == 3);
+        }
+
+        fn testPointerZ() void {
+            var array = [5:0]u8{ 1, 2, 3, 4, 5 };
+            var pointer: [*:0]u8 = &array;
+            comptime expect(@TypeOf(pointer[1..3]) == *[2]u8);
+            comptime expect(@TypeOf(pointer[1..3 :4]) == *[2:4]u8);
+        }
+
+        fn testSlice() void {
+            var array = [5]u8{ 1, 2, 3, 4, 5 };
+            var src_slice: []u8 = &array;
+            var slice = src_slice[1..3];
+            comptime expect(@TypeOf(slice) == *[2]u8);
+            expect(slice[0] == 2);
+            expect(slice[1] == 3);
+        }
+
+        fn testSliceZ() void {
+            var array = [5:0]u8{ 1, 2, 3, 4, 5 };
+            var slice: [:0]u8 = &array;
+            comptime expect(@TypeOf(slice[1..3]) == *[2]u8);
+            comptime expect(@TypeOf(slice[1..]) == [:0]u8);
+            comptime expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8);
+        }
+    };
+
+    S.doTheTest();
+    comptime S.doTheTest();
+}