Commit 1f81887a78
Changed files (3)
lib
lib/std/zig/ast.zig
@@ -129,6 +129,7 @@ pub const Error = union(enum) {
ExpectedStatement: ExpectedStatement,
ExpectedVarDeclOrFn: ExpectedVarDeclOrFn,
ExpectedVarDecl: ExpectedVarDecl,
+ ExpectedFn: ExpectedFn,
ExpectedReturnType: ExpectedReturnType,
ExpectedAggregateKw: ExpectedAggregateKw,
UnattachedDocComment: UnattachedDocComment,
@@ -179,6 +180,7 @@ pub const Error = union(enum) {
.ExpectedStatement => |*x| return x.render(tokens, stream),
.ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),
.ExpectedVarDecl => |*x| return x.render(tokens, stream),
+ .ExpectedFn => |*x| return x.render(tokens, stream),
.ExpectedReturnType => |*x| return x.render(tokens, stream),
.ExpectedAggregateKw => |*x| return x.render(tokens, stream),
.UnattachedDocComment => |*x| return x.render(tokens, stream),
@@ -231,6 +233,7 @@ pub const Error = union(enum) {
.ExpectedStatement => |x| return x.token,
.ExpectedVarDeclOrFn => |x| return x.token,
.ExpectedVarDecl => |x| return x.token,
+ .ExpectedFn => |x| return x.token,
.ExpectedReturnType => |x| return x.token,
.ExpectedAggregateKw => |x| return x.token,
.UnattachedDocComment => |x| return x.token,
@@ -280,6 +283,7 @@ pub const Error = union(enum) {
pub const ExpectedStatement = SingleTokenError("Expected statement, found '{}'");
pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found '{}'");
pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{}'");
+ pub const ExpectedFn = SingleTokenError("Expected function, found '{}'");
pub const ExpectedReturnType = SingleTokenError("Expected 'var' or return type expression, found '{}'");
pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Id.Keyword_struct.symbol() ++ "', '" ++ Token.Id.Keyword_union.symbol() ++ "', or '" ++ Token.Id.Keyword_enum.symbol() ++ "', found '{}'");
pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{}'");
lib/std/zig/parse.zig
@@ -360,15 +360,17 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
try tree.errors.push(.{
.ExpectedSemiOrLBrace = .{ .token = it.index },
});
- return null;
+ return error.ParseError;
}
if (extern_export_inline_token) |token| {
if (tree.tokens.at(token).id == .Keyword_inline or
tree.tokens.at(token).id == .Keyword_noinline)
{
- putBackToken(it, token);
- return null;
+ try tree.errors.push(.{
+ .ExpectedFn = .{ .token = it.index },
+ });
+ return error.ParseError;
}
}
@@ -399,10 +401,11 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
}
if (extern_export_inline_token) |token| {
- if (lib_name) |string_literal_node|
- putBackToken(it, string_literal_node.cast(Node.StringLiteral).?.token);
- putBackToken(it, token);
- return null;
+ try tree.errors.push(.{
+ .ExpectedVarDeclOrFn = .{ .token = it.index },
+ });
+ // ignore this and try again;
+ return error.ParseError;
}
return parseUse(arena, it, tree) catch |err| switch (err) {
lib/std/zig/parser_test.zig
@@ -84,6 +84,21 @@ test "recovery: continue after invalid decl" {
});
}
+test "recovery: invalid extern/inline" {
+ try testError(
+ \\inline test "" { a && b; }
+ , &[_]Error{
+ .ExpectedFn,
+ .InvalidAnd,
+ });
+ try testError(
+ \\extern "" test "" { a && b; }
+ , &[_]Error{
+ .ExpectedVarDeclOrFn,
+ .InvalidAnd,
+ });
+}
+
test "zig fmt: top-level fields" {
try testCanonical(
\\a: did_you_know,