parser: port upstream error detection, unskip all 14 tests

Mechanically port error handling patterns from upstream Parse.zig:
- &&/whitespace validation in binary operator parsing
- varargs state tracking in parameter lists
- invalid_bit_range check for slice types
- same-line doc comment detection in eatDocComments
- required for-loop payload validation
- error keyword requiring '.' for error values
- expected_semi_or_else checks in if/for/while statements
- labeled for/while/inline expressions in parsePrimaryExpr
- doc comment validation for test/comptime blocks
- EOF check in parseRoot
- comptime handling in else-branch context

All 381/381 tests pass with 0 skipped.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-11 12:57:56 +00:00
parent f3e70a0568
commit cd07751d13
2 changed files with 232 additions and 30 deletions

View File

@@ -4397,7 +4397,6 @@ test "zig fmt: comptime before comptime field" {
}
test "zig fmt: invalid doc comments on comptime and test blocks" {
if (true) return error.SkipZigTest;
try testError(
\\/// This is a doc comment for a comptime block.
\\comptime {}
@@ -4491,7 +4490,6 @@ test "zig fmt: extern without container keyword returns error" {
}
test "zig fmt: same line doc comment returns error" {
if (true) return error.SkipZigTest;
try testError(
\\const Foo = struct{
\\ bar: u32, /// comment
@@ -5099,7 +5097,6 @@ test "zig fmt: extern function with missing param name" {
}
test "zig fmt: line comment after multiline single expr if statement with multiline string" {
if (true) return error.SkipZigTest;
try testCanonical(
\\test {
\\ if (foo)
@@ -5592,7 +5589,6 @@ test "zig fmt: canonicalize symbols (simple)" {
// Contextually unescape when shadowing primitive types and values.
test "zig fmt: canonicalize symbols (primitive types)" {
if (true) return error.SkipZigTest;
try testTransform(
\\const @"anyopaque" = struct {
\\ @"u8": @"type" = true,
@@ -5885,7 +5881,6 @@ test "zig fmt: error for missing sentinel value in sentinel slice" {
}
test "zig fmt: error for invalid bit range" {
if (true) return error.SkipZigTest;
try testError(
\\var x: []align(0:0:0)u8 = bar;
, &[_]Error{
@@ -6168,7 +6163,6 @@ test "recovery: invalid extern/inline" {
}
test "recovery: missing semicolon" {
if (true) return error.SkipZigTest;
try testError(
\\test "" {
\\ comptime a & b
@@ -6188,7 +6182,6 @@ test "recovery: missing semicolon" {
// reporting a parse error and yet also parsing all the decls even
// inside structs.
test "recovery: extra '}' at top level" {
if (true) return error.SkipZigTest;
try testError(
\\}}}
\\test "" {
@@ -6210,7 +6203,6 @@ test "recovery: mismatched bracket at top level" {
}
test "recovery: invalid global error set access" {
if (true) return error.SkipZigTest;
try testError(
\\test "" {
\\ error & foo;
@@ -6240,7 +6232,6 @@ test "recovery: invalid asterisk after pointer dereference" {
}
test "recovery: missing semicolon after if, for, while stmt" {
if (true) return error.SkipZigTest;
try testError(
\\test "" {
\\ if (foo) bar
@@ -6256,7 +6247,6 @@ test "recovery: missing semicolon after if, for, while stmt" {
}
test "recovery: invalid comptime" {
if (true) return error.SkipZigTest;
try testError(
\\comptime
, &[_]Error{
@@ -6290,7 +6280,6 @@ test "recovery: missing block after for/while loops" {
}
test "recovery: missing for payload" {
if (true) return error.SkipZigTest;
try testError(
\\comptime {
\\ const a = for(a) {};
@@ -6327,7 +6316,6 @@ test "recovery: missing while rbrace" {
}
test "recovery: nonfinal varargs" {
if (true) return error.SkipZigTest;
try testError(
\\extern fn f(a: u32, ..., b: u32) void;
\\extern fn g(a: u32, ..., b: anytype) void;
@@ -6348,7 +6336,6 @@ test "recovery: eof in c pointer" {
}
test "matching whitespace on minus op" {
if (true) return error.SkipZigTest;
try testError(
\\ _ = 2 -1,
\\ _ = 2- 1,
@@ -6377,7 +6364,6 @@ test "matching whitespace on minus op" {
}
test "ampersand" {
if (true) return error.SkipZigTest;
try testError(
\\ _ = bar && foo,
\\ _ = bar&&foo,
@@ -6439,10 +6425,13 @@ fn testCanonical(source: [:0]const u8) !void {
const Error = std.zig.Ast.Error.Tag;
fn testError(source: [:0]const u8, expected_errors: []const Error) !void {
_ = expected_errors;
var c_tree = c.astParse(source, @intCast(source.len));
defer c.astDeinit(&c_tree);
try std.testing.expect(c_tree.has_error);
if (expected_errors.len == 0) {
try std.testing.expect(!c_tree.has_error);
} else {
try std.testing.expect(c_tree.has_error);
}
}
const testing = std.testing;