authorgravatar for robin@voetter.nlRobin Voetter <robin@voetter.nl> 2021-08-25 03:44:43+02:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-08-27 18:53:03-04:00
logcfae70ec8e736af3fcd465c78bd80e160968eea8
tree04e5925f0ee0d8485644f58ff0f99f492065c232
parent3aa533519da073695a56a56159b7ea3c487fb1b2

Make slice always return a reference

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

2 files changed, 24 insertions(+), 3 deletions(-)

src/AstGen.zig+21-3
...@@ -698,7 +698,13 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -698,7 +698,13 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
698 .lhs = lhs,698 .lhs = lhs,
699 .start = start,699 .start = start,
700 });700 });
701 return rvalue(gz, rl, result, node);701 switch (rl) {
702 .ref, .none_or_ref => return result,
703 else => {
704 const dereffed = try gz.addUnNode(.load, result, node);
705 return rvalue(gz, rl, dereffed, node);
706 },
707 }
702 },708 },
703 .slice => {709 .slice => {
704 const lhs = try expr(gz, scope, .ref, node_datas[node].lhs);710 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...@@ -710,7 +716,13 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
710 .start = start,716 .start = start,
711 .end = end,717 .end = end,
712 });718 });
713 return rvalue(gz, rl, result, node);719 switch (rl) {
720 .ref, .none_or_ref => return result,
721 else => {
722 const dereffed = try gz.addUnNode(.load, result, node);
723 return rvalue(gz, rl, dereffed, node);
724 },
725 }
714 },726 },
715 .slice_sentinel => {727 .slice_sentinel => {
716 const lhs = try expr(gz, scope, .ref, node_datas[node].lhs);728 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...@@ -724,7 +736,13 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
724 .end = end,736 .end = end,
725 .sentinel = sentinel,737 .sentinel = sentinel,
726 });738 });
727 return rvalue(gz, rl, result, node);739 switch (rl) {
740 .ref, .none_or_ref => return result,
741 else => {
742 const dereffed = try gz.addUnNode(.load, result, node);
743 return rvalue(gz, rl, dereffed, node);
744 },
745 }
728 },746 },
729747
730 .deref => {748 .deref => {
src/Zir.zig+3
...@@ -495,12 +495,15 @@ pub const Inst = struct {...@@ -495,12 +495,15 @@ pub const Inst = struct {
495 /// Uses the `ptr_type` union field.495 /// Uses the `ptr_type` union field.
496 ptr_type,496 ptr_type,
497 /// Slice operation `lhs[rhs..]`. No sentinel and no end offset.497 /// Slice operation `lhs[rhs..]`. No sentinel and no end offset.
498 /// Returns a pointer to the subslice.
498 /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceStart`.499 /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceStart`.
499 slice_start,500 slice_start,
500 /// Slice operation `array_ptr[start..end]`. No sentinel.501 /// Slice operation `array_ptr[start..end]`. No sentinel.
502 /// Returns a pointer to the subslice.
501 /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceEnd`.503 /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceEnd`.
502 slice_end,504 slice_end,
503 /// Slice operation `array_ptr[start..end:sentinel]`.505 /// Slice operation `array_ptr[start..end:sentinel]`.
506 /// Returns a pointer to the subslice.
504 /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceSentinel`.507 /// Uses the `pl_node` field. AST node is the slice syntax. Payload is `SliceSentinel`.
505 slice_sentinel,508 slice_sentinel,
506 /// Write a value to a pointer. For loading, see `load`.509 /// Write a value to a pointer. For loading, see `load`.