mirror of
https://github.com/ziglang/zig.git
synced 2025-01-19 08:22:43 +00:00
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
This commit is contained in:
parent
e4225ca5f7
commit
00982f75e9
@ -999,7 +999,7 @@ fn tokenizeAndPrintRaw(docgen_tokenizer: *Tokenizer, out: anytype, source_token:
|
||||
.tilde,
|
||||
=> try writeEscaped(out, src[token.loc.start..token.loc.end]),
|
||||
|
||||
.invalid, .invalid_ampersands, .invalid_periodasterisks => return parseError(
|
||||
.invalid, .invalid_periodasterisks => return parseError(
|
||||
docgen_tokenizer,
|
||||
source_token,
|
||||
"syntax error",
|
||||
|
@ -280,9 +280,6 @@ pub const Tree = struct {
|
||||
token_tags[parse_error.token].symbol(),
|
||||
});
|
||||
},
|
||||
.invalid_and => {
|
||||
return stream.writeAll("`&&` is invalid; note that `and` is boolean AND");
|
||||
},
|
||||
.invalid_bit_range => {
|
||||
return stream.writeAll("bit range not allowed on slices and arrays");
|
||||
},
|
||||
@ -2412,7 +2409,6 @@ pub const Error = struct {
|
||||
extra_const_qualifier,
|
||||
extra_volatile_qualifier,
|
||||
ptr_mod_on_array_child_type,
|
||||
invalid_and,
|
||||
invalid_bit_range,
|
||||
invalid_token,
|
||||
same_line_doc_comment,
|
||||
|
@ -1333,7 +1333,6 @@ const Parser = struct {
|
||||
.keyword_or = .{ .prec = 10, .tag = .bool_or },
|
||||
|
||||
.keyword_and = .{ .prec = 20, .tag = .bool_and },
|
||||
.invalid_ampersands = .{ .prec = 20, .tag = .bool_and },
|
||||
|
||||
.equal_equal = .{ .prec = 30, .tag = .equal_equal, .assoc = Assoc.none },
|
||||
.bang_equal = .{ .prec = 30, .tag = .bang_equal, .assoc = Assoc.none },
|
||||
@ -1385,9 +1384,6 @@ const Parser = struct {
|
||||
.keyword_catch => {
|
||||
_ = try p.parsePayload();
|
||||
},
|
||||
.invalid_ampersands => {
|
||||
try p.warn(.invalid_and);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
const rhs = try p.parseExprPrecedence(info.prec + 1);
|
||||
|
@ -4930,7 +4930,6 @@ test "recovery: missing comma" {
|
||||
, &[_]Error{
|
||||
.expected_token,
|
||||
.expected_token,
|
||||
.invalid_and,
|
||||
.invalid_token,
|
||||
});
|
||||
}
|
||||
@ -4963,7 +4962,6 @@ test "recovery: missing return type" {
|
||||
\\test ""
|
||||
, &[_]Error{
|
||||
.expected_return_type,
|
||||
.invalid_and,
|
||||
.expected_block,
|
||||
});
|
||||
}
|
||||
@ -4980,7 +4978,6 @@ test "recovery: continue after invalid decl" {
|
||||
.expected_token,
|
||||
.expected_pub_item,
|
||||
.expected_param_list,
|
||||
.invalid_and,
|
||||
});
|
||||
try testError(
|
||||
\\threadlocal test "" {
|
||||
@ -4989,7 +4986,6 @@ test "recovery: continue after invalid decl" {
|
||||
, &[_]Error{
|
||||
.expected_var_decl,
|
||||
.expected_param_list,
|
||||
.invalid_and,
|
||||
});
|
||||
}
|
||||
|
||||
@ -4998,13 +4994,11 @@ test "recovery: invalid extern/inline" {
|
||||
\\inline test "" { a && b; }
|
||||
, &[_]Error{
|
||||
.expected_fn,
|
||||
.invalid_and,
|
||||
});
|
||||
try testError(
|
||||
\\extern "" test "" { a && b; }
|
||||
, &[_]Error{
|
||||
.expected_var_decl_or_fn,
|
||||
.invalid_and,
|
||||
});
|
||||
}
|
||||
|
||||
@ -5016,9 +5010,7 @@ test "recovery: missing semicolon" {
|
||||
\\ @foo
|
||||
\\}
|
||||
, &[_]Error{
|
||||
.invalid_and,
|
||||
.expected_token,
|
||||
.invalid_and,
|
||||
.expected_token,
|
||||
.expected_param_list,
|
||||
.expected_token,
|
||||
@ -5038,7 +5030,6 @@ test "recovery: invalid container members" {
|
||||
.expected_expr,
|
||||
.expected_token,
|
||||
.expected_container_members,
|
||||
.invalid_and,
|
||||
.expected_token,
|
||||
});
|
||||
}
|
||||
@ -5076,7 +5067,6 @@ test "recovery: invalid global error set access" {
|
||||
, &[_]Error{
|
||||
.expected_token,
|
||||
.expected_token,
|
||||
.invalid_and,
|
||||
});
|
||||
}
|
||||
|
||||
@ -5094,7 +5084,6 @@ test "recovery: invalid asterisk after pointer dereference" {
|
||||
\\}
|
||||
, &[_]Error{
|
||||
.asterisk_after_ptr_deref,
|
||||
.invalid_and,
|
||||
});
|
||||
}
|
||||
|
||||
@ -5110,7 +5099,6 @@ test "recovery: missing semicolon after if, for, while stmt" {
|
||||
.expected_semi_or_else,
|
||||
.expected_semi_or_else,
|
||||
.expected_semi_or_else,
|
||||
.invalid_and,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -76,7 +76,6 @@ pub const Token = struct {
|
||||
|
||||
pub const Tag = enum {
|
||||
invalid,
|
||||
invalid_ampersands,
|
||||
invalid_periodasterisks,
|
||||
identifier,
|
||||
string_literal,
|
||||
@ -210,7 +209,6 @@ pub const Token = struct {
|
||||
.container_doc_comment,
|
||||
=> null,
|
||||
|
||||
.invalid_ampersands => "&&",
|
||||
.invalid_periodasterisks => ".**",
|
||||
.bang => "!",
|
||||
.pipe => "|",
|
||||
@ -579,11 +577,6 @@ pub const Tokenizer = struct {
|
||||
},
|
||||
|
||||
.ampersand => switch (c) {
|
||||
'&' => {
|
||||
result.tag = .invalid_ampersands;
|
||||
self.index += 1;
|
||||
break;
|
||||
},
|
||||
'=' => {
|
||||
result.tag = .ampersand_equal;
|
||||
self.index += 1;
|
||||
|
@ -551,7 +551,23 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerEr
|
||||
.mul_wrap => return simpleBinOp(gz, scope, rl, node, .mulwrap),
|
||||
.div => return simpleBinOp(gz, scope, rl, node, .div),
|
||||
.mod => return simpleBinOp(gz, scope, rl, node, .mod_rem),
|
||||
.bit_and => return simpleBinOp(gz, scope, rl, node, .bit_and),
|
||||
.bit_and => {
|
||||
const current_ampersand_token = main_tokens[node];
|
||||
if (token_tags[current_ampersand_token + 1] == .ampersand) {
|
||||
const token_starts = tree.tokens.items(.start);
|
||||
const current_token_offset = token_starts[current_ampersand_token];
|
||||
const next_token_offset = token_starts[current_ampersand_token + 1];
|
||||
if (current_token_offset + 1 == next_token_offset) {
|
||||
return astgen.failTok(
|
||||
current_ampersand_token,
|
||||
"`&&` is invalid; note that `and` is boolean AND",
|
||||
.{},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return simpleBinOp(gz, scope, rl, node, .bit_and);
|
||||
},
|
||||
.bit_or => return simpleBinOp(gz, scope, rl, node, .bit_or),
|
||||
.bit_xor => return simpleBinOp(gz, scope, rl, node, .xor),
|
||||
|
||||
|
@ -1565,4 +1565,27 @@ pub fn addCases(ctx: *TestContext) !void {
|
||||
\\}
|
||||
, "HeHelHellHello");
|
||||
}
|
||||
|
||||
{
|
||||
var case = ctx.exe("double ampersand", linux_x64);
|
||||
|
||||
case.addError(
|
||||
\\pub const a = if (true && false) 1 else 2;
|
||||
, &[_][]const u8{":1:24: error: `&&` is invalid; note that `and` is boolean AND"});
|
||||
|
||||
case.addError(
|
||||
\\pub fn main() void {
|
||||
\\ const a = true;
|
||||
\\ const b = false;
|
||||
\\ _ = a & &b;
|
||||
\\}
|
||||
, &[_][]const u8{":4:11: error: incompatible types: 'bool' and '*const bool'"});
|
||||
|
||||
case.addCompareOutput(
|
||||
\\pub fn main() void {
|
||||
\\ const b: u8 = 1;
|
||||
\\ _ = &&b;
|
||||
\\}
|
||||
, "");
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user