aboutsummaryrefslogtreecommitdiff
path: root/lib/std
diff options
context:
space:
mode:
authorMatthew Borkowski <matthew.h.borkowski@gmail.com>2021-12-02 03:50:23 -0500
committerAndrew Kelley <andrew@ziglang.org>2021-12-02 11:59:29 -0800
commitc98b020ce29467e80217718e0a1856b7fccd6b53 (patch)
treea8b4385bc6d9403d8762f63329d423a2789487f3 /lib/std
parentfb9fcf5632468b2aa8af73f4e3269a01535076f5 (diff)
downloadzig-c98b020ce29467e80217718e0a1856b7fccd6b53.tar.gz
zig-c98b020ce29467e80217718e0a1856b7fccd6b53.zip
parse.zig: make chained comparison operators a parse error
Diffstat (limited to 'lib/std')
-rw-r--r--lib/std/zig/Ast.zig4
-rw-r--r--lib/std/zig/parse.zig6
-rw-r--r--lib/std/zig/parser_test.zig4
3 files changed, 11 insertions, 3 deletions
diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig
index 7729805c88..da8616ed9e 100644
--- a/lib/std/zig/Ast.zig
+++ b/lib/std/zig/Ast.zig
@@ -136,6 +136,9 @@ pub fn renderError(tree: Tree, parse_error: Error, stream: anytype) !void {
// location would point to the `*` after the `.*`.
return stream.writeAll("'.*' cannot be followed by '*'. Are you missing a space?");
},
+ .chained_comparison_operators => {
+ return stream.writeAll("comparison operators cannot be chained");
+ },
.decl_between_fields => {
return stream.writeAll("declarations are not allowed between container fields");
},
@@ -2424,6 +2427,7 @@ pub const Error = struct {
pub const Tag = enum {
asterisk_after_ptr_deref,
+ chained_comparison_operators,
decl_between_fields,
expected_block,
expected_block_or_assignment,
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index 89abb35006..28219fa085 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -1374,6 +1374,7 @@ const Parser = struct {
});
fn parseExprPrecedence(p: *Parser, min_prec: i32) Error!Node.Index {
+ assert(min_prec >= 0);
var node = try p.parsePrefixExpr();
if (node == 0) {
return null_node;
@@ -1384,9 +1385,12 @@ const Parser = struct {
while (true) {
const tok_tag = p.token_tags[p.tok_i];
const info = operTable[@intCast(usize, @enumToInt(tok_tag))];
- if (info.prec < min_prec or info.prec == banned_prec) {
+ if (info.prec < min_prec) {
break;
}
+ if (info.prec == banned_prec) {
+ return p.fail(.chained_comparison_operators);
+ }
const oper_token = p.nextToken();
// Special-case handling for "catch" and "&&".
switch (tok_tag) {
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index ef716ffb32..b4cc67de28 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -5056,8 +5056,8 @@ test "recovery: non-associative operators" {
\\const x = a == b == c;
\\const x = a == b != c;
, &[_]Error{
- .expected_token,
- .expected_token,
+ .chained_comparison_operators,
+ .chained_comparison_operators,
});
}