authorgravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-11-07 20:19:59+11:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2023-11-07 17:01:32+02:00
log81219586bc3d41cc462cd383269e06c069ab8004
treef7ea086747b95c923580c55870aead0877167437
parent03abac382457e071540314d050e21799b59b1d5b

sema: allow slicing [*]T without end


3 files changed, 41 insertions(+), 2 deletions(-)

doc/langref.html.in+5-1
...@@ -2649,7 +2649,7 @@ test "Conversion between vectors, arrays, and slices" {...@@ -2649,7 +2649,7 @@ test "Conversion between vectors, arrays, and slices" {
2649 <li>{#syntax#}[*]T{#endsyntax#} - many-item pointer to unknown number of items.2649 <li>{#syntax#}[*]T{#endsyntax#} - many-item pointer to unknown number of items.
2650 <ul>2650 <ul>
2651 <li>Supports index syntax: {#syntax#}ptr[i]{#endsyntax#}</li>2651 <li>Supports index syntax: {#syntax#}ptr[i]{#endsyntax#}</li>
2652 <li>Supports slice syntax: {#syntax#}ptr[start..end]{#endsyntax#}</li>2652 <li>Supports slice syntax: {#syntax#}ptr[start..end]{#endsyntax#} and {#syntax#}ptr[start..]{#endsyntax#}</li>
2653 <li>Supports pointer arithmetic: {#syntax#}ptr + x{#endsyntax#}, {#syntax#}ptr - x{#endsyntax#}</li>2653 <li>Supports pointer arithmetic: {#syntax#}ptr + x{#endsyntax#}, {#syntax#}ptr - x{#endsyntax#}</li>
2654 <li>{#syntax#}T{#endsyntax#} must have a known size, which means that it cannot be2654 <li>{#syntax#}T{#endsyntax#} must have a known size, which means that it cannot be
2655 {#syntax#}anyopaque{#endsyntax#} or any other {#link|opaque type|opaque#}.</li>2655 {#syntax#}anyopaque{#endsyntax#} or any other {#link|opaque type|opaque#}.</li>
...@@ -2724,6 +2724,10 @@ test "pointer arithmetic with many-item pointer" {...@@ -2724,6 +2724,10 @@ test "pointer arithmetic with many-item pointer" {
2724 try expect(ptr[0] == 1);2724 try expect(ptr[0] == 1);
2725 ptr += 1;2725 ptr += 1;
2726 try expect(ptr[0] == 2);2726 try expect(ptr[0] == 2);
2727
2728 // slicing a many-item pointer without an end is equivalent to
2729 // pointer arithmetic: `ptr[start..] == ptr + start`
2730 try expect(ptr[1..] == ptr + 1);
2727}2731}
27282732
2729test "pointer arithmetic with slices" {2733test "pointer arithmetic with slices" {
src/Sema.zig+1-1
...@@ -32182,7 +32182,7 @@ fn analyzeSlice(...@@ -32182,7 +32182,7 @@ fn analyzeSlice(
32182 break :e try sema.coerce(block, Type.usize, uncasted_end, end_src);32182 break :e try sema.coerce(block, Type.usize, uncasted_end, end_src);
32183 } else break :e try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);32183 } else break :e try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
32184 }32184 }
32185 return sema.fail(block, src, "slice of pointer must include end value", .{});32185 return sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src);
32186 };32186 };
3218732187
32188 const sentinel = s: {32188 const sentinel = s: {
test/behavior/slice.zig+35
...@@ -348,6 +348,41 @@ test "@ptrCast slice to pointer" {...@@ -348,6 +348,41 @@ test "@ptrCast slice to pointer" {
348 try comptime S.doTheTest();348 try comptime S.doTheTest();
349}349}
350350
351test "slice multi-pointer without end" {
352 const S = struct {
353 fn doTheTest() !void {
354 try testPointer();
355 try testPointerZ();
356 }
357
358 fn testPointer() !void {
359 var array = [5]u8{ 1, 2, 3, 4, 5 };
360 var pointer: [*]u8 = &array;
361 var slice = pointer[1..];
362 try comptime expect(@TypeOf(slice) == [*]u8);
363 try expect(slice[0] == 2);
364 try expect(slice[1] == 3);
365 }
366
367 fn testPointerZ() !void {
368 var array = [5:0]u8{ 1, 2, 3, 4, 5 };
369 var pointer: [*:0]u8 = &array;
370
371 try comptime expect(@TypeOf(pointer[1..3]) == *[2]u8);
372 try comptime expect(@TypeOf(pointer[1..3 :4]) == *[2:4]u8);
373 try comptime expect(@TypeOf(pointer[1..5 :0]) == *[4:0]u8);
374
375 var slice = pointer[1..];
376 try comptime expect(@TypeOf(slice) == [*:0]u8);
377 try expect(slice[0] == 2);
378 try expect(slice[1] == 3);
379 }
380 };
381
382 try S.doTheTest();
383 try comptime S.doTheTest();
384}
385
351test "slice syntax resulting in pointer-to-array" {386test "slice syntax resulting in pointer-to-array" {
352 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO387 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
353 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO388 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO