| ... | ... | @@ -92,7 +92,7 @@ fn reserveNode(p: *Parse, tag: Ast.Node.Tag) !usize { |
| 92 | 92 | } |
| 93 | 93 | |
| 94 | 94 | fn unreserveNode(p: *Parse, node_index: usize) void { |
| 95 | | if (p.nodes.len == node_index) { |
| 95 | if (p.nodes.len == node_index + 1) { |
| 96 | 96 | p.nodes.resize(p.gpa, p.nodes.len - 1) catch unreachable; |
| 97 | 97 | } else { |
| 98 | 98 | // There is zombie node left in the tree, let's make it as inoffensive as possible |
| ... | ... | @@ -3417,3 +3417,22 @@ const Token = std.zig.Token; |
| 3417 | 3417 | test { |
| 3418 | 3418 | _ = @import("parser_test.zig"); |
| 3419 | 3419 | } |
| 3420 | |
| 3421 | test "unreserving a freshly reserved AST node must not create zombies" { |
| 3422 | const gpa = std.testing.allocator; |
| 3423 | var parser: Parse = .{ |
| 3424 | .gpa = gpa, |
| 3425 | .nodes = .empty, |
| 3426 | .errors = .empty, |
| 3427 | .extra_data = .empty, |
| 3428 | .scratch = .empty, |
| 3429 | .source = "", |
| 3430 | .tok_i = 0, |
| 3431 | .tokens = undefined, |
| 3432 | .recover = false, |
| 3433 | }; |
| 3434 | defer parser.nodes.deinit(gpa); |
| 3435 | const last = try parser.reserveNode(.@"try"); |
| 3436 | parser.unreserveNode(last); |
| 3437 | try std.testing.expectEqual(parser.nodes.len, 0); |
| 3438 | } |