diff options
| author | Matthew Borkowski <matthew.h.borkowski@gmail.com> | 2021-12-02 03:50:23 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2021-12-02 11:59:29 -0800 |
| commit | c98b020ce29467e80217718e0a1856b7fccd6b53 (patch) | |
| tree | a8b4385bc6d9403d8762f63329d423a2789487f3 /lib/std | |
| parent | fb9fcf5632468b2aa8af73f4e3269a01535076f5 (diff) | |
| download | zig-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.zig | 4 | ||||
| -rw-r--r-- | lib/std/zig/parse.zig | 6 | ||||
| -rw-r--r-- | lib/std/zig/parser_test.zig | 4 |
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, }); } |
