authorgravatar for greenfork.lists@yandex.comDmitry Matveyev <greenfork.lists@yandex.com> 2021-06-21 00:04:14+06:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2021-06-20 21:04:14+03:00
log00982f75e92119aac6182ab9876adfb13305d1ed
tree6ee0b5c6964620a1263eb44498bf1905e20915ec
parente4225ca5f76760568c632d1f1c455e9d8759dce1
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

stage2: Remove special double ampersand parsing case (#9114)

* Remove parser error on double ampersand * Add failing test for double ampersand case * Add error when encountering double ampersand in AstGen "Bit and" operator should not make sense when one of its operands is an address. * Check that 2 ampersands are adjacent to each other in source string * Remove cases of unused variables in tests

7 files changed, 41 insertions(+), 29 deletions(-)

doc/docgen.zig+1-1
...@@ -999,7 +999,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: anytype, source_token:...@@ -999,7 +999,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: anytype, source_token:
999 .tilde,999 .tilde,
1000 => try writeEscaped(out, src[token.loc.start..token.loc.end]),1000 => try writeEscaped(out, src[token.loc.start..token.loc.end]),
10011001
1002 .invalid, .invalid_ampersands, .invalid_periodasterisks => return parseError(1002 .invalid, .invalid_periodasterisks => return parseError(
1003 docgen_tokenizer,1003 docgen_tokenizer,
1004 source_token,1004 source_token,
1005 "syntax error",1005 "syntax error",
lib/std/zig/ast.zig-4
...@@ -280,9 +280,6 @@ pub const Tree = struct {...@@ -280,9 +280,6 @@ pub const Tree = struct {
280 token_tags[parse_error.token].symbol(),280 token_tags[parse_error.token].symbol(),
281 });281 });
282 },282 },
283 .invalid_and => {
284 return stream.writeAll("`&&` is invalid; note that `and` is boolean AND");
285 },
286 .invalid_bit_range => {283 .invalid_bit_range => {
287 return stream.writeAll("bit range not allowed on slices and arrays");284 return stream.writeAll("bit range not allowed on slices and arrays");
288 },285 },
...@@ -2412,7 +2409,6 @@ pub const Error = struct {...@@ -2412,7 +2409,6 @@ pub const Error = struct {
2412 extra_const_qualifier,2409 extra_const_qualifier,
2413 extra_volatile_qualifier,2410 extra_volatile_qualifier,
2414 ptr_mod_on_array_child_type,2411 ptr_mod_on_array_child_type,
2415 invalid_and,
2416 invalid_bit_range,2412 invalid_bit_range,
2417 invalid_token,2413 invalid_token,
2418 same_line_doc_comment,2414 same_line_doc_comment,
lib/std/zig/parse.zig-4
...@@ -1333,7 +1333,6 @@ const Parser = struct {...@@ -1333,7 +1333,6 @@ const Parser = struct {
1333 .keyword_or = .{ .prec = 10, .tag = .bool_or },1333 .keyword_or = .{ .prec = 10, .tag = .bool_or },
13341334
1335 .keyword_and = .{ .prec = 20, .tag = .bool_and },1335 .keyword_and = .{ .prec = 20, .tag = .bool_and },
1336 .invalid_ampersands = .{ .prec = 20, .tag = .bool_and },
13371336
1338 .equal_equal = .{ .prec = 30, .tag = .equal_equal, .assoc = Assoc.none },1337 .equal_equal = .{ .prec = 30, .tag = .equal_equal, .assoc = Assoc.none },
1339 .bang_equal = .{ .prec = 30, .tag = .bang_equal, .assoc = Assoc.none },1338 .bang_equal = .{ .prec = 30, .tag = .bang_equal, .assoc = Assoc.none },
...@@ -1385,9 +1384,6 @@ const Parser = struct {...@@ -1385,9 +1384,6 @@ const Parser = struct {
1385 .keyword_catch => {1384 .keyword_catch => {
1386 _ = try p.parsePayload();1385 _ = try p.parsePayload();
1387 },1386 },
1388 .invalid_ampersands => {
1389 try p.warn(.invalid_and);
1390 },
1391 else => {},1387 else => {},
1392 }1388 }
1393 const rhs = try p.parseExprPrecedence(info.prec + 1);1389 const rhs = try p.parseExprPrecedence(info.prec + 1);
lib/std/zig/parser_test.zig-12
...@@ -4930,7 +4930,6 @@ test "recovery: missing comma" {...@@ -4930,7 +4930,6 @@ test "recovery: missing comma" {
4930 , &[_]Error{4930 , &[_]Error{
4931 .expected_token,4931 .expected_token,
4932 .expected_token,4932 .expected_token,
4933 .invalid_and,
4934 .invalid_token,4933 .invalid_token,
4935 });4934 });
4936}4935}
...@@ -4963,7 +4962,6 @@ test "recovery: missing return type" {...@@ -4963,7 +4962,6 @@ test "recovery: missing return type" {
4963 \\test ""4962 \\test ""
4964 , &[_]Error{4963 , &[_]Error{
4965 .expected_return_type,4964 .expected_return_type,
4966 .invalid_and,
4967 .expected_block,4965 .expected_block,
4968 });4966 });
4969}4967}
...@@ -4980,7 +4978,6 @@ test "recovery: continue after invalid decl" {...@@ -4980,7 +4978,6 @@ test "recovery: continue after invalid decl" {
4980 .expected_token,4978 .expected_token,
4981 .expected_pub_item,4979 .expected_pub_item,
4982 .expected_param_list,4980 .expected_param_list,
4983 .invalid_and,
4984 });4981 });
4985 try testError(4982 try testError(
4986 \\threadlocal test "" {4983 \\threadlocal test "" {
...@@ -4989,7 +4986,6 @@ test "recovery: continue after invalid decl" {...@@ -4989,7 +4986,6 @@ test "recovery: continue after invalid decl" {
4989 , &[_]Error{4986 , &[_]Error{
4990 .expected_var_decl,4987 .expected_var_decl,
4991 .expected_param_list,4988 .expected_param_list,
4992 .invalid_and,
4993 });4989 });
4994}4990}
49954991
...@@ -4998,13 +4994,11 @@ test "recovery: invalid extern/inline" {...@@ -4998,13 +4994,11 @@ test "recovery: invalid extern/inline" {
4998 \\inline test "" { a && b; }4994 \\inline test "" { a && b; }
4999 , &[_]Error{4995 , &[_]Error{
5000 .expected_fn,4996 .expected_fn,
5001 .invalid_and,
5002 });4997 });
5003 try testError(4998 try testError(
5004 \\extern "" test "" { a && b; }4999 \\extern "" test "" { a && b; }
5005 , &[_]Error{5000 , &[_]Error{
5006 .expected_var_decl_or_fn,5001 .expected_var_decl_or_fn,
5007 .invalid_and,
5008 });5002 });
5009}5003}
50105004
...@@ -5016,9 +5010,7 @@ test "recovery: missing semicolon" {...@@ -5016,9 +5010,7 @@ test "recovery: missing semicolon" {
5016 \\ @foo5010 \\ @foo
5017 \\}5011 \\}
5018 , &[_]Error{5012 , &[_]Error{
5019 .invalid_and,
5020 .expected_token,5013 .expected_token,
5021 .invalid_and,
5022 .expected_token,5014 .expected_token,
5023 .expected_param_list,5015 .expected_param_list,
5024 .expected_token,5016 .expected_token,
...@@ -5038,7 +5030,6 @@ test "recovery: invalid container members" {...@@ -5038,7 +5030,6 @@ test "recovery: invalid container members" {
5038 .expected_expr,5030 .expected_expr,
5039 .expected_token,5031 .expected_token,
5040 .expected_container_members,5032 .expected_container_members,
5041 .invalid_and,
5042 .expected_token,5033 .expected_token,
5043 });5034 });
5044}5035}
...@@ -5076,7 +5067,6 @@ test "recovery: invalid global error set access" {...@@ -5076,7 +5067,6 @@ test "recovery: invalid global error set access" {
5076 , &[_]Error{5067 , &[_]Error{
5077 .expected_token,5068 .expected_token,
5078 .expected_token,5069 .expected_token,
5079 .invalid_and,
5080 });5070 });
5081}5071}
50825072
...@@ -5094,7 +5084,6 @@ test "recovery: invalid asterisk after pointer dereference" {...@@ -5094,7 +5084,6 @@ test "recovery: invalid asterisk after pointer dereference" {
5094 \\}5084 \\}
5095 , &[_]Error{5085 , &[_]Error{
5096 .asterisk_after_ptr_deref,5086 .asterisk_after_ptr_deref,
5097 .invalid_and,
5098 });5087 });
5099}5088}
51005089
...@@ -5110,7 +5099,6 @@ test "recovery: missing semicolon after if, for, while stmt" {...@@ -5110,7 +5099,6 @@ test "recovery: missing semicolon after if, for, while stmt" {
5110 .expected_semi_or_else,5099 .expected_semi_or_else,
5111 .expected_semi_or_else,5100 .expected_semi_or_else,
5112 .expected_semi_or_else,5101 .expected_semi_or_else,
5113 .invalid_and,
5114 });5102 });
5115}5103}
51165104
lib/std/zig/tokenizer.zig-7
...@@ -76,7 +76,6 @@ pub const Token = struct {...@@ -76,7 +76,6 @@ pub const Token = struct {
7676
77 pub const Tag = enum {77 pub const Tag = enum {
78 invalid,78 invalid,
79 invalid_ampersands,
80 invalid_periodasterisks,79 invalid_periodasterisks,
81 identifier,80 identifier,
82 string_literal,81 string_literal,
...@@ -210,7 +209,6 @@ pub const Token = struct {...@@ -210,7 +209,6 @@ pub const Token = struct {
210 .container_doc_comment,209 .container_doc_comment,
211 => null,210 => null,
212211
213 .invalid_ampersands => "&&",
214 .invalid_periodasterisks => ".**",212 .invalid_periodasterisks => ".**",
215 .bang => "!",213 .bang => "!",
216 .pipe => "|",214 .pipe => "|",
...@@ -579,11 +577,6 @@ pub const Tokenizer = struct {...@@ -579,11 +577,6 @@ pub const Tokenizer = struct {
579 },577 },
580578
581 .ampersand => switch (c) {579 .ampersand => switch (c) {
582 '&' => {
583 result.tag = .invalid_ampersands;
584 self.index += 1;
585 break;
586 },
587 '=' => {580 '=' => {
588 result.tag = .ampersand_equal;581 result.tag = .ampersand_equal;
589 self.index += 1;582 self.index += 1;
src/AstGen.zig+17-1
...@@ -551,7 +551,23 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr...@@ -551,7 +551,23 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
551 .mul_wrap => return simpleBinOp(gz, scope, rl, node, .mulwrap),551 .mul_wrap => return simpleBinOp(gz, scope, rl, node, .mulwrap),
552 .div => return simpleBinOp(gz, scope, rl, node, .div),552 .div => return simpleBinOp(gz, scope, rl, node, .div),
553 .mod => return simpleBinOp(gz, scope, rl, node, .mod_rem),553 .mod => return simpleBinOp(gz, scope, rl, node, .mod_rem),
554 .bit_and => return simpleBinOp(gz, scope, rl, node, .bit_and),554 .bit_and => {
555 const current_ampersand_token = main_tokens[node];
556 if (token_tags[current_ampersand_token + 1] == .ampersand) {
557 const token_starts = tree.tokens.items(.start);
558 const current_token_offset = token_starts[current_ampersand_token];
559 const next_token_offset = token_starts[current_ampersand_token + 1];
560 if (current_token_offset + 1 == next_token_offset) {
561 return astgen.failTok(
562 current_ampersand_token,
563 "`&&` is invalid; note that `and` is boolean AND",
564 .{},
565 );
566 }
567 }
568
569 return simpleBinOp(gz, scope, rl, node, .bit_and);
570 },
555 .bit_or => return simpleBinOp(gz, scope, rl, node, .bit_or),571 .bit_or => return simpleBinOp(gz, scope, rl, node, .bit_or),
556 .bit_xor => return simpleBinOp(gz, scope, rl, node, .xor),572 .bit_xor => return simpleBinOp(gz, scope, rl, node, .xor),
557573
test/stage2/test.zig+23
...@@ -1565,4 +1565,27 @@ pub fn addCases(ctx: *TestContext) !void {...@@ -1565,4 +1565,27 @@ pub fn addCases(ctx: *TestContext) !void {
1565 \\}1565 \\}
1566 , "HeHelHellHello");1566 , "HeHelHellHello");
1567 }1567 }
1568
1569 {
1570 var case = ctx.exe("double ampersand", linux_x64);
1571
1572 case.addError(
1573 \\pub const a = if (true && false) 1 else 2;
1574 , &[_][]const u8{":1:24: error: `&&` is invalid; note that `and` is boolean AND"});
1575
1576 case.addError(
1577 \\pub fn main() void {
1578 \\ const a = true;
1579 \\ const b = false;
1580 \\ _ = a & &b;
1581 \\}
1582 , &[_][]const u8{":4:11: error: incompatible types: 'bool' and '*const bool'"});
1583
1584 case.addCompareOutput(
1585 \\pub fn main() void {
1586 \\ const b: u8 = 1;
1587 \\ _ = &&b;
1588 \\}
1589 , "");
1590 }
1568}1591}