Commit 95fbce2b95

Andrew Kelley <andrew@ziglang.org>
2022-02-04 07:57:05
Sema: fixes to fieldVal, resolveStructFully, Type.eql
fieldVal handles pointer to pointer to array. This can happen for example, if a pointer to an array is used as the condition expression of a for loop. resolveStructFully handles tuples (by doing nothing). fixed Type comparison for tuples to handle comptime fields properly.
1 parent 64f7231
src/Sema.zig
@@ -12998,7 +12998,7 @@ fn fieldVal(
         .Array => {
             if (mem.eql(u8, field_name, "len")) {
                 return sema.addConstant(
-                    Type.initTag(.comptime_int),
+                    Type.comptime_int,
                     try Value.Tag.int_u64.create(arena, inner_ty.arrayLen()),
                 );
             } else {
@@ -13010,26 +13010,43 @@ fn fieldVal(
                 );
             }
         },
-        .Pointer => if (inner_ty.isSlice()) {
-            if (mem.eql(u8, field_name, "ptr")) {
-                const slice = if (is_pointer_to)
-                    try sema.analyzeLoad(block, src, object, object_src)
-                else
-                    object;
-                return sema.analyzeSlicePtr(block, src, slice, inner_ty, object_src);
-            } else if (mem.eql(u8, field_name, "len")) {
-                const slice = if (is_pointer_to)
-                    try sema.analyzeLoad(block, src, object, object_src)
-                else
-                    object;
-                return sema.analyzeSliceLen(block, src, slice);
-            } else {
-                return sema.fail(
-                    block,
-                    field_name_src,
-                    "no member named '{s}' in '{}'",
-                    .{ field_name, object_ty },
-                );
+        .Pointer => {
+            const ptr_info = inner_ty.ptrInfo().data;
+            if (ptr_info.size == .Slice) {
+                if (mem.eql(u8, field_name, "ptr")) {
+                    const slice = if (is_pointer_to)
+                        try sema.analyzeLoad(block, src, object, object_src)
+                    else
+                        object;
+                    return sema.analyzeSlicePtr(block, src, slice, inner_ty, object_src);
+                } else if (mem.eql(u8, field_name, "len")) {
+                    const slice = if (is_pointer_to)
+                        try sema.analyzeLoad(block, src, object, object_src)
+                    else
+                        object;
+                    return sema.analyzeSliceLen(block, src, slice);
+                } else {
+                    return sema.fail(
+                        block,
+                        field_name_src,
+                        "no member named '{s}' in '{}'",
+                        .{ field_name, object_ty },
+                    );
+                }
+            } else if (ptr_info.pointee_type.zigTypeTag() == .Array) {
+                if (mem.eql(u8, field_name, "len")) {
+                    return sema.addConstant(
+                        Type.comptime_int,
+                        try Value.Tag.int_u64.create(arena, ptr_info.pointee_type.arrayLen()),
+                    );
+                } else {
+                    return sema.fail(
+                        block,
+                        field_name_src,
+                        "no member named '{s}' in '{}'",
+                        .{ field_name, ptr_info.pointee_type },
+                    );
+                }
             }
         },
         .Type => {
@@ -16371,7 +16388,8 @@ fn resolveStructFully(
     try resolveStructLayout(sema, block, src, ty);
 
     const resolved_ty = try sema.resolveTypeFields(block, src, ty);
-    const struct_obj = resolved_ty.castTag(.@"struct").?.data;
+    const payload = resolved_ty.castTag(.@"struct") orelse return;
+    const struct_obj = payload.data;
     switch (struct_obj.status) {
         .none, .have_field_types, .field_types_wip, .layout_wip, .have_layout => {},
         .fully_resolved_wip, .fully_resolved => return,
src/type.zig
@@ -634,7 +634,19 @@ pub const Type = extern union {
                         for (a_payload.data.values) |a_val, i| {
                             const ty = a_payload.data.types[i];
                             const b_val = b_payload.data.values[i];
-                            if (!Value.eql(a_val, b_val, ty)) return false;
+                            if (a_val.tag() == .unreachable_value) {
+                                if (b_val.tag() == .unreachable_value) {
+                                    continue;
+                                } else {
+                                    return false;
+                                }
+                            } else {
+                                if (b_val.tag() == .unreachable_value) {
+                                    return false;
+                                } else {
+                                    if (!Value.eql(a_val, b_val, ty)) return false;
+                                }
+                            }
                         }
 
                         return true;
test/behavior/slice.zig
@@ -204,3 +204,355 @@ test "slice string literal has correct type" {
     const array = [_]i32{ 1, 2, 3, 4 };
     comptime try expect(@TypeOf(array[runtime_zero..]) == []const i32);
 }
+
+test "result location zero sized array inside struct field implicit cast to slice" {
+    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+
+    const E = struct {
+        entries: []u32,
+    };
+    var foo = E{ .entries = &[_]u32{} };
+    try expect(foo.entries.len == 0);
+}
+
+test "runtime safety lets us slice from len..len" {
+    var an_array = [_]u8{ 1, 2, 3 };
+    try expect(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));
+}
+
+fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
+    return a_slice[start..end];
+}
+
+test "C pointer" {
+    var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";
+    var len: u32 = 10;
+    var slice = buf[0..len];
+    try expect(mem.eql(u8, "kjdhfkjdhf", slice));
+}
+
+test "C pointer slice access" {
+    var buf: [10]u32 = [1]u32{42} ** 10;
+    const c_ptr = @ptrCast([*c]const u32, &buf);
+
+    var runtime_zero: usize = 0;
+    comptime try expectEqual([]const u32, @TypeOf(c_ptr[runtime_zero..1]));
+    comptime try expectEqual(*const [1]u32, @TypeOf(c_ptr[0..1]));
+
+    for (c_ptr[0..5]) |*cl| {
+        try expect(@as(u32, 42) == cl.*);
+    }
+}
+
+test "comptime slices are disambiguated" {
+    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+    try expect(sliceSum(&[_]u8{ 1, 2 }) == 3);
+    try expect(sliceSum(&[_]u8{ 3, 4 }) == 7);
+}
+
+fn sliceSum(comptime q: []const u8) i32 {
+    comptime var result = 0;
+    inline for (q) |item| {
+        result += item;
+    }
+    return result;
+}
+
+test "slice type with custom alignment" {
+    const LazilyResolvedType = struct {
+        anything: i32,
+    };
+    var slice: []align(32) LazilyResolvedType = undefined;
+    var array: [10]LazilyResolvedType align(32) = undefined;
+    slice = &array;
+    slice[1].anything = 42;
+    try expect(array[1].anything == 42);
+}
+
+test "obtaining a null terminated slice" {
+    if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
+
+    // here we have a normal array
+    var buf: [50]u8 = undefined;
+
+    buf[0] = 'a';
+    buf[1] = 'b';
+    buf[2] = 'c';
+    buf[3] = 0;
+
+    // now we obtain a null terminated slice:
+    const ptr = buf[0..3 :0];
+    _ = ptr;
+
+    var runtime_len: usize = 3;
+    const ptr2 = buf[0..runtime_len :0];
+    // ptr2 is a null-terminated slice
+    comptime try expect(@TypeOf(ptr2) == [:0]u8);
+    comptime try expect(@TypeOf(ptr2[0..2]) == *[2]u8);
+    var runtime_zero: usize = 0;
+    comptime try expect(@TypeOf(ptr2[runtime_zero..2]) == []u8);
+}
+
+test "empty array to slice" {
+    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+    const S = struct {
+        fn doTheTest() !void {
+            const empty: []align(16) u8 = &[_]u8{};
+            const align_1: []align(1) u8 = empty;
+            const align_4: []align(4) u8 = empty;
+            const align_16: []align(16) u8 = empty;
+            try expectEqual(1, @typeInfo(@TypeOf(align_1)).Pointer.alignment);
+            try expectEqual(4, @typeInfo(@TypeOf(align_4)).Pointer.alignment);
+            try expectEqual(16, @typeInfo(@TypeOf(align_16)).Pointer.alignment);
+        }
+    };
+
+    try S.doTheTest();
+    comptime try S.doTheTest();
+}
+
+test "@ptrCast slice to pointer" {
+    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+    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);
+            try expect(ptr.* == 65535);
+        }
+    };
+
+    try S.doTheTest();
+    comptime try S.doTheTest();
+}
+
+test "slice syntax resulting in pointer-to-array" {
+    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+    const S = struct {
+        fn doTheTest() !void {
+            try testArray();
+            try testArrayZ();
+            try testArray0();
+            try testArrayAlign();
+            try testPointer();
+            try testPointerZ();
+            try testPointer0();
+            try testPointerAlign();
+            try testSlice();
+            try testSliceZ();
+            try testSlice0();
+            try testSliceOpt();
+            try testSliceAlign();
+        }
+
+        fn testArray() !void {
+            var array = [5]u8{ 1, 2, 3, 4, 5 };
+            var slice = array[1..3];
+            comptime try expect(@TypeOf(slice) == *[2]u8);
+            try expect(slice[0] == 2);
+            try expect(slice[1] == 3);
+        }
+
+        fn testArrayZ() !void {
+            var array = [5:0]u8{ 1, 2, 3, 4, 5 };
+            comptime try expect(@TypeOf(array[1..3]) == *[2]u8);
+            comptime try expect(@TypeOf(array[1..5]) == *[4:0]u8);
+            comptime try expect(@TypeOf(array[1..]) == *[4:0]u8);
+            comptime try expect(@TypeOf(array[1..3 :4]) == *[2:4]u8);
+        }
+
+        fn testArray0() !void {
+            {
+                var array = [0]u8{};
+                var slice = array[0..0];
+                comptime try expect(@TypeOf(slice) == *[0]u8);
+            }
+            {
+                var array = [0:0]u8{};
+                var slice = array[0..0];
+                comptime try expect(@TypeOf(slice) == *[0:0]u8);
+                try expect(slice[0] == 0);
+            }
+        }
+
+        fn testArrayAlign() !void {
+            var array align(4) = [5]u8{ 1, 2, 3, 4, 5 };
+            var slice = array[4..5];
+            comptime try expect(@TypeOf(slice) == *align(4) [1]u8);
+            try expect(slice[0] == 5);
+            comptime try expect(@TypeOf(array[0..2]) == *align(4) [2]u8);
+        }
+
+        fn testPointer() !void {
+            var array = [5]u8{ 1, 2, 3, 4, 5 };
+            var pointer: [*]u8 = &array;
+            var slice = pointer[1..3];
+            comptime try expect(@TypeOf(slice) == *[2]u8);
+            try expect(slice[0] == 2);
+            try expect(slice[1] == 3);
+        }
+
+        fn testPointerZ() !void {
+            var array = [5:0]u8{ 1, 2, 3, 4, 5 };
+            var pointer: [*:0]u8 = &array;
+            comptime try expect(@TypeOf(pointer[1..3]) == *[2]u8);
+            comptime try expect(@TypeOf(pointer[1..3 :4]) == *[2:4]u8);
+        }
+
+        fn testPointer0() !void {
+            var pointer: [*]const u0 = &[1]u0{0};
+            var slice = pointer[0..1];
+            comptime try expect(@TypeOf(slice) == *const [1]u0);
+            try expect(slice[0] == 0);
+        }
+
+        fn testPointerAlign() !void {
+            var array align(4) = [5]u8{ 1, 2, 3, 4, 5 };
+            var pointer: [*]align(4) u8 = &array;
+            var slice = pointer[4..5];
+            comptime try expect(@TypeOf(slice) == *align(4) [1]u8);
+            try expect(slice[0] == 5);
+            comptime try expect(@TypeOf(pointer[0..2]) == *align(4) [2]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 try expect(@TypeOf(slice) == *[2]u8);
+            try expect(slice[0] == 2);
+            try expect(slice[1] == 3);
+        }
+
+        fn testSliceZ() !void {
+            var array = [5:0]u8{ 1, 2, 3, 4, 5 };
+            var slice: [:0]u8 = &array;
+            comptime try expect(@TypeOf(slice[1..3]) == *[2]u8);
+            comptime try expect(@TypeOf(slice[1..]) == [:0]u8);
+            comptime try expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8);
+        }
+
+        fn testSliceOpt() !void {
+            var array: [2]u8 = [2]u8{ 1, 2 };
+            var slice: ?[]u8 = &array;
+            comptime try expect(@TypeOf(&array, slice) == ?[]u8);
+            comptime try expect(@TypeOf(slice.?[0..2]) == *[2]u8);
+        }
+
+        fn testSlice0() !void {
+            {
+                var array = [0]u8{};
+                var src_slice: []u8 = &array;
+                var slice = src_slice[0..0];
+                comptime try expect(@TypeOf(slice) == *[0]u8);
+            }
+            {
+                var array = [0:0]u8{};
+                var src_slice: [:0]u8 = &array;
+                var slice = src_slice[0..0];
+                comptime try expect(@TypeOf(slice) == *[0]u8);
+            }
+        }
+
+        fn testSliceAlign() !void {
+            var array align(4) = [5]u8{ 1, 2, 3, 4, 5 };
+            var src_slice: []align(4) u8 = &array;
+            var slice = src_slice[4..5];
+            comptime try expect(@TypeOf(slice) == *align(4) [1]u8);
+            try expect(slice[0] == 5);
+            comptime try expect(@TypeOf(src_slice[0..2]) == *align(4) [2]u8);
+        }
+
+        fn testConcatStrLiterals() !void {
+            try expectEqualSlices("a"[0..] ++ "b"[0..], "ab");
+            try expectEqualSlices("a"[0.. :0] ++ "b"[0.. :0], "ab");
+        }
+    };
+
+    try S.doTheTest();
+    comptime try S.doTheTest();
+}
+
+test "type coercion of pointer to anon struct literal to pointer to slice" {
+    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+    const S = struct {
+        const U = union {
+            a: u32,
+            b: bool,
+            c: []const u8,
+        };
+
+        fn doTheTest() !void {
+            var x1: u8 = 42;
+            const t1 = &.{ x1, 56, 54 };
+            var slice1: []const u8 = t1;
+            try expect(slice1.len == 3);
+            try expect(slice1[0] == 42);
+            try expect(slice1[1] == 56);
+            try expect(slice1[2] == 54);
+
+            var x2: []const u8 = "hello";
+            const t2 = &.{ x2, ", ", "world!" };
+            // @compileLog(@TypeOf(t2));
+            var slice2: []const []const u8 = t2;
+            try expect(slice2.len == 3);
+            try expect(mem.eql(u8, slice2[0], "hello"));
+            try expect(mem.eql(u8, slice2[1], ", "));
+            try expect(mem.eql(u8, slice2[2], "world!"));
+        }
+    };
+    // try S.doTheTest();
+    comptime try S.doTheTest();
+}
+
+test "array concat of slices gives slice" {
+    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+    comptime {
+        var a: []const u8 = "aoeu";
+        var b: []const u8 = "asdf";
+        const c = a ++ b;
+        try expect(std.mem.eql(u8, c, "aoeuasdf"));
+    }
+}
+
+test "slice bounds in comptime concatenation" {
+    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+    const bs = comptime blk: {
+        const b = "........1........";
+        break :blk b[8..9];
+    };
+    const str = "" ++ bs;
+    try expect(str.len == 1);
+    try expect(std.mem.eql(u8, str, "1"));
+
+    const str2 = bs ++ "";
+    try expect(str2.len == 1);
+    try expect(std.mem.eql(u8, str2, "1"));
+}
+
+test "slice sentinel access at comptime" {
+    if (builtin.zig_backend != .stage1) return error.SkipZigTest; // TODO
+
+    {
+        const str0 = &[_:0]u8{ '1', '2', '3' };
+        const slice0: [:0]const u8 = str0;
+
+        try expect(slice0.len == 3);
+        try expect(slice0[slice0.len] == 0);
+    }
+    {
+        const str0 = "123";
+        _ = &str0[0];
+        const slice0: [:0]const u8 = str0;
+
+        try expect(slice0.len == 3);
+        try expect(slice0[slice0.len] == 0);
+    }
+}
test/behavior/slice_stage1.zig
@@ -1,347 +0,0 @@
-const std = @import("std");
-const expect = std.testing.expect;
-const expectEqualSlices = std.testing.expectEqualSlices;
-const expectEqual = std.testing.expectEqual;
-const mem = std.mem;
-
-test "result location zero sized array inside struct field implicit cast to slice" {
-    const E = struct {
-        entries: []u32,
-    };
-    var foo = E{ .entries = &[_]u32{} };
-    try expect(foo.entries.len == 0);
-}
-
-const x = @intToPtr([*]i32, 0x1000)[0..0x500];
-const y = x[0x100..];
-test "compile time slice of pointer to hard coded address" {
-    try expect(@ptrToInt(x) == 0x1000);
-    try expect(x.len == 0x500);
-
-    try expect(@ptrToInt(y) == 0x1100);
-    try expect(y.len == 0x400);
-}
-
-test "runtime safety lets us slice from len..len" {
-    var an_array = [_]u8{ 1, 2, 3 };
-    try expect(mem.eql(u8, sliceFromLenToLen(an_array[0..], 3, 3), ""));
-}
-
-fn sliceFromLenToLen(a_slice: []u8, start: usize, end: usize) []u8 {
-    return a_slice[start..end];
-}
-
-test "C pointer" {
-    var buf: [*c]const u8 = "kjdhfkjdhfdkjhfkfjhdfkjdhfkdjhfdkjhf";
-    var len: u32 = 10;
-    var slice = buf[0..len];
-    try expectEqualSlices(u8, "kjdhfkjdhf", slice);
-}
-
-test "C pointer slice access" {
-    var buf: [10]u32 = [1]u32{42} ** 10;
-    const c_ptr = @ptrCast([*c]const u32, &buf);
-
-    var runtime_zero: usize = 0;
-    comptime try expectEqual([]const u32, @TypeOf(c_ptr[runtime_zero..1]));
-    comptime try expectEqual(*const [1]u32, @TypeOf(c_ptr[0..1]));
-
-    for (c_ptr[0..5]) |*cl| {
-        try expectEqual(@as(u32, 42), cl.*);
-    }
-}
-
-fn sliceSum(comptime q: []const u8) i32 {
-    comptime var result = 0;
-    inline for (q) |item| {
-        result += item;
-    }
-    return result;
-}
-
-test "comptime slices are disambiguated" {
-    try expect(sliceSum(&[_]u8{ 1, 2 }) == 3);
-    try expect(sliceSum(&[_]u8{ 3, 4 }) == 7);
-}
-
-test "slice type with custom alignment" {
-    const LazilyResolvedType = struct {
-        anything: i32,
-    };
-    var slice: []align(32) LazilyResolvedType = undefined;
-    var array: [10]LazilyResolvedType align(32) = undefined;
-    slice = &array;
-    slice[1].anything = 42;
-    try expect(array[1].anything == 42);
-}
-
-test "obtaining a null terminated slice" {
-    // here we have a normal array
-    var buf: [50]u8 = undefined;
-
-    buf[0] = 'a';
-    buf[1] = 'b';
-    buf[2] = 'c';
-    buf[3] = 0;
-
-    // now we obtain a null terminated slice:
-    const ptr = buf[0..3 :0];
-    _ = ptr;
-
-    var runtime_len: usize = 3;
-    const ptr2 = buf[0..runtime_len :0];
-    // ptr2 is a null-terminated slice
-    comptime try expect(@TypeOf(ptr2) == [:0]u8);
-    comptime try expect(@TypeOf(ptr2[0..2]) == *[2]u8);
-    var runtime_zero: usize = 0;
-    comptime try expect(@TypeOf(ptr2[runtime_zero..2]) == []u8);
-}
-
-test "empty array to slice" {
-    const S = struct {
-        fn doTheTest() !void {
-            const empty: []align(16) u8 = &[_]u8{};
-            const align_1: []align(1) u8 = empty;
-            const align_4: []align(4) u8 = empty;
-            const align_16: []align(16) u8 = empty;
-            try expectEqual(1, @typeInfo(@TypeOf(align_1)).Pointer.alignment);
-            try expectEqual(4, @typeInfo(@TypeOf(align_4)).Pointer.alignment);
-            try expectEqual(16, @typeInfo(@TypeOf(align_16)).Pointer.alignment);
-        }
-    };
-
-    try S.doTheTest();
-    comptime try 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);
-            try expect(ptr.* == 65535);
-        }
-    };
-
-    try S.doTheTest();
-    comptime try S.doTheTest();
-}
-
-test "slice syntax resulting in pointer-to-array" {
-    const S = struct {
-        fn doTheTest() !void {
-            try testArray();
-            try testArrayZ();
-            try testArray0();
-            try testArrayAlign();
-            try testPointer();
-            try testPointerZ();
-            try testPointer0();
-            try testPointerAlign();
-            try testSlice();
-            try testSliceZ();
-            try testSlice0();
-            try testSliceOpt();
-            try testSliceAlign();
-        }
-
-        fn testArray() !void {
-            var array = [5]u8{ 1, 2, 3, 4, 5 };
-            var slice = array[1..3];
-            comptime try expect(@TypeOf(slice) == *[2]u8);
-            try expect(slice[0] == 2);
-            try expect(slice[1] == 3);
-        }
-
-        fn testArrayZ() !void {
-            var array = [5:0]u8{ 1, 2, 3, 4, 5 };
-            comptime try expect(@TypeOf(array[1..3]) == *[2]u8);
-            comptime try expect(@TypeOf(array[1..5]) == *[4:0]u8);
-            comptime try expect(@TypeOf(array[1..]) == *[4:0]u8);
-            comptime try expect(@TypeOf(array[1..3 :4]) == *[2:4]u8);
-        }
-
-        fn testArray0() !void {
-            {
-                var array = [0]u8{};
-                var slice = array[0..0];
-                comptime try expect(@TypeOf(slice) == *[0]u8);
-            }
-            {
-                var array = [0:0]u8{};
-                var slice = array[0..0];
-                comptime try expect(@TypeOf(slice) == *[0:0]u8);
-                try expect(slice[0] == 0);
-            }
-        }
-
-        fn testArrayAlign() !void {
-            var array align(4) = [5]u8{ 1, 2, 3, 4, 5 };
-            var slice = array[4..5];
-            comptime try expect(@TypeOf(slice) == *align(4) [1]u8);
-            try expect(slice[0] == 5);
-            comptime try expect(@TypeOf(array[0..2]) == *align(4) [2]u8);
-        }
-
-        fn testPointer() !void {
-            var array = [5]u8{ 1, 2, 3, 4, 5 };
-            var pointer: [*]u8 = &array;
-            var slice = pointer[1..3];
-            comptime try expect(@TypeOf(slice) == *[2]u8);
-            try expect(slice[0] == 2);
-            try expect(slice[1] == 3);
-        }
-
-        fn testPointerZ() !void {
-            var array = [5:0]u8{ 1, 2, 3, 4, 5 };
-            var pointer: [*:0]u8 = &array;
-            comptime try expect(@TypeOf(pointer[1..3]) == *[2]u8);
-            comptime try expect(@TypeOf(pointer[1..3 :4]) == *[2:4]u8);
-        }
-
-        fn testPointer0() !void {
-            var pointer: [*]const u0 = &[1]u0{0};
-            var slice = pointer[0..1];
-            comptime try expect(@TypeOf(slice) == *const [1]u0);
-            try expect(slice[0] == 0);
-        }
-
-        fn testPointerAlign() !void {
-            var array align(4) = [5]u8{ 1, 2, 3, 4, 5 };
-            var pointer: [*]align(4) u8 = &array;
-            var slice = pointer[4..5];
-            comptime try expect(@TypeOf(slice) == *align(4) [1]u8);
-            try expect(slice[0] == 5);
-            comptime try expect(@TypeOf(pointer[0..2]) == *align(4) [2]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 try expect(@TypeOf(slice) == *[2]u8);
-            try expect(slice[0] == 2);
-            try expect(slice[1] == 3);
-        }
-
-        fn testSliceZ() !void {
-            var array = [5:0]u8{ 1, 2, 3, 4, 5 };
-            var slice: [:0]u8 = &array;
-            comptime try expect(@TypeOf(slice[1..3]) == *[2]u8);
-            comptime try expect(@TypeOf(slice[1..]) == [:0]u8);
-            comptime try expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8);
-        }
-
-        fn testSliceOpt() !void {
-            var array: [2]u8 = [2]u8{ 1, 2 };
-            var slice: ?[]u8 = &array;
-            comptime try expect(@TypeOf(&array, slice) == ?[]u8);
-            comptime try expect(@TypeOf(slice.?[0..2]) == *[2]u8);
-        }
-
-        fn testSlice0() !void {
-            {
-                var array = [0]u8{};
-                var src_slice: []u8 = &array;
-                var slice = src_slice[0..0];
-                comptime try expect(@TypeOf(slice) == *[0]u8);
-            }
-            {
-                var array = [0:0]u8{};
-                var src_slice: [:0]u8 = &array;
-                var slice = src_slice[0..0];
-                comptime try expect(@TypeOf(slice) == *[0]u8);
-            }
-        }
-
-        fn testSliceAlign() !void {
-            var array align(4) = [5]u8{ 1, 2, 3, 4, 5 };
-            var src_slice: []align(4) u8 = &array;
-            var slice = src_slice[4..5];
-            comptime try expect(@TypeOf(slice) == *align(4) [1]u8);
-            try expect(slice[0] == 5);
-            comptime try expect(@TypeOf(src_slice[0..2]) == *align(4) [2]u8);
-        }
-
-        fn testConcatStrLiterals() !void {
-            try expectEqualSlices("a"[0..] ++ "b"[0..], "ab");
-            try expectEqualSlices("a"[0.. :0] ++ "b"[0.. :0], "ab");
-        }
-    };
-
-    try S.doTheTest();
-    comptime try S.doTheTest();
-}
-
-test "type coercion of pointer to anon struct literal to pointer to slice" {
-    const S = struct {
-        const U = union {
-            a: u32,
-            b: bool,
-            c: []const u8,
-        };
-
-        fn doTheTest() !void {
-            var x1: u8 = 42;
-            const t1 = &.{ x1, 56, 54 };
-            var slice1: []const u8 = t1;
-            try expect(slice1.len == 3);
-            try expect(slice1[0] == 42);
-            try expect(slice1[1] == 56);
-            try expect(slice1[2] == 54);
-
-            var x2: []const u8 = "hello";
-            const t2 = &.{ x2, ", ", "world!" };
-            // @compileLog(@TypeOf(t2));
-            var slice2: []const []const u8 = t2;
-            try expect(slice2.len == 3);
-            try expect(mem.eql(u8, slice2[0], "hello"));
-            try expect(mem.eql(u8, slice2[1], ", "));
-            try expect(mem.eql(u8, slice2[2], "world!"));
-        }
-    };
-    // try S.doTheTest();
-    comptime try S.doTheTest();
-}
-
-test "array concat of slices gives slice" {
-    comptime {
-        var a: []const u8 = "aoeu";
-        var b: []const u8 = "asdf";
-        const c = a ++ b;
-        try expect(std.mem.eql(u8, c, "aoeuasdf"));
-    }
-}
-
-test "slice bounds in comptime concatenation" {
-    const bs = comptime blk: {
-        const b = "........1........";
-        break :blk b[8..9];
-    };
-    const str = "" ++ bs;
-    try expect(str.len == 1);
-    try expect(std.mem.eql(u8, str, "1"));
-
-    const str2 = bs ++ "";
-    try expect(str2.len == 1);
-    try expect(std.mem.eql(u8, str2, "1"));
-}
-
-test "slice sentinel access at comptime" {
-    {
-        const str0 = &[_:0]u8{ '1', '2', '3' };
-        const slice0: [:0]const u8 = str0;
-
-        try expect(slice0.len == 3);
-        try expect(slice0[slice0.len] == 0);
-    }
-    {
-        const str0 = "123";
-        _ = &str0[0];
-        const slice0: [:0]const u8 = str0;
-
-        try expect(slice0.len == 3);
-        try expect(slice0[slice0.len] == 0);
-    }
-}
test/behavior.zig
@@ -163,7 +163,6 @@ test {
                     _ = @import("behavior/select.zig");
                     _ = @import("behavior/shuffle.zig");
                     _ = @import("behavior/sizeof_and_typeof_stage1.zig");
-                    _ = @import("behavior/slice_stage1.zig");
                     _ = @import("behavior/struct_contains_null_ptr_itself.zig");
                     _ = @import("behavior/struct_contains_slice_of_itself.zig");
                     _ = @import("behavior/switch_prong_err_enum.zig");