authorgravatar for goon.pri.low@gmail.comKendall Condon <goon.pri.low@gmail.com> 2026-05-26 17:11:33-04:00
committergravatar for alex@alexrp.comAlex Rønne Petersen <alex@alexrp.com> 2026-10-09 10:09:42+02:00
log7287181ff52660615a4f05e4b45f9ade0fed267d
treeb60916aead071055bc7e4c5de2b21de60ebce91f
parent9195b36a6c55c2f2084d8a2edfd9a98c2e077e8c

AstGen: add missing cursor restores


3 files changed, 35 insertions(+), 0 deletions(-)

lib/std/zig/AstGen.zig+8
...@@ -1460,6 +1460,7 @@ fn arrayInitExpr(...@@ -1460,6 +1460,7 @@ fn arrayInitExpr(
1460 mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(array_type.ast.elem_count)), "_"))1460 mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(array_type.ast.elem_count)), "_"))
1461 {1461 {
1462 const len_inst = try gz.addInt(array_init.ast.elements.len);1462 const len_inst = try gz.addInt(array_init.ast.elements.len);
1463 const saved_cursor = astgen.saveSourceCursor();
1463 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);1464 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);
1464 if (array_type.ast.sentinel == .none) {1465 if (array_type.ast.sentinel == .none) {
1465 const array_type_inst = try gz.addPlNode(.array_type, type_expr, Zir.Inst.Bin{1466 const array_type_inst = try gz.addPlNode(.array_type, type_expr, Zir.Inst.Bin{
...@@ -1468,6 +1469,7 @@ fn arrayInitExpr(...@@ -1468,6 +1469,7 @@ fn arrayInitExpr(
1468 });1469 });
1469 break :inst .{ array_type_inst, elem_type };1470 break :inst .{ array_type_inst, elem_type };
1470 } else {1471 } else {
1472 astgen.restoreSourceCursor(saved_cursor);
1471 const sentinel_node = array_type.ast.sentinel.unwrap().?;1473 const sentinel_node = array_type.ast.sentinel.unwrap().?;
1472 const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, sentinel_node, .array_sentinel);1474 const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, sentinel_node, .array_sentinel);
1473 const array_type_inst = try gz.addPlNode(1475 const array_type_inst = try gz.addPlNode(
...@@ -1729,6 +1731,7 @@ fn structInitExpr(...@@ -1729,6 +1731,7 @@ fn structInitExpr(
1729 mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(array_type.ast.elem_count)), "_");1731 mem.eql(u8, tree.tokenSlice(tree.nodeMainToken(array_type.ast.elem_count)), "_");
1730 if (struct_init.ast.fields.len == 0) {1732 if (struct_init.ast.fields.len == 0) {
1731 if (is_inferred_array_len) {1733 if (is_inferred_array_len) {
1734 const saved_cursor = astgen.saveSourceCursor();
1732 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);1735 const elem_type = try typeExpr(gz, scope, array_type.ast.elem_type);
1733 const array_type_inst = if (array_type.ast.sentinel == .none) blk: {1736 const array_type_inst = if (array_type.ast.sentinel == .none) blk: {
1734 break :blk try gz.addPlNode(.array_type, type_expr, Zir.Inst.Bin{1737 break :blk try gz.addPlNode(.array_type, type_expr, Zir.Inst.Bin{
...@@ -1736,6 +1739,7 @@ fn structInitExpr(...@@ -1736,6 +1739,7 @@ fn structInitExpr(
1736 .rhs = elem_type,1739 .rhs = elem_type,
1737 });1740 });
1738 } else blk: {1741 } else blk: {
1742 astgen.restoreSourceCursor(saved_cursor);
1739 const sentinel_node = array_type.ast.sentinel.unwrap().?;1743 const sentinel_node = array_type.ast.sentinel.unwrap().?;
1740 const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, sentinel_node, .array_sentinel);1744 const sentinel = try comptimeExpr(gz, scope, .{ .rl = .{ .ty = elem_type } }, sentinel_node, .array_sentinel);
1741 break :blk try gz.addPlNode(1745 break :blk try gz.addPlNode(
...@@ -3436,6 +3440,7 @@ fn assignDestructureMaybeDecls(...@@ -3436,6 +3440,7 @@ fn assignDestructureMaybeDecls(
3436 const is_comptime = full.comptime_token != null or gz.is_comptime;3440 const is_comptime = full.comptime_token != null or gz.is_comptime;
3437 const value_is_comptime = tree.nodeTag(full.ast.value_expr) == .@"comptime";3441 const value_is_comptime = tree.nodeTag(full.ast.value_expr) == .@"comptime";
34383442
3443 const saved_cursor = astgen.saveSourceCursor();
3439 // When declaring consts via a destructure, we always use a result pointer.3444 // When declaring consts via a destructure, we always use a result pointer.
3440 // This avoids the need to create tuple types, and is also likely easier to3445 // This avoids the need to create tuple types, and is also likely easier to
3441 // optimize, since it's a bit tricky for the optimizer to "split up" the3446 // optimize, since it's a bit tricky for the optimizer to "split up" the
...@@ -3563,6 +3568,7 @@ fn assignDestructureMaybeDecls(...@@ -3563,6 +3568,7 @@ fn assignDestructureMaybeDecls(
3563 if (any_lvalue_expr) {3568 if (any_lvalue_expr) {
3564 // At least one variable was an lvalue expr. Iterate again in order to3569 // At least one variable was an lvalue expr. Iterate again in order to
3565 // evaluate the lvalues from within the possible block_comptime.3570 // evaluate the lvalues from within the possible block_comptime.
3571 astgen.restoreSourceCursor(saved_cursor);
3566 for (rl_components, full.ast.variables) |*variable_rl, variable_node| {3572 for (rl_components, full.ast.variables) |*variable_rl, variable_node| {
3567 if (variable_rl.* != .typed_ptr) continue;3573 if (variable_rl.* != .typed_ptr) continue;
3568 switch (tree.nodeTag(variable_node)) {3574 switch (tree.nodeTag(variable_node)) {
...@@ -3896,7 +3902,9 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node....@@ -3896,7 +3902,9 @@ fn arrayTypeSentinel(gz: *GenZir, scope: *Scope, ri: ResultInfo, node: Ast.Node.
3896 return astgen.failNode(len_node, "unable to infer array size", .{});3902 return astgen.failNode(len_node, "unable to infer array size", .{});
3897 }3903 }
3898 const len = try reachableExprComptime(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, len_node, node, .array_length);3904 const len = try reachableExprComptime(gz, scope, .{ .rl = .{ .coerced_ty = .usize_type } }, len_node, node, .array_length);
3905 const saved_cursor = astgen.saveSourceCursor();
3899 const elem_type = try typeExpr(gz, scope, extra.elem_type);3906 const elem_type = try typeExpr(gz, scope, extra.elem_type);
3907 astgen.restoreSourceCursor(saved_cursor);
3900 const sentinel = try reachableExprComptime(gz, scope, .{ .rl = .{ .coerced_ty = elem_type } }, extra.sentinel, node, .array_sentinel);3908 const sentinel = try reachableExprComptime(gz, scope, .{ .rl = .{ .coerced_ty = elem_type } }, extra.sentinel, node, .array_sentinel);
39013909
3902 const result = try gz.addPlNode(.array_type_sentinel, node, Zir.Inst.ArrayTypeSentinel{3910 const result = try gz.addPlNode(.array_type_sentinel, node, Zir.Inst.ArrayTypeSentinel{
test/cases/array_sentinel_cursor.zig created+14
...@@ -0,0 +1,14 @@
1fn s() usize {
2 return 64;
3}
4
5fn T() type {
6 return u64;
7}
8
9const Array = [64:s()]T();
10const empty = [_:s()]T(){};
11const items = [_:s()]T(){100};
12
13// compile
14// output_mode=Obj
test/cases/tuple_assign_cursor.zig created+13
...@@ -0,0 +1,13 @@
1fn T() type {
2 return u64;
3}
4
5test {
6 struct {
7 var a: u64 = 0;
8 }.a, const b: T() = .{ 1, 2 };
9 _ = b;
10}
11
12// compile
13// output_mode=Obj