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" {
26492649 <li>{#syntax#}[*]T{#endsyntax#} - many-item pointer to unknown number of items.
26502650 <ul>
26512651 <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>
26532653 <li>Supports pointer arithmetic: {#syntax#}ptr + x{#endsyntax#}, {#syntax#}ptr - x{#endsyntax#}</li>
26542654 <li>{#syntax#}T{#endsyntax#} must have a known size, which means that it cannot be
26552655 {#syntax#}anyopaque{#endsyntax#} or any other {#link|opaque type|opaque#}.</li>
......@@ -2724,6 +2724,10 @@ test "pointer arithmetic with many-item pointer" {
27242724 try expect(ptr[0] == 1);
27252725 ptr += 1;
27262726 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);
27272731}
27282732
27292733test "pointer arithmetic with slices" {
src/Sema.zig+1-1
......@@ -32182,7 +32182,7 @@ fn analyzeSlice(
3218232182 break :e try sema.coerce(block, Type.usize, uncasted_end, end_src);
3218332183 } else break :e try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
3218432184 }
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);
3218632186 };
3218732187
3218832188 const sentinel = s: {
test/behavior/slice.zig+35
......@@ -348,6 +348,41 @@ test "@ptrCast slice to pointer" {
348348 try comptime S.doTheTest();
349349}
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
351386test "slice syntax resulting in pointer-to-array" {
352387 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
353388 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO