diff --git a/doc/langref.html.in b/doc/langref.html.in
index 8ba932c2bc..0b91420109 100644
--- a/doc/langref.html.in
+++ b/doc/langref.html.in
@@ -12094,7 +12094,9 @@ FnProto <- KEYWORD_fn IDENTIFIER? LPAREN ParamDeclList RPAREN ByteAlign? AddrSpa
VarDecl <- (KEYWORD_const / KEYWORD_var) IDENTIFIER (COLON TypeExpr)? ByteAlign? AddrSpace? LinkSection? (EQUAL Expr)? SEMICOLON
-ContainerField <- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
+ContainerField
+ <- doc_comment? KEYWORD_comptime? IDENTIFIER (COLON TypeExpr ByteAlign?)? (EQUAL Expr)?
+ / doc_comment? KEYWORD_comptime? (IDENTIFIER COLON)? !KEYWORD_fn TypeExpr ByteAlign? (EQUAL Expr)?
# *** Block Level ***
Statement
@@ -12479,8 +12481,8 @@ string_char
<- char_escape
/ [^\\"\n]
-container_doc_comment <- ('//!' [^\n]* [ \n]*)+
-doc_comment <- ('///' [^\n]* [ \n]*)+ skip
+container_doc_comment <- ('//!' [^\n]* [ \n]* skip)+
+doc_comment <- ('///' [^\n]* [ \n]* skip)+
line_comment <- '//' ![!/][^\n]* / '////' [^\n]*
line_string <- ("\\\\" [^\n]* [ \n]*)+
skip <- ([ \n] / line_comment)*
diff --git a/lib/std/zig/Ast.zig b/lib/std/zig/Ast.zig
index 74b1048470..6986424b5f 100644
--- a/lib/std/zig/Ast.zig
+++ b/lib/std/zig/Ast.zig
@@ -559,8 +559,7 @@ pub fn firstToken(tree: Ast, node: Node.Index) TokenIndex {
.container_field,
=> {
const name_token = main_tokens[n];
- if (token_tags[name_token + 1] != .colon) return name_token - end_offset;
- if (name_token > 0 and token_tags[name_token - 1] == .keyword_comptime) {
+ if (token_tags[name_token] != .keyword_comptime and name_token > 0 and token_tags[name_token - 1] == .keyword_comptime) {
end_offset += 1;
}
return name_token - end_offset;
diff --git a/lib/std/zig/parse.zig b/lib/std/zig/parse.zig
index ced4b05ba9..6fc82fcad5 100644
--- a/lib/std/zig/parse.zig
+++ b/lib/std/zig/parse.zig
@@ -313,7 +313,6 @@ const Parser = struct {
trailing = false;
},
else => {
- p.tok_i += 1;
const identifier = p.tok_i;
defer last_field = identifier;
const container_field = p.expectContainerField() catch |err| switch (err) {
diff --git a/lib/std/zig/parser_test.zig b/lib/std/zig/parser_test.zig
index e65a9fcaac..1b8a240642 100644
--- a/lib/std/zig/parser_test.zig
+++ b/lib/std/zig/parser_test.zig
@@ -1,7 +1,9 @@
test "zig fmt: tuple struct" {
try testCanonical(
\\const T = struct {
- \\ comptime u32,
+ \\ /// doc comment on tuple field
+ \\ comptime comptime u32,
+ \\ /// another doc comment on tuple field
\\ *u32 = 1,
\\ // needs to be wrapped in parentheses to not be parsed as a function decl
\\ (fn () void) align(1),
@@ -4238,6 +4240,18 @@ test "zig fmt: remove newlines surrounding doc comment within container decl" {
);
}
+test "zig fmt: comptime before comptime field" {
+ try testError(
+ \\const Foo = struct {
+ \\ a: i32,
+ \\ comptime comptime b: i32 = 1234,
+ \\};
+ \\
+ , &[_]Error{
+ .expected_comma_after_field,
+ });
+}
+
test "zig fmt: invalid else branch statement" {
try testError(
\\/// This is a doc comment for a comptime block.