mirror of
https://github.com/ziglang/zig.git
synced 2026-01-21 06:45:24 +00:00
parser: warn on missing for loop payload, recover from invalid global error set access
This commit is contained in:
parent
621ad241d6
commit
67dac2936c
@ -253,6 +253,11 @@ pub const Tree = struct {
|
||||
token_tags[parse_error.token].symbol(),
|
||||
});
|
||||
},
|
||||
.expected_loop_payload => {
|
||||
return stream.print("expected loop payload, found '{s}'", .{
|
||||
token_tags[parse_error.token].symbol(),
|
||||
});
|
||||
},
|
||||
.extra_align_qualifier => {
|
||||
return stream.writeAll("extra align qualifier");
|
||||
},
|
||||
@ -2332,6 +2337,7 @@ pub const Error = struct {
|
||||
expected_type_expr,
|
||||
expected_var_decl,
|
||||
expected_var_decl_or_fn,
|
||||
expected_loop_payload,
|
||||
extra_align_qualifier,
|
||||
extra_allowzero_qualifier,
|
||||
extra_const_qualifier,
|
||||
|
||||
@ -1052,7 +1052,8 @@ const Parser = struct {
|
||||
_ = try p.expectToken(.l_paren);
|
||||
const array_expr = try p.expectExpr();
|
||||
_ = try p.expectToken(.r_paren);
|
||||
_ = try p.parsePtrIndexPayload();
|
||||
const found_payload = try p.parsePtrIndexPayload();
|
||||
if (found_payload == 0) try p.warn(.expected_loop_payload);
|
||||
|
||||
// TODO propose to change the syntax so that semicolons are always required
|
||||
// inside while statements, even if there is an `else`.
|
||||
@ -2067,7 +2068,8 @@ const Parser = struct {
|
||||
_ = try p.expectToken(.l_paren);
|
||||
const array_expr = try p.expectExpr();
|
||||
_ = try p.expectToken(.r_paren);
|
||||
_ = try p.parsePtrIndexPayload();
|
||||
const found_payload = try p.parsePtrIndexPayload();
|
||||
if (found_payload == 0) try p.warn(.expected_loop_payload);
|
||||
|
||||
const then_expr = try p.expectExpr();
|
||||
const else_token = p.eatToken(.keyword_else) orelse {
|
||||
@ -2672,6 +2674,16 @@ const Parser = struct {
|
||||
},
|
||||
}),
|
||||
},
|
||||
.keyword_inline => {
|
||||
p.tok_i += 1;
|
||||
switch (p.token_tags[p.tok_i]) {
|
||||
.keyword_for => return p.parseForTypeExpr(),
|
||||
.keyword_while => return p.parseWhileTypeExpr(),
|
||||
else => return p.fail(.expected_inlinable),
|
||||
}
|
||||
},
|
||||
.keyword_for => return p.parseForTypeExpr(),
|
||||
.keyword_while => return p.parseWhileTypeExpr(),
|
||||
.period => switch (p.token_tags[p.tok_i + 1]) {
|
||||
.identifier => return p.addNode(.{
|
||||
.tag = .enum_literal,
|
||||
@ -2879,14 +2891,21 @@ const Parser = struct {
|
||||
},
|
||||
});
|
||||
},
|
||||
else => return p.addNode(.{
|
||||
.tag = .error_value,
|
||||
.main_token = p.nextToken(),
|
||||
.data = .{
|
||||
.lhs = try p.expectToken(.period),
|
||||
.rhs = try p.expectToken(.identifier),
|
||||
},
|
||||
}),
|
||||
else => {
|
||||
const main_token = p.nextToken();
|
||||
const period = p.eatToken(.period);
|
||||
if (period == null) try p.warnExpected(.period);
|
||||
const identifier = p.eatToken(.identifier);
|
||||
if (identifier == null) try p.warnExpected(.identifier);
|
||||
return p.addNode(.{
|
||||
.tag = .error_value,
|
||||
.main_token = main_token,
|
||||
.data = .{
|
||||
.lhs = period orelse 0,
|
||||
.rhs = identifier orelse 0,
|
||||
},
|
||||
});
|
||||
},
|
||||
},
|
||||
.l_paren => return p.addNode(.{
|
||||
.tag = .grouped_expression,
|
||||
@ -2913,9 +2932,10 @@ const Parser = struct {
|
||||
fn parseForTypeExpr(p: *Parser) !Node.Index {
|
||||
const for_token = p.eatToken(.keyword_for) orelse return null_node;
|
||||
_ = try p.expectToken(.l_paren);
|
||||
const array_expr = try p.expectTypeExpr();
|
||||
const array_expr = try p.expectExpr();
|
||||
_ = try p.expectToken(.r_paren);
|
||||
_ = try p.parsePtrIndexPayload();
|
||||
const found_payload = try p.parsePtrIndexPayload();
|
||||
if (found_payload == 0) try p.warn(.expected_loop_payload);
|
||||
|
||||
const then_expr = try p.expectExpr();
|
||||
const else_token = p.eatToken(.keyword_else) orelse {
|
||||
|
||||
@ -4215,6 +4215,8 @@ test "recovery: invalid global error set access" {
|
||||
\\}
|
||||
, &[_]Error{
|
||||
.expected_token,
|
||||
.expected_token,
|
||||
.invalid_and,
|
||||
});
|
||||
}
|
||||
|
||||
@ -4273,6 +4275,20 @@ test "recovery: missing block after for/while loops" {
|
||||
});
|
||||
}
|
||||
|
||||
test "recovery: missing for payload" {
|
||||
try testError(
|
||||
\\comptime {
|
||||
\\ const a = for(a) {};
|
||||
\\ const a: for(a) {};
|
||||
\\ for(a) {}
|
||||
\\}
|
||||
, &[_]Error{
|
||||
.expected_loop_payload,
|
||||
.expected_loop_payload,
|
||||
.expected_loop_payload,
|
||||
});
|
||||
}
|
||||
|
||||
const std = @import("std");
|
||||
const mem = std.mem;
|
||||
const warn = std.debug.warn;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user