zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

commit cfae70ec8e736af3fcd465c78bd80e160968eea8 (tree)
parent 3aa533519da073695a56a56159b7ea3c487fb1b2
Author: Robin Voetter <robin@voetter.nl>
Date:   Wed, 25 Aug 2021 03:44:43 +0200

Make slice always return a reference

Previously this returned an rvalue, which leads to unexpected behaviour
when writing expressions such as `x[1..][1..].`

Diffstat:
Msrc/AstGen.zig | 24+++++++++++++++++++++---
Msrc/Zir.zig | 3+++
2 files changed, 24 insertions(+), 3 deletions(-)

diff --git a/src/AstGen.zig b/src/AstGen.zig @@ -698,7 +698,13 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr .lhs = lhs, .start = start, }); - return rvalue(gz, rl, result, node); + switch (rl) { + .ref, .none_or_ref => return result, + else => { + const dereffed = try gz.addUnNode(.load, result, node); + return rvalue(gz, rl, dereffed, node); + }, + } }, .slice => { const lhs = try expr(gz, scope, .ref, node_datas[node].lhs); @@ -710,7 +716,13 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr .start = start, .end = end, }); - return rvalue(gz, rl, result, node); + switch (rl) { + .ref, .none_or_ref => return result, + else => { + const dereffed = try gz.addUnNode(.load, result, node); + return rvalue(gz, rl, dereffed, node); + }, + } }, .slice_sentinel => { const lhs = try expr(gz, scope, .ref, node_datas[node].lhs); @@ -724,7 +736,13 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr .end = end, .sentinel = sentinel, }); - return rvalue(gz, rl, result, node); + switch (rl) { + .ref, .none_or_ref => return result, + else => { + const dereffed = try gz.addUnNode(.load, result, node); + return rvalue(gz, rl, dereffed, node); + }, + } }, .deref => { diff --git a/src/Zir.zig b/src/Zir.zig @@ -495,12 +495,15 @@ pub const Inst = struct { /// Uses the `ptr_type` union field. ptr_type, /// Slice operation `lhs[rhs..]`. No sentinel and no end offset. + /// Returns a pointer to the subslice. /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceStart`. slice_start, /// Slice operation `array_ptr[start..end]`. No sentinel. + /// Returns a pointer to the subslice. /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceEnd`. slice_end, /// Slice operation `array_ptr[start..end:sentinel]`. + /// Returns a pointer to the subslice. /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceSentinel`. slice_sentinel, /// Write a value to a pointer. For loading, see `load`.