authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-13 23:35:58+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2020-05-13 23:35:58+03:00
log1f81887a7863545d8b89bff6cc7d31941da0abf0
tree0afe1df9c8a090d24dceab7486b1ad2fd8abff4b
parentad71d959d7d1b5f3a771dc2c1eaf37dbd7cd0852
signature Commit is signed but in an unrecognized format.

recover after invalid inline/extern


3 files changed, 29 insertions(+), 7 deletions(-)

lib/std/zig/ast.zig+4
......@@ -129,6 +129,7 @@ pub const Error = union(enum) {
129129 ExpectedStatement: ExpectedStatement,
130130 ExpectedVarDeclOrFn: ExpectedVarDeclOrFn,
131131 ExpectedVarDecl: ExpectedVarDecl,
132 ExpectedFn: ExpectedFn,
132133 ExpectedReturnType: ExpectedReturnType,
133134 ExpectedAggregateKw: ExpectedAggregateKw,
134135 UnattachedDocComment: UnattachedDocComment,
......@@ -179,6 +180,7 @@ pub const Error = union(enum) {
179180 .ExpectedStatement => |*x| return x.render(tokens, stream),
180181 .ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),
181182 .ExpectedVarDecl => |*x| return x.render(tokens, stream),
183 .ExpectedFn => |*x| return x.render(tokens, stream),
182184 .ExpectedReturnType => |*x| return x.render(tokens, stream),
183185 .ExpectedAggregateKw => |*x| return x.render(tokens, stream),
184186 .UnattachedDocComment => |*x| return x.render(tokens, stream),
......@@ -231,6 +233,7 @@ pub const Error = union(enum) {
231233 .ExpectedStatement => |x| return x.token,
232234 .ExpectedVarDeclOrFn => |x| return x.token,
233235 .ExpectedVarDecl => |x| return x.token,
236 .ExpectedFn => |x| return x.token,
234237 .ExpectedReturnType => |x| return x.token,
235238 .ExpectedAggregateKw => |x| return x.token,
236239 .UnattachedDocComment => |x| return x.token,
......@@ -280,6 +283,7 @@ pub const Error = union(enum) {
280283 pub const ExpectedStatement = SingleTokenError("Expected statement, found '{}'");
281284 pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found '{}'");
282285 pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{}'");
286 pub const ExpectedFn = SingleTokenError("Expected function, found '{}'");
283287 pub const ExpectedReturnType = SingleTokenError("Expected 'var' or return type expression, found '{}'");
284288 pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Id.Keyword_struct.symbol() ++ "', '" ++ Token.Id.Keyword_union.symbol() ++ "', or '" ++ Token.Id.Keyword_enum.symbol() ++ "', found '{}'");
285289 pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{}'");
lib/std/zig/parse.zig+10-7
......@@ -360,15 +360,17 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
360360 try tree.errors.push(.{
361361 .ExpectedSemiOrLBrace = .{ .token = it.index },
362362 });
363 return null;
363 return error.ParseError;
364364 }
365365
366366 if (extern_export_inline_token) |token| {
367367 if (tree.tokens.at(token).id == .Keyword_inline or
368368 tree.tokens.at(token).id == .Keyword_noinline)
369369 {
370 putBackToken(it, token);
371 return null;
370 try tree.errors.push(.{
371 .ExpectedFn = .{ .token = it.index },
372 });
373 return error.ParseError;
372374 }
373375 }
374376
......@@ -399,10 +401,11 @@ fn parseTopLevelDecl(arena: *Allocator, it: *TokenIterator, tree: *Tree) Error!?
399401 }
400402
401403 if (extern_export_inline_token) |token| {
402 if (lib_name) |string_literal_node|
403 putBackToken(it, string_literal_node.cast(Node.StringLiteral).?.token);
404 putBackToken(it, token);
405 return null;
404 try tree.errors.push(.{
405 .ExpectedVarDeclOrFn = .{ .token = it.index },
406 });
407 // ignore this and try again;
408 return error.ParseError;
406409 }
407410
408411 return parseUse(arena, it, tree) catch |err| switch (err) {
lib/std/zig/parser_test.zig+15
......@@ -84,6 +84,21 @@ test "recovery: continue after invalid decl" {
8484 });
8585}
8686
87test "recovery: invalid extern/inline" {
88 try testError(
89 \\inline test "" { a && b; }
90 , &[_]Error{
91 .ExpectedFn,
92 .InvalidAnd,
93 });
94 try testError(
95 \\extern "" test "" { a && b; }
96 , &[_]Error{
97 .ExpectedVarDeclOrFn,
98 .InvalidAnd,
99 });
100}
101
87102test "zig fmt: top-level fields" {
88103 try testCanonical(
89104 \\a: did_you_know,