Commit 5b6326ec65
Changed files (4)
lib
std
zig
test
lib/std/zig/AstGen.zig
@@ -881,21 +881,14 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE
.slice_sentinel,
=> {
const full = tree.fullSlice(node).?;
- const lhs_tag = node_tags[full.ast.sliced];
- const lhs_is_slice_sentinel = lhs_tag == .slice_sentinel;
- const lhs_is_open_slice = lhs_tag == .slice_open or
- (lhs_is_slice_sentinel and tree.fullSlice(full.ast.sliced).?.ast.end == 0);
if (full.ast.end != 0 and
- lhs_is_open_slice and
+ node_tags[full.ast.sliced] == .slice_open and
nodeIsTriviallyZero(tree, full.ast.start))
{
- const lhs = try expr(gz, scope, .{ .rl = .ref }, node_datas[full.ast.sliced].lhs);
-
- const start = if (lhs_is_slice_sentinel) start: {
- const lhs_extra = tree.extraData(node_datas[full.ast.sliced].rhs, Ast.Node.SliceSentinel);
- break :start try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, lhs_extra.start);
- } else try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[full.ast.sliced].rhs);
+ const lhs_extra = tree.sliceOpen(full.ast.sliced).ast;
+ const lhs = try expr(gz, scope, .{ .rl = .ref }, lhs_extra.sliced);
+ const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, lhs_extra.start);
const cursor = maybeAdvanceSourceCursorToMainToken(gz, node);
const len = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, full.ast.end);
const sentinel = if (full.ast.sentinel != 0) try expr(gz, scope, .{ .rl = .none }, full.ast.sentinel) else .none;
test/behavior/slice.zig
@@ -115,6 +115,23 @@ test "open slice of open slice with sentinel" {
try expect(slice[1..][0.. :0][4] == 0);
}
+test "open slice with sentinel of slice with end index" {
+ if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO
+
+ var slice: [:0]const u8 = "hello";
+ _ = &slice;
+
+ comptime assert(@TypeOf(slice[0.. :0][0..5]) == *const [5]u8);
+ try expect(slice[0.. :0][0..5].len == 5);
+ try expect(slice[0.. :0][0..5][0] == 'h');
+ try expect(slice[0.. :0][0..5][4] == 'o');
+
+ comptime assert(@TypeOf(slice[0.. :0][0..5 :0]) == *const [5:0]u8);
+ try expect(slice[0.. :0][0..5 :0].len == 5);
+ try expect(slice[0.. :0][0..5 :0][0] == 'h');
+ try expect(slice[0.. :0][0..5 :0][5] == 0);
+}
+
test "slice of type" {
comptime {
var types_array = [_]type{ i32, f64, type };
test/cases/safety/slice by length sentinel mismatch on lhs.zig
@@ -0,0 +1,18 @@
+const std = @import("std");
+
+pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
+ _ = stack_trace;
+ if (std.mem.eql(u8, message, "sentinel mismatch: expected 1, found 3")) {
+ std.process.exit(0);
+ }
+ std.process.exit(1);
+}
+pub fn main() !void {
+ var buf: [4:0]u8 = .{ 1, 2, 3, 4 };
+ const slice = buf[0..][0..2 :1];
+ _ = slice;
+ return error.TestFailed;
+}
+// run
+// backend=llvm
+// target=native
test/cases/safety/slice by length sentinel mismatch on rhs.zig
@@ -0,0 +1,18 @@
+const std = @import("std");
+
+pub fn panic(message: []const u8, stack_trace: ?*std.builtin.StackTrace, _: ?usize) noreturn {
+ _ = stack_trace;
+ if (std.mem.eql(u8, message, "sentinel mismatch: expected 1, found 0")) {
+ std.process.exit(0);
+ }
+ std.process.exit(1);
+}
+pub fn main() !void {
+ var buf: [4:0]u8 = .{ 1, 2, 3, 4 };
+ const slice = buf[0.. :1][0..2];
+ _ = slice;
+ return error.TestFailed;
+}
+// run
+// backend=llvm
+// target=native