authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-10-28 16:09:24+03:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-10-29 14:55:43+03:00
log9607bd90e6927eea0fc7d57e042d03657afbf70d
tree7ca539104ffc8e42b49f70ae73592b338836fec7
parent1ea1228036b6d3424c46a3ce66f4b7cbf461fc21

parser: improve error message for missing var/const before local variable

Closes #12721

3 files changed, 43 insertions(+), 2 deletions(-)

lib/std/zig/Ast.zig+5-1
...@@ -197,7 +197,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {...@@ -197,7 +197,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
197 });197 });
198 },198 },
199 .expected_labelable => {199 .expected_labelable => {
200 return stream.print("expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'", .{200 return stream.print("expected 'while', 'for', 'inline', or '{{', found '{s}'", .{
201 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),201 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
202 });202 });
203 },203 },
...@@ -356,6 +356,9 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {...@@ -356,6 +356,9 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
356 .next_field => {356 .next_field => {
357 return stream.writeAll("field after declarations here");357 return stream.writeAll("field after declarations here");
358 },358 },
359 .expected_var_const => {
360 return stream.writeAll("expected 'var' or 'const' before variable declaration");
361 },
359362
360 .expected_token => {363 .expected_token => {
361 const found_tag = token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)];364 const found_tag = token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)];
...@@ -2579,6 +2582,7 @@ pub const Error = struct {...@@ -2579,6 +2582,7 @@ pub const Error = struct {
2579 mismatched_binary_op_whitespace,2582 mismatched_binary_op_whitespace,
2580 invalid_ampersand_ampersand,2583 invalid_ampersand_ampersand,
2581 c_style_container,2584 c_style_container,
2585 expected_var_const,
25822586
2583 zig_style_container,2587 zig_style_container,
2584 previous_field,2588 previous_field,
lib/std/zig/parse.zig+12-1
...@@ -1118,7 +1118,18 @@ const Parser = struct {...@@ -1118,7 +1118,18 @@ const Parser = struct {
1118 if (loop_stmt != 0) return loop_stmt;1118 if (loop_stmt != 0) return loop_stmt;
11191119
1120 if (label_token != 0) {1120 if (label_token != 0) {
1121 return p.fail(.expected_labelable);1121 const after_colon = p.tok_i;
1122 const node = try p.parseTypeExpr();
1123 if (node != 0) {
1124 const a = try p.parseByteAlign();
1125 const b = try p.parseAddrSpace();
1126 const c = try p.parseLinkSection();
1127 const d = if (p.eatToken(.equal) == null) 0 else try p.expectExpr();
1128 if (a != 0 or b != 0 or c != 0 or d != 0) {
1129 return p.failMsg(.{ .tag = .expected_var_const, .token = label_token });
1130 }
1131 }
1132 return p.failMsg(.{ .tag = .expected_labelable, .token = after_colon });
1122 }1133 }
11231134
1124 return null_node;1135 return null_node;
lib/std/zig/parser_test.zig+26
...@@ -5145,6 +5145,32 @@ test "zig fmt: make single-line if no trailing comma" {...@@ -5145,6 +5145,32 @@ test "zig fmt: make single-line if no trailing comma" {
5145 );5145 );
5146}5146}
51475147
5148test "zig fmt: missing const/var before local variable" {
5149 try testError(
5150 \\comptime {
5151 \\ z: u32;
5152 \\}
5153 \\comptime {
5154 \\ z: u32 align(1);
5155 \\}
5156 \\comptime {
5157 \\ z: u32 addrspace(.generic);
5158 \\}
5159 \\comptime {
5160 \\ z: u32 linksection("foo");
5161 \\}
5162 \\comptime {
5163 \\ z: u32 = 1;
5164 \\}
5165 , &.{
5166 .expected_labelable,
5167 .expected_var_const,
5168 .expected_var_const,
5169 .expected_var_const,
5170 .expected_var_const,
5171 });
5172}
5173
5148test "zig fmt: while continue expr" {5174test "zig fmt: while continue expr" {
5149 try testCanonical(5175 try testCanonical(
5150 \\test {5176 \\test {