From 5d51d4474a0c61f08c264c03ecbdf651d91afe82 Mon Sep 17 00:00:00 2001 From: Techatrix Date: Sun, 29 Dec 2024 05:53:47 +0100 Subject: [PATCH] fix slice of slice with sentinel but no end index example: ```zig test { var foo = ""; _ = foo[0..][0.. :0]; } ``` A `.slice_sentinel` ast node may not have an end index. --- lib/std/zig/AstGen.zig | 4 ++-- test/behavior/slice.zig | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/lib/std/zig/AstGen.zig b/lib/std/zig/AstGen.zig index 4ec5d3c60e..90d88d0d78 100644 --- a/lib/std/zig/AstGen.zig +++ b/lib/std/zig/AstGen.zig @@ -885,7 +885,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE 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 (node_tags[node] != .slice_open and + if (full.ast.end != 0 and lhs_is_open_slice and nodeIsTriviallyZero(tree, full.ast.start)) { @@ -897,7 +897,7 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE } else try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, node_datas[full.ast.sliced].rhs); const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); - const len = if (full.ast.end != 0) try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, full.ast.end) else .none; + 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; try emitDbgStmt(gz, cursor); const result = try gz.addPlNode(.slice_length, node, Zir.Inst.SliceLength{ diff --git a/test/behavior/slice.zig b/test/behavior/slice.zig index 4f5367ad85..7c03bb8a20 100644 --- a/test/behavior/slice.zig +++ b/test/behavior/slice.zig @@ -98,6 +98,23 @@ test "comptime slice of slice preserves comptime var" { } } +test "open slice of open slice with sentinel" { + if (builtin.zig_backend == .stage2_sparc64) return error.SkipZigTest; // TODO + + var slice: [:0]const u8 = "hello"; + _ = &slice; + + comptime assert(@TypeOf(slice[0..][0.. :0]) == [:0]const u8); + try expect(slice[0..][0.. :0].len == 5); + try expect(slice[0..][0.. :0][0] == 'h'); + try expect(slice[0..][0.. :0][5] == 0); + + comptime assert(@TypeOf(slice[1..][0.. :0]) == [:0]const u8); + try expect(slice[1..][0.. :0].len == 4); + try expect(slice[1..][0.. :0][0] == 'e'); + try expect(slice[1..][0.. :0][4] == 0); +} + test "slice of type" { comptime { var types_array = [_]type{ i32, f64, type };