Skip to content

Commit f5043ad

Browse files
authored
Merge pull request #16042 from mlugg/fix/slice-len-comptime-mutation
Fix comptime mutation of slice len
2 parents 11d0dfb + 57f6e67 commit f5043ad

File tree

2 files changed

+34
-9
lines changed

2 files changed

+34
-9
lines changed

src/Sema.zig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10069,7 +10069,7 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
1006910069
const extra = sema.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data;
1007010070
const array_ptr = try sema.resolveInst(extra.lhs);
1007110071
const start = try sema.resolveInst(extra.start);
10072-
const end = try sema.resolveInst(extra.end);
10072+
const end: Air.Inst.Ref = if (extra.end == .none) .none else try sema.resolveInst(extra.end);
1007310073
const sentinel = try sema.resolveInst(extra.sentinel);
1007410074
const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node };
1007510075
const start_src: LazySrcLoc = .{ .node_offset_slice_start = inst_data.src_node };
@@ -29280,7 +29280,7 @@ fn beginComptimePtrLoad(
2928029280
},
2928129281
Value.slice_len_index => TypedValue{
2928229282
.ty = Type.usize,
29283-
.val = mod.intern_pool.indexToKey(tv.val.toIntern()).ptr.len.toValue(),
29283+
.val = mod.intern_pool.indexToKey(try tv.val.intern(tv.ty, mod)).ptr.len.toValue(),
2928429284
},
2928529285
else => unreachable,
2928629286
};

test/behavior/slice.zig

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -378,12 +378,16 @@ test "slice syntax resulting in pointer-to-array" {
378378
try testPointer0();
379379
try testPointerAlign();
380380
try testSlice();
381+
try testSliceZ();
381382
try testSliceOpt();
382383
try testSliceAlign();
384+
try testConcatStrLiterals();
383385
try testSliceLength();
384386
try testSliceLengthZ();
385387
try testArrayLength();
386388
try testArrayLengthZ();
389+
try testMultiPointer();
390+
try testMultiPointerLengthZ();
387391
}
388392

389393
fn testArray() !void {
@@ -469,8 +473,12 @@ test "slice syntax resulting in pointer-to-array" {
469473
var array = [5:0]u8{ 1, 2, 3, 4, 5 };
470474
var slice: [:0]u8 = &array;
471475
try comptime expect(@TypeOf(slice[1..3]) == *[2]u8);
472-
try comptime expect(@TypeOf(slice[1..]) == [:0]u8);
473476
try comptime expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8);
477+
if (@inComptime()) {
478+
try comptime expect(@TypeOf(slice[1..]) == *[4:0]u8);
479+
} else {
480+
try comptime expect(@TypeOf(slice[1..]) == [:0]u8);
481+
}
474482
}
475483

476484
fn testSliceOpt() !void {
@@ -491,8 +499,8 @@ test "slice syntax resulting in pointer-to-array" {
491499
}
492500

493501
fn testConcatStrLiterals() !void {
494-
try expectEqualSlices("a"[0..] ++ "b"[0..], "ab");
495-
try expectEqualSlices("a"[0.. :0] ++ "b"[0.. :0], "ab");
502+
try expectEqualSlices(u8, "ab", "a"[0..] ++ "b"[0..]);
503+
try expectEqualSlices(u8, "ab", "a"[0.. :0] ++ "b"[0.. :0]);
496504
}
497505

498506
fn testSliceLength() !void {
@@ -541,18 +549,18 @@ test "slice syntax resulting in pointer-to-array" {
541549
var array = [5:0]u8{ 1, 2, 3, 4, 5 };
542550
var ptr: [*]u8 = &array;
543551
try comptime expect(@TypeOf(ptr[1..][0..2]) == *[2]u8);
544-
try comptime expect(@TypeOf(ptr[1..][0..4]) == *[4:0]u8);
552+
try comptime expect(@TypeOf(ptr[1..][0..4]) == *[4]u8);
545553
try comptime expect(@TypeOf(ptr[1..][0..2 :4]) == *[2:4]u8);
546554
try comptime expect(@TypeOf(ptr[1.. :0][0..2]) == *[2]u8);
547-
try comptime expect(@TypeOf(ptr[1.. :0][0..4]) == *[4:0]u8);
555+
try comptime expect(@TypeOf(ptr[1.. :0][0..4]) == *[4]u8);
548556
try comptime expect(@TypeOf(ptr[1.. :0][0..2 :4]) == *[2:4]u8);
549557

550558
var ptr_z: [*:0]u8 = &array;
551559
try comptime expect(@TypeOf(ptr_z[1..][0..2]) == *[2]u8);
552-
try comptime expect(@TypeOf(ptr_z[1..][0..4]) == *[4:0]u8);
560+
try comptime expect(@TypeOf(ptr_z[1..][0..4]) == *[4]u8);
553561
try comptime expect(@TypeOf(ptr_z[1..][0..2 :4]) == *[2:4]u8);
554562
try comptime expect(@TypeOf(ptr_z[1.. :0][0..2]) == *[2]u8);
555-
try comptime expect(@TypeOf(ptr_z[1.. :0][0..4]) == *[4:0]u8);
563+
try comptime expect(@TypeOf(ptr_z[1.. :0][0..4]) == *[4]u8);
556564
try comptime expect(@TypeOf(ptr_z[1.. :0][0..2 :4]) == *[2:4]u8);
557565
}
558566
};
@@ -869,3 +877,20 @@ test "write through pointer to optional slice arg" {
869877
try S.bar(&foo);
870878
try expectEqualStrings(foo.?, "ok");
871879
}
880+
881+
test "modify slice length at comptime" {
882+
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
883+
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
884+
if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest;
885+
if (builtin.zig_backend == .stage2_spirv64) return error.SkipZigTest;
886+
887+
const arr: [2]u8 = .{ 10, 20 };
888+
comptime var s: []const u8 = arr[0..0];
889+
s.len += 1;
890+
const a = s;
891+
s.len += 1;
892+
const b = s;
893+
894+
try expectEqualSlices(u8, &.{10}, a);
895+
try expectEqualSlices(u8, &.{ 10, 20 }, b);
896+
}

0 commit comments

Comments
 (0)