From 9607bd90e6927eea0fc7d57e042d03657afbf70d Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Fri, 28 Oct 2022 16:09:24 +0300 Subject: [PATCH] parser: improve error message for missing var/const before local variable Closes #12721 --- lib/std/zig/Ast.zig | 6 +++++- lib/std/zig/parse.zig | 13 ++++++++++++- lib/std/zig/parser_test.zig | 26 ++++++++++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig index 62a567387f..62eea275a8 100644 --- a/lib/std/zig/Ast.zig +++ b/lib/std/zig/Ast.zig @@ -197,7 +197,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { }); }, .expected_labelable => { - return stream.print("expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'", .{ + return stream.print("expected 'while', 'for', 'inline', or '{{', found '{s}'", .{ token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(), }); }, @@ -356,6 +356,9 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void { .next_field => { return stream.writeAll("field after declarations here"); }, + .expected_var_const => { + return stream.writeAll("expected 'var' or 'const' before variable declaration"); + }, .expected_token => { const found_tag = token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)]; @@ -2579,6 +2582,7 @@ pub const Error = struct { mismatched_binary_op_whitespace, invalid_ampersand_ampersand, c_style_container, + expected_var_const, zig_style_container, previous_field, diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig index db56cef21e..6429372d74 100644 --- a/lib/std/zig/parse.zig +++ b/lib/std/zig/parse.zig @@ -1118,7 +1118,18 @@ const Parser = struct { if (loop_stmt != 0) return loop_stmt; if (label_token != 0) { - return p.fail(.expected_labelable); + const after_colon = p.tok_i; + const node = try p.parseTypeExpr(); + if (node != 0) { + const a = try p.parseByteAlign(); + const b = try p.parseAddrSpace(); + const c = try p.parseLinkSection(); + const d = if (p.eatToken(.equal) == null) 0 else try p.expectExpr(); + if (a != 0 or b != 0 or c != 0 or d != 0) { + return p.failMsg(.{ .tag = .expected_var_const, .token = label_token }); + } + } + return p.failMsg(.{ .tag = .expected_labelable, .token = after_colon }); } return null_node; diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig index 4e155df6d8..06acd84092 100644 --- a/lib/std/zig/parser_test.zig +++ b/lib/std/zig/parser_test.zig @@ -5145,6 +5145,32 @@ test "zig fmt: make single-line if no trailing comma" { ); } +test "zig fmt: missing const/var before local variable" { + try testError( + \\comptime { + \\ z: u32; + \\} + \\comptime { + \\ z: u32 align(1); + \\} + \\comptime { + \\ z: u32 addrspace(.generic); + \\} + \\comptime { + \\ z: u32 linksection("foo"); + \\} + \\comptime { + \\ z: u32 = 1; + \\} + , &.{ + .expected_labelable, + .expected_var_const, + .expected_var_const, + .expected_var_const, + .expected_var_const, + }); +} + test "zig fmt: while continue expr" { try testCanonical( \\test {