authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-16 13:06:11+02:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-02-17 14:23:35+02:00
log9c36cf92f009eda14cb773e89148547dadb137c6
tree7be6ab7d21cd37709e3ed877264b9a4b135171d3
parent5283a52af565521094bcd1186efc179b4be7ee8c

parser: make some errors point to end of previous token

For some errors if the found token is not on the same line as the previous token, point to the end of the previous token. This usually results in more helpful errors.

8 files changed, 148 insertions(+), 169 deletions(-)

lib/std/zig/Ast.zig+30-40
...@@ -66,20 +66,11 @@ pub fn renderToArrayList(tree: Ast, buffer: *std.ArrayList(u8)) RenderError!void...@@ -66,20 +66,11 @@ pub fn renderToArrayList(tree: Ast, buffer: *std.ArrayList(u8)) RenderError!void
6666
67/// Returns an extra offset for column and byte offset of errors that67/// Returns an extra offset for column and byte offset of errors that
68/// should point after the token in the error message.68/// should point after the token in the error message.
69pub fn errorOffset(tree: Ast, error_tag: Error.Tag, token: TokenIndex) u32 {69pub fn errorOffset(tree: Ast, parse_error: Error) u32 {
70 return switch (error_tag) {70 return if (parse_error.token_is_prev)
71 .expected_semi_after_decl,71 @intCast(u32, tree.tokenSlice(parse_error.token).len)
72 .expected_semi_after_stmt,72 else
73 .expected_comma_after_field,73 0;
74 .expected_comma_after_arg,
75 .expected_comma_after_param,
76 .expected_comma_after_initializer,
77 .expected_comma_after_switch_prong,
78 .expected_semi_or_else,
79 .expected_semi_or_lbrace,
80 => @intCast(u32, tree.tokenSlice(token).len),
81 else => 0,
82 };
83}74}
8475
85pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenIndex) Location {76pub fn tokenLocation(self: Ast, start_offset: ByteOffset, token_index: TokenIndex) Location {
...@@ -162,22 +153,22 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {...@@ -162,22 +153,22 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
162 },153 },
163 .expected_block => {154 .expected_block => {
164 return stream.print("expected block or field, found '{s}'", .{155 return stream.print("expected block or field, found '{s}'", .{
165 token_tags[parse_error.token].symbol(),156 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
166 });157 });
167 },158 },
168 .expected_block_or_assignment => {159 .expected_block_or_assignment => {
169 return stream.print("expected block or assignment, found '{s}'", .{160 return stream.print("expected block or assignment, found '{s}'", .{
170 token_tags[parse_error.token].symbol(),161 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
171 });162 });
172 },163 },
173 .expected_block_or_expr => {164 .expected_block_or_expr => {
174 return stream.print("expected block or expression, found '{s}'", .{165 return stream.print("expected block or expression, found '{s}'", .{
175 token_tags[parse_error.token].symbol(),166 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
176 });167 });
177 },168 },
178 .expected_block_or_field => {169 .expected_block_or_field => {
179 return stream.print("expected block or field, found '{s}'", .{170 return stream.print("expected block or field, found '{s}'", .{
180 token_tags[parse_error.token].symbol(),171 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
181 });172 });
182 },173 },
183 .expected_container_members => {174 .expected_container_members => {
...@@ -187,42 +178,42 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {...@@ -187,42 +178,42 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
187 },178 },
188 .expected_expr => {179 .expected_expr => {
189 return stream.print("expected expression, found '{s}'", .{180 return stream.print("expected expression, found '{s}'", .{
190 token_tags[parse_error.token].symbol(),181 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
191 });182 });
192 },183 },
193 .expected_expr_or_assignment => {184 .expected_expr_or_assignment => {
194 return stream.print("expected expression or assignment, found '{s}'", .{185 return stream.print("expected expression or assignment, found '{s}'", .{
195 token_tags[parse_error.token].symbol(),186 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
196 });187 });
197 },188 },
198 .expected_fn => {189 .expected_fn => {
199 return stream.print("expected function, found '{s}'", .{190 return stream.print("expected function, found '{s}'", .{
200 token_tags[parse_error.token].symbol(),191 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
201 });192 });
202 },193 },
203 .expected_inlinable => {194 .expected_inlinable => {
204 return stream.print("expected 'while' or 'for', found '{s}'", .{195 return stream.print("expected 'while' or 'for', found '{s}'", .{
205 token_tags[parse_error.token].symbol(),196 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
206 });197 });
207 },198 },
208 .expected_labelable => {199 .expected_labelable => {
209 return stream.print("expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'", .{200 return stream.print("expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'", .{
210 token_tags[parse_error.token].symbol(),201 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
211 });202 });
212 },203 },
213 .expected_param_list => {204 .expected_param_list => {
214 return stream.print("expected parameter list, found '{s}'", .{205 return stream.print("expected parameter list, found '{s}'", .{
215 token_tags[parse_error.token].symbol(),206 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
216 });207 });
217 },208 },
218 .expected_prefix_expr => {209 .expected_prefix_expr => {
219 return stream.print("expected prefix expression, found '{s}'", .{210 return stream.print("expected prefix expression, found '{s}'", .{
220 token_tags[parse_error.token].symbol(),211 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
221 });212 });
222 },213 },
223 .expected_primary_type_expr => {214 .expected_primary_type_expr => {
224 return stream.print("expected primary type expression, found '{s}'", .{215 return stream.print("expected primary type expression, found '{s}'", .{
225 token_tags[parse_error.token].symbol(),216 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
226 });217 });
227 },218 },
228 .expected_pub_item => {219 .expected_pub_item => {
...@@ -230,7 +221,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {...@@ -230,7 +221,7 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
230 },221 },
231 .expected_return_type => {222 .expected_return_type => {
232 return stream.print("expected return type expression, found '{s}'", .{223 return stream.print("expected return type expression, found '{s}'", .{
233 token_tags[parse_error.token].symbol(),224 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
234 });225 });
235 },226 },
236 .expected_semi_or_else => {227 .expected_semi_or_else => {
...@@ -244,39 +235,34 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {...@@ -244,39 +235,34 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
244 token_tags[parse_error.token].symbol(),235 token_tags[parse_error.token].symbol(),
245 });236 });
246 },237 },
247 .expected_string_literal => {
248 return stream.print("expected string literal, found '{s}'", .{
249 token_tags[parse_error.token].symbol(),
250 });
251 },
252 .expected_suffix_op => {238 .expected_suffix_op => {
253 return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{239 return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{
254 token_tags[parse_error.token].symbol(),240 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
255 });241 });
256 },242 },
257 .expected_type_expr => {243 .expected_type_expr => {
258 return stream.print("expected type expression, found '{s}'", .{244 return stream.print("expected type expression, found '{s}'", .{
259 token_tags[parse_error.token].symbol(),245 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
260 });246 });
261 },247 },
262 .expected_var_decl => {248 .expected_var_decl => {
263 return stream.print("expected variable declaration, found '{s}'", .{249 return stream.print("expected variable declaration, found '{s}'", .{
264 token_tags[parse_error.token].symbol(),250 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
265 });251 });
266 },252 },
267 .expected_var_decl_or_fn => {253 .expected_var_decl_or_fn => {
268 return stream.print("expected variable declaration or function, found '{s}'", .{254 return stream.print("expected variable declaration or function, found '{s}'", .{
269 token_tags[parse_error.token].symbol(),255 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
270 });256 });
271 },257 },
272 .expected_loop_payload => {258 .expected_loop_payload => {
273 return stream.print("expected loop payload, found '{s}'", .{259 return stream.print("expected loop payload, found '{s}'", .{
274 token_tags[parse_error.token].symbol(),260 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
275 });261 });
276 },262 },
277 .expected_container => {263 .expected_container => {
278 return stream.print("expected a struct, enum or union, found '{s}'", .{264 return stream.print("expected a struct, enum or union, found '{s}'", .{
279 token_tags[parse_error.token].symbol(),265 token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)].symbol(),
280 });266 });
281 },267 },
282 .extern_fn_body => {268 .extern_fn_body => {
...@@ -341,9 +327,12 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {...@@ -341,9 +327,12 @@ pub fn renderError(tree: Ast, parse_error: Error, stream: anytype) !void {
341 .expected_comma_after_switch_prong => {327 .expected_comma_after_switch_prong => {
342 return stream.writeAll("expected ',' after switch prong");328 return stream.writeAll("expected ',' after switch prong");
343 },329 },
330 .expected_initializer => {
331 return stream.writeAll("expected field initializer");
332 },
344333
345 .expected_token => {334 .expected_token => {
346 const found_tag = token_tags[parse_error.token];335 const found_tag = token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)];
347 const expected_symbol = parse_error.extra.expected_tag.symbol();336 const expected_symbol = parse_error.extra.expected_tag.symbol();
348 switch (found_tag) {337 switch (found_tag) {
349 .invalid => return stream.print("expected '{s}', found invalid bytes", .{338 .invalid => return stream.print("expected '{s}', found invalid bytes", .{
...@@ -2483,6 +2472,7 @@ pub const full = struct {...@@ -2483,6 +2472,7 @@ pub const full = struct {
24832472
2484pub const Error = struct {2473pub const Error = struct {
2485 tag: Tag,2474 tag: Tag,
2475 token_is_prev: bool = false,
2486 token: TokenIndex,2476 token: TokenIndex,
2487 extra: union {2477 extra: union {
2488 none: void,2478 none: void,
...@@ -2511,7 +2501,6 @@ pub const Error = struct {...@@ -2511,7 +2501,6 @@ pub const Error = struct {
2511 expected_semi_or_else,2501 expected_semi_or_else,
2512 expected_semi_or_lbrace,2502 expected_semi_or_lbrace,
2513 expected_statement,2503 expected_statement,
2514 expected_string_literal,
2515 expected_suffix_op,2504 expected_suffix_op,
2516 expected_type_expr,2505 expected_type_expr,
2517 expected_var_decl,2506 expected_var_decl,
...@@ -2539,6 +2528,7 @@ pub const Error = struct {...@@ -2539,6 +2528,7 @@ pub const Error = struct {
2539 expected_comma_after_param,2528 expected_comma_after_param,
2540 expected_comma_after_initializer,2529 expected_comma_after_initializer,
2541 expected_comma_after_switch_prong,2530 expected_comma_after_switch_prong,
2531 expected_initializer,
25422532
2543 /// `expected_tag` is populated.2533 /// `expected_tag` is populated.
2544 expected_token,2534 expected_token,
lib/std/zig/parse.zig+69-93
...@@ -147,11 +147,6 @@ const Parser = struct {...@@ -147,11 +147,6 @@ const Parser = struct {
147 return result;147 return result;
148 }148 }
149149
150 fn warn(p: *Parser, tag: Ast.Error.Tag) error{OutOfMemory}!void {
151 @setCold(true);
152 try p.warnMsg(.{ .tag = tag, .token = p.tok_i });
153 }
154
155 fn warnExpected(p: *Parser, expected_token: Token.Tag) error{OutOfMemory}!void {150 fn warnExpected(p: *Parser, expected_token: Token.Tag) error{OutOfMemory}!void {
156 @setCold(true);151 @setCold(true);
157 try p.warnMsg(.{152 try p.warnMsg(.{
...@@ -161,13 +156,53 @@ const Parser = struct {...@@ -161,13 +156,53 @@ const Parser = struct {
161 });156 });
162 }157 }
163158
164 fn warnExpectedAfter(p: *Parser, error_tag: AstError.Tag) error{OutOfMemory}!void {159 fn warn(p: *Parser, error_tag: AstError.Tag) error{OutOfMemory}!void {
165 @setCold(true);160 @setCold(true);
166 try p.warnMsg(.{ .tag = error_tag, .token = p.tok_i - 1 });161 try p.warnMsg(.{ .tag = error_tag, .token = p.tok_i });
167 }162 }
168163
169 fn warnMsg(p: *Parser, msg: Ast.Error) error{OutOfMemory}!void {164 fn warnMsg(p: *Parser, msg: Ast.Error) error{OutOfMemory}!void {
170 @setCold(true);165 @setCold(true);
166 switch (msg.tag) {
167 .expected_semi_after_decl,
168 .expected_semi_after_stmt,
169 .expected_comma_after_field,
170 .expected_comma_after_arg,
171 .expected_comma_after_param,
172 .expected_comma_after_initializer,
173 .expected_comma_after_switch_prong,
174 .expected_semi_or_else,
175 .expected_semi_or_lbrace,
176 .expected_token,
177 .expected_block,
178 .expected_block_or_assignment,
179 .expected_block_or_expr,
180 .expected_block_or_field,
181 .expected_container_members,
182 .expected_expr,
183 .expected_expr_or_assignment,
184 .expected_fn,
185 .expected_inlinable,
186 .expected_labelable,
187 .expected_param_list,
188 .expected_prefix_expr,
189 .expected_primary_type_expr,
190 .expected_pub_item,
191 .expected_return_type,
192 .expected_suffix_op,
193 .expected_type_expr,
194 .expected_var_decl,
195 .expected_var_decl_or_fn,
196 .expected_loop_payload,
197 .expected_container,
198 => if (msg.token != 0 and !p.tokensOnSameLine(msg.token - 1, msg.token)) {
199 var copy = msg;
200 copy.token_is_prev = true;
201 copy.token -= 1;
202 return p.errors.append(p.gpa, copy);
203 },
204 else => {},
205 }
171 try p.errors.append(p.gpa, msg);206 try p.errors.append(p.gpa, msg);
172 }207 }
173208
...@@ -264,7 +299,7 @@ const Parser = struct {...@@ -264,7 +299,7 @@ const Parser = struct {
264 }299 }
265 // There is not allowed to be a decl after a field with no comma.300 // There is not allowed to be a decl after a field with no comma.
266 // Report error but recover parser.301 // Report error but recover parser.
267 try p.warnExpectedAfter(.expected_comma_after_field);302 try p.warn(.expected_comma_after_field);
268 p.findNextContainerMember();303 p.findNextContainerMember();
269 }304 }
270 },305 },
...@@ -367,7 +402,7 @@ const Parser = struct {...@@ -367,7 +402,7 @@ const Parser = struct {
367 }402 }
368 // There is not allowed to be a decl after a field with no comma.403 // There is not allowed to be a decl after a field with no comma.
369 // Report error but recover parser.404 // Report error but recover parser.
370 try p.warnExpectedAfter(.expected_comma_after_field);405 try p.warn(.expected_comma_after_field);
371 p.findNextContainerMember();406 p.findNextContainerMember();
372 }407 }
373 },408 },
...@@ -585,7 +620,7 @@ const Parser = struct {...@@ -585,7 +620,7 @@ const Parser = struct {
585 // Since parseBlock only return error.ParseError on620 // Since parseBlock only return error.ParseError on
586 // a missing '}' we can assume this function was621 // a missing '}' we can assume this function was
587 // supposed to end here.622 // supposed to end here.
588 try p.warnExpectedAfter(.expected_semi_or_lbrace);623 try p.warn(.expected_semi_or_lbrace);
589 return null_node;624 return null_node;
590 },625 },
591 }626 }
...@@ -996,7 +1031,7 @@ const Parser = struct {...@@ -996,7 +1031,7 @@ const Parser = struct {
996 };1031 };
997 _ = p.eatToken(.keyword_else) orelse {1032 _ = p.eatToken(.keyword_else) orelse {
998 if (else_required) {1033 if (else_required) {
999 try p.warnExpectedAfter(.expected_semi_or_else);1034 try p.warn(.expected_semi_or_else);
1000 }1035 }
1001 return p.addNode(.{1036 return p.addNode(.{
1002 .tag = .if_simple,1037 .tag = .if_simple,
...@@ -1091,7 +1126,7 @@ const Parser = struct {...@@ -1091,7 +1126,7 @@ const Parser = struct {
1091 };1126 };
1092 _ = p.eatToken(.keyword_else) orelse {1127 _ = p.eatToken(.keyword_else) orelse {
1093 if (else_required) {1128 if (else_required) {
1094 try p.warnExpectedAfter(.expected_semi_or_else);1129 try p.warn(.expected_semi_or_else);
1095 }1130 }
1096 return p.addNode(.{1131 return p.addNode(.{
1097 .tag = .for_simple,1132 .tag = .for_simple,
...@@ -1166,7 +1201,7 @@ const Parser = struct {...@@ -1166,7 +1201,7 @@ const Parser = struct {
1166 };1201 };
1167 _ = p.eatToken(.keyword_else) orelse {1202 _ = p.eatToken(.keyword_else) orelse {
1168 if (else_required) {1203 if (else_required) {
1169 try p.warnExpectedAfter(.expected_semi_or_else);1204 try p.warn(.expected_semi_or_else);
1170 }1205 }
1171 if (cont_expr == 0) {1206 if (cont_expr == 0) {
1172 return p.addNode(.{1207 return p.addNode(.{
...@@ -2050,7 +2085,7 @@ const Parser = struct {...@@ -2050,7 +2085,7 @@ const Parser = struct {
2050 },2085 },
2051 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),2086 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
2052 // Likely just a missing comma; give error but continue parsing.2087 // Likely just a missing comma; give error but continue parsing.
2053 else => try p.warnExpectedAfter(.expected_comma_after_initializer),2088 else => try p.warn(.expected_comma_after_initializer),
2054 }2089 }
2055 if (p.eatToken(.r_brace)) |_| break;2090 if (p.eatToken(.r_brace)) |_| break;
2056 const next = try p.expectFieldInit();2091 const next = try p.expectFieldInit();
...@@ -2091,7 +2126,7 @@ const Parser = struct {...@@ -2091,7 +2126,7 @@ const Parser = struct {
2091 },2126 },
2092 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),2127 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
2093 // Likely just a missing comma; give error but continue parsing.2128 // Likely just a missing comma; give error but continue parsing.
2094 else => try p.warnExpectedAfter(.expected_comma_after_initializer),2129 else => try p.warn(.expected_comma_after_initializer),
2095 }2130 }
2096 }2131 }
2097 const comma = (p.token_tags[p.tok_i - 2] == .comma);2132 const comma = (p.token_tags[p.tok_i - 2] == .comma);
...@@ -2170,7 +2205,7 @@ const Parser = struct {...@@ -2170,7 +2205,7 @@ const Parser = struct {
2170 },2205 },
2171 .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren),2206 .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren),
2172 // Likely just a missing comma; give error but continue parsing.2207 // Likely just a missing comma; give error but continue parsing.
2173 else => try p.warnExpectedAfter(.expected_comma_after_arg),2208 else => try p.warn(.expected_comma_after_arg),
2174 }2209 }
2175 }2210 }
2176 const comma = (p.token_tags[p.tok_i - 2] == .comma);2211 const comma = (p.token_tags[p.tok_i - 2] == .comma);
...@@ -2226,7 +2261,7 @@ const Parser = struct {...@@ -2226,7 +2261,7 @@ const Parser = struct {
2226 },2261 },
2227 .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren),2262 .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren),
2228 // Likely just a missing comma; give error but continue parsing.2263 // Likely just a missing comma; give error but continue parsing.
2229 else => try p.warnExpectedAfter(.expected_comma_after_arg),2264 else => try p.warn(.expected_comma_after_arg),
2230 }2265 }
2231 }2266 }
2232 const comma = (p.token_tags[p.tok_i - 2] == .comma);2267 const comma = (p.token_tags[p.tok_i - 2] == .comma);
...@@ -2467,7 +2502,7 @@ const Parser = struct {...@@ -2467,7 +2502,7 @@ const Parser = struct {
2467 },2502 },
2468 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),2503 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
2469 // Likely just a missing comma; give error but continue parsing.2504 // Likely just a missing comma; give error but continue parsing.
2470 else => try p.warnExpectedAfter(.expected_comma_after_initializer),2505 else => try p.warn(.expected_comma_after_initializer),
2471 }2506 }
2472 if (p.eatToken(.r_brace)) |_| break;2507 if (p.eatToken(.r_brace)) |_| break;
2473 const next = try p.expectFieldInit();2508 const next = try p.expectFieldInit();
...@@ -2519,7 +2554,7 @@ const Parser = struct {...@@ -2519,7 +2554,7 @@ const Parser = struct {
2519 },2554 },
2520 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),2555 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
2521 // Likely just a missing comma; give error but continue parsing.2556 // Likely just a missing comma; give error but continue parsing.
2522 else => try p.warnExpectedAfter(.expected_comma_after_initializer),2557 else => try p.warn(.expected_comma_after_initializer),
2523 }2558 }
2524 }2559 }
2525 const comma = (p.token_tags[p.tok_i - 2] == .comma);2560 const comma = (p.token_tags[p.tok_i - 2] == .comma);
...@@ -2580,7 +2615,7 @@ const Parser = struct {...@@ -2580,7 +2615,7 @@ const Parser = struct {
2580 },2615 },
2581 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),2616 .colon, .r_paren, .r_bracket => return p.failExpected(.r_brace),
2582 // Likely just a missing comma; give error but continue parsing.2617 // Likely just a missing comma; give error but continue parsing.
2583 else => try p.warnExpectedAfter(.expected_comma_after_field),2618 else => try p.warn(.expected_comma_after_field),
2584 }2619 }
2585 }2620 }
2586 return p.addNode(.{2621 return p.addNode(.{
...@@ -2879,7 +2914,7 @@ const Parser = struct {...@@ -2879,7 +2914,7 @@ const Parser = struct {
2879 p.tok_i += 2;2914 p.tok_i += 2;
2880 return identifier;2915 return identifier;
2881 }2916 }
2882 return 0;2917 return null_node;
2883 }2918 }
28842919
2885 /// FieldInit <- DOT IDENTIFIER EQUAL Expr2920 /// FieldInit <- DOT IDENTIFIER EQUAL Expr
...@@ -2896,9 +2931,12 @@ const Parser = struct {...@@ -2896,9 +2931,12 @@ const Parser = struct {
2896 }2931 }
28972932
2898 fn expectFieldInit(p: *Parser) !Node.Index {2933 fn expectFieldInit(p: *Parser) !Node.Index {
2899 _ = try p.expectToken(.period);2934 if (p.token_tags[p.tok_i] != .period or
2900 _ = try p.expectToken(.identifier);2935 p.token_tags[p.tok_i + 1] != .identifier or
2901 _ = try p.expectToken(.equal);2936 p.token_tags[p.tok_i + 2] != .equal)
2937 return p.fail(.expected_initializer);
2938
2939 p.tok_i += 3;
2902 return p.expectExpr();2940 return p.expectExpr();
2903 }2941 }
29042942
...@@ -3413,7 +3451,7 @@ const Parser = struct {...@@ -3413,7 +3451,7 @@ const Parser = struct {
3413 // All possible delimiters.3451 // All possible delimiters.
3414 .colon, .r_paren, .r_brace, .r_bracket => break,3452 .colon, .r_paren, .r_brace, .r_bracket => break,
3415 // Likely just a missing comma; give error but continue parsing.3453 // Likely just a missing comma; give error but continue parsing.
3416 else => try p.warnExpectedAfter(.expected_comma_after_switch_prong),3454 else => try p.warn(.expected_comma_after_switch_prong),
3417 }3455 }
3418 }3456 }
3419 return p.listToSpan(p.scratch.items[scratch_top..]);3457 return p.listToSpan(p.scratch.items[scratch_top..]);
...@@ -3442,7 +3480,7 @@ const Parser = struct {...@@ -3442,7 +3480,7 @@ const Parser = struct {
3442 },3480 },
3443 .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren),3481 .colon, .r_brace, .r_bracket => return p.failExpected(.r_paren),
3444 // Likely just a missing comma; give error but continue parsing.3482 // Likely just a missing comma; give error but continue parsing.
3445 else => try p.warnExpectedAfter(.expected_comma_after_param),3483 else => try p.warn(.expected_comma_after_param),
3446 }3484 }
3447 }3485 }
3448 if (varargs == .nonfinal) {3486 if (varargs == .nonfinal) {
...@@ -3486,7 +3524,7 @@ const Parser = struct {...@@ -3486,7 +3524,7 @@ const Parser = struct {
3486 break;3524 break;
3487 },3525 },
3488 // Likely just a missing comma; give error but continue parsing.3526 // Likely just a missing comma; give error but continue parsing.
3489 else => try p.warnExpectedAfter(.expected_comma_after_arg),3527 else => try p.warn(.expected_comma_after_arg),
3490 }3528 }
3491 }3529 }
3492 const comma = (p.token_tags[p.tok_i - 2] == .comma);3530 const comma = (p.token_tags[p.tok_i - 2] == .comma);
...@@ -3530,57 +3568,6 @@ const Parser = struct {...@@ -3530,57 +3568,6 @@ const Parser = struct {
3530 }3568 }
3531 }3569 }
35323570
3533 // string literal or multiline string literal
3534 fn parseStringLiteral(p: *Parser) !Node.Index {
3535 switch (p.token_tags[p.tok_i]) {
3536 .string_literal => {
3537 const main_token = p.nextToken();
3538 return p.addNode(.{
3539 .tag = .string_literal,
3540 .main_token = main_token,
3541 .data = .{
3542 .lhs = undefined,
3543 .rhs = undefined,
3544 },
3545 });
3546 },
3547 .multiline_string_literal_line => {
3548 const first_line = p.nextToken();
3549 while (p.token_tags[p.tok_i] == .multiline_string_literal_line) {
3550 p.tok_i += 1;
3551 }
3552 return p.addNode(.{
3553 .tag = .multiline_string_literal,
3554 .main_token = first_line,
3555 .data = .{
3556 .lhs = first_line,
3557 .rhs = p.tok_i - 1,
3558 },
3559 });
3560 },
3561 else => return null_node,
3562 }
3563 }
3564
3565 fn expectStringLiteral(p: *Parser) !Node.Index {
3566 const node = try p.parseStringLiteral();
3567 if (node == 0) {
3568 return p.fail(.expected_string_literal);
3569 }
3570 return node;
3571 }
3572
3573 fn expectIntegerLiteral(p: *Parser) !Node.Index {
3574 return p.addNode(.{
3575 .tag = .integer_literal,
3576 .main_token = try p.expectToken(.integer_literal),
3577 .data = .{
3578 .lhs = undefined,
3579 .rhs = undefined,
3580 },
3581 });
3582 }
3583
3584 /// KEYWORD_if LPAREN Expr RPAREN PtrPayload? Body (KEYWORD_else Payload? Body)?3571 /// KEYWORD_if LPAREN Expr RPAREN PtrPayload? Body (KEYWORD_else Payload? Body)?
3585 fn parseIf(p: *Parser, bodyParseFn: fn (p: *Parser) Error!Node.Index) !Node.Index {3572 fn parseIf(p: *Parser, bodyParseFn: fn (p: *Parser) Error!Node.Index) !Node.Index {
3586 const if_token = p.eatToken(.keyword_if) orelse return null_node;3573 const if_token = p.eatToken(.keyword_if) orelse return null_node;
...@@ -3649,25 +3636,14 @@ const Parser = struct {...@@ -3649,25 +3636,14 @@ const Parser = struct {
3649 }3636 }
36503637
3651 fn expectToken(p: *Parser, tag: Token.Tag) Error!TokenIndex {3638 fn expectToken(p: *Parser, tag: Token.Tag) Error!TokenIndex {
3652 const token = p.nextToken();3639 if (p.token_tags[p.tok_i] != tag) {
3653 if (p.token_tags[token] != tag) {
3654 p.tok_i -= 1; // Go back so that we can recover properly.
3655 return p.failMsg(.{3640 return p.failMsg(.{
3656 .tag = .expected_token,3641 .tag = .expected_token,
3657 .token = token,3642 .token = p.tok_i,
3658 .extra = .{ .expected_tag = tag },3643 .extra = .{ .expected_tag = tag },
3659 });3644 });
3660 }3645 }
3661 return token;3646 return p.nextToken();
3662 }
3663
3664 fn expectTokenRecoverable(p: *Parser, tag: Token.Tag) !?TokenIndex {
3665 if (p.token_tags[p.tok_i] != tag) {
3666 try p.warnExpected(tag);
3667 return null;
3668 } else {
3669 return p.nextToken();
3670 }
3671 }3647 }
36723648
3673 fn expectSemicolon(p: *Parser, error_tag: AstError.Tag, recoverable: bool) Error!void {3649 fn expectSemicolon(p: *Parser, error_tag: AstError.Tag, recoverable: bool) Error!void {
...@@ -3675,7 +3651,7 @@ const Parser = struct {...@@ -3675,7 +3651,7 @@ const Parser = struct {
3675 _ = p.nextToken();3651 _ = p.nextToken();
3676 return;3652 return;
3677 }3653 }
3678 try p.warnExpectedAfter(error_tag);3654 try p.warn(error_tag);
3679 if (!recoverable) return error.ParseError;3655 if (!recoverable) return error.ParseError;
3680 }3656 }
36813657
lib/std/zig/parser_test.zig+4-2
...@@ -5057,7 +5057,9 @@ test "recovery: block statements" {...@@ -5057,7 +5057,9 @@ test "recovery: block statements" {
5057 \\ inline;5057 \\ inline;
5058 \\}5058 \\}
5059 , &[_]Error{5059 , &[_]Error{
5060 .invalid_token,5060 .expected_expr,
5061 .expected_semi_after_stmt,
5062 .expected_statement,
5061 .expected_inlinable,5063 .expected_inlinable,
5062 });5064 });
5063}5065}
...@@ -5076,7 +5078,7 @@ test "recovery: missing comma" {...@@ -5076,7 +5078,7 @@ test "recovery: missing comma" {
5076 , &[_]Error{5078 , &[_]Error{
5077 .expected_comma_after_switch_prong,5079 .expected_comma_after_switch_prong,
5078 .expected_comma_after_switch_prong,5080 .expected_comma_after_switch_prong,
5079 .invalid_token,5081 .expected_expr,
5080 });5082 });
5081}5083}
50825084
lib/std/zig/tokenizer.zig+12-1
...@@ -322,7 +322,18 @@ pub const Token = struct {...@@ -322,7 +322,18 @@ pub const Token = struct {
322 }322 }
323323
324 pub fn symbol(tag: Tag) []const u8 {324 pub fn symbol(tag: Tag) []const u8 {
325 return tag.lexeme() orelse @tagName(tag);325 return tag.lexeme() orelse switch (tag) {
326 .invalid => "invalid bytes",
327 .identifier => "an identifier",
328 .string_literal, .multiline_string_literal_line => "a string literal",
329 .char_literal => "a character literal",
330 .eof => "EOF",
331 .builtin => "a builtin function",
332 .integer_literal => "an integer literal",
333 .float_literal => "a floating point literal",
334 .doc_comment, .container_doc_comment => "a document comment",
335 else => unreachable,
336 };
326 }337 }
327 };338 };
328};339};
src/Module.zig+4-4
...@@ -2995,7 +2995,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void {...@@ -2995,7 +2995,7 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
2995 const token_starts = file.tree.tokens.items(.start);2995 const token_starts = file.tree.tokens.items(.start);
2996 const token_tags = file.tree.tokens.items(.tag);2996 const token_tags = file.tree.tokens.items(.tag);
29972997
2998 const extra_offset = file.tree.errorOffset(parse_err.tag, parse_err.token);2998 const extra_offset = file.tree.errorOffset(parse_err);
2999 try file.tree.renderError(parse_err, msg.writer());2999 try file.tree.renderError(parse_err, msg.writer());
3000 const err_msg = try gpa.create(ErrorMsg);3000 const err_msg = try gpa.create(ErrorMsg);
3001 err_msg.* = .{3001 err_msg.* = .{
...@@ -3006,9 +3006,9 @@ pub fn astGenFile(mod: *Module, file: *File) !void {...@@ -3006,9 +3006,9 @@ pub fn astGenFile(mod: *Module, file: *File) !void {
3006 },3006 },
3007 .msg = msg.toOwnedSlice(),3007 .msg = msg.toOwnedSlice(),
3008 };3008 };
3009 if (token_tags[parse_err.token] == .invalid) {3009 if (token_tags[parse_err.token + @boolToInt(parse_err.token_is_prev)] == .invalid) {
3010 const bad_off = @intCast(u32, file.tree.tokenSlice(parse_err.token).len);3010 const bad_off = @intCast(u32, file.tree.tokenSlice(parse_err.token + @boolToInt(parse_err.token_is_prev)).len);
3011 const byte_abs = token_starts[parse_err.token] + bad_off;3011 const byte_abs = token_starts[parse_err.token + @boolToInt(parse_err.token_is_prev)] + bad_off;
3012 try mod.errNoteNonLazy(.{3012 try mod.errNoteNonLazy(.{
3013 .file_scope = file,3013 .file_scope = file,
3014 .parent_decl_node = 0,3014 .parent_decl_node = 0,
src/main.zig+4-4
...@@ -4063,9 +4063,9 @@ fn printErrMsgToStdErr(...@@ -4063,9 +4063,9 @@ fn printErrMsgToStdErr(
4063 var notes_buffer: [1]Compilation.AllErrors.Message = undefined;4063 var notes_buffer: [1]Compilation.AllErrors.Message = undefined;
4064 var notes_len: usize = 0;4064 var notes_len: usize = 0;
40654065
4066 if (token_tags[parse_error.token] == .invalid) {4066 if (token_tags[parse_error.token + @boolToInt(parse_error.token_is_prev)] == .invalid) {
4067 const bad_off = @intCast(u32, tree.tokenSlice(parse_error.token).len);4067 const bad_off = @intCast(u32, tree.tokenSlice(parse_error.token + @boolToInt(parse_error.token_is_prev)).len);
4068 const byte_offset = @intCast(u32, start_loc.line_start) + bad_off;4068 const byte_offset = @intCast(u32, start_loc.line_start) + @intCast(u32, start_loc.column) + bad_off;
4069 notes_buffer[notes_len] = .{4069 notes_buffer[notes_len] = .{
4070 .src = .{4070 .src = .{
4071 .src_path = path,4071 .src_path = path,
...@@ -4081,7 +4081,7 @@ fn printErrMsgToStdErr(...@@ -4081,7 +4081,7 @@ fn printErrMsgToStdErr(
4081 notes_len += 1;4081 notes_len += 1;
4082 }4082 }
40834083
4084 const extra_offset = tree.errorOffset(parse_error.tag, parse_error.token);4084 const extra_offset = tree.errorOffset(parse_error);
4085 const message: Compilation.AllErrors.Message = .{4085 const message: Compilation.AllErrors.Message = .{
4086 .src = .{4086 .src = .{
4087 .src_path = path,4087 .src_path = path,
test/compile_errors.zig+24-24
...@@ -1540,7 +1540,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1540,7 +1540,7 @@ pub fn addCases(ctx: *TestContext) !void {
1540 \\ std.debug.assert(bad_float < 1.0);1540 \\ std.debug.assert(bad_float < 1.0);
1541 \\}1541 \\}
1542 , &[_][]const u8{1542 , &[_][]const u8{
1543 "tmp.zig:5:29: error: invalid token: '.'",1543 "tmp.zig:5:29: error: expected expression, found '.'",
1544 });1544 });
15451545
1546 ctx.objErrStage1("invalid exponent in float literal - 1",1546 ctx.objErrStage1("invalid exponent in float literal - 1",
...@@ -1549,7 +1549,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1549,7 +1549,7 @@ pub fn addCases(ctx: *TestContext) !void {
1549 \\ _ = bad;1549 \\ _ = bad;
1550 \\}1550 \\}
1551 , &[_][]const u8{1551 , &[_][]const u8{
1552 "tmp.zig:2:21: error: expected expression, found 'invalid'",1552 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1553 "tmp.zig:2:28: note: invalid byte: 'a'",1553 "tmp.zig:2:28: note: invalid byte: 'a'",
1554 });1554 });
15551555
...@@ -1559,7 +1559,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1559,7 +1559,7 @@ pub fn addCases(ctx: *TestContext) !void {
1559 \\ _ = bad;1559 \\ _ = bad;
1560 \\}1560 \\}
1561 , &[_][]const u8{1561 , &[_][]const u8{
1562 "tmp.zig:2:21: error: expected expression, found 'invalid'",1562 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1563 "tmp.zig:2:29: note: invalid byte: 'F'",1563 "tmp.zig:2:29: note: invalid byte: 'F'",
1564 });1564 });
15651565
...@@ -1569,7 +1569,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1569,7 +1569,7 @@ pub fn addCases(ctx: *TestContext) !void {
1569 \\ _ = bad;1569 \\ _ = bad;
1570 \\}1570 \\}
1571 , &[_][]const u8{1571 , &[_][]const u8{
1572 "tmp.zig:2:21: error: expected expression, found 'invalid'",1572 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1573 "tmp.zig:2:23: note: invalid byte: '_'",1573 "tmp.zig:2:23: note: invalid byte: '_'",
1574 });1574 });
15751575
...@@ -1579,7 +1579,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1579,7 +1579,7 @@ pub fn addCases(ctx: *TestContext) !void {
1579 \\ _ = bad;1579 \\ _ = bad;
1580 \\}1580 \\}
1581 , &[_][]const u8{1581 , &[_][]const u8{
1582 "tmp.zig:2:21: error: expected expression, found 'invalid'",1582 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1583 "tmp.zig:2:23: note: invalid byte: '.'",1583 "tmp.zig:2:23: note: invalid byte: '.'",
1584 });1584 });
15851585
...@@ -1589,7 +1589,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1589,7 +1589,7 @@ pub fn addCases(ctx: *TestContext) !void {
1589 \\ _ = bad;1589 \\ _ = bad;
1590 \\}1590 \\}
1591 , &[_][]const u8{1591 , &[_][]const u8{
1592 "tmp.zig:2:21: error: expected expression, found 'invalid'",1592 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1593 "tmp.zig:2:25: note: invalid byte: ';'",1593 "tmp.zig:2:25: note: invalid byte: ';'",
1594 });1594 });
15951595
...@@ -1599,7 +1599,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1599,7 +1599,7 @@ pub fn addCases(ctx: *TestContext) !void {
1599 \\ _ = bad;1599 \\ _ = bad;
1600 \\}1600 \\}
1601 , &[_][]const u8{1601 , &[_][]const u8{
1602 "tmp.zig:2:21: error: expected expression, found 'invalid'",1602 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1603 "tmp.zig:2:25: note: invalid byte: '_'",1603 "tmp.zig:2:25: note: invalid byte: '_'",
1604 });1604 });
16051605
...@@ -1609,7 +1609,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1609,7 +1609,7 @@ pub fn addCases(ctx: *TestContext) !void {
1609 \\ _ = bad;1609 \\ _ = bad;
1610 \\}1610 \\}
1611 , &[_][]const u8{1611 , &[_][]const u8{
1612 "tmp.zig:2:21: error: expected expression, found 'invalid'",1612 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1613 "tmp.zig:2:26: note: invalid byte: '_'",1613 "tmp.zig:2:26: note: invalid byte: '_'",
1614 });1614 });
16151615
...@@ -1619,7 +1619,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1619,7 +1619,7 @@ pub fn addCases(ctx: *TestContext) !void {
1619 \\ _ = bad;1619 \\ _ = bad;
1620 \\}1620 \\}
1621 , &[_][]const u8{1621 , &[_][]const u8{
1622 "tmp.zig:2:21: error: expected expression, found 'invalid'",1622 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1623 "tmp.zig:2:26: note: invalid byte: '_'",1623 "tmp.zig:2:26: note: invalid byte: '_'",
1624 });1624 });
16251625
...@@ -1629,7 +1629,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1629,7 +1629,7 @@ pub fn addCases(ctx: *TestContext) !void {
1629 \\ _ = bad;1629 \\ _ = bad;
1630 \\}1630 \\}
1631 , &[_][]const u8{1631 , &[_][]const u8{
1632 "tmp.zig:2:21: error: expected expression, found 'invalid'",1632 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1633 "tmp.zig:2:28: note: invalid byte: ';'",1633 "tmp.zig:2:28: note: invalid byte: ';'",
1634 });1634 });
16351635
...@@ -1639,7 +1639,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1639,7 +1639,7 @@ pub fn addCases(ctx: *TestContext) !void {
1639 \\ _ = bad;1639 \\ _ = bad;
1640 \\}1640 \\}
1641 , &[_][]const u8{1641 , &[_][]const u8{
1642 "tmp.zig:2:21: error: expected expression, found 'invalid'",1642 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1643 "tmp.zig:2:23: note: invalid byte: '_'",1643 "tmp.zig:2:23: note: invalid byte: '_'",
1644 });1644 });
16451645
...@@ -1649,7 +1649,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1649,7 +1649,7 @@ pub fn addCases(ctx: *TestContext) !void {
1649 \\ _ = bad;1649 \\ _ = bad;
1650 \\}1650 \\}
1651 , &[_][]const u8{1651 , &[_][]const u8{
1652 "tmp.zig:2:21: error: expected expression, found 'invalid'",1652 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1653 "tmp.zig:2:25: note: invalid byte: '_'",1653 "tmp.zig:2:25: note: invalid byte: '_'",
1654 });1654 });
16551655
...@@ -1659,7 +1659,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1659,7 +1659,7 @@ pub fn addCases(ctx: *TestContext) !void {
1659 \\ _ = bad;1659 \\ _ = bad;
1660 \\}1660 \\}
1661 , &[_][]const u8{1661 , &[_][]const u8{
1662 "tmp.zig:2:21: error: expected expression, found 'invalid'",1662 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1663 "tmp.zig:2:28: note: invalid byte: '_'",1663 "tmp.zig:2:28: note: invalid byte: '_'",
1664 });1664 });
16651665
...@@ -1669,7 +1669,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1669,7 +1669,7 @@ pub fn addCases(ctx: *TestContext) !void {
1669 \\ _ = bad;1669 \\ _ = bad;
1670 \\}1670 \\}
1671 , &[_][]const u8{1671 , &[_][]const u8{
1672 "tmp.zig:2:21: error: expected expression, found 'invalid'",1672 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1673 "tmp.zig:2:23: note: invalid byte: 'x'",1673 "tmp.zig:2:23: note: invalid byte: 'x'",
1674 });1674 });
16751675
...@@ -1679,7 +1679,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1679,7 +1679,7 @@ pub fn addCases(ctx: *TestContext) !void {
1679 \\ _ = bad;1679 \\ _ = bad;
1680 \\}1680 \\}
1681 , &[_][]const u8{1681 , &[_][]const u8{
1682 "tmp.zig:2:21: error: expected expression, found 'invalid'",1682 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1683 "tmp.zig:2:23: note: invalid byte: '_'",1683 "tmp.zig:2:23: note: invalid byte: '_'",
1684 });1684 });
16851685
...@@ -1689,7 +1689,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1689,7 +1689,7 @@ pub fn addCases(ctx: *TestContext) !void {
1689 \\ _ = bad;1689 \\ _ = bad;
1690 \\}1690 \\}
1691 , &[_][]const u8{1691 , &[_][]const u8{
1692 "tmp.zig:2:21: error: expected expression, found 'invalid'",1692 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1693 "tmp.zig:2:27: note: invalid byte: 'p'",1693 "tmp.zig:2:27: note: invalid byte: 'p'",
1694 });1694 });
16951695
...@@ -1699,7 +1699,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1699,7 +1699,7 @@ pub fn addCases(ctx: *TestContext) !void {
1699 \\ _ = bad;1699 \\ _ = bad;
1700 \\}1700 \\}
1701 , &[_][]const u8{1701 , &[_][]const u8{
1702 "tmp.zig:2:21: error: expected expression, found 'invalid'",1702 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1703 "tmp.zig:2:26: note: invalid byte: ';'",1703 "tmp.zig:2:26: note: invalid byte: ';'",
1704 });1704 });
17051705
...@@ -1709,7 +1709,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1709,7 +1709,7 @@ pub fn addCases(ctx: *TestContext) !void {
1709 \\ _ = bad;1709 \\ _ = bad;
1710 \\}1710 \\}
1711 , &[_][]const u8{1711 , &[_][]const u8{
1712 "tmp.zig:2:21: error: expected expression, found 'invalid'",1712 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1713 "tmp.zig:2:28: note: invalid byte: ';'",1713 "tmp.zig:2:28: note: invalid byte: ';'",
1714 });1714 });
17151715
...@@ -1719,7 +1719,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1719,7 +1719,7 @@ pub fn addCases(ctx: *TestContext) !void {
1719 \\ _ = bad;1719 \\ _ = bad;
1720 \\}1720 \\}
1721 , &[_][]const u8{1721 , &[_][]const u8{
1722 "tmp.zig:2:21: error: expected expression, found 'invalid'",1722 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1723 "tmp.zig:2:28: note: invalid byte: ';'",1723 "tmp.zig:2:28: note: invalid byte: ';'",
1724 });1724 });
17251725
...@@ -1729,7 +1729,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1729,7 +1729,7 @@ pub fn addCases(ctx: *TestContext) !void {
1729 \\ _ = bad;1729 \\ _ = bad;
1730 \\}1730 \\}
1731 , &[_][]const u8{1731 , &[_][]const u8{
1732 "tmp.zig:2:21: error: expected expression, found 'invalid'",1732 "tmp.zig:2:21: error: expected expression, found 'invalid bytes'",
1733 "tmp.zig:2:28: note: invalid byte: ';'",1733 "tmp.zig:2:28: note: invalid byte: ';'",
1734 });1734 });
17351735
...@@ -2171,7 +2171,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -2171,7 +2171,7 @@ pub fn addCases(ctx: *TestContext) !void {
2171 \\ _ = x;2171 \\ _ = x;
2172 \\}2172 \\}
2173 , &[_][]const u8{2173 , &[_][]const u8{
2174 "tmp.zig:3:6: error: expected ',' after field",2174 "tmp.zig:3:7: error: expected ',' after field",
2175 });2175 });
21762176
2177 ctx.objErrStage1("bad alignment type",2177 ctx.objErrStage1("bad alignment type",
...@@ -5733,7 +5733,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -5733,7 +5733,7 @@ pub fn addCases(ctx: *TestContext) !void {
5733 \\const foo = "a5733 \\const foo = "a
5734 \\b";5734 \\b";
5735 , &[_][]const u8{5735 , &[_][]const u8{
5736 "tmp.zig:1:13: error: expected expression, found 'invalid'",5736 "tmp.zig:1:13: error: expected expression, found 'invalid bytes'",
5737 "tmp.zig:1:15: note: invalid byte: '\\n'",5737 "tmp.zig:1:15: note: invalid byte: '\\n'",
5738 });5738 });
57395739
...@@ -7638,7 +7638,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -7638,7 +7638,7 @@ pub fn addCases(ctx: *TestContext) !void {
7638 \\ const a = '\U1234';7638 \\ const a = '\U1234';
7639 \\}7639 \\}
7640 , &[_][]const u8{7640 , &[_][]const u8{
7641 "tmp.zig:2:15: error: expected expression, found 'invalid'",7641 "tmp.zig:2:15: error: expected expression, found 'invalid bytes'",
7642 "tmp.zig:2:18: note: invalid byte: '1'",7642 "tmp.zig:2:18: note: invalid byte: '1'",
7643 });7643 });
76447644
...@@ -7654,7 +7654,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -7654,7 +7654,7 @@ pub fn addCases(ctx: *TestContext) !void {
7654 "fn foo() bool {\r\n" ++7654 "fn foo() bool {\r\n" ++
7655 " return true;\r\n" ++7655 " return true;\r\n" ++
7656 "}\r\n", &[_][]const u8{7656 "}\r\n", &[_][]const u8{
7657 "tmp.zig:1:1: error: expected test, comptime, var decl, or container field, found 'invalid'",7657 "tmp.zig:1:1: error: expected test, comptime, var decl, or container field, found 'invalid bytes'",
7658 "tmp.zig:1:1: note: invalid byte: '\\xff'",7658 "tmp.zig:1:1: note: invalid byte: '\\xff'",
7659 });7659 });
76607660
test/stage2/cbe.zig+1-1
...@@ -693,7 +693,7 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -693,7 +693,7 @@ pub fn addCases(ctx: *TestContext) !void {
693 \\ _ = E1.a;693 \\ _ = E1.a;
694 \\}694 \\}
695 , &.{695 , &.{
696 ":3:6: error: expected ',' after field",696 ":3:7: error: expected ',' after field",
697 });697 });
698698
699 // Redundant non-exhaustive enum mark.699 // Redundant non-exhaustive enum mark.