From 0f38558435a0f73c4c025b5641bd8e531f063e0c Mon Sep 17 00:00:00 2001 From: mlugg Date: Wed, 5 Feb 2025 19:36:14 +0000 Subject: compiler: provide result type to sentinel expression in slice operation Resolves: #21867 --- lib/std/zig/AstGen.zig | 6 +++++- lib/std/zig/Zir.zig | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) (limited to 'lib/std') diff --git a/lib/std/zig/AstGen.zig b/lib/std/zig/AstGen.zig index c105a371ef..d43a837b2f 100644 --- a/lib/std/zig/AstGen.zig +++ b/lib/std/zig/AstGen.zig @@ -920,7 +920,10 @@ fn expr(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.Index) InnerE const cursor = maybeAdvanceSourceCursorToMainToken(gz, node); const start = try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, full.ast.start); const end = if (full.ast.end != 0) try expr(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, full.ast.end) else .none; - const sentinel = if (full.ast.sentinel != 0) try expr(gz, scope, .{ .rl = .none }, full.ast.sentinel) else .none; + const sentinel = if (full.ast.sentinel != 0) s: { + const sentinel_ty = try gz.addUnNode(.slice_sentinel_ty, lhs, node); + break :s try expr(gz, scope, .{ .rl = .{ .coerced_ty = sentinel_ty } }, full.ast.sentinel); + } else .none; try emitDbgStmt(gz, cursor); if (sentinel != .none) { const result = try gz.addPlNode(.slice_sentinel, node, Zir.Inst.SliceSentinel{ @@ -2855,6 +2858,7 @@ fn addEnsureResult(gz: *GenZir, maybe_unused_result: Zir.Inst.Ref, statement: As .slice_end, .slice_sentinel, .slice_length, + .slice_sentinel_ty, .import, .switch_block, .switch_block_ref, diff --git a/lib/std/zig/Zir.zig b/lib/std/zig/Zir.zig index 092a354de6..32872eeabc 100644 --- a/lib/std/zig/Zir.zig +++ b/lib/std/zig/Zir.zig @@ -599,6 +599,10 @@ pub const Inst = struct { /// Returns a pointer to the subslice. /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceLength`. slice_length, + /// Given a value which is a pointer to the LHS of a slice operation, return the sentinel + /// type, used as the result type of the slice sentinel (i.e. `s` in `lhs[a..b :s]`). + /// Uses the `un_node` field. AST node is the slice syntax. Operand is `lhs`. + slice_sentinel_ty, /// Same as `store` except provides a source location. /// Uses the `pl_node` union field. Payload is `Bin`. store_node, @@ -1185,6 +1189,7 @@ pub const Inst = struct { .slice_end, .slice_sentinel, .slice_length, + .slice_sentinel_ty, .import, .typeof_log2_int_type, .resolve_inferred_alloc, @@ -1472,6 +1477,7 @@ pub const Inst = struct { .slice_end, .slice_sentinel, .slice_length, + .slice_sentinel_ty, .import, .typeof_log2_int_type, .switch_block, @@ -1702,6 +1708,7 @@ pub const Inst = struct { .slice_end = .pl_node, .slice_sentinel = .pl_node, .slice_length = .pl_node, + .slice_sentinel_ty = .un_node, .store_node = .pl_node, .store_to_inferred_ptr = .pl_node, .str = .str, @@ -4162,6 +4169,7 @@ fn findTrackableInner( .slice_end, .slice_sentinel, .slice_length, + .slice_sentinel_ty, .store_node, .store_to_inferred_ptr, .str, -- cgit v1.2.3