commit f5043ad6a3232dc5ce3cadcbf04c2ee038d34810 (tree)
parent 11d0dfb8829f7a247b21b417157bafeebd6a2a90
Author: Andrew Kelley <andrew@ziglang.org>
Date: Thu, 15 Jun 2023 09:49:59 -0700
Merge pull request #16042 from mlugg/fix/slice-len-comptime-mutation
Fix comptime mutation of slice len
Diffstat:
2 files changed, 34 insertions(+), 9 deletions(-)
diff --git a/src/Sema.zig b/src/Sema.zig
@@ -10069,7 +10069,7 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
const extra = sema.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data;
const array_ptr = try sema.resolveInst(extra.lhs);
const start = try sema.resolveInst(extra.start);
- const end = try sema.resolveInst(extra.end);
+ const end: Air.Inst.Ref = if (extra.end == .none) .none else try sema.resolveInst(extra.end);
const sentinel = try sema.resolveInst(extra.sentinel);
const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node };
const start_src: LazySrcLoc = .{ .node_offset_slice_start = inst_data.src_node };
@@ -29280,7 +29280,7 @@ fn beginComptimePtrLoad(
},
Value.slice_len_index => TypedValue{
.ty = Type.usize,
- .val = mod.intern_pool.indexToKey(tv.val.toIntern()).ptr.len.toValue(),
+ .val = mod.intern_pool.indexToKey(try tv.val.intern(tv.ty, mod)).ptr.len.toValue(),
},
else => unreachable,
};
diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig
@@ -378,12 +378,16 @@ test "slice syntax resulting in pointer-to-array" {
try testPointer0();
try testPointerAlign();
try testSlice();
+ try testSliceZ();
try testSliceOpt();
try testSliceAlign();
+ try testConcatStrLiterals();
try testSliceLength();
try testSliceLengthZ();
try testArrayLength();
try testArrayLengthZ();
+ try testMultiPointer();
+ try testMultiPointerLengthZ();
}
fn testArray() !void {
@@ -469,8 +473,12 @@ test "slice syntax resulting in pointer-to-array" {
var array = [5:0]u8{ 1, 2, 3, 4, 5 };
var slice: [:0]u8 = &array;
try comptime expect(@TypeOf(slice[1..3]) == *[2]u8);
- try comptime expect(@TypeOf(slice[1..]) == [:0]u8);
try comptime expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8);
+ if (@inComptime()) {
+ try comptime expect(@TypeOf(slice[1..]) == *[4:0]u8);
+ } else {
+ try comptime expect(@TypeOf(slice[1..]) == [:0]u8);
+ }
}
fn testSliceOpt() !void {
@@ -491,8 +499,8 @@ test "slice syntax resulting in pointer-to-array" {
}
fn testConcatStrLiterals() !void {
- try expectEqualSlices("a"[0..] ++ "b"[0..], "ab");
- try expectEqualSlices("a"[0.. :0] ++ "b"[0.. :0], "ab");
+ try expectEqualSlices(u8, "ab", "a"[0..] ++ "b"[0..]);
+ try expectEqualSlices(u8, "ab", "a"[0.. :0] ++ "b"[0.. :0]);
}
fn testSliceLength() !void {
@@ -541,18 +549,18 @@ test "slice syntax resulting in pointer-to-array" {
var array = [5:0]u8{ 1, 2, 3, 4, 5 };
var ptr: [*]u8 = &array;
try comptime expect(@TypeOf(ptr[1..][0..2]) == *[2]u8);
- try comptime expect(@TypeOf(ptr[1..][0..4]) == *[4:0]u8);
+ try comptime expect(@TypeOf(ptr[1..][0..4]) == *[4]u8);
try comptime expect(@TypeOf(ptr[1..][0..2 :4]) == *[2:4]u8);
try comptime expect(@TypeOf(ptr[1.. :0][0..2]) == *[2]u8);
- try comptime expect(@TypeOf(ptr[1.. :0][0..4]) == *[4:0]u8);
+ try comptime expect(@TypeOf(ptr[1.. :0][0..4]) == *[4]u8);
try comptime expect(@TypeOf(ptr[1.. :0][0..2 :4]) == *[2:4]u8);
var ptr_z: [*:0]u8 = &array;
try comptime expect(@TypeOf(ptr_z[1..][0..2]) == *[2]u8);
- try comptime expect(@TypeOf(ptr_z[1..][0..4]) == *[4:0]u8);
+ try comptime expect(@TypeOf(ptr_z[1..][0..4]) == *[4]u8);
try comptime expect(@TypeOf(ptr_z[1..][0..2 :4]) == *[2:4]u8);
try comptime expect(@TypeOf(ptr_z[1.. :0][0..2]) == *[2]u8);
- try comptime expect(@TypeOf(ptr_z[1.. :0][0..4]) == *[4:0]u8);
+ try comptime expect(@TypeOf(ptr_z[1.. :0][0..4]) == *[4]u8);
try comptime expect(@TypeOf(ptr_z[1.. :0][0..2 :4]) == *[2:4]u8);
}
};
@@ -869,3 +877,20 @@ test "write through pointer to optional slice arg" {
try S.bar(&foo);
try expectEqualStrings(foo.?, "ok");
}
+
+test "modify slice length at comptime" {
+ if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
+ if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
+
+ const arr: [2]u8 = .{ 10, 20 };
+ comptime var s: []const u8 = arr[0..0];
+ s.len += 1;
+ const a = s;
+ s.len += 1;
+ const b = s;
+
+ try expectEqualSlices(u8, &.{10}, a);
+ try expectEqualSlices(u8, &.{ 10, 20 }, b);
+}