authorgravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-11-09 23:30:53+11:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-01-14 17:26:45-08:00
log8afafa717f5c036595a3a781c63b6be7b478c025
tree2145251bc86112d102000e07c1ba3e9d3a8dfd97
parent4debd4338ce2c27a0dd6127ce5736ca56538214c

sema: allow slicing *T with comptime known [0..1]


4 files changed, 127 insertions(+), 12 deletions(-)

src/Sema.zig+74-2
......@@ -32572,14 +32572,86 @@ fn analyzeSlice(
3257232572 .Pointer => switch (ptr_ptr_child_ty.ptrSize(mod)) {
3257332573 .One => {
3257432574 const double_child_ty = ptr_ptr_child_ty.childType(mod);
32575 ptr_or_slice = try sema.analyzeLoad(block, src, ptr_ptr, ptr_src);
3257532576 if (double_child_ty.zigTypeTag(mod) == .Array) {
3257632577 ptr_sentinel = double_child_ty.sentinel(mod);
32577 ptr_or_slice = try sema.analyzeLoad(block, src, ptr_ptr, ptr_src);
3257832578 slice_ty = ptr_ptr_child_ty;
3257932579 array_ty = double_child_ty;
3258032580 elem_ty = double_child_ty.childType(mod);
3258132581 } else {
32582 return sema.fail(block, src, "slice of single-item pointer", .{});
32582 const bounds_error_message = "slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]";
32583 if (uncasted_end_opt == .none) {
32584 return sema.fail(block, src, bounds_error_message, .{});
32585 }
32586 const start_value = try sema.resolveConstDefinedValue(
32587 block,
32588 start_src,
32589 uncasted_start,
32590 .{ .needed_comptime_reason = bounds_error_message },
32591 );
32592
32593 const end_value = try sema.resolveConstDefinedValue(
32594 block,
32595 end_src,
32596 uncasted_end_opt,
32597 .{ .needed_comptime_reason = bounds_error_message },
32598 );
32599
32600 if (try sema.compareScalar(start_value, .neq, end_value, Type.comptime_int)) {
32601 if (try sema.compareScalar(start_value, .neq, InternPool.Index.zero.toValue(), Type.comptime_int)) {
32602 const err_msg = try sema.errMsg(block, start_src, bounds_error_message, .{});
32603 try sema.errNote(
32604 block,
32605 start_src,
32606 err_msg,
32607 "expected '{}', found '{}'",
32608 .{
32609 Value.zero_comptime_int.fmtValue(Type.comptime_int, mod),
32610 start_value.fmtValue(Type.comptime_int, mod),
32611 },
32612 );
32613 return sema.failWithOwnedErrorMsg(block, err_msg);
32614 } else if (try sema.compareScalar(end_value, .neq, InternPool.Index.one.toValue(), Type.comptime_int)) {
32615 const err_msg = try sema.errMsg(block, end_src, bounds_error_message, .{});
32616 try sema.errNote(
32617 block,
32618 end_src,
32619 err_msg,
32620 "expected '{}', found '{}'",
32621 .{
32622 Value.one_comptime_int.fmtValue(Type.comptime_int, mod),
32623 end_value.fmtValue(Type.comptime_int, mod),
32624 },
32625 );
32626 return sema.failWithOwnedErrorMsg(block, err_msg);
32627 }
32628 } else {
32629 if (try sema.compareScalar(end_value, .gt, InternPool.Index.one.toValue(), Type.comptime_int)) {
32630 return sema.fail(
32631 block,
32632 end_src,
32633 "end index {} out of bounds for slice of single-item pointer",
32634 .{end_value.fmtValue(Type.comptime_int, mod)},
32635 );
32636 }
32637 }
32638
32639 array_ty = try mod.arrayType(.{
32640 .len = 1,
32641 .child = double_child_ty.toIntern(),
32642 });
32643 const ptr_info = ptr_ptr_child_ty.ptrInfo(mod);
32644 slice_ty = try mod.ptrType(.{
32645 .child = array_ty.toIntern(),
32646 .flags = .{
32647 .alignment = ptr_info.flags.alignment,
32648 .is_const = ptr_info.flags.is_const,
32649 .is_allowzero = ptr_info.flags.is_allowzero,
32650 .is_volatile = ptr_info.flags.is_volatile,
32651 .address_space = ptr_info.flags.address_space,
32652 },
32653 });
32654 elem_ty = double_child_ty;
3258332655 }
3258432656 },
3258532657 .Many, .C => {
test/behavior/slice.zig+12
......@@ -416,6 +416,7 @@ test "slice syntax resulting in pointer-to-array" {
416416 try testArrayLengthZ();
417417 try testMultiPointer();
418418 try testMultiPointerLengthZ();
419 try testSingleItemPointer();
419420 }
420421
421422 fn testArray() !void {
......@@ -591,6 +592,17 @@ test "slice syntax resulting in pointer-to-array" {
591592 try comptime expect(@TypeOf(ptr_z[1.. :0][0..4]) == *[4]u8);
592593 try comptime expect(@TypeOf(ptr_z[1.. :0][0..2 :4]) == *[2:4]u8);
593594 }
595
596 fn testSingleItemPointer() !void {
597 var value: u8 = 1;
598 var ptr = &value;
599
600 const slice = ptr[0..1];
601 try comptime expect(@TypeOf(slice) == *[1]u8);
602 try expect(slice[0] == 1);
603
604 try comptime expect(@TypeOf(ptr[0..0]) == *[0]u8);
605 }
594606 };
595607
596608 try S.doTheTest();
test/cases/compile_errors/slice_of_single-item_pointer_bounds.zig created+41
......@@ -0,0 +1,41 @@
1const value: u8 = 1;
2const ptr = &value;
3
4comptime {
5 _ = ptr[0..];
6}
7
8comptime {
9 _ = ptr[1..2];
10}
11
12comptime {
13 _ = ptr[0..2];
14}
15
16comptime {
17 _ = ptr[2..2];
18}
19
20export fn entry1() void {
21 var start: usize = 0;
22 _ = ptr[start..2];
23}
24
25export fn entry2() void {
26 var end: usize = 0;
27 _ = ptr[0..end];
28}
29
30// error
31//
32// :5:12: error: slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]
33// :9:13: error: slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]
34// :9:13: note: expected '0', found '1'
35// :13:16: error: slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]
36// :13:16: note: expected '1', found '2'
37// :17:16: error: end index 2 out of bounds for slice of single-item pointer
38// :22:13: error: unable to resolve comptime value
39// :22:13: note: slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]
40// :27:16: error: unable to resolve comptime value
41// :27:16: note: slice of single-item pointer must have comptime-known bounds [0..0], [0..1], or [1..1]
test/cases/compile_errors/slicing_single-item_pointer.zig deleted-10
......@@ -1,10 +0,0 @@
1export fn entry(ptr: *i32) void {
2 const slice = ptr[0..2];
3 _ = slice;
4}
5
6// error
7// backend=stage2
8// target=native
9//
10// :2:22: error: slice of single-item pointer