authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-06-15 09:49:59-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2023-06-15 09:49:59-07:00
logf5043ad6a3232dc5ce3cadcbf04c2ee038d34810
tree1c45bb6c99bd45a44f73b8d2ad1a1d42915601e2
parent11d0dfb8829f7a247b21b417157bafeebd6a2a90
parent57f6e6729f74bc7f43848aff6cd52e89465cc49e
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #16042 from mlugg/fix/slice-len-comptime-mutation

Fix comptime mutation of slice len

2 files changed, 34 insertions(+), 9 deletions(-)

src/Sema.zig+2-2
...@@ -10069,7 +10069,7 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr...@@ -10069,7 +10069,7 @@ fn zirSliceSentinel(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileErr
10069 const extra = sema.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data;10069 const extra = sema.code.extraData(Zir.Inst.SliceSentinel, inst_data.payload_index).data;
10070 const array_ptr = try sema.resolveInst(extra.lhs);10070 const array_ptr = try sema.resolveInst(extra.lhs);
10071 const start = try sema.resolveInst(extra.start);10071 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);
10073 const sentinel = try sema.resolveInst(extra.sentinel);10073 const sentinel = try sema.resolveInst(extra.sentinel);
10074 const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node };10074 const ptr_src: LazySrcLoc = .{ .node_offset_slice_ptr = inst_data.src_node };
10075 const start_src: LazySrcLoc = .{ .node_offset_slice_start = inst_data.src_node };10075 const start_src: LazySrcLoc = .{ .node_offset_slice_start = inst_data.src_node };
...@@ -29280,7 +29280,7 @@ fn beginComptimePtrLoad(...@@ -29280,7 +29280,7 @@ fn beginComptimePtrLoad(
29280 },29280 },
29281 Value.slice_len_index => TypedValue{29281 Value.slice_len_index => TypedValue{
29282 .ty = Type.usize,29282 .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(),
29284 },29284 },
29285 else => unreachable,29285 else => unreachable,
29286 };29286 };
test/behavior/slice.zig+32-7
...@@ -378,12 +378,16 @@ test "slice syntax resulting in pointer-to-array" {...@@ -378,12 +378,16 @@ test "slice syntax resulting in pointer-to-array" {
378 try testPointer0();378 try testPointer0();
379 try testPointerAlign();379 try testPointerAlign();
380 try testSlice();380 try testSlice();
381 try testSliceZ();
381 try testSliceOpt();382 try testSliceOpt();
382 try testSliceAlign();383 try testSliceAlign();
384 try testConcatStrLiterals();
383 try testSliceLength();385 try testSliceLength();
384 try testSliceLengthZ();386 try testSliceLengthZ();
385 try testArrayLength();387 try testArrayLength();
386 try testArrayLengthZ();388 try testArrayLengthZ();
389 try testMultiPointer();
390 try testMultiPointerLengthZ();
387 }391 }
388392
389 fn testArray() !void {393 fn testArray() !void {
...@@ -469,8 +473,12 @@ test "slice syntax resulting in pointer-to-array" {...@@ -469,8 +473,12 @@ test "slice syntax resulting in pointer-to-array" {
469 var array = [5:0]u8{ 1, 2, 3, 4, 5 };473 var array = [5:0]u8{ 1, 2, 3, 4, 5 };
470 var slice: [:0]u8 = &array;474 var slice: [:0]u8 = &array;
471 try comptime expect(@TypeOf(slice[1..3]) == *[2]u8);475 try comptime expect(@TypeOf(slice[1..3]) == *[2]u8);
472 try comptime expect(@TypeOf(slice[1..]) == [:0]u8);
473 try comptime expect(@TypeOf(slice[1..3 :4]) == *[2:4]u8);476 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 }
474 }482 }
475483
476 fn testSliceOpt() !void {484 fn testSliceOpt() !void {
...@@ -491,8 +499,8 @@ test "slice syntax resulting in pointer-to-array" {...@@ -491,8 +499,8 @@ test "slice syntax resulting in pointer-to-array" {
491 }499 }
492500
493 fn testConcatStrLiterals() !void {501 fn testConcatStrLiterals() !void {
494 try expectEqualSlices("a"[0..] ++ "b"[0..], "ab");502 try expectEqualSlices(u8, "ab", "a"[0..] ++ "b"[0..]);
495 try expectEqualSlices("a"[0.. :0] ++ "b"[0.. :0], "ab");503 try expectEqualSlices(u8, "ab", "a"[0.. :0] ++ "b"[0.. :0]);
496 }504 }
497505
498 fn testSliceLength() !void {506 fn testSliceLength() !void {
...@@ -541,18 +549,18 @@ test "slice syntax resulting in pointer-to-array" {...@@ -541,18 +549,18 @@ test "slice syntax resulting in pointer-to-array" {
541 var array = [5:0]u8{ 1, 2, 3, 4, 5 };549 var array = [5:0]u8{ 1, 2, 3, 4, 5 };
542 var ptr: [*]u8 = &array;550 var ptr: [*]u8 = &array;
543 try comptime expect(@TypeOf(ptr[1..][0..2]) == *[2]u8);551 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);
545 try comptime expect(@TypeOf(ptr[1..][0..2 :4]) == *[2:4]u8);553 try comptime expect(@TypeOf(ptr[1..][0..2 :4]) == *[2:4]u8);
546 try comptime expect(@TypeOf(ptr[1.. :0][0..2]) == *[2]u8);554 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);
548 try comptime expect(@TypeOf(ptr[1.. :0][0..2 :4]) == *[2:4]u8);556 try comptime expect(@TypeOf(ptr[1.. :0][0..2 :4]) == *[2:4]u8);
549557
550 var ptr_z: [*:0]u8 = &array;558 var ptr_z: [*:0]u8 = &array;
551 try comptime expect(@TypeOf(ptr_z[1..][0..2]) == *[2]u8);559 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);
553 try comptime expect(@TypeOf(ptr_z[1..][0..2 :4]) == *[2:4]u8);561 try comptime expect(@TypeOf(ptr_z[1..][0..2 :4]) == *[2:4]u8);
554 try comptime expect(@TypeOf(ptr_z[1.. :0][0..2]) == *[2]u8);562 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);
556 try comptime expect(@TypeOf(ptr_z[1.. :0][0..2 :4]) == *[2:4]u8);564 try comptime expect(@TypeOf(ptr_z[1.. :0][0..2 :4]) == *[2:4]u8);
557 }565 }
558 };566 };
...@@ -869,3 +877,20 @@ test "write through pointer to optional slice arg" {...@@ -869,3 +877,20 @@ test "write through pointer to optional slice arg" {
869 try S.bar(&foo);877 try S.bar(&foo);
870 try expectEqualStrings(foo.?, "ok");878 try expectEqualStrings(foo.?, "ok");
871}879}
880
881test "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}