Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion doc/langref.html.in
Original file line number Diff line number Diff line change
Expand Up @@ -2649,7 +2649,7 @@ test "Conversion between vectors, arrays, and slices" {
<li>{#syntax#}[*]T{#endsyntax#} - many-item pointer to unknown number of items.
<ul>
<li>Supports index syntax: {#syntax#}ptr[i]{#endsyntax#}</li>
<li>Supports slice syntax: {#syntax#}ptr[start..end]{#endsyntax#}</li>
<li>Supports slice syntax: {#syntax#}ptr[start..end]{#endsyntax#} and {#syntax#}ptr[start..]{#endsyntax#}</li>
<li>Supports pointer arithmetic: {#syntax#}ptr + x{#endsyntax#}, {#syntax#}ptr - x{#endsyntax#}</li>
<li>{#syntax#}T{#endsyntax#} must have a known size, which means that it cannot be
{#syntax#}anyopaque{#endsyntax#} or any other {#link|opaque type|opaque#}.</li>
Expand Down Expand Up @@ -2724,6 +2724,10 @@ test "pointer arithmetic with many-item pointer" {
try expect(ptr[0] == 1);
ptr += 1;
try expect(ptr[0] == 2);

// slicing a many-item pointer without an end is equivalent to
// pointer arithmetic: `ptr[start..] == ptr + start`
try expect(ptr[1..] == ptr + 1);
}

test "pointer arithmetic with slices" {
Expand Down
2 changes: 1 addition & 1 deletion src/Sema.zig
Original file line number Diff line number Diff line change
Expand Up @@ -32157,7 +32157,7 @@ fn analyzeSlice(
break :e try sema.coerce(block, Type.usize, uncasted_end, end_src);
} else break :e try sema.coerce(block, Type.usize, uncasted_end_opt, end_src);
}
return sema.fail(block, src, "slice of pointer must include end value", .{});
return sema.analyzePtrArithmetic(block, src, ptr, start, .ptr_add, ptr_src, start_src);
};

const sentinel = s: {
Expand Down
35 changes: 35 additions & 0 deletions test/behavior/slice.zig
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,41 @@ test "@ptrCast slice to pointer" {
try comptime S.doTheTest();
}

test "slice multi-pointer without end" {
const S = struct {
fn doTheTest() !void {
try testPointer();
try testPointerZ();
}

fn testPointer() !void {
var array = [5]u8{ 1, 2, 3, 4, 5 };
var pointer: [*]u8 = &array;
var slice = pointer[1..];
try comptime expect(@TypeOf(slice) == [*]u8);
try expect(slice[0] == 2);
try expect(slice[1] == 3);
}

fn testPointerZ() !void {
var array = [5:0]u8{ 1, 2, 3, 4, 5 };
var pointer: [*:0]u8 = &array;

try comptime expect(@TypeOf(pointer[1..3]) == *[2]u8);
try comptime expect(@TypeOf(pointer[1..3 :4]) == *[2:4]u8);
try comptime expect(@TypeOf(pointer[1..5 :0]) == *[4:0]u8);

var slice = pointer[1..];
try comptime expect(@TypeOf(slice) == [*:0]u8);
try expect(slice[0] == 2);
try expect(slice[1] == 3);
}
};

try S.doTheTest();
try comptime S.doTheTest();
}

test "slice syntax resulting in pointer-to-array" {
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
Expand Down