Commit d7f9128b5d
Changed files (4)
lib
lib/std/zig/ast.zig
@@ -171,6 +171,7 @@ pub const Error = union(enum) {
ExpectedBlockOrField: ExpectedBlockOrField,
DeclBetweenFields: DeclBetweenFields,
InvalidAnd: InvalidAnd,
+ AsteriskAfterPointerDereference: AsteriskAfterPointerDereference,
pub fn render(self: *const Error, tokens: []const Token.Id, stream: anytype) !void {
switch (self.*) {
@@ -222,6 +223,7 @@ pub const Error = union(enum) {
.ExpectedBlockOrField => |*x| return x.render(tokens, stream),
.DeclBetweenFields => |*x| return x.render(tokens, stream),
.InvalidAnd => |*x| return x.render(tokens, stream),
+ .AsteriskAfterPointerDereference => |*x| return x.render(tokens, stream),
}
}
@@ -275,6 +277,7 @@ pub const Error = union(enum) {
.ExpectedBlockOrField => |x| return x.token,
.DeclBetweenFields => |x| return x.token,
.InvalidAnd => |x| return x.token,
+ .AsteriskAfterPointerDereference => |x| return x.token,
}
}
@@ -323,6 +326,7 @@ pub const Error = union(enum) {
pub const ExtraAllowZeroQualifier = SimpleError("Extra allowzero qualifier");
pub const DeclBetweenFields = SimpleError("Declarations are not allowed between container fields");
pub const InvalidAnd = SimpleError("`&&` is invalid. Note that `and` is boolean AND.");
+ pub const AsteriskAfterPointerDereference = SimpleError("`.*` can't be followed by `*`. Are you missing a space?");
pub const ExpectedCall = struct {
node: *Node,
lib/std/zig/parse.zig
@@ -2701,6 +2701,13 @@ const Parser = struct {
return &node.base;
}
+ if (p.token_ids[p.tok_i] == .Invalid_periodasterisks) {
+ try p.errors.append(p.gpa, .{
+ .AsteriskAfterPointerDereference = .{ .token = p.tok_i },
+ });
+ return null;
+ }
+
if (p.eatToken(.Period)) |period| {
if (try p.parseIdentifier()) |identifier| {
const node = try p.arena.allocator.create(Node.SimpleInfixOp);
lib/std/zig/parser_test.zig
@@ -219,6 +219,17 @@ test "recovery: invalid global error set access" {
});
}
+test "recovery: invalid asterisk after pointer dereference" {
+ try testError(
+ \\test "" {
+ \\ var sequence = "repeat".*** 10;
+ \\}
+ , &[_]Error{
+ .AsteriskAfterPointerDereference,
+ .ExpectedToken,
+ });
+}
+
test "recovery: missing semicolon after if, for, while stmt" {
try testError(
\\test "" {
lib/std/zig/tokenizer.zig
@@ -78,6 +78,7 @@ pub const Token = struct {
pub const Id = enum {
Invalid,
Invalid_ampersands,
+ Invalid_periodasterisks,
Identifier,
StringLiteral,
MultilineStringLiteralLine,
@@ -201,6 +202,7 @@ pub const Token = struct {
return switch (id) {
.Invalid => "Invalid",
.Invalid_ampersands => "&&",
+ .Invalid_periodasterisks => ".**",
.Identifier => "Identifier",
.StringLiteral => "StringLiteral",
.MultilineStringLiteralLine => "MultilineStringLiteralLine",
@@ -1002,13 +1004,13 @@ pub const Tokenizer = struct {
.period_asterisk => switch (c) {
'*' => {
- result.id = .Invalid;
+ result.id = .Invalid_periodasterisks;
break;
},
else => {
result.id = .PeriodAsterisk;
break;
- }
+ },
},
.slash => switch (c) {
@@ -1794,7 +1796,7 @@ test "correctly parse pointer dereference followed by asterisk" {
testTokenize("\"b\".*** 10", &[_]Token.Id{
.StringLiteral,
- .Invalid,
+ .Invalid_periodasterisks,
.AsteriskAsterisk,
.IntegerLiteral,
});