authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-19 18:04:52-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-02-19 18:04:52-07:00
log8fee41b1d528d598521525574206e200fd332c67
tree2c5ad20494b34a9391474d06a7d1e97b6732612d
parent74878565e5112fed04336089ed769443e08e605b

stage2: AST: clean up parse errors

* struct instead of tagged union * delete dead code * simplify parser code * remove unnecessary metaprogramming

5 files changed, 390 insertions(+), 608 deletions(-)

lib/std/zig/ast.zig+195-334
...@@ -132,113 +132,160 @@ pub const Tree = struct {...@@ -132,113 +132,160 @@ pub const Tree = struct {
132 }132 }
133133
134 pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void {134 pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void {
135 const tokens = tree.tokens.items(.tag);135 const token_tags = tree.tokens.items(.tag);
136 switch (parse_error) {136 switch (parse_error.tag) {
137 .InvalidToken => |*x| return x.render(tokens, stream),137 .asterisk_after_ptr_deref => {
138 .ExpectedContainerMembers => |*x| return x.render(tokens, stream),138 return stream.writeAll("'.*' cannot be followed by '*'. Are you missing a space?");
139 .ExpectedStringLiteral => |*x| return x.render(tokens, stream),139 },
140 .ExpectedIntegerLiteral => |*x| return x.render(tokens, stream),140 .decl_between_fields => {
141 .ExpectedPubItem => |*x| return x.render(tokens, stream),141 return stream.writeAll("declarations are not allowed between container fields");
142 .ExpectedIdentifier => |*x| return x.render(tokens, stream),142 },
143 .ExpectedStatement => |*x| return x.render(tokens, stream),143 .expected_block => {
144 .ExpectedVarDeclOrFn => |*x| return x.render(tokens, stream),144 return stream.print("expected block or field, found '{s}'", .{
145 .ExpectedVarDecl => |*x| return x.render(tokens, stream),145 token_tags[parse_error.token].symbol(),
146 .ExpectedFn => |*x| return x.render(tokens, stream),146 });
147 .ExpectedReturnType => |*x| return x.render(tokens, stream),147 },
148 .ExpectedAggregateKw => |*x| return x.render(tokens, stream),148 .expected_block_or_assignment => {
149 .SameLineDocComment => |*x| return x.render(tokens, stream),149 return stream.print("expected block or assignment, found '{s}'", .{
150 .UnattachedDocComment => |*x| return x.render(tokens, stream),150 token_tags[parse_error.token].symbol(),
151 .ExpectedEqOrSemi => |*x| return x.render(tokens, stream),151 });
152 .ExpectedSemiOrLBrace => |*x| return x.render(tokens, stream),152 },
153 .ExpectedSemiOrElse => |*x| return x.render(tokens, stream),153 .expected_block_or_expr => {
154 .ExpectedLabelOrLBrace => |*x| return x.render(tokens, stream),154 return stream.print("expected block or expression, found '{s}'", .{
155 .ExpectedLBrace => |*x| return x.render(tokens, stream),155 token_tags[parse_error.token].symbol(),
156 .ExpectedColonOrRParen => |*x| return x.render(tokens, stream),156 });
157 .ExpectedLabelable => |*x| return x.render(tokens, stream),157 },
158 .ExpectedInlinable => |*x| return x.render(tokens, stream),158 .expected_block_or_field => {
159 .ExpectedAsmOutputReturnOrType => |*x| return x.render(tokens, stream),159 return stream.print("expected block or field, found '{s}'", .{
160 .ExpectedCall => |x| return x.render(tree, stream),160 token_tags[parse_error.token].symbol(),
161 .ExpectedCallOrFnProto => |x| return x.render(tree, stream),161 });
162 .ExpectedSliceOrRBracket => |*x| return x.render(tokens, stream),162 },
163 .ExtraAlignQualifier => |*x| return x.render(tokens, stream),163 .expected_container_members => {
164 .ExtraConstQualifier => |*x| return x.render(tokens, stream),164 return stream.print("expected test, comptime, var decl, or container field, found '{s}'", .{
165 .ExtraVolatileQualifier => |*x| return x.render(tokens, stream),165 token_tags[parse_error.token].symbol(),
166 .ExtraAllowZeroQualifier => |*x| return x.render(tokens, stream),166 });
167 .ExpectedTypeExpr => |*x| return x.render(tokens, stream),167 },
168 .ExpectedPrimaryTypeExpr => |*x| return x.render(tokens, stream),168 .expected_expr => {
169 .ExpectedParamType => |*x| return x.render(tokens, stream),169 return stream.print("expected expression, found '{s}'", .{
170 .ExpectedExpr => |*x| return x.render(tokens, stream),170 token_tags[parse_error.token].symbol(),
171 .ExpectedPrimaryExpr => |*x| return x.render(tokens, stream),171 });
172 .ExpectedToken => |*x| return x.render(tokens, stream),172 },
173 .ExpectedCommaOrEnd => |*x| return x.render(tokens, stream),173 .expected_expr_or_assignment => {
174 .ExpectedParamList => |*x| return x.render(tokens, stream),174 return stream.print("expected expression or assignment, found '{s}'", .{
175 .ExpectedPayload => |*x| return x.render(tokens, stream),175 token_tags[parse_error.token].symbol(),
176 .ExpectedBlockOrAssignment => |*x| return x.render(tokens, stream),176 });
177 .ExpectedBlockOrExpression => |*x| return x.render(tokens, stream),177 },
178 .ExpectedExprOrAssignment => |*x| return x.render(tokens, stream),178 .expected_fn => {
179 .ExpectedPrefixExpr => |*x| return x.render(tokens, stream),179 return stream.print("expected function, found '{s}'", .{
180 .ExpectedLoopExpr => |*x| return x.render(tokens, stream),180 token_tags[parse_error.token].symbol(),
181 .ExpectedDerefOrUnwrap => |*x| return x.render(tokens, stream),181 });
182 .ExpectedSuffixOp => |*x| return x.render(tokens, stream),182 },
183 .ExpectedBlockOrField => |*x| return x.render(tokens, stream),183 .expected_inlinable => {
184 .DeclBetweenFields => |*x| return x.render(tokens, stream),184 return stream.print("expected 'while' or 'for', found '{s}'", .{
185 .InvalidAnd => |*x| return x.render(tokens, stream),185 token_tags[parse_error.token].symbol(),
186 .AsteriskAfterPointerDereference => |*x| return x.render(tokens, stream),186 });
187 }187 },
188 }188 .expected_labelable => {
189 return stream.print("expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'", .{
190 token_tags[parse_error.token].symbol(),
191 });
192 },
193 .expected_param_list => {
194 return stream.print("expected parameter list, found '{s}'", .{
195 token_tags[parse_error.token].symbol(),
196 });
197 },
198 .expected_prefix_expr => {
199 return stream.print("expected prefix expression, found '{s}'", .{
200 token_tags[parse_error.token].symbol(),
201 });
202 },
203 .expected_primary_type_expr => {
204 return stream.print("expected primary type expression, found '{s}'", .{
205 token_tags[parse_error.token].symbol(),
206 });
207 },
208 .expected_return_type => {
209 return stream.print("expected return type expression, found '{s}'", .{
210 token_tags[parse_error.token].symbol(),
211 });
212 },
213 .expected_semi_or_else => {
214 return stream.print("expected ';' or 'else', found '{s}'", .{
215 token_tags[parse_error.token].symbol(),
216 });
217 },
218 .expected_semi_or_lbrace => {
219 return stream.print("expected ';' or '{{', found '{s}'", .{
220 token_tags[parse_error.token].symbol(),
221 });
222 },
223 .expected_statement => {
224 return stream.print("expected statement, found '{s}'", .{
225 token_tags[parse_error.token].symbol(),
226 });
227 },
228 .expected_string_literal => {
229 return stream.print("expected string literal, found '{s}'", .{
230 token_tags[parse_error.token].symbol(),
231 });
232 },
233 .expected_suffix_op => {
234 return stream.print("expected pointer dereference, optional unwrap, or field access, found '{s}'", .{
235 token_tags[parse_error.token].symbol(),
236 });
237 },
238 .expected_type_expr => {
239 return stream.print("expected type expression, found '{s}'", .{
240 token_tags[parse_error.token].symbol(),
241 });
242 },
243 .expected_var_decl => {
244 return stream.print("expected variable declaration, found '{s}'", .{
245 token_tags[parse_error.token].symbol(),
246 });
247 },
248 .expected_var_decl_or_fn => {
249 return stream.print("expected variable declaration or function, found '{s}'", .{
250 token_tags[parse_error.token].symbol(),
251 });
252 },
253 .extra_align_qualifier => {
254 return stream.writeAll("extra align qualifier");
255 },
256 .extra_allowzero_qualifier => {
257 return stream.writeAll("extra allowzero qualifier");
258 },
259 .extra_const_qualifier => {
260 return stream.writeAll("extra const qualifier");
261 },
262 .extra_volatile_qualifier => {
263 return stream.writeAll("extra volatile qualifier");
264 },
265 .invalid_token => {
266 return stream.print("invalid token '{s}'", .{
267 token_tags[parse_error.token].symbol(),
268 });
269 },
270 .same_line_doc_comment => {
271 return stream.writeAll("same line documentation comment");
272 },
273 .unattached_doc_comment => {
274 return stream.writeAll("unattached documentation comment");
275 },
189276
190 pub fn errorToken(tree: Tree, parse_error: Error) TokenIndex {277 .expected_token => {
191 switch (parse_error) {278 const found_tag = token_tags[parse_error.token];
192 .InvalidToken => |x| return x.token,279 const expected_symbol = parse_error.extra.expected_tag.symbol();
193 .ExpectedContainerMembers => |x| return x.token,280 switch (found_tag) {
194 .ExpectedStringLiteral => |x| return x.token,281 .invalid => return stream.print("expected '{s}', found invalid bytes", .{
195 .ExpectedIntegerLiteral => |x| return x.token,282 expected_symbol,
196 .ExpectedPubItem => |x| return x.token,283 }),
197 .ExpectedIdentifier => |x| return x.token,284 else => return stream.print("expected '{s}', found '{s}'", .{
198 .ExpectedStatement => |x| return x.token,285 expected_symbol, found_tag.symbol(),
199 .ExpectedVarDeclOrFn => |x| return x.token,286 }),
200 .ExpectedVarDecl => |x| return x.token,287 }
201 .ExpectedFn => |x| return x.token,288 },
202 .ExpectedReturnType => |x| return x.token,
203 .ExpectedAggregateKw => |x| return x.token,
204 .SameLineDocComment => |x| return x.token,
205 .UnattachedDocComment => |x| return x.token,
206 .ExpectedEqOrSemi => |x| return x.token,
207 .ExpectedSemiOrLBrace => |x| return x.token,
208 .ExpectedSemiOrElse => |x| return x.token,
209 .ExpectedLabelOrLBrace => |x| return x.token,
210 .ExpectedLBrace => |x| return x.token,
211 .ExpectedColonOrRParen => |x| return x.token,
212 .ExpectedLabelable => |x| return x.token,
213 .ExpectedInlinable => |x| return x.token,
214 .ExpectedAsmOutputReturnOrType => |x| return x.token,
215 .ExpectedCall => |x| return tree.nodes.items(.main_token)[x.node],
216 .ExpectedCallOrFnProto => |x| return tree.nodes.items(.main_token)[x.node],
217 .ExpectedSliceOrRBracket => |x| return x.token,
218 .ExtraAlignQualifier => |x| return x.token,
219 .ExtraConstQualifier => |x| return x.token,
220 .ExtraVolatileQualifier => |x| return x.token,
221 .ExtraAllowZeroQualifier => |x| return x.token,
222 .ExpectedTypeExpr => |x| return x.token,
223 .ExpectedPrimaryTypeExpr => |x| return x.token,
224 .ExpectedParamType => |x| return x.token,
225 .ExpectedExpr => |x| return x.token,
226 .ExpectedPrimaryExpr => |x| return x.token,
227 .ExpectedToken => |x| return x.token,
228 .ExpectedCommaOrEnd => |x| return x.token,
229 .ExpectedParamList => |x| return x.token,
230 .ExpectedPayload => |x| return x.token,
231 .ExpectedBlockOrAssignment => |x| return x.token,
232 .ExpectedBlockOrExpression => |x| return x.token,
233 .ExpectedExprOrAssignment => |x| return x.token,
234 .ExpectedPrefixExpr => |x| return x.token,
235 .ExpectedLoopExpr => |x| return x.token,
236 .ExpectedDerefOrUnwrap => |x| return x.token,
237 .ExpectedSuffixOp => |x| return x.token,
238 .ExpectedBlockOrField => |x| return x.token,
239 .DeclBetweenFields => |x| return x.token,
240 .InvalidAnd => |x| return x.token,
241 .AsteriskAfterPointerDereference => |x| return x.token,
242 }289 }
243 }290 }
244291
...@@ -2239,236 +2286,50 @@ pub const full = struct {...@@ -2239,236 +2286,50 @@ pub const full = struct {
2239 };2286 };
2240};2287};
22412288
2242pub const Error = union(enum) {2289pub const Error = struct {
2243 InvalidToken: InvalidToken,2290 tag: Tag,
2244 ExpectedContainerMembers: ExpectedContainerMembers,2291 token: TokenIndex,
2245 ExpectedStringLiteral: ExpectedStringLiteral,2292 extra: union {
2246 ExpectedIntegerLiteral: ExpectedIntegerLiteral,2293 none: void,
2247 ExpectedPubItem: ExpectedPubItem,2294 expected_tag: Token.Tag,
2248 ExpectedIdentifier: ExpectedIdentifier,2295 } = .{ .none = {} },
2249 ExpectedStatement: ExpectedStatement,
2250 ExpectedVarDeclOrFn: ExpectedVarDeclOrFn,
2251 ExpectedVarDecl: ExpectedVarDecl,
2252 ExpectedFn: ExpectedFn,
2253 ExpectedReturnType: ExpectedReturnType,
2254 ExpectedAggregateKw: ExpectedAggregateKw,
2255 SameLineDocComment: SameLineDocComment,
2256 UnattachedDocComment: UnattachedDocComment,
2257 ExpectedEqOrSemi: ExpectedEqOrSemi,
2258 ExpectedSemiOrLBrace: ExpectedSemiOrLBrace,
2259 ExpectedSemiOrElse: ExpectedSemiOrElse,
2260 ExpectedLabelOrLBrace: ExpectedLabelOrLBrace,
2261 ExpectedLBrace: ExpectedLBrace,
2262 ExpectedColonOrRParen: ExpectedColonOrRParen,
2263 ExpectedLabelable: ExpectedLabelable,
2264 ExpectedInlinable: ExpectedInlinable,
2265 ExpectedAsmOutputReturnOrType: ExpectedAsmOutputReturnOrType,
2266 ExpectedCall: ExpectedCall,
2267 ExpectedCallOrFnProto: ExpectedCallOrFnProto,
2268 ExpectedSliceOrRBracket: ExpectedSliceOrRBracket,
2269 ExtraAlignQualifier: ExtraAlignQualifier,
2270 ExtraConstQualifier: ExtraConstQualifier,
2271 ExtraVolatileQualifier: ExtraVolatileQualifier,
2272 ExtraAllowZeroQualifier: ExtraAllowZeroQualifier,
2273 ExpectedTypeExpr: ExpectedTypeExpr,
2274 ExpectedPrimaryTypeExpr: ExpectedPrimaryTypeExpr,
2275 ExpectedParamType: ExpectedParamType,
2276 ExpectedExpr: ExpectedExpr,
2277 ExpectedPrimaryExpr: ExpectedPrimaryExpr,
2278 ExpectedToken: ExpectedToken,
2279 ExpectedCommaOrEnd: ExpectedCommaOrEnd,
2280 ExpectedParamList: ExpectedParamList,
2281 ExpectedPayload: ExpectedPayload,
2282 ExpectedBlockOrAssignment: ExpectedBlockOrAssignment,
2283 ExpectedBlockOrExpression: ExpectedBlockOrExpression,
2284 ExpectedExprOrAssignment: ExpectedExprOrAssignment,
2285 ExpectedPrefixExpr: ExpectedPrefixExpr,
2286 ExpectedLoopExpr: ExpectedLoopExpr,
2287 ExpectedDerefOrUnwrap: ExpectedDerefOrUnwrap,
2288 ExpectedSuffixOp: ExpectedSuffixOp,
2289 ExpectedBlockOrField: ExpectedBlockOrField,
2290 DeclBetweenFields: DeclBetweenFields,
2291 InvalidAnd: InvalidAnd,
2292 AsteriskAfterPointerDereference: AsteriskAfterPointerDereference,
2293
2294 pub const InvalidToken = SingleTokenError("Invalid token '{s}'");
2295 pub const ExpectedContainerMembers = SingleTokenError("Expected test, comptime, var decl, or container field, found '{s}'");
2296 pub const ExpectedStringLiteral = SingleTokenError("Expected string literal, found '{s}'");
2297 pub const ExpectedIntegerLiteral = SingleTokenError("Expected integer literal, found '{s}'");
2298 pub const ExpectedIdentifier = SingleTokenError("Expected identifier, found '{s}'");
2299 pub const ExpectedStatement = SingleTokenError("Expected statement, found '{s}'");
2300 pub const ExpectedVarDeclOrFn = SingleTokenError("Expected variable declaration or function, found '{s}'");
2301 pub const ExpectedVarDecl = SingleTokenError("Expected variable declaration, found '{s}'");
2302 pub const ExpectedFn = SingleTokenError("Expected function, found '{s}'");
2303 pub const ExpectedReturnType = SingleTokenError("Expected return type expression, found '{s}'");
2304 pub const ExpectedAggregateKw = SingleTokenError("Expected '" ++ Token.Tag.keyword_struct.symbol() ++ "', '" ++ Token.Tag.keyword_union.symbol() ++ "', '" ++ Token.Tag.keyword_enum.symbol() ++ "', or '" ++ Token.Tag.keyword_opaque.symbol() ++ "', found '{s}'");
2305 pub const ExpectedEqOrSemi = SingleTokenError("Expected '=' or ';', found '{s}'");
2306 pub const ExpectedSemiOrLBrace = SingleTokenError("Expected ';' or '{{', found '{s}'");
2307 pub const ExpectedSemiOrElse = SingleTokenError("Expected ';' or 'else', found '{s}'");
2308 pub const ExpectedLBrace = SingleTokenError("Expected '{{', found '{s}'");
2309 pub const ExpectedLabelOrLBrace = SingleTokenError("Expected label or '{{', found '{s}'");
2310 pub const ExpectedColonOrRParen = SingleTokenError("Expected ':' or ')', found '{s}'");
2311 pub const ExpectedLabelable = SingleTokenError("Expected 'while', 'for', 'inline', 'suspend', or '{{', found '{s}'");
2312 pub const ExpectedInlinable = SingleTokenError("Expected 'while' or 'for', found '{s}'");
2313 pub const ExpectedAsmOutputReturnOrType = SingleTokenError("Expected '->' or '" ++ Token.Tag.identifier.symbol() ++ "', found '{s}'");
2314 pub const ExpectedSliceOrRBracket = SingleTokenError("Expected ']' or '..', found '{s}'");
2315 pub const ExpectedTypeExpr = SingleTokenError("Expected type expression, found '{s}'");
2316 pub const ExpectedPrimaryTypeExpr = SingleTokenError("Expected primary type expression, found '{s}'");
2317 pub const ExpectedExpr = SingleTokenError("Expected expression, found '{s}'");
2318 pub const ExpectedPrimaryExpr = SingleTokenError("Expected primary expression, found '{s}'");
2319 pub const ExpectedParamList = SingleTokenError("Expected parameter list, found '{s}'");
2320 pub const ExpectedPayload = SingleTokenError("Expected loop payload, found '{s}'");
2321 pub const ExpectedBlockOrAssignment = SingleTokenError("Expected block or assignment, found '{s}'");
2322 pub const ExpectedBlockOrExpression = SingleTokenError("Expected block or expression, found '{s}'");
2323 pub const ExpectedExprOrAssignment = SingleTokenError("Expected expression or assignment, found '{s}'");
2324 pub const ExpectedPrefixExpr = SingleTokenError("Expected prefix expression, found '{s}'");
2325 pub const ExpectedLoopExpr = SingleTokenError("Expected loop expression, found '{s}'");
2326 pub const ExpectedDerefOrUnwrap = SingleTokenError("Expected pointer dereference or optional unwrap, found '{s}'");
2327 pub const ExpectedSuffixOp = SingleTokenError("Expected pointer dereference, optional unwrap, or field access, found '{s}'");
2328 pub const ExpectedBlockOrField = SingleTokenError("Expected block or field, found '{s}'");
2329
2330 pub const ExpectedParamType = SimpleError("Expected parameter type");
2331 pub const ExpectedPubItem = SimpleError("Expected function or variable declaration after pub");
2332 pub const SameLineDocComment = SimpleError("Same line documentation comment");
2333 pub const UnattachedDocComment = SimpleError("Unattached documentation comment");
2334 pub const ExtraAlignQualifier = SimpleError("Extra align qualifier");
2335 pub const ExtraConstQualifier = SimpleError("Extra const qualifier");
2336 pub const ExtraVolatileQualifier = SimpleError("Extra volatile qualifier");
2337 pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
2338 pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
2339 pub const InvalidAnd = SimpleError("`&&` is invalid. Note that `and` is boolean AND.");
2340 pub const AsteriskAfterPointerDereference = SimpleError("`.*` can't be followed by `*`. Are you missing a space?");
2341
2342 pub const ExpectedCall = struct {
2343 node: Node.Index,
2344
2345 pub fn render(self: ExpectedCall, tree: Tree, stream: anytype) !void {
2346 const node_tag = tree.nodes.items(.tag)[self.node];
2347 return stream.print("expected " ++ @tagName(Node.Tag.call) ++ ", found {s}", .{
2348 @tagName(node_tag),
2349 });
2350 }
2351 };
2352
2353 pub const ExpectedCallOrFnProto = struct {
2354 node: Node.Index,
2355
2356 pub fn render(self: ExpectedCallOrFnProto, tree: Tree, stream: anytype) !void {
2357 const node_tag = tree.nodes.items(.tag)[self.node];
2358 return stream.print("expected " ++ @tagName(Node.Tag.call) ++ " or " ++
2359 @tagName(Node.Tag.fn_proto) ++ ", found {s}", .{@tagName(node_tag)});
2360 }
2361 };
2362
2363 pub const ExpectedToken = struct {
2364 token: TokenIndex,
2365 expected_id: Token.Tag,
2366
2367 pub fn render(self: *const ExpectedToken, tokens: []const Token.Tag, stream: anytype) !void {
2368 const found_token = tokens[self.token];
2369 switch (found_token) {
2370 .invalid => {
2371 return stream.print("expected '{s}', found invalid bytes", .{self.expected_id.symbol()});
2372 },
2373 else => {
2374 const token_name = found_token.symbol();
2375 return stream.print("expected '{s}', found '{s}'", .{ self.expected_id.symbol(), token_name });
2376 },
2377 }
2378 }
2379 };
2380
2381 pub const ExpectedCommaOrEnd = struct {
2382 token: TokenIndex,
2383 end_id: Token.Tag,
23842296
2385 pub fn render(self: *const ExpectedCommaOrEnd, tokens: []const Token.Tag, stream: anytype) !void {2297 pub const Tag = enum {
2386 const actual_token = tokens[self.token];2298 asterisk_after_ptr_deref,
2387 return stream.print("expected ',' or '{s}', found '{s}'", .{2299 decl_between_fields,
2388 self.end_id.symbol(),2300 expected_block,
2389 actual_token.symbol(),2301 expected_block_or_assignment,
2390 });2302 expected_block_or_expr,
2391 }2303 expected_block_or_field,
2304 expected_container_members,
2305 expected_expr,
2306 expected_expr_or_assignment,
2307 expected_fn,
2308 expected_inlinable,
2309 expected_labelable,
2310 expected_param_list,
2311 expected_prefix_expr,
2312 expected_primary_type_expr,
2313 expected_return_type,
2314 expected_semi_or_else,
2315 expected_semi_or_lbrace,
2316 expected_statement,
2317 expected_string_literal,
2318 expected_suffix_op,
2319 expected_type_expr,
2320 expected_var_decl,
2321 expected_var_decl_or_fn,
2322 extra_align_qualifier,
2323 extra_allowzero_qualifier,
2324 extra_const_qualifier,
2325 extra_volatile_qualifier,
2326 invalid_token,
2327 same_line_doc_comment,
2328 unattached_doc_comment,
2329
2330 /// `expected_tag` is populated.
2331 expected_token,
2392 };2332 };
2393
2394 fn SingleTokenError(comptime msg: []const u8) type {
2395 return struct {
2396 const ThisError = @This();
2397
2398 token: TokenIndex,
2399
2400 pub fn render(self: *const ThisError, tokens: []const Token.Tag, stream: anytype) !void {
2401 const actual_token = tokens[self.token];
2402 return stream.print(msg, .{actual_token.symbol()});
2403 }
2404 };
2405 }
2406
2407 fn SimpleError(comptime msg: []const u8) type {
2408 return struct {
2409 const ThisError = @This();
2410
2411 token: TokenIndex,
2412
2413 pub fn render(self: *const ThisError, tokens: []const Token.Tag, stream: anytype) !void {
2414 return stream.writeAll(msg);
2415 }
2416 };
2417 }
2418
2419 pub fn loc(self: Error) TokenIndex {
2420 switch (self) {
2421 .InvalidToken => |x| return x.token,
2422 .ExpectedContainerMembers => |x| return x.token,
2423 .ExpectedStringLiteral => |x| return x.token,
2424 .ExpectedIntegerLiteral => |x| return x.token,
2425 .ExpectedPubItem => |x| return x.token,
2426 .ExpectedIdentifier => |x| return x.token,
2427 .ExpectedStatement => |x| return x.token,
2428 .ExpectedVarDeclOrFn => |x| return x.token,
2429 .ExpectedVarDecl => |x| return x.token,
2430 .ExpectedFn => |x| return x.token,
2431 .ExpectedReturnType => |x| return x.token,
2432 .ExpectedAggregateKw => |x| return x.token,
2433 .UnattachedDocComment => |x| return x.token,
2434 .ExpectedEqOrSemi => |x| return x.token,
2435 .ExpectedSemiOrLBrace => |x| return x.token,
2436 .ExpectedSemiOrElse => |x| return x.token,
2437 .ExpectedLabelOrLBrace => |x| return x.token,
2438 .ExpectedLBrace => |x| return x.token,
2439 .ExpectedColonOrRParen => |x| return x.token,
2440 .ExpectedLabelable => |x| return x.token,
2441 .ExpectedInlinable => |x| return x.token,
2442 .ExpectedAsmOutputReturnOrType => |x| return x.token,
2443 .ExpectedCall => |x| @panic("TODO redo ast errors"),
2444 .ExpectedCallOrFnProto => |x| @panic("TODO redo ast errors"),
2445 .ExpectedSliceOrRBracket => |x| return x.token,
2446 .ExtraAlignQualifier => |x| return x.token,
2447 .ExtraConstQualifier => |x| return x.token,
2448 .ExtraVolatileQualifier => |x| return x.token,
2449 .ExtraAllowZeroQualifier => |x| return x.token,
2450 .ExpectedTypeExpr => |x| return x.token,
2451 .ExpectedPrimaryTypeExpr => |x| return x.token,
2452 .ExpectedParamType => |x| return x.token,
2453 .ExpectedExpr => |x| return x.token,
2454 .ExpectedPrimaryExpr => |x| return x.token,
2455 .ExpectedToken => |x| return x.token,
2456 .ExpectedCommaOrEnd => |x| return x.token,
2457 .ExpectedParamList => |x| return x.token,
2458 .ExpectedPayload => |x| return x.token,
2459 .ExpectedBlockOrAssignment => |x| return x.token,
2460 .ExpectedBlockOrExpression => |x| return x.token,
2461 .ExpectedExprOrAssignment => |x| return x.token,
2462 .ExpectedPrefixExpr => |x| return x.token,
2463 .ExpectedLoopExpr => |x| return x.token,
2464 .ExpectedDerefOrUnwrap => |x| return x.token,
2465 .ExpectedSuffixOp => |x| return x.token,
2466 .ExpectedBlockOrField => |x| return x.token,
2467 .DeclBetweenFields => |x| return x.token,
2468 .InvalidAnd => |x| return x.token,
2469 .AsteriskAfterPointerDereference => |x| return x.token,
2470 }
2471 }
2472};2333};
24732334
2474pub const Node = struct {2335pub const Node = struct {
lib/std/zig/parse.zig+130-208
...@@ -150,14 +150,41 @@ const Parser = struct {...@@ -150,14 +150,41 @@ const Parser = struct {
150 return result;150 return result;
151 }151 }
152152
153 fn warn(p: *Parser, msg: ast.Error) error{OutOfMemory}!void {153 fn warn(p: *Parser, tag: ast.Error.Tag) error{OutOfMemory}!void {
154 @setCold(true);
155 try p.warnMsg(.{ .tag = tag, .token = p.tok_i });
156 }
157
158 fn warnExpected(p: *Parser, expected_token: Token.Tag) error{OutOfMemory}!void {
159 @setCold(true);
160 try p.warnMsg(.{
161 .tag = .expected_token,
162 .token = p.tok_i,
163 .extra = .{ .expected_tag = expected_token },
164 });
165 }
166 fn warnMsg(p: *Parser, msg: ast.Error) error{OutOfMemory}!void {
154 @setCold(true);167 @setCold(true);
155 try p.errors.append(p.gpa, msg);168 try p.errors.append(p.gpa, msg);
156 }169 }
157170
158 fn fail(p: *Parser, msg: ast.Error) error{ ParseError, OutOfMemory } {171 fn fail(p: *Parser, tag: ast.Error.Tag) error{ ParseError, OutOfMemory } {
172 @setCold(true);
173 return p.failMsg(.{ .tag = tag, .token = p.tok_i });
174 }
175
176 fn failExpected(p: *Parser, expected_token: Token.Tag) error{ ParseError, OutOfMemory } {
159 @setCold(true);177 @setCold(true);
160 try p.warn(msg);178 return p.failMsg(.{
179 .tag = .expected_token,
180 .token = p.tok_i,
181 .extra = .{ .expected_tag = expected_token },
182 });
183 }
184
185 fn failMsg(p: *Parser, msg: ast.Error) error{ ParseError, OutOfMemory } {
186 @setCold(true);
187 try p.warnMsg(msg);
161 return error.ParseError;188 return error.ParseError;
162 }189 }
163190
...@@ -190,7 +217,7 @@ const Parser = struct {...@@ -190,7 +217,7 @@ const Parser = struct {
190217
191 var trailing_comma = false;218 var trailing_comma = false;
192 while (true) {219 while (true) {
193 const doc_comment = try p.eatDocComments ();220 const doc_comment = try p.eatDocComments();
194221
195 switch (p.token_tags[p.tok_i]) {222 switch (p.token_tags[p.tok_i]) {
196 .keyword_test => {223 .keyword_test => {
...@@ -212,8 +239,9 @@ const Parser = struct {...@@ -212,8 +239,9 @@ const Parser = struct {
212 .none => field_state = .seen,239 .none => field_state = .seen,
213 .err, .seen => {},240 .err, .seen => {},
214 .end => |node| {241 .end => |node| {
215 try p.warn(.{242 try p.warnMsg(.{
216 .DeclBetweenFields = .{ .token = p.nodes.items(.main_token)[node] },243 .tag = .decl_between_fields,
244 .token = p.nodes.items(.main_token)[node],
217 });245 });
218 // Continue parsing; error will be reported later.246 // Continue parsing; error will be reported later.
219 field_state = .err;247 field_state = .err;
...@@ -234,9 +262,7 @@ const Parser = struct {...@@ -234,9 +262,7 @@ const Parser = struct {
234 }262 }
235 // There is not allowed to be a decl after a field with no comma.263 // There is not allowed to be a decl after a field with no comma.
236 // Report error but recover parser.264 // Report error but recover parser.
237 try p.warn(.{265 try p.warnExpected(.comma);
238 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
239 });
240 p.findNextContainerMember();266 p.findNextContainerMember();
241 }267 }
242 },268 },
...@@ -267,7 +293,7 @@ const Parser = struct {...@@ -267,7 +293,7 @@ const Parser = struct {
267 },293 },
268 else => {294 else => {
269 p.tok_i += 1;295 p.tok_i += 1;
270 try p.warn(.{ .ExpectedBlockOrField = .{ .token = p.tok_i } });296 try p.warn(.expected_block_or_field);
271 },297 },
272 },298 },
273 .keyword_pub => {299 .keyword_pub => {
...@@ -316,8 +342,9 @@ const Parser = struct {...@@ -316,8 +342,9 @@ const Parser = struct {
316 .none => field_state = .seen,342 .none => field_state = .seen,
317 .err, .seen => {},343 .err, .seen => {},
318 .end => |node| {344 .end => |node| {
319 try p.warn(.{345 try p.warnMsg(.{
320 .DeclBetweenFields = .{ .token = p.nodes.items(.main_token)[node] },346 .tag = .decl_between_fields,
347 .token = p.nodes.items(.main_token)[node],
321 });348 });
322 // Continue parsing; error will be reported later.349 // Continue parsing; error will be reported later.
323 field_state = .err;350 field_state = .err;
...@@ -338,20 +365,21 @@ const Parser = struct {...@@ -338,20 +365,21 @@ const Parser = struct {
338 }365 }
339 // There is not allowed to be a decl after a field with no comma.366 // There is not allowed to be a decl after a field with no comma.
340 // Report error but recover parser.367 // Report error but recover parser.
341 try p.warn(.{368 try p.warnExpected(.comma);
342 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
343 });
344 p.findNextContainerMember();369 p.findNextContainerMember();
345 }370 }
346 },371 },
347 .eof, .r_brace => {372 .eof, .r_brace => {
348 if (doc_comment) |tok| {373 if (doc_comment) |tok| {
349 try p.warn(.{ .UnattachedDocComment = .{ .token = tok } });374 try p.warnMsg(.{
375 .tag = .unattached_doc_comment,
376 .token = tok,
377 });
350 }378 }
351 break;379 break;
352 },380 },
353 else => {381 else => {
354 try p.warn(.{ .ExpectedContainerMembers = .{ .token = p.tok_i } });382 try p.warn(.expected_container_members);
355 // This was likely not supposed to end yet; try to find the next declaration.383 // This was likely not supposed to end yet; try to find the next declaration.
356 p.findNextContainerMember();384 p.findNextContainerMember();
357 },385 },
...@@ -475,7 +503,7 @@ const Parser = struct {...@@ -475,7 +503,7 @@ const Parser = struct {
475 const test_token = p.assertToken(.keyword_test);503 const test_token = p.assertToken(.keyword_test);
476 const name_token = p.eatToken(.string_literal);504 const name_token = p.eatToken(.string_literal);
477 const block_node = try p.parseBlock();505 const block_node = try p.parseBlock();
478 if (block_node == 0) return p.fail(.{ .ExpectedLBrace = .{ .token = p.tok_i } });506 if (block_node == 0) return p.fail(.expected_block);
479 return p.addNode(.{507 return p.addNode(.{
480 .tag = .test_decl,508 .tag = .test_decl,
481 .main_token = test_token,509 .main_token = test_token,
...@@ -540,15 +568,13 @@ const Parser = struct {...@@ -540,15 +568,13 @@ const Parser = struct {
540 // Since parseBlock only return error.ParseError on568 // Since parseBlock only return error.ParseError on
541 // a missing '}' we can assume this function was569 // a missing '}' we can assume this function was
542 // supposed to end here.570 // supposed to end here.
543 try p.warn(.{ .ExpectedSemiOrLBrace = .{ .token = p.tok_i } });571 try p.warn(.expected_semi_or_lbrace);
544 return null_node;572 return null_node;
545 },573 },
546 }574 }
547 }575 }
548 if (expect_fn) {576 if (expect_fn) {
549 try p.warn(.{577 try p.warn(.expected_fn);
550 .ExpectedFn = .{ .token = p.tok_i },
551 });
552 return error.ParseError;578 return error.ParseError;
553 }579 }
554580
...@@ -559,11 +585,11 @@ const Parser = struct {...@@ -559,11 +585,11 @@ const Parser = struct {
559 return var_decl;585 return var_decl;
560 }586 }
561 if (thread_local_token != null) {587 if (thread_local_token != null) {
562 return p.fail(.{ .ExpectedVarDecl = .{ .token = p.tok_i } });588 return p.fail(.expected_var_decl);
563 }589 }
564590
565 if (exported) {591 if (exported) {
566 return p.fail(.{ .ExpectedVarDeclOrFn = .{ .token = p.tok_i } });592 return p.fail(.expected_var_decl_or_fn);
567 }593 }
568594
569 return p.expectUsingNamespace();595 return p.expectUsingNamespace();
...@@ -618,7 +644,7 @@ const Parser = struct {...@@ -618,7 +644,7 @@ const Parser = struct {
618 if (return_type_expr == 0) {644 if (return_type_expr == 0) {
619 // most likely the user forgot to specify the return type.645 // most likely the user forgot to specify the return type.
620 // Mark return type as invalid and try to continue.646 // Mark return type as invalid and try to continue.
621 try p.warn(.{ .ExpectedReturnType = .{ .token = p.tok_i } });647 try p.warn(.expected_return_type);
622 }648 }
623649
624 if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) {650 if (align_expr == 0 and section_expr == 0 and callconv_expr == 0) {
...@@ -901,7 +927,7 @@ const Parser = struct {...@@ -901,7 +927,7 @@ const Parser = struct {
901 fn expectStatement(p: *Parser) !Node.Index {927 fn expectStatement(p: *Parser) !Node.Index {
902 const statement = try p.parseStatement();928 const statement = try p.parseStatement();
903 if (statement == 0) {929 if (statement == 0) {
904 return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });930 return p.fail(.expected_statement);
905 }931 }
906 return statement;932 return statement;
907 }933 }
...@@ -940,7 +966,7 @@ const Parser = struct {...@@ -940,7 +966,7 @@ const Parser = struct {
940 if (block_expr != 0) break :blk block_expr;966 if (block_expr != 0) break :blk block_expr;
941 const assign_expr = try p.parseAssignExpr();967 const assign_expr = try p.parseAssignExpr();
942 if (assign_expr == 0) {968 if (assign_expr == 0) {
943 return p.fail(.{ .ExpectedBlockOrAssignment = .{ .token = p.tok_i } });969 return p.fail(.expected_block_or_assignment);
944 }970 }
945 if (p.eatToken(.semicolon)) |_| {971 if (p.eatToken(.semicolon)) |_| {
946 return p.addNode(.{972 return p.addNode(.{
...@@ -957,7 +983,7 @@ const Parser = struct {...@@ -957,7 +983,7 @@ const Parser = struct {
957 };983 };
958 const else_token = p.eatToken(.keyword_else) orelse {984 const else_token = p.eatToken(.keyword_else) orelse {
959 if (else_required) {985 if (else_required) {
960 return p.fail(.{ .ExpectedSemiOrElse = .{ .token = p.tok_i } });986 return p.fail(.expected_semi_or_else);
961 }987 }
962 return p.addNode(.{988 return p.addNode(.{
963 .tag = .if_simple,989 .tag = .if_simple,
...@@ -993,7 +1019,7 @@ const Parser = struct {...@@ -993,7 +1019,7 @@ const Parser = struct {
993 if (loop_stmt != 0) return loop_stmt;1019 if (loop_stmt != 0) return loop_stmt;
9941020
995 if (label_token != 0) {1021 if (label_token != 0) {
996 return p.fail(.{ .ExpectedLabelable = .{ .token = p.tok_i } });1022 return p.fail(.expected_labelable);
997 }1023 }
9981024
999 return null_node;1025 return null_node;
...@@ -1012,7 +1038,7 @@ const Parser = struct {...@@ -1012,7 +1038,7 @@ const Parser = struct {
1012 if (inline_token == null) return null_node;1038 if (inline_token == null) return null_node;
10131039
1014 // If we've seen "inline", there should have been a "for" or "while"1040 // If we've seen "inline", there should have been a "for" or "while"
1015 return p.fail(.{ .ExpectedInlinable = .{ .token = p.tok_i } });1041 return p.fail(.expected_inlinable);
1016 }1042 }
10171043
1018 /// ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload1044 /// ForPrefix <- KEYWORD_for LPAREN Expr RPAREN PtrIndexPayload
...@@ -1034,7 +1060,7 @@ const Parser = struct {...@@ -1034,7 +1060,7 @@ const Parser = struct {
1034 if (block_expr != 0) break :blk block_expr;1060 if (block_expr != 0) break :blk block_expr;
1035 const assign_expr = try p.parseAssignExpr();1061 const assign_expr = try p.parseAssignExpr();
1036 if (assign_expr == 0) {1062 if (assign_expr == 0) {
1037 return p.fail(.{ .ExpectedBlockOrAssignment = .{ .token = p.tok_i } });1063 return p.fail(.expected_block_or_assignment);
1038 }1064 }
1039 if (p.eatToken(.semicolon)) |_| {1065 if (p.eatToken(.semicolon)) |_| {
1040 return p.addNode(.{1066 return p.addNode(.{
...@@ -1051,7 +1077,7 @@ const Parser = struct {...@@ -1051,7 +1077,7 @@ const Parser = struct {
1051 };1077 };
1052 const else_token = p.eatToken(.keyword_else) orelse {1078 const else_token = p.eatToken(.keyword_else) orelse {
1053 if (else_required) {1079 if (else_required) {
1054 return p.fail(.{ .ExpectedSemiOrElse = .{ .token = p.tok_i } });1080 return p.fail(.expected_semi_or_else);
1055 }1081 }
1056 return p.addNode(.{1082 return p.addNode(.{
1057 .tag = .for_simple,1083 .tag = .for_simple,
...@@ -1095,7 +1121,7 @@ const Parser = struct {...@@ -1095,7 +1121,7 @@ const Parser = struct {
1095 if (block_expr != 0) break :blk block_expr;1121 if (block_expr != 0) break :blk block_expr;
1096 const assign_expr = try p.parseAssignExpr();1122 const assign_expr = try p.parseAssignExpr();
1097 if (assign_expr == 0) {1123 if (assign_expr == 0) {
1098 return p.fail(.{ .ExpectedBlockOrAssignment = .{ .token = p.tok_i } });1124 return p.fail(.expected_block_or_assignment);
1099 }1125 }
1100 if (p.eatToken(.semicolon)) |_| {1126 if (p.eatToken(.semicolon)) |_| {
1101 if (cont_expr == 0) {1127 if (cont_expr == 0) {
...@@ -1126,7 +1152,7 @@ const Parser = struct {...@@ -1126,7 +1152,7 @@ const Parser = struct {
1126 };1152 };
1127 const else_token = p.eatToken(.keyword_else) orelse {1153 const else_token = p.eatToken(.keyword_else) orelse {
1128 if (else_required) {1154 if (else_required) {
1129 return p.fail(.{ .ExpectedSemiOrElse = .{ .token = p.tok_i } });1155 return p.fail(.expected_semi_or_else);
1130 }1156 }
1131 if (cont_expr == 0) {1157 if (cont_expr == 0) {
1132 return p.addNode(.{1158 return p.addNode(.{
...@@ -1186,7 +1212,7 @@ const Parser = struct {...@@ -1186,7 +1212,7 @@ const Parser = struct {
1186 fn expectBlockExprStatement(p: *Parser) !Node.Index {1212 fn expectBlockExprStatement(p: *Parser) !Node.Index {
1187 const node = try p.parseBlockExprStatement();1213 const node = try p.parseBlockExprStatement();
1188 if (node == 0) {1214 if (node == 0) {
1189 return p.fail(.{ .ExpectedBlockOrExpression = .{ .token = p.tok_i } });1215 return p.fail(.expected_block_or_expr);
1190 }1216 }
1191 return node;1217 return node;
1192 }1218 }
...@@ -1259,7 +1285,7 @@ const Parser = struct {...@@ -1259,7 +1285,7 @@ const Parser = struct {
1259 fn expectAssignExpr(p: *Parser) !Node.Index {1285 fn expectAssignExpr(p: *Parser) !Node.Index {
1260 const expr = try p.parseAssignExpr();1286 const expr = try p.parseAssignExpr();
1261 if (expr == 0) {1287 if (expr == 0) {
1262 return p.fail(.{ .ExpectedExprOrAssignment = .{ .token = p.tok_i } });1288 return p.fail(.expected_expr_or_assignment);
1263 }1289 }
1264 return expr;1290 return expr;
1265 }1291 }
...@@ -1272,7 +1298,7 @@ const Parser = struct {...@@ -1272,7 +1298,7 @@ const Parser = struct {
1272 fn expectExpr(p: *Parser) Error!Node.Index {1298 fn expectExpr(p: *Parser) Error!Node.Index {
1273 const node = try p.parseExpr();1299 const node = try p.parseExpr();
1274 if (node == 0) {1300 if (node == 0) {
1275 return p.fail(.{ .ExpectedExpr = .{ .token = p.tok_i } });1301 return p.fail(.expected_expr);
1276 } else {1302 } else {
1277 return node;1303 return node;
1278 }1304 }
...@@ -1289,7 +1315,7 @@ const Parser = struct {...@@ -1289,7 +1315,7 @@ const Parser = struct {
1289 const or_token = p.nextToken();1315 const or_token = p.nextToken();
1290 const rhs = try p.parseBoolAndExpr();1316 const rhs = try p.parseBoolAndExpr();
1291 if (rhs == 0) {1317 if (rhs == 0) {
1292 return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });1318 return p.fail(.invalid_token);
1293 }1319 }
1294 res = try p.addNode(.{1320 res = try p.addNode(.{
1295 .tag = .bool_or,1321 .tag = .bool_or,
...@@ -1316,7 +1342,7 @@ const Parser = struct {...@@ -1316,7 +1342,7 @@ const Parser = struct {
1316 const and_token = p.nextToken();1342 const and_token = p.nextToken();
1317 const rhs = try p.parseCompareExpr();1343 const rhs = try p.parseCompareExpr();
1318 if (rhs == 0) {1344 if (rhs == 0) {
1319 return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });1345 return p.fail(.invalid_token);
1320 }1346 }
1321 res = try p.addNode(.{1347 res = try p.addNode(.{
1322 .tag = .bool_and,1348 .tag = .bool_and,
...@@ -1385,7 +1411,7 @@ const Parser = struct {...@@ -1385,7 +1411,7 @@ const Parser = struct {
1385 _ = try p.parsePayload();1411 _ = try p.parsePayload();
1386 const rhs = try p.parseBitShiftExpr();1412 const rhs = try p.parseBitShiftExpr();
1387 if (rhs == 0) {1413 if (rhs == 0) {
1388 return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });1414 return p.fail(.invalid_token);
1389 }1415 }
1390 res = try p.addNode(.{1416 res = try p.addNode(.{
1391 .tag = .@"catch",1417 .tag = .@"catch",
...@@ -1413,7 +1439,7 @@ const Parser = struct {...@@ -1413,7 +1439,7 @@ const Parser = struct {
1413 fn expectBitwiseExpr(p: *Parser) Error!Node.Index {1439 fn expectBitwiseExpr(p: *Parser) Error!Node.Index {
1414 const node = try p.parseBitwiseExpr();1440 const node = try p.parseBitwiseExpr();
1415 if (node == 0) {1441 if (node == 0) {
1416 return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });1442 return p.fail(.invalid_token);
1417 } else {1443 } else {
1418 return node;1444 return node;
1419 }1445 }
...@@ -1447,7 +1473,7 @@ const Parser = struct {...@@ -1447,7 +1473,7 @@ const Parser = struct {
1447 fn expectBitShiftExpr(p: *Parser) Error!Node.Index {1473 fn expectBitShiftExpr(p: *Parser) Error!Node.Index {
1448 const node = try p.parseBitShiftExpr();1474 const node = try p.parseBitShiftExpr();
1449 if (node == 0) {1475 if (node == 0) {
1450 return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });1476 return p.fail(.invalid_token);
1451 } else {1477 } else {
1452 return node;1478 return node;
1453 }1479 }
...@@ -1487,7 +1513,7 @@ const Parser = struct {...@@ -1487,7 +1513,7 @@ const Parser = struct {
1487 fn expectAdditionExpr(p: *Parser) Error!Node.Index {1513 fn expectAdditionExpr(p: *Parser) Error!Node.Index {
1488 const node = try p.parseAdditionExpr();1514 const node = try p.parseAdditionExpr();
1489 if (node == 0) {1515 if (node == 0) {
1490 return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });1516 return p.fail(.invalid_token);
1491 }1517 }
1492 return node;1518 return node;
1493 }1519 }
...@@ -1528,7 +1554,7 @@ const Parser = struct {...@@ -1528,7 +1554,7 @@ const Parser = struct {
1528 fn expectMultiplyExpr(p: *Parser) Error!Node.Index {1554 fn expectMultiplyExpr(p: *Parser) Error!Node.Index {
1529 const node = try p.parseMultiplyExpr();1555 const node = try p.parseMultiplyExpr();
1530 if (node == 0) {1556 if (node == 0) {
1531 return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });1557 return p.fail(.invalid_token);
1532 }1558 }
1533 return node;1559 return node;
1534 }1560 }
...@@ -1566,7 +1592,7 @@ const Parser = struct {...@@ -1566,7 +1592,7 @@ const Parser = struct {
1566 fn expectPrefixExpr(p: *Parser) Error!Node.Index {1592 fn expectPrefixExpr(p: *Parser) Error!Node.Index {
1567 const node = try p.parsePrefixExpr();1593 const node = try p.parsePrefixExpr();
1568 if (node == 0) {1594 if (node == 0) {
1569 return p.fail(.{ .ExpectedPrefixExpr = .{ .token = p.tok_i } });1595 return p.fail(.expected_prefix_expr);
1570 }1596 }
1571 return node;1597 return node;
1572 }1598 }
...@@ -1827,7 +1853,7 @@ const Parser = struct {...@@ -1827,7 +1853,7 @@ const Parser = struct {
1827 fn expectTypeExpr(p: *Parser) Error!Node.Index {1853 fn expectTypeExpr(p: *Parser) Error!Node.Index {
1828 const node = try p.parseTypeExpr();1854 const node = try p.parseTypeExpr();
1829 if (node == 0) {1855 if (node == 0) {
1830 return p.fail(.{ .ExpectedTypeExpr = .{ .token = p.tok_i } });1856 return p.fail(.expected_type_expr);
1831 }1857 }
1832 return node;1858 return node;
1833 }1859 }
...@@ -1922,9 +1948,7 @@ const Parser = struct {...@@ -1922,9 +1948,7 @@ const Parser = struct {
1922 switch (p.token_tags[p.tok_i]) {1948 switch (p.token_tags[p.tok_i]) {
1923 .keyword_for => return p.parseForExpr(),1949 .keyword_for => return p.parseForExpr(),
1924 .keyword_while => return p.parseWhileExpr(),1950 .keyword_while => return p.parseWhileExpr(),
1925 else => return p.fail(.{1951 else => return p.fail(.expected_inlinable),
1926 .ExpectedInlinable = .{ .token = p.tok_i },
1927 }),
1928 }1952 }
1929 },1953 },
1930 .keyword_for => {1954 .keyword_for => {
...@@ -1950,9 +1974,7 @@ const Parser = struct {...@@ -1950,9 +1974,7 @@ const Parser = struct {
1950 switch (p.token_tags[p.tok_i]) {1974 switch (p.token_tags[p.tok_i]) {
1951 .keyword_for => return p.parseForExpr(),1975 .keyword_for => return p.parseForExpr(),
1952 .keyword_while => return p.parseWhileExpr(),1976 .keyword_while => return p.parseWhileExpr(),
1953 else => return p.fail(.{1977 else => return p.fail(.expected_inlinable),
1954 .ExpectedInlinable = .{ .token = p.tok_i },
1955 }),
1956 }1978 }
1957 },1979 },
1958 .keyword_for => return p.parseForExpr(),1980 .keyword_for => return p.parseForExpr(),
...@@ -2170,20 +2192,13 @@ const Parser = struct {...@@ -2170,20 +2192,13 @@ const Parser = struct {
2170 .r_brace => break,2192 .r_brace => break,
2171 .colon, .r_paren, .r_bracket => {2193 .colon, .r_paren, .r_bracket => {
2172 p.tok_i -= 1;2194 p.tok_i -= 1;
2173 return p.fail(.{2195 return p.failExpected(.r_brace);
2174 .ExpectedToken = .{
2175 .token = p.tok_i,
2176 .expected_id = .r_brace,
2177 },
2178 });
2179 },2196 },
2180 else => {2197 else => {
2181 // This is likely just a missing comma;2198 // This is likely just a missing comma;
2182 // give an error but continue parsing this list.2199 // give an error but continue parsing this list.
2183 p.tok_i -= 1;2200 p.tok_i -= 1;
2184 try p.warn(.{2201 try p.warnExpected(.comma);
2185 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
2186 });
2187 },2202 },
2188 }2203 }
2189 }2204 }
...@@ -2214,9 +2229,7 @@ const Parser = struct {...@@ -2214,9 +2229,7 @@ const Parser = struct {
2214 });2229 });
2215 }2230 }
2216 if (comma_one == null) {2231 if (comma_one == null) {
2217 try p.warn(.{2232 try p.warnExpected(.comma);
2218 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
2219 });
2220 }2233 }
22212234
2222 var init_list = std.ArrayList(Node.Index).init(p.gpa);2235 var init_list = std.ArrayList(Node.Index).init(p.gpa);
...@@ -2278,7 +2291,7 @@ const Parser = struct {...@@ -2278,7 +2291,7 @@ const Parser = struct {
2278 res = node;2291 res = node;
2279 }2292 }
2280 const lparen = (try p.expectTokenRecoverable(.l_paren)) orelse {2293 const lparen = (try p.expectTokenRecoverable(.l_paren)) orelse {
2281 try p.warn(.{ .ExpectedParamList = .{ .token = p.tok_i } });2294 try p.warn(.expected_param_list);
2282 return res;2295 return res;
2283 };2296 };
2284 if (p.eatToken(.r_paren)) |_| {2297 if (p.eatToken(.r_paren)) |_| {
...@@ -2304,9 +2317,7 @@ const Parser = struct {...@@ -2304,9 +2317,7 @@ const Parser = struct {
2304 });2317 });
2305 }2318 }
2306 if (comma_one == null) {2319 if (comma_one == null) {
2307 try p.warn(.{2320 try p.warnExpected(.comma);
2308 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
2309 });
2310 }2321 }
23112322
2312 var param_list = std.ArrayList(Node.Index).init(p.gpa);2323 var param_list = std.ArrayList(Node.Index).init(p.gpa);
...@@ -2352,21 +2363,11 @@ const Parser = struct {...@@ -2352,21 +2363,11 @@ const Parser = struct {
2352 },2363 },
2353 .colon, .r_brace, .r_bracket => {2364 .colon, .r_brace, .r_bracket => {
2354 p.tok_i -= 1;2365 p.tok_i -= 1;
2355 return p.fail(.{2366 return p.failExpected(.r_paren);
2356 .ExpectedToken = .{
2357 .token = p.tok_i,
2358 .expected_id = .r_paren,
2359 },
2360 });
2361 },2367 },
2362 else => {2368 else => {
2363 p.tok_i -= 1;2369 p.tok_i -= 1;
2364 try p.warn(.{2370 try p.warnExpected(.comma);
2365 .ExpectedToken = .{
2366 .token = p.tok_i,
2367 .expected_id = .comma,
2368 },
2369 });
2370 },2371 },
2371 }2372 }
2372 }2373 }
...@@ -2405,9 +2406,7 @@ const Parser = struct {...@@ -2405,9 +2406,7 @@ const Parser = struct {
2405 });2406 });
2406 }2407 }
2407 if (comma_one == null) {2408 if (comma_one == null) {
2408 try p.warn(.{2409 try p.warnExpected(.comma);
2409 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
2410 });
2411 }2410 }
24122411
2413 var param_list = std.ArrayList(Node.Index).init(p.gpa);2412 var param_list = std.ArrayList(Node.Index).init(p.gpa);
...@@ -2453,21 +2452,11 @@ const Parser = struct {...@@ -2453,21 +2452,11 @@ const Parser = struct {
2453 },2452 },
2454 .colon, .r_brace, .r_bracket => {2453 .colon, .r_brace, .r_bracket => {
2455 p.tok_i -= 1;2454 p.tok_i -= 1;
2456 return p.fail(.{2455 return p.failExpected(.r_paren);
2457 .ExpectedToken = .{
2458 .token = p.tok_i,
2459 .expected_id = .r_paren,
2460 },
2461 });
2462 },2456 },
2463 else => {2457 else => {
2464 p.tok_i -= 1;2458 p.tok_i -= 1;
2465 try p.warn(.{2459 try p.warnExpected(.comma);
2466 .ExpectedToken = .{
2467 .token = p.tok_i,
2468 .expected_id = .comma,
2469 },
2470 });
2471 },2460 },
2472 }2461 }
2473 }2462 }
...@@ -2645,9 +2634,7 @@ const Parser = struct {...@@ -2645,9 +2634,7 @@ const Parser = struct {
2645 switch (p.token_tags[p.tok_i]) {2634 switch (p.token_tags[p.tok_i]) {
2646 .keyword_for => return p.parseForTypeExpr(),2635 .keyword_for => return p.parseForTypeExpr(),
2647 .keyword_while => return p.parseWhileTypeExpr(),2636 .keyword_while => return p.parseWhileTypeExpr(),
2648 else => return p.fail(.{2637 else => return p.fail(.expected_inlinable),
2649 .ExpectedInlinable = .{ .token = p.tok_i },
2650 }),
2651 }2638 }
2652 },2639 },
2653 .keyword_for => {2640 .keyword_for => {
...@@ -2716,9 +2703,7 @@ const Parser = struct {...@@ -2716,9 +2703,7 @@ const Parser = struct {
2716 });2703 });
2717 }2704 }
2718 if (comma_one == null) {2705 if (comma_one == null) {
2719 try p.warn(.{2706 try p.warnExpected(.comma);
2720 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
2721 });
2722 }2707 }
2723 const field_init_two = try p.expectFieldInit();2708 const field_init_two = try p.expectFieldInit();
2724 const comma_two = p.eatToken(.comma);2709 const comma_two = p.eatToken(.comma);
...@@ -2733,9 +2718,7 @@ const Parser = struct {...@@ -2733,9 +2718,7 @@ const Parser = struct {
2733 });2718 });
2734 }2719 }
2735 if (comma_two == null) {2720 if (comma_two == null) {
2736 try p.warn(.{2721 try p.warnExpected(.comma);
2737 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
2738 });
2739 }2722 }
2740 var init_list = std.ArrayList(Node.Index).init(p.gpa);2723 var init_list = std.ArrayList(Node.Index).init(p.gpa);
2741 defer init_list.deinit();2724 defer init_list.deinit();
...@@ -2754,21 +2737,11 @@ const Parser = struct {...@@ -2754,21 +2737,11 @@ const Parser = struct {
2754 .r_brace => break,2737 .r_brace => break,
2755 .colon, .r_paren, .r_bracket => {2738 .colon, .r_paren, .r_bracket => {
2756 p.tok_i -= 1;2739 p.tok_i -= 1;
2757 return p.fail(.{2740 return p.failExpected(.r_brace);
2758 .ExpectedToken = .{
2759 .token = p.tok_i,
2760 .expected_id = .r_brace,
2761 },
2762 });
2763 },2741 },
2764 else => {2742 else => {
2765 p.tok_i -= 1;2743 p.tok_i -= 1;
2766 try p.warn(.{2744 try p.warnExpected(.comma);
2767 .ExpectedToken = .{
2768 .token = p.tok_i,
2769 .expected_id = .comma,
2770 },
2771 });
2772 },2745 },
2773 }2746 }
2774 }2747 }
...@@ -2797,9 +2770,7 @@ const Parser = struct {...@@ -2797,9 +2770,7 @@ const Parser = struct {
2797 });2770 });
2798 }2771 }
2799 if (comma_one == null) {2772 if (comma_one == null) {
2800 try p.warn(.{2773 try p.warnExpected(.comma);
2801 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
2802 });
2803 }2774 }
2804 const elem_init_two = try p.expectExpr();2775 const elem_init_two = try p.expectExpr();
2805 const comma_two = p.eatToken(.comma);2776 const comma_two = p.eatToken(.comma);
...@@ -2814,9 +2785,7 @@ const Parser = struct {...@@ -2814,9 +2785,7 @@ const Parser = struct {
2814 });2785 });
2815 }2786 }
2816 if (comma_two == null) {2787 if (comma_two == null) {
2817 try p.warn(.{2788 try p.warnExpected(.comma);
2818 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
2819 });
2820 }2789 }
2821 var init_list = std.ArrayList(Node.Index).init(p.gpa);2790 var init_list = std.ArrayList(Node.Index).init(p.gpa);
2822 defer init_list.deinit();2791 defer init_list.deinit();
...@@ -2835,21 +2804,11 @@ const Parser = struct {...@@ -2835,21 +2804,11 @@ const Parser = struct {
2835 .r_brace => break,2804 .r_brace => break,
2836 .colon, .r_paren, .r_bracket => {2805 .colon, .r_paren, .r_bracket => {
2837 p.tok_i -= 1;2806 p.tok_i -= 1;
2838 return p.fail(.{2807 return p.failExpected(.r_brace);
2839 .ExpectedToken = .{
2840 .token = p.tok_i,
2841 .expected_id = .r_brace,
2842 },
2843 });
2844 },2808 },
2845 else => {2809 else => {
2846 p.tok_i -= 1;2810 p.tok_i -= 1;
2847 try p.warn(.{2811 try p.warnExpected(.comma);
2848 .ExpectedToken = .{
2849 .token = p.tok_i,
2850 .expected_id = .comma,
2851 },
2852 });
2853 },2812 },
2854 }2813 }
2855 }2814 }
...@@ -2892,20 +2851,13 @@ const Parser = struct {...@@ -2892,20 +2851,13 @@ const Parser = struct {
2892 .r_brace => break,2851 .r_brace => break,
2893 .colon, .r_paren, .r_bracket => {2852 .colon, .r_paren, .r_bracket => {
2894 p.tok_i -= 1;2853 p.tok_i -= 1;
2895 return p.fail(.{2854 return p.failExpected(.r_brace);
2896 .ExpectedToken = .{
2897 .token = p.tok_i,
2898 .expected_id = .r_brace,
2899 },
2900 });
2901 },2855 },
2902 else => {2856 else => {
2903 // This is likely just a missing comma;2857 // This is likely just a missing comma;
2904 // give an error but continue parsing this list.2858 // give an error but continue parsing this list.
2905 p.tok_i -= 1;2859 p.tok_i -= 1;
2906 try p.warn(.{2860 try p.warnExpected(.comma);
2907 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
2908 });
2909 },2861 },
2910 }2862 }
2911 }2863 }
...@@ -2942,7 +2894,7 @@ const Parser = struct {...@@ -2942,7 +2894,7 @@ const Parser = struct {
2942 fn expectPrimaryTypeExpr(p: *Parser) !Node.Index {2894 fn expectPrimaryTypeExpr(p: *Parser) !Node.Index {
2943 const node = try p.parsePrimaryTypeExpr();2895 const node = try p.parsePrimaryTypeExpr();
2944 if (node == 0) {2896 if (node == 0) {
2945 return p.fail(.{ .ExpectedPrimaryTypeExpr = .{ .token = p.tok_i } });2897 return p.fail(.expected_primary_type_expr);
2946 }2898 }
2947 return node;2899 return node;
2948 }2900 }
...@@ -3095,9 +3047,7 @@ const Parser = struct {...@@ -3095,9 +3047,7 @@ const Parser = struct {
3095 else => {3047 else => {
3096 // This is likely just a missing comma;3048 // This is likely just a missing comma;
3097 // give an error but continue parsing this list.3049 // give an error but continue parsing this list.
3098 try p.warn(.{3050 try p.warnExpected(.comma);
3099 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
3100 });
3101 },3051 },
3102 }3052 }
3103 }3053 }
...@@ -3112,9 +3062,7 @@ const Parser = struct {...@@ -3112,9 +3062,7 @@ const Parser = struct {
3112 else => {3062 else => {
3113 // This is likely just a missing comma;3063 // This is likely just a missing comma;
3114 // give an error but continue parsing this list.3064 // give an error but continue parsing this list.
3115 try p.warn(.{3065 try p.warnExpected(.comma);
3116 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
3117 });
3118 },3066 },
3119 }3067 }
3120 }3068 }
...@@ -3126,9 +3074,7 @@ const Parser = struct {...@@ -3126,9 +3074,7 @@ const Parser = struct {
3126 else => {3074 else => {
3127 // This is likely just a missing comma;3075 // This is likely just a missing comma;
3128 // give an error but continue parsing this list.3076 // give an error but continue parsing this list.
3129 try p.warn(.{3077 try p.warnExpected(.comma);
3130 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
3131 });
3132 },3078 },
3133 }3079 }
3134 }3080 }
...@@ -3238,7 +3184,7 @@ const Parser = struct {...@@ -3238,7 +3184,7 @@ const Parser = struct {
3238 _ = p.eatToken(.colon) orelse return null_node;3184 _ = p.eatToken(.colon) orelse return null_node;
3239 _ = try p.expectToken(.l_paren);3185 _ = try p.expectToken(.l_paren);
3240 const node = try p.parseAssignExpr();3186 const node = try p.parseAssignExpr();
3241 if (node == 0) return p.fail(.{ .ExpectedExprOrAssignment = .{ .token = p.tok_i } });3187 if (node == 0) return p.fail(.expected_expr_or_assignment);
3242 _ = try p.expectToken(.r_paren);3188 _ = try p.expectToken(.r_paren);
3243 return node;3189 return node;
3244 }3190 }
...@@ -3418,9 +3364,7 @@ const Parser = struct {...@@ -3418,9 +3364,7 @@ const Parser = struct {
3418 switch (p.token_tags[p.tok_i]) {3364 switch (p.token_tags[p.tok_i]) {
3419 .keyword_align => {3365 .keyword_align => {
3420 if (result.align_node != 0) {3366 if (result.align_node != 0) {
3421 try p.warn(.{3367 try p.warn(.extra_align_qualifier);
3422 .ExtraAlignQualifier = .{ .token = p.tok_i },
3423 });
3424 }3368 }
3425 p.tok_i += 1;3369 p.tok_i += 1;
3426 _ = try p.expectToken(.l_paren);3370 _ = try p.expectToken(.l_paren);
...@@ -3436,27 +3380,21 @@ const Parser = struct {...@@ -3436,27 +3380,21 @@ const Parser = struct {
3436 },3380 },
3437 .keyword_const => {3381 .keyword_const => {
3438 if (saw_const) {3382 if (saw_const) {
3439 try p.warn(.{3383 try p.warn(.extra_const_qualifier);
3440 .ExtraConstQualifier = .{ .token = p.tok_i },
3441 });
3442 }3384 }
3443 p.tok_i += 1;3385 p.tok_i += 1;
3444 saw_const = true;3386 saw_const = true;
3445 },3387 },
3446 .keyword_volatile => {3388 .keyword_volatile => {
3447 if (saw_volatile) {3389 if (saw_volatile) {
3448 try p.warn(.{3390 try p.warn(.extra_volatile_qualifier);
3449 .ExtraVolatileQualifier = .{ .token = p.tok_i },
3450 });
3451 }3391 }
3452 p.tok_i += 1;3392 p.tok_i += 1;
3453 saw_volatile = true;3393 saw_volatile = true;
3454 },3394 },
3455 .keyword_allowzero => {3395 .keyword_allowzero => {
3456 if (saw_allowzero) {3396 if (saw_allowzero) {
3457 try p.warn(.{3397 try p.warn(.extra_allowzero_qualifier);
3458 .ExtraAllowZeroQualifier = .{ .token = p.tok_i },
3459 });
3460 }3398 }
3461 p.tok_i += 1;3399 p.tok_i += 1;
3462 saw_allowzero = true;3400 saw_allowzero = true;
...@@ -3539,11 +3477,10 @@ const Parser = struct {...@@ -3539,11 +3477,10 @@ const Parser = struct {
3539 },3477 },
3540 }),3478 }),
3541 .invalid_periodasterisks => {3479 .invalid_periodasterisks => {
3542 const period_asterisk = p.nextToken();3480 try p.warn(.asterisk_after_ptr_deref);
3543 try p.warn(.{ .AsteriskAfterPointerDereference = .{ .token = period_asterisk } });
3544 return p.addNode(.{3481 return p.addNode(.{
3545 .tag = .deref,3482 .tag = .deref,
3546 .main_token = period_asterisk,3483 .main_token = p.nextToken(),
3547 .data = .{3484 .data = .{
3548 .lhs = lhs,3485 .lhs = lhs,
3549 .rhs = undefined,3486 .rhs = undefined,
...@@ -3569,7 +3506,7 @@ const Parser = struct {...@@ -3569,7 +3506,7 @@ const Parser = struct {
3569 }),3506 }),
3570 else => {3507 else => {
3571 p.tok_i += 1;3508 p.tok_i += 1;
3572 try p.warn(.{ .ExpectedSuffixOp = .{ .token = p.tok_i } });3509 try p.warn(.expected_suffix_op);
3573 return null_node;3510 return null_node;
3574 },3511 },
3575 },3512 },
...@@ -3743,9 +3680,7 @@ const Parser = struct {...@@ -3743,9 +3680,7 @@ const Parser = struct {
3743 // This is likely just a missing comma;3680 // This is likely just a missing comma;
3744 // give an error but continue parsing this list.3681 // give an error but continue parsing this list.
3745 p.tok_i -= 1;3682 p.tok_i -= 1;
3746 try p.warn(.{3683 try p.warnExpected(.comma);
3747 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
3748 });
3749 },3684 },
3750 }3685 }
3751 } else unreachable;3686 } else unreachable;
...@@ -3763,17 +3698,13 @@ const Parser = struct {...@@ -3763,17 +3698,13 @@ const Parser = struct {
3763 .r_paren => return SmallSpan{ .zero_or_one = param_one },3698 .r_paren => return SmallSpan{ .zero_or_one = param_one },
3764 .colon, .r_brace, .r_bracket => {3699 .colon, .r_brace, .r_bracket => {
3765 p.tok_i -= 1;3700 p.tok_i -= 1;
3766 return p.fail(.{3701 return p.failExpected(.r_paren);
3767 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .r_paren },
3768 });
3769 },3702 },
3770 else => {3703 else => {
3771 // This is likely just a missing comma;3704 // This is likely just a missing comma;
3772 // give an error but continue parsing this list.3705 // give an error but continue parsing this list.
3773 p.tok_i -= 1;3706 p.tok_i -= 1;
3774 try p.warn(.{3707 try p.warnExpected(.comma);
3775 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
3776 });
3777 },3708 },
3778 }3709 }
3779 } else unreachable;3710 } else unreachable;
...@@ -3799,17 +3730,13 @@ const Parser = struct {...@@ -3799,17 +3730,13 @@ const Parser = struct {
3799 .r_paren => return SmallSpan{ .multi = list.toOwnedSlice() },3730 .r_paren => return SmallSpan{ .multi = list.toOwnedSlice() },
3800 .colon, .r_brace, .r_bracket => {3731 .colon, .r_brace, .r_bracket => {
3801 p.tok_i -= 1;3732 p.tok_i -= 1;
3802 return p.fail(.{3733 return p.failExpected(.r_paren);
3803 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .r_paren },
3804 });
3805 },3734 },
3806 else => {3735 else => {
3807 // This is likely just a missing comma;3736 // This is likely just a missing comma;
3808 // give an error but continue parsing this list.3737 // give an error but continue parsing this list.
3809 p.tok_i -= 1;3738 p.tok_i -= 1;
3810 try p.warn(.{3739 try p.warnExpected(.comma);
3811 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
3812 });
3813 },3740 },
3814 }3741 }
3815 }3742 }
...@@ -3836,9 +3763,7 @@ const Parser = struct {...@@ -3836,9 +3763,7 @@ const Parser = struct {
3836 else => {3763 else => {
3837 // This is likely just a missing comma;3764 // This is likely just a missing comma;
3838 // give an error but continue parsing this list.3765 // give an error but continue parsing this list.
3839 try p.warn(.{3766 try p.warnExpected(.comma);
3840 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
3841 });
3842 },3767 },
3843 }3768 }
3844 }3769 }
...@@ -3852,9 +3777,7 @@ const Parser = struct {...@@ -3852,9 +3777,7 @@ const Parser = struct {
3852 fn parseBuiltinCall(p: *Parser) !Node.Index {3777 fn parseBuiltinCall(p: *Parser) !Node.Index {
3853 const builtin_token = p.assertToken(.builtin);3778 const builtin_token = p.assertToken(.builtin);
3854 _ = (try p.expectTokenRecoverable(.l_paren)) orelse {3779 _ = (try p.expectTokenRecoverable(.l_paren)) orelse {
3855 try p.warn(.{3780 try p.warn(.expected_param_list);
3856 .ExpectedParamList = .{ .token = p.tok_i },
3857 });
3858 // Pretend this was an identifier so we can continue parsing.3781 // Pretend this was an identifier so we can continue parsing.
3859 return p.addNode(.{3782 return p.addNode(.{
3860 .tag = .identifier,3783 .tag = .identifier,
...@@ -3901,9 +3824,7 @@ const Parser = struct {...@@ -3901,9 +3824,7 @@ const Parser = struct {
3901 // This is likely just a missing comma;3824 // This is likely just a missing comma;
3902 // give an error but continue parsing this list.3825 // give an error but continue parsing this list.
3903 p.tok_i -= 1;3826 p.tok_i -= 1;
3904 try p.warn(.{3827 try p.warnExpected(.comma);
3905 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
3906 });
3907 },3828 },
3908 }3829 }
3909 const param_two = try p.expectExpr();3830 const param_two = try p.expectExpr();
...@@ -3932,9 +3853,7 @@ const Parser = struct {...@@ -3932,9 +3853,7 @@ const Parser = struct {
3932 // This is likely just a missing comma;3853 // This is likely just a missing comma;
3933 // give an error but continue parsing this list.3854 // give an error but continue parsing this list.
3934 p.tok_i -= 1;3855 p.tok_i -= 1;
3935 try p.warn(.{3856 try p.warnExpected(.comma);
3936 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
3937 });
3938 },3857 },
3939 }3858 }
39403859
...@@ -3976,9 +3895,7 @@ const Parser = struct {...@@ -3976,9 +3895,7 @@ const Parser = struct {
3976 // This is likely just a missing comma;3895 // This is likely just a missing comma;
3977 // give an error but continue parsing this list.3896 // give an error but continue parsing this list.
3978 p.tok_i -= 1;3897 p.tok_i -= 1;
3979 try p.warn(.{3898 try p.warnExpected(.comma);
3980 .ExpectedToken = .{ .token = p.tok_i, .expected_id = .comma },
3981 });
3982 },3899 },
3983 }3900 }
3984 }3901 }
...@@ -4019,7 +3936,7 @@ const Parser = struct {...@@ -4019,7 +3936,7 @@ const Parser = struct {
4019 fn expectStringLiteral(p: *Parser) !Node.Index {3936 fn expectStringLiteral(p: *Parser) !Node.Index {
4020 const node = try p.parseStringLiteral();3937 const node = try p.parseStringLiteral();
4021 if (node == 0) {3938 if (node == 0) {
4022 return p.fail(.{ .ExpectedStringLiteral = .{ .token = p.tok_i } });3939 return p.fail(.expected_string_literal);
4023 }3940 }
4024 return node;3941 return node;
4025 }3942 }
...@@ -4044,7 +3961,7 @@ const Parser = struct {...@@ -4044,7 +3961,7 @@ const Parser = struct {
4044 const then_payload = try p.parsePtrPayload();3961 const then_payload = try p.parsePtrPayload();
40453962
4046 const then_expr = try bodyParseFn(p);3963 const then_expr = try bodyParseFn(p);
4047 if (then_expr == 0) return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });3964 if (then_expr == 0) return p.fail(.invalid_token);
40483965
4049 const else_token = p.eatToken(.keyword_else) orelse return p.addNode(.{3966 const else_token = p.eatToken(.keyword_else) orelse return p.addNode(.{
4050 .tag = .if_simple,3967 .tag = .if_simple,
...@@ -4056,7 +3973,7 @@ const Parser = struct {...@@ -4056,7 +3973,7 @@ const Parser = struct {
4056 });3973 });
4057 const else_payload = try p.parsePayload();3974 const else_payload = try p.parsePayload();
4058 const else_expr = try bodyParseFn(p);3975 const else_expr = try bodyParseFn(p);
4059 if (else_expr == 0) return p.fail(.{ .InvalidToken = .{ .token = p.tok_i } });3976 if (else_expr == 0) return p.fail(.invalid_token);
40603977
4061 return p.addNode(.{3978 return p.addNode(.{
4062 .tag = .@"if",3979 .tag = .@"if",
...@@ -4076,7 +3993,10 @@ const Parser = struct {...@@ -4076,7 +3993,10 @@ const Parser = struct {
4076 if (p.eatToken(.doc_comment)) |tok| {3993 if (p.eatToken(.doc_comment)) |tok| {
4077 var first_line = tok;3994 var first_line = tok;
4078 if (tok > 0 and tokensOnSameLine(p, tok - 1, tok)) {3995 if (tok > 0 and tokensOnSameLine(p, tok - 1, tok)) {
4079 try p.warn(.{ .SameLineDocComment = .{ .token = tok } });3996 try p.warnMsg(.{
3997 .tag = .same_line_doc_comment,
3998 .token = tok,
3999 });
4080 first_line = p.eatToken(.doc_comment) orelse return null;4000 first_line = p.eatToken(.doc_comment) orelse return null;
4081 }4001 }
4082 while (p.eatToken(.doc_comment)) |_| {}4002 while (p.eatToken(.doc_comment)) |_| {}
...@@ -4102,16 +4022,18 @@ const Parser = struct {...@@ -4102,16 +4022,18 @@ const Parser = struct {
4102 fn expectToken(p: *Parser, tag: Token.Tag) Error!TokenIndex {4022 fn expectToken(p: *Parser, tag: Token.Tag) Error!TokenIndex {
4103 const token = p.nextToken();4023 const token = p.nextToken();
4104 if (p.token_tags[token] != tag) {4024 if (p.token_tags[token] != tag) {
4105 return p.fail(.{ .ExpectedToken = .{ .token = token, .expected_id = tag } });4025 return p.failMsg(.{
4026 .tag = .expected_token,
4027 .token = token,
4028 .extra = .{ .expected_tag = tag },
4029 });
4106 }4030 }
4107 return token;4031 return token;
4108 }4032 }
41094033
4110 fn expectTokenRecoverable(p: *Parser, tag: Token.Tag) !?TokenIndex {4034 fn expectTokenRecoverable(p: *Parser, tag: Token.Tag) !?TokenIndex {
4111 if (p.token_tags[p.tok_i] != tag) {4035 if (p.token_tags[p.tok_i] != tag) {
4112 try p.warn(.{4036 try p.warnExpected(tag);
4113 .ExpectedToken = .{ .token = p.tok_i, .expected_id = tag },
4114 });
4115 return null;4037 return null;
4116 } else {4038 } else {
4117 return p.nextToken();4039 return p.nextToken();
lib/std/zig/parser_test.zig+63-64
...@@ -127,7 +127,7 @@ test "zig fmt: decl between fields" {...@@ -127,7 +127,7 @@ test "zig fmt: decl between fields" {
127 \\ b: usize,127 \\ b: usize,
128 \\};128 \\};
129 , &[_]Error{129 , &[_]Error{
130 .DeclBetweenFields,130 .decl_between_fields,
131 });131 });
132}132}
133133
...@@ -135,7 +135,7 @@ test "zig fmt: eof after missing comma" {...@@ -135,7 +135,7 @@ test "zig fmt: eof after missing comma" {
135 try testError(135 try testError(
136 \\foo()136 \\foo()
137 , &[_]Error{137 , &[_]Error{
138 .ExpectedToken,138 .expected_token,
139 });139 });
140}140}
141141
...@@ -3578,7 +3578,7 @@ test "zig fmt: file ends with struct field" {...@@ -3578,7 +3578,7 @@ test "zig fmt: file ends with struct field" {
3578// \\const container = extern {};3578// \\const container = extern {};
3579// \\3579// \\
3580// , &[_]Error{3580// , &[_]Error{
3581// .ExpectedExpr,3581// .expected_expr,
3582// .ExpectedVarDeclOrFn,3582// .ExpectedVarDeclOrFn,
3583// });3583// });
3584//}3584//}
...@@ -3598,12 +3598,12 @@ test "zig fmt: same line doc comment returns error" {...@@ -3598,12 +3598,12 @@ test "zig fmt: same line doc comment returns error" {
3598 \\/// comment3598 \\/// comment
3599 \\3599 \\
3600 , &[_]Error{3600 , &[_]Error{
3601 .SameLineDocComment,3601 .same_line_doc_comment,
3602 .SameLineDocComment,3602 .same_line_doc_comment,
3603 .UnattachedDocComment,3603 .unattached_doc_comment,
3604 .SameLineDocComment,3604 .same_line_doc_comment,
3605 .SameLineDocComment,3605 .same_line_doc_comment,
3606 .UnattachedDocComment,3606 .unattached_doc_comment,
3607 });3607 });
3608}3608}
36093609
...@@ -3678,10 +3678,10 @@ test "zig fmt: hexadeciaml float literals with underscore separators" {...@@ -3678,10 +3678,10 @@ test "zig fmt: hexadeciaml float literals with underscore separators" {
3678}3678}
36793679
3680test "zig fmt: C var args" {3680test "zig fmt: C var args" {
3681 try testCanonical(3681 try testCanonical(
3682 \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;3682 \\pub extern "c" fn printf(format: [*:0]const u8, ...) c_int;
3683 \\3683 \\
3684 );3684 );
3685}3685}
36863686
3687//test "zig fmt: Only indent multiline string literals in function calls" {3687//test "zig fmt: Only indent multiline string literals in function calls" {
...@@ -4037,8 +4037,8 @@ test "recovery: top level" {...@@ -4037,8 +4037,8 @@ test "recovery: top level" {
4037 \\test "" {inline}4037 \\test "" {inline}
4038 \\test "" {inline}4038 \\test "" {inline}
4039 , &[_]Error{4039 , &[_]Error{
4040 .ExpectedInlinable,4040 .expected_inlinable,
4041 .ExpectedInlinable,4041 .expected_inlinable,
4042 });4042 });
4043}4043}
40444044
...@@ -4049,8 +4049,8 @@ test "recovery: block statements" {...@@ -4049,8 +4049,8 @@ test "recovery: block statements" {
4049 \\ inline;4049 \\ inline;
4050 \\}4050 \\}
4051 , &[_]Error{4051 , &[_]Error{
4052 .InvalidToken,4052 .invalid_token,
4053 .ExpectedInlinable,4053 .expected_inlinable,
4054 });4054 });
4055}4055}
40564056
...@@ -4066,10 +4066,10 @@ test "recovery: block statements" {...@@ -4066,10 +4066,10 @@ test "recovery: block statements" {
4066// \\ }4066// \\ }
4067// \\}4067// \\}
4068// , &[_]Error{4068// , &[_]Error{
4069// .ExpectedToken,4069// .expected_token,
4070// .ExpectedToken,4070// .expected_token,
4071// .InvalidAnd,4071// .invalid_and,
4072// .InvalidToken,4072// .invalid_token,
4073// });4073// });
4074//}4074//}
40754075
...@@ -4078,8 +4078,8 @@ test "recovery: extra qualifier" {...@@ -4078,8 +4078,8 @@ test "recovery: extra qualifier" {
4078 \\const a: *const const u8;4078 \\const a: *const const u8;
4079 \\test ""4079 \\test ""
4080 , &[_]Error{4080 , &[_]Error{
4081 .ExtraConstQualifier,4081 .extra_const_qualifier,
4082 .ExpectedLBrace,4082 .expected_block,
4083 });4083 });
4084}4084}
40854085
...@@ -4091,8 +4091,8 @@ test "recovery: extra qualifier" {...@@ -4091,8 +4091,8 @@ test "recovery: extra qualifier" {
4091// \\test ""4091// \\test ""
4092// , &[_]Error{4092// , &[_]Error{
4093// .ExpectedReturnType,4093// .ExpectedReturnType,
4094// .InvalidAnd,4094// .invalid_and,
4095// .ExpectedLBrace,4095// .expected_block,
4096// });4096// });
4097//}4097//}
40984098
...@@ -4105,10 +4105,10 @@ test "recovery: extra qualifier" {...@@ -4105,10 +4105,10 @@ test "recovery: extra qualifier" {
4105// \\ async a && b;4105// \\ async a && b;
4106// \\}4106// \\}
4107// , &[_]Error{4107// , &[_]Error{
4108// .ExpectedToken,4108// .expected_token,
4109// .ExpectedPubItem,4109// .ExpectedPubItem,
4110// .ExpectedParamList,4110// .ExpectedParamList,
4111// .InvalidAnd,4111// .invalid_and,
4112// });4112// });
4113// try testError(4113// try testError(
4114// \\threadlocal test "" {4114// \\threadlocal test "" {
...@@ -4117,7 +4117,7 @@ test "recovery: extra qualifier" {...@@ -4117,7 +4117,7 @@ test "recovery: extra qualifier" {
4117// , &[_]Error{4117// , &[_]Error{
4118// .ExpectedVarDecl,4118// .ExpectedVarDecl,
4119// .ExpectedParamList,4119// .ExpectedParamList,
4120// .InvalidAnd,4120// .invalid_and,
4121// });4121// });
4122//}4122//}
41234123
...@@ -4126,13 +4126,13 @@ test "recovery: extra qualifier" {...@@ -4126,13 +4126,13 @@ test "recovery: extra qualifier" {
4126// \\inline test "" { a && b; }4126// \\inline test "" { a && b; }
4127// , &[_]Error{4127// , &[_]Error{
4128// .ExpectedFn,4128// .ExpectedFn,
4129// .InvalidAnd,4129// .invalid_and,
4130// });4130// });
4131// try testError(4131// try testError(
4132// \\extern "" test "" { a && b; }4132// \\extern "" test "" { a && b; }
4133// , &[_]Error{4133// , &[_]Error{
4134// .ExpectedVarDeclOrFn,4134// .ExpectedVarDeclOrFn,
4135// .InvalidAnd,4135// .invalid_and,
4136// });4136// });
4137//}4137//}
41384138
...@@ -4144,12 +4144,12 @@ test "recovery: extra qualifier" {...@@ -4144,12 +4144,12 @@ test "recovery: extra qualifier" {
4144// \\ @foo4144// \\ @foo
4145// \\}4145// \\}
4146// , &[_]Error{4146// , &[_]Error{
4147// .InvalidAnd,4147// .invalid_and,
4148// .ExpectedToken,4148// .expected_token,
4149// .InvalidAnd,4149// .invalid_and,
4150// .ExpectedToken,4150// .expected_token,
4151// .ExpectedParamList,4151// .ExpectedParamList,
4152// .ExpectedToken,4152// .expected_token,
4153// });4153// });
4154//}4154//}
41554155
...@@ -4163,12 +4163,12 @@ test "recovery: extra qualifier" {...@@ -4163,12 +4163,12 @@ test "recovery: extra qualifier" {
4163// \\ a && b4163// \\ a && b
4164// \\}4164// \\}
4165// , &[_]Error{4165// , &[_]Error{
4166// .ExpectedExpr,4166// .expected_expr,
4167// .ExpectedToken,4167// .expected_token,
4168// .ExpectedToken,4168// .expected_token,
4169// .ExpectedContainerMembers,4169// .expected_container_members,
4170// .InvalidAnd,4170// .invalid_and,
4171// .ExpectedToken,4171// .expected_token,
4172// });4172// });
4173//}4173//}
41744174
...@@ -4178,7 +4178,7 @@ test "recovery: extra qualifier" {...@@ -4178,7 +4178,7 @@ test "recovery: extra qualifier" {
4178// \\ a(comptime T: type)4178// \\ a(comptime T: type)
4179// \\}4179// \\}
4180// , &[_]Error{4180// , &[_]Error{
4181// .ExpectedToken,4181// .expected_token,
4182// });4182// });
4183//}4183//}
41844184
...@@ -4189,10 +4189,10 @@ test "recovery: extra qualifier" {...@@ -4189,10 +4189,10 @@ test "recovery: extra qualifier" {
4189// \\ a && b;4189// \\ a && b;
4190// \\}4190// \\}
4191// , &[_]Error{4191// , &[_]Error{
4192// .ExpectedContainerMembers,4192// .expected_container_members,
4193// .ExpectedContainerMembers,4193// .expected_container_members,
4194// .ExpectedContainerMembers,4194// .expected_container_members,
4195// .InvalidAnd,4195// .invalid_and,
4196// });4196// });
4197//}4197//}
4198//4198//
...@@ -4202,7 +4202,7 @@ test "recovery: mismatched bracket at top level" {...@@ -4202,7 +4202,7 @@ test "recovery: mismatched bracket at top level" {
4202 \\ arr: 128]?G4202 \\ arr: 128]?G
4203 \\};4203 \\};
4204 , &[_]Error{4204 , &[_]Error{
4205 .ExpectedToken,4205 .expected_token,
4206 });4206 });
4207}4207}
42084208
...@@ -4212,9 +4212,9 @@ test "recovery: mismatched bracket at top level" {...@@ -4212,9 +4212,9 @@ test "recovery: mismatched bracket at top level" {
4212// \\ error && foo;4212// \\ error && foo;
4213// \\}4213// \\}
4214// , &[_]Error{4214// , &[_]Error{
4215// .ExpectedToken,4215// .expected_token,
4216// .ExpectedIdentifier,4216// .ExpectedIdentifier,
4217// .InvalidAnd,4217// .invalid_and,
4218// });4218// });
4219//}4219//}
42204220
...@@ -4224,15 +4224,15 @@ test "recovery: mismatched bracket at top level" {...@@ -4224,15 +4224,15 @@ test "recovery: mismatched bracket at top level" {
4224// \\ var sequence = "repeat".*** 10;4224// \\ var sequence = "repeat".*** 10;
4225// \\}4225// \\}
4226// , &[_]Error{4226// , &[_]Error{
4227// .AsteriskAfterPointerDereference,4227// .asterisk_after_ptr_deref,
4228// });4228// });
4229// try testError(4229// try testError(
4230// \\test "" {4230// \\test "" {
4231// \\ var sequence = "repeat".** 10&&a;4231// \\ var sequence = "repeat".** 10&&a;
4232// \\}4232// \\}
4233// , &[_]Error{4233// , &[_]Error{
4234// .AsteriskAfterPointerDereference,4234// .asterisk_after_ptr_deref,
4235// .InvalidAnd,4235// .invalid_and,
4236// });4236// });
4237//}4237//}
42384238
...@@ -4245,10 +4245,10 @@ test "recovery: mismatched bracket at top level" {...@@ -4245,10 +4245,10 @@ test "recovery: mismatched bracket at top level" {
4245// \\ a && b;4245// \\ a && b;
4246// \\}4246// \\}
4247// , &[_]Error{4247// , &[_]Error{
4248// .ExpectedSemiOrElse,4248// .expected_semi_or_else,
4249// .ExpectedSemiOrElse,4249// .expected_semi_or_else,
4250// .ExpectedSemiOrElse,4250// .expected_semi_or_else,
4251// .InvalidAnd,4251// .invalid_and,
4252// });4252// });
4253//}4253//}
42544254
...@@ -4256,7 +4256,7 @@ test "recovery: invalid comptime" {...@@ -4256,7 +4256,7 @@ test "recovery: invalid comptime" {
4256 try testError(4256 try testError(
4257 \\comptime4257 \\comptime
4258 , &[_]Error{4258 , &[_]Error{
4259 .ExpectedBlockOrField,4259 .expected_block_or_field,
4260 });4260 });
4261}4261}
42624262
...@@ -4264,12 +4264,12 @@ test "recovery: missing block after for/while loops" {...@@ -4264,12 +4264,12 @@ test "recovery: missing block after for/while loops" {
4264 try testError(4264 try testError(
4265 \\test "" { while (foo) }4265 \\test "" { while (foo) }
4266 , &[_]Error{4266 , &[_]Error{
4267 .ExpectedBlockOrAssignment,4267 .expected_block_or_assignment,
4268 });4268 });
4269 try testError(4269 try testError(
4270 \\test "" { for (foo) |bar| }4270 \\test "" { for (foo) |bar| }
4271 , &[_]Error{4271 , &[_]Error{
4272 .ExpectedBlockOrAssignment,4272 .expected_block_or_assignment,
4273 });4273 });
4274}4274}
42754275
...@@ -4288,9 +4288,8 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b...@@ -4288,9 +4288,8 @@ fn testParse(source: []const u8, allocator: *mem.Allocator, anything_changed: *b
4288 defer tree.deinit(allocator);4288 defer tree.deinit(allocator);
42894289
4290 for (tree.errors) |parse_error| {4290 for (tree.errors) |parse_error| {
4291 const error_token = tree.errorToken(parse_error);4291 const token_start = tree.tokens.items(.start)[parse_error.token];
4292 const token_start = tree.tokens.items(.start)[error_token];4292 const loc = tree.tokenLocation(0, parse_error.token);
4293 const loc = tree.tokenLocation(0, error_token);
4294 try stderr.print("(memory buffer):{d}:{d}: error: ", .{ loc.line + 1, loc.column + 1 });4293 try stderr.print("(memory buffer):{d}:{d}: error: ", .{ loc.line + 1, loc.column + 1 });
4295 try tree.renderError(parse_error, stderr);4294 try tree.renderError(parse_error, stderr);
4296 try stderr.print("\n{s}\n", .{source[loc.line_start..loc.line_end]});4295 try stderr.print("\n{s}\n", .{source[loc.line_start..loc.line_end]});
...@@ -4362,7 +4361,7 @@ fn testCanonical(source: []const u8) !void {...@@ -4362,7 +4361,7 @@ fn testCanonical(source: []const u8) !void {
4362 return testTransform(source, source);4361 return testTransform(source, source);
4363}4362}
43644363
4365const Error = std.meta.Tag(std.zig.ast.Error);4364const Error = std.zig.ast.Error.Tag;
43664365
4367fn testError(source: []const u8, expected_errors: []const Error) !void {4366fn testError(source: []const u8, expected_errors: []const Error) !void {
4368 var tree = try std.zig.parse(std.testing.allocator, source);4367 var tree = try std.zig.parse(std.testing.allocator, source);
...@@ -4370,6 +4369,6 @@ fn testError(source: []const u8, expected_errors: []const Error) !void {...@@ -4370,6 +4369,6 @@ fn testError(source: []const u8, expected_errors: []const Error) !void {
43704369
4371 std.testing.expect(tree.errors.len == expected_errors.len);4370 std.testing.expect(tree.errors.len == expected_errors.len);
4372 for (expected_errors) |expected, i| {4371 for (expected_errors) |expected, i| {
4373 std.testing.expectEqual(expected, tree.errors[i]);4372 std.testing.expectEqual(expected, tree.errors[i].tag);
4374 }4373 }
4375}4374}
src/Module.zig+1-1
...@@ -1723,7 +1723,7 @@ pub fn getAstTree(self: *Module, root_scope: *Scope.File) !*const ast.Tree {...@@ -1723,7 +1723,7 @@ pub fn getAstTree(self: *Module, root_scope: *Scope.File) !*const ast.Tree {
1723 err_msg.* = .{1723 err_msg.* = .{
1724 .src_loc = .{1724 .src_loc = .{
1725 .file_scope = root_scope,1725 .file_scope = root_scope,
1726 .byte_offset = tree.tokens.items(.start)[parse_err.loc()],1726 .byte_offset = tree.tokens.items(.start)[parse_err.token],
1727 },1727 },
1728 .msg = msg.toOwnedSlice(),1728 .msg = msg.toOwnedSlice(),
1729 };1729 };
src/main.zig+1-1
...@@ -2898,7 +2898,7 @@ fn printErrMsgToFile(...@@ -2898,7 +2898,7 @@ fn printErrMsgToFile(
2898 .on => true,2898 .on => true,
2899 .off => false,2899 .off => false,
2900 };2900 };
2901 const lok_token = parse_error.loc();2901 const lok_token = parse_error.token;
29022902
2903 const token_starts = tree.tokens.items(.start);2903 const token_starts = tree.tokens.items(.start);
2904 const token_tags = tree.tokens.items(.tag);2904 const token_tags = tree.tokens.items(.tag);